diff --git a/Code/GameLogic/Camera.cpp b/Code/GameLogic/Camera.cpp
new file mode 100644
index 00000000..bad0bdf9
--- /dev/null
+++ b/Code/GameLogic/Camera.cpp
@@ -0,0 +1,182 @@
+#include "Camera.h"
+
+Camera::Camera()
+{
+ this->m_position = Oyster::Math::Float3(0, 50, 0);
+ this->mRight = Oyster::Math::Float3(1, 0, 0);
+ this->mUp = Oyster::Math::Float3(0, 1, 0);
+ this->mLook = Oyster::Math::Float3(0, 0, 1);
+}
+
+Camera::~Camera()
+{
+}
+
+void Camera::SetPosition(const Oyster::Math::Float3& v)
+{
+ this->m_position = v;
+}
+
+Oyster::Math::Float3 Camera::GetPosition()const
+{
+ return this->m_position;
+}
+
+Oyster::Math::Float3 Camera::GetRight()const
+{
+ return this->mRight;
+}
+
+Oyster::Math::Float3 Camera::GetUp()const
+{
+ return this->mUp;
+}
+
+Oyster::Math::Float3 Camera::GetLook()const
+{
+ return this->mLook;
+}
+
+float Camera::GetNearZ()const
+{
+ return this->mNearZ;
+}
+
+float Camera::GetFarZ()const
+{
+ return this->mFarZ;
+}
+
+float Camera::GetAspect()const
+{
+ return this->mAspect;
+}
+
+Oyster::Math::Float3 Camera::CrossMatrix(const Oyster::Math::Float3& vector, const Oyster::Math::Float4x4& matrix)
+{
+ Oyster::Math::Float3 vec;
+ vec.x = matrix.m11*vector.x + matrix.m12*vector.y + matrix.m13*vector.z;
+ vec.y = matrix.m21*vector.x + matrix.m22*vector.y + matrix.m23*vector.z;
+ vec.z = matrix.m31*vector.x + matrix.m32*vector.y + matrix.m33*vector.z;
+ return vec;
+}
+
+void Camera::SetLens(float fovY, float aspect, float zn, float zf)
+{
+ this->mFovY = fovY;
+ this->mAspect = aspect;
+ this->mNearZ = zn;
+ this->mFarZ = zf;
+
+ float yScale = tan((Oyster::Math::pi*0.5f) - (mFovY*0.5f));
+ float xScale = yScale/this->mAspect;
+
+ mProj = Oyster::Math::Float4x4(xScale, 0, 0, 0,
+ 0, yScale, 0, 0,
+ 0, 0, zf/(zf-zn), 1,
+ 0, 0, -zn*zf/(zf-zn), 0);
+}
+
+void Camera::LookAt(Oyster::Math::Float3 pos, Oyster::Math::Float3 target, Oyster::Math::Float3 worldUp)
+{
+ Oyster::Math::Float3 L;
+
+ D3DXVec3Subtract(&L, &target, &pos);
+ L = target - pos;
+ D3DXVec3Normalize(&L, &L);
+ Oyster::Math::Float3 R;
+ D3DXVec3Cross(&R, &worldUp, &L);
+ D3DXVec3Normalize(&R, &R);
+ Oyster::Math::Float3 U;
+ D3DXVec3Cross(&U, &L, &R);
+
+ this->m_position = pos;
+ this->mLook = L;
+ this->mRight = R;
+ this->mUp = U;
+}
+
+Oyster::Math::Float4x4 Camera::View()const
+{
+ return this->mView;
+}
+
+Oyster::Math::Float4x4 Camera::Proj()const
+{
+ return this->mProj;
+}
+
+Oyster::Math::Float4x4 Camera::ViewsProj()const
+{
+ Oyster::Math::Float4x4 M;
+ D3DXMatrixMultiply(&M, &this->mView, &this->mProj);
+ return M;
+}
+
+void Camera::Walk(float dist)
+{
+ this->m_position += dist*Oyster::Math::Float3(1,0,0);
+}
+
+void Camera::Strafe(float dist)
+{
+ this->m_position += dist*this->mRight;
+}
+
+void Camera::Pitch(float angle)
+{
+ float radians = angle * 0.0174532925f;
+
+ Oyster::Math::Float4x4 R;
+
+ D3DXMatrixRotationAxis(&R, &-mRight, radians);
+ this->mUp = CrossMatrix(this->mUp, R);
+ this->mLook = CrossMatrix(this->mLook, R);
+}
+
+void Camera::Yaw(float angle)
+{
+ float radians = angle * 0.0174532925f;
+
+ Oyster::Math::Float4x4 R;
+
+ Oyster::Math::Float3 up(0,1,0);
+ D3DXMatrixRotationAxis(&R, &-up, radians);
+
+ this->mRight = CrossMatrix(this->mRight, R);
+ this->mUp = CrossMatrix(mUp, R);
+ this->mLook = CrossMatrix(this->mLook, R);
+}
+
+void Camera::UpdateViewMatrix()
+{
+ D3DXVec3Normalize(&this->mLook, &this->mLook);
+ D3DXVec3Cross(&this->mUp, &this->mLook, &this->mRight);
+ D3DXVec3Normalize(&this->mUp, &this->mUp);
+ D3DXVec3Cross(&this->mRight, &this->mUp, &this->mLook);
+
+
+ float x = -D3DXVec3Dot(&this->m_position, &mRight);
+ float y = -D3DXVec3Dot(&this->m_position, &mUp);
+ float z = -D3DXVec3Dot(&this->m_position, &mLook);
+
+ this->mView(0, 0) = this->mRight.x;
+ this->mView(1, 0) = this->mRight.y;
+ this->mView(2, 0) = this->mRight.z;
+ this->mView(3, 0) = x;
+
+ this->mView(0, 1) = this->mUp.x;
+ this->mView(1, 1) = this->mUp.y;
+ this->mView(2, 1) = this->mUp.z;
+ this->mView(3, 1) = y;
+
+ this->mView(0, 2) = this->mLook.x;
+ this->mView(1, 2) = this->mLook.y;
+ this->mView(2, 2) = this->mLook.z;
+ this->mView(3, 2) = z;
+
+ this->mView(0, 3) = 0.0f;
+ this->mView(1, 3) = 0.0f;
+ this->mView(2, 3) = 0.0f;
+ this->mView(3, 3) = 1.0f;
+}
\ No newline at end of file
diff --git a/Code/GameLogic/Camera.h b/Code/GameLogic/Camera.h
new file mode 100644
index 00000000..deb9df62
--- /dev/null
+++ b/Code/GameLogic/Camera.h
@@ -0,0 +1,63 @@
+#ifndef CAMERA__H
+#define CAMERA__H
+
+#include "OysterMath.h"
+
+class Camera
+{
+private:
+
+ Oyster::Math::Float3 m_position;
+ Oyster::Math::Float3 mRight;
+ Oyster::Math::Float3 mUp;
+ Oyster::Math::Float3 mLook;
+
+
+
+ float mNearZ;
+ float mFarZ;
+ float mAspect;
+ float mFovY;
+
+ Oyster::Math::Float4x4 mView;
+ Oyster::Math::Float4x4 mProj;
+
+public:
+ Camera();
+ virtual ~Camera();
+
+ void SetPosition(const Oyster::Math::Float3& v);
+
+ Oyster::Math::Float3 GetPosition()const;
+
+ Oyster::Math::Float3 GetRight()const;
+ Oyster::Math::Float3 GetUp()const;
+ Oyster::Math::Float3 GetLook()const;
+
+ float GetNearZ()const;
+ float GetFarZ()const;
+ float GetAspect()const;
+
+ Oyster::Math::Float3 CrossMatrix(const Oyster::Math::Float3& v, const Oyster::Math::Float4x4& m);
+
+ void SetLens(float fovY, float aspect, float zn, float zf);
+
+ void LookAt(Oyster::Math::Float3 pos, Oyster::Math::Float3 target, Oyster::Math::Float3 worldUp);
+
+ void setLook(Oyster::Math::Float3 look) { mLook = look; }
+ void setUp(Oyster::Math::Float3 up) { mUp = up; }
+ void setRight(Oyster::Math::Float3 right) { mRight = right; }
+
+ Oyster::Math::Float4x4 View()const;
+ Oyster::Math::Float4x4 Proj()const;
+ Oyster::Math::Float4x4 ViewsProj()const;
+
+ void Walk(float dist);
+ void Strafe(float dist);
+
+ void Pitch(float angle);
+ void Yaw(float angle);
+
+ void UpdateViewMatrix();
+};
+#endif
\ No newline at end of file
diff --git a/Code/GameLogic/Object.cpp b/Code/GameLogic/Object.cpp
index d93dba63..4d01332b 100644
--- a/Code/GameLogic/Object.cpp
+++ b/Code/GameLogic/Object.cpp
@@ -18,14 +18,7 @@ Object::Object(void)
model = new Model();
model = Oyster::Graphics::API::CreateModel(L"bth.obj");
- ICustomBody* temp = rigidBody = API::Instance().CreateSimpleRigidBody().Release();
-
- rigidBody->SetCenter(Float3(50,0,0));
- rigidBody->SetMass_KeepMomentum(30);
- rigidBody->SetSize(Float3(2,2,2));
- rigidBody->SetSubscription(true);
- rigidBody->SetMomentOfInertiaTensor_KeepMomentum(Float4x4(MomentOfInertia::CreateCuboidMatrix(30, 2, 2, 2)));
-
+ ICustomBody* temp = rigidBody = API::Instance().CreateRigidBody().Release();
GameLogic::RefManager::getInstance()->AddMapping(*rigidBody, *this);
diff --git a/Code/GamePhysics/GamePhysics.vcxproj.filters b/Code/GamePhysics/GamePhysics.vcxproj.filters
index 4c0fd5f3..cc9a84c8 100644
--- a/Code/GamePhysics/GamePhysics.vcxproj.filters
+++ b/Code/GamePhysics/GamePhysics.vcxproj.filters
@@ -33,6 +33,9 @@
Header Files\Implementation
+
+ Header Files\Implementation
+
diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp
index 6c3e4a27..2c745500 100644
--- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp
+++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp
@@ -1,6 +1,7 @@
#include "PhysicsAPI_Impl.h"
-#include "SimpleRigidBody.h"
#include "OysterPhysics3D.h"
+#include "SimpleRigidBody.h"
+#include "SphericalRigidBody.h"
using namespace ::Oyster::Physics;
using namespace ::Oyster::Physics3D;
@@ -10,14 +11,6 @@ using namespace ::Utility::DynamicMemory;
API_Impl API_instance;
-// default API::EventAction_Collision
-void defaultCollisionAction( const ICustomBody *proto, const ICustomBody *deuter )
-{ /* do nothing */ }
-
-// default API::EventAction_Destruction
-void defaultDestructionAction( UniquePointer proto )
-{ /* do nothing besides proto auto deleting itself. */ }
-
Float4x4 & MomentOfInertia::CreateSphereMatrix( const Float mass, const Float radius)
{
return Formula::MomentOfInertia::Sphere(mass, radius);
@@ -51,8 +44,7 @@ API & API::Instance()
API_Impl::API_Impl()
: gravityConstant( Constant::gravity_constant ),
updateFrameLength( 1.0f / 120.0f ),
- collisionAction( defaultCollisionAction ),
- destructionAction( defaultDestructionAction )
+ destructionAction( Default::EventAction_Destruction )
{}
API_Impl::~API_Impl() {}
@@ -66,17 +58,22 @@ void API_Impl::SetDeltaTime( float deltaTime )
{
updateFrameLength = deltaTime;
}
+
void API_Impl::SetGravityConstant( float g )
{
this->gravityConstant = g;
}
-void API_Impl::SetAction( API::EventAction_Collision functionPointer )
+
+void API_Impl::SetSubscription( API::EventAction_Destruction functionPointer )
{
- this->collisionAction = functionPointer;
-}
-void API_Impl::SetAction( API::EventAction_Destruction functionPointer )
-{
- this->destructionAction = functionPointer;
+ if( functionPointer )
+ {
+ this->destructionAction = functionPointer;
+ }
+ else
+ {
+ this->destructionAction = Default::EventAction_Destruction;
+ }
}
void API_Impl::Update()
@@ -165,7 +162,25 @@ void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size )
//! @todo TODO: implement stub
}
-UniquePointer API_Impl::CreateSimpleRigidBody() const
+UniquePointer API_Impl::CreateRigidBody( const API::SimpleBodyDescription &desc ) const
{
- return new SimpleRigidBody();
-}
\ No newline at end of file
+ return new SimpleRigidBody( desc );
+}
+
+UniquePointer API_Impl::CreateRigidBody( const API::SphericalBodyDescription &desc ) const
+{
+ return new SphericalRigidBody();
+}
+
+namespace Oyster { namespace Physics { namespace Default
+{
+
+ void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto )
+ { /* Do nothing except allowing the proto uniquePointer destroy itself. */ }
+
+ ::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_Collision( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter )
+ { /* Do nothing except returning business as usual. */
+ return ::Oyster::Physics::ICustomBody::SubscriptMessage_none;
+ }
+
+} } }
\ No newline at end of file
diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h
index 5a2e3ef6..7d6858f0 100644
--- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h
+++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h
@@ -17,8 +17,7 @@ namespace Oyster
void SetDeltaTime( float deltaTime );
void SetGravityConstant( float g );
- void SetAction( EventAction_Collision functionPointer );
- void SetAction( EventAction_Destruction functionPointer );
+ void SetSubscription( EventAction_Destruction functionPointer );
void Update();
@@ -42,14 +41,20 @@ namespace Oyster
void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation );
void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size );
- ::Utility::DynamicMemory::UniquePointer CreateSimpleRigidBody() const;
+ ::Utility::DynamicMemory::UniquePointer CreateRigidBody( const SimpleBodyDescription &desc ) const;
+ ::Utility::DynamicMemory::UniquePointer CreateRigidBody( const SphericalBodyDescription &desc ) const;
+
private:
::Oyster::Math::Float gravityConstant, updateFrameLength;
- EventAction_Collision collisionAction;
EventAction_Destruction destructionAction;
};
- }
+ namespace Default
+ {
+ void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto );
+ ::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_Collision( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter );
+ }
+ }
}
#endif
\ No newline at end of file
diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp
index cc1f847b..d83aa399 100644
--- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp
+++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp
@@ -2,16 +2,38 @@
#include "PhysicsAPI_Impl.h"
using namespace ::Oyster::Physics;
+using namespace ::Oyster::Physics3D;
using namespace ::Oyster::Math3D;
using namespace ::Oyster::Collision3D;
using namespace ::Utility::DynamicMemory;
using namespace ::Utility::Value;
SimpleRigidBody::SimpleRigidBody()
- : previous(), current(),
- gravityNormal(0.0f),
- subscribeCollision(true),
- ignoreGravity(false) {}
+{
+ this->rigid = RigidBody();
+ this->gravityNormal = Float3::null;
+ this->collisionAction = Default::EventAction_Collision;
+ this->ignoreGravity = false;
+}
+
+SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
+{
+ this->rigid = RigidBody( Box( desc.rotation, desc.centerPosition, desc.size ),
+ desc.mass,
+ desc.inertiaTensor );
+ this->gravityNormal = Float3::null;
+
+ if( desc.subscription )
+ {
+ this->collisionAction = desc.subscription;
+ }
+ else
+ {
+ this->collisionAction = Default::EventAction_Collision;
+ }
+
+ this->ignoreGravity = desc.ignoreGravity;
+}
SimpleRigidBody::~SimpleRigidBody() {}
@@ -20,11 +42,6 @@ UniquePointer SimpleRigidBody::Clone() const
return new SimpleRigidBody( *this );
}
-bool SimpleRigidBody::IsSubscribingCollisions() const
-{ // Assumption
- return this->subscribeCollision;
-}
-
bool SimpleRigidBody::IsAffectedByGravity() const
{
return !this->ignoreGravity;
@@ -32,10 +49,10 @@ bool SimpleRigidBody::IsAffectedByGravity() const
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const
{
- if( object.Intersects(this->current.box) )
+ if( object.Intersects(this->rigid.box) )
{ //! @todo TODO: better implementation needed
deltaWhen = timeStepLength;
- worldPointOfContact = Average( this->current.box.center, object.GetCenter() );
+ worldPointOfContact = Average( this->rigid.box.center, object.GetCenter() );
return true;
}
else
@@ -46,18 +63,18 @@ bool SimpleRigidBody::Intersects( const ICustomBody &object, Float timeStepLengt
bool SimpleRigidBody::Intersects( const ICollideable &shape ) const
{
- return this->current.box.Intersects( shape );
+ return this->rigid.box.Intersects( shape );
}
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
{
- return targetMem = Sphere( this->current.box.center, this->current.box.boundingOffset.GetMagnitude() );
+ return targetMem = Sphere( this->rigid.box.center, this->rigid.box.boundingOffset.GetMagnitude() );
}
Float3 & SimpleRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const
{
//! @todo TODO: better implementation needed
- return targetMem = (worldPos - this->current.box.center).GetNormalized();
+ return targetMem = (worldPos - this->rigid.box.center).GetNormalized();
}
Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const
@@ -67,32 +84,43 @@ Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const
Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const
{
- return targetMem = this->current.box.center;
+ return targetMem = this->rigid.box.center;
}
Float4x4 & SimpleRigidBody::GetRotation( Float4x4 &targetMem ) const
{
- return targetMem = this->current.box.rotation;
+ return targetMem = this->rigid.box.rotation;
}
Float4x4 & SimpleRigidBody::GetOrientation( Float4x4 &targetMem ) const
{
- return targetMem = this->current.GetOrientation();
+ return targetMem = this->rigid.GetOrientation();
}
Float4x4 & SimpleRigidBody::GetView( Float4x4 &targetMem ) const
{
- return targetMem = this->current.GetView();
+ return targetMem = this->rigid.GetView();
}
UpdateState SimpleRigidBody::Update( Float timeStepLength )
{
- this->previous = this->current; // memorizing the old state
-
- this->current.Update_LeapFrog( timeStepLength );
+ this->rigid.Update_LeapFrog( timeStepLength );
// compare previous and new state and return result
- return this->current == this->previous ? resting : altered;
+ //return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
+ return UpdateState_altered;
+}
+
+void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer )
+{
+ if( functionPointer )
+ {
+ this->collisionAction = functionPointer;
+ }
+ else
+ {
+ this->collisionAction = Default::EventAction_Collision;
+ }
}
void SimpleRigidBody::SetGravity( bool ignore)
@@ -106,47 +134,42 @@ void SimpleRigidBody::SetGravityNormal( const Float3 &normalizedVector )
this->gravityNormal = normalizedVector;
}
-void SimpleRigidBody::SetSubscription( bool subscribeCollision )
-{
- this->subscribeCollision = subscribeCollision;
-}
-
void SimpleRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
{
- this->current.SetMomentOfInertia_KeepVelocity( localI );
+ this->rigid.SetMomentOfInertia_KeepVelocity( localI );
}
void SimpleRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
{
- this->current.SetMomentOfInertia_KeepMomentum( localI );
+ this->rigid.SetMomentOfInertia_KeepMomentum( localI );
}
void SimpleRigidBody::SetMass_KeepVelocity( Float m )
{
- this->current.SetMass_KeepVelocity( m );
+ this->rigid.SetMass_KeepVelocity( m );
}
void SimpleRigidBody::SetMass_KeepMomentum( Float m )
{
- this->current.SetMass_KeepMomentum( m );
+ this->rigid.SetMass_KeepMomentum( m );
}
void SimpleRigidBody::SetCenter( const Float3 &worldPos )
{
- this->current.SetCenter( worldPos );
+ this->rigid.SetCenter( worldPos );
}
void SimpleRigidBody::SetRotation( const Float4x4 &rotation )
{
- this->current.SetRotation( rotation );
+ this->rigid.SetRotation( rotation );
}
void SimpleRigidBody::SetOrientation( const Float4x4 &orientation )
{
- this->current.SetOrientation( orientation );
+ this->rigid.SetOrientation( orientation );
}
void SimpleRigidBody::SetSize( const Float3 &size )
{
- this->current.SetSize( size );
+ this->rigid.SetSize( size );
}
\ No newline at end of file
diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h
index 41be919b..c76f6a51 100644
--- a/Code/GamePhysics/Implementation/SimpleRigidBody.h
+++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h
@@ -10,11 +10,11 @@ namespace Oyster { namespace Physics
{
public:
SimpleRigidBody();
+ SimpleRigidBody( const API::SimpleBodyDescription &desc );
virtual ~SimpleRigidBody();
::Utility::DynamicMemory::UniquePointer Clone() const;
- bool IsSubscribingCollisions() const;
bool IsAffectedByGravity() const;
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const;
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
@@ -29,9 +29,9 @@ namespace Oyster { namespace Physics
UpdateState Update( ::Oyster::Math::Float timeStepLength );
+ void SetSubscription( EventAction_Collision functionPointer );
void SetGravity( bool ignore);
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
- void SetSubscription( bool subscribeCollision );
void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
@@ -42,9 +42,10 @@ namespace Oyster { namespace Physics
void SetSize( const ::Oyster::Math::Float3 &size );
private:
- ::Oyster::Physics3D::RigidBody previous, current;
+ ::Oyster::Physics3D::RigidBody rigid;
::Oyster::Math::Float3 gravityNormal;
- bool subscribeCollision, ignoreGravity;
+ EventAction_Collision collisionAction;
+ bool ignoreGravity;
};
} }
diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp
index 20d806c9..1c9b7b52 100644
--- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp
+++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp
@@ -2,6 +2,7 @@
#include "PhysicsAPI_Impl.h"
using namespace ::Oyster::Physics;
+using namespace ::Oyster::Physics3D;
using namespace ::Oyster::Math3D;
using namespace ::Oyster::Collision3D;
using namespace ::Utility::DynamicMemory;
@@ -10,7 +11,7 @@ using namespace ::Utility::Value;
SphericalRigidBody::SphericalRigidBody()
: previous(), current( Box(Float4x4::identity, Float3::null, Float3(1.0f)) ),
gravityNormal( 0.0f ),
- subscribeCollision( true ),
+ collisionAction(Default::EventAction_Collision),
ignoreGravity( false ),
body( Float3::null, 0.5f ) {}
@@ -21,11 +22,6 @@ UniquePointer SphericalRigidBody::Clone() const
return new SphericalRigidBody( *this );
}
-bool SphericalRigidBody::IsSubscribingCollisions() const
-{ // Assumption
- return this->subscribeCollision;
-}
-
bool SphericalRigidBody::IsAffectedByGravity() const
{
return !this->ignoreGravity;
@@ -94,7 +90,19 @@ UpdateState SphericalRigidBody::Update( Float timeStepLength )
this->body.center = this->current.GetCenter();
// compare previous and new state and return result
- return this->current == this->previous ? resting : altered;
+ return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
+}
+
+void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer )
+{
+ if( functionPointer )
+ {
+ this->collisionAction = functionPointer;
+ }
+ else
+ {
+ this->collisionAction = Default::EventAction_Collision;
+ }
}
void SphericalRigidBody::SetGravity( bool ignore)
@@ -108,11 +116,6 @@ void SphericalRigidBody::SetGravityNormal( const Float3 &normalizedVector )
this->gravityNormal = normalizedVector;
}
-void SphericalRigidBody::SetSubscription( bool subscribeCollision )
-{
- this->subscribeCollision = subscribeCollision;
-}
-
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
{
this->current.SetMomentOfInertia_KeepVelocity( localI );
diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.h b/Code/GamePhysics/Implementation/SphericalRigidBody.h
index 7a727ee8..1540f7a1 100644
--- a/Code/GamePhysics/Implementation/SphericalRigidBody.h
+++ b/Code/GamePhysics/Implementation/SphericalRigidBody.h
@@ -30,9 +30,9 @@ namespace Oyster { namespace Physics
UpdateState Update( ::Oyster::Math::Float timeStepLength );
+ void SetSubscription( EventAction_Collision functionPointer );
void SetGravity( bool ignore);
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
- void SetSubscription( bool subscribeCollision );
void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
@@ -45,7 +45,8 @@ namespace Oyster { namespace Physics
private:
::Oyster::Physics3D::RigidBody previous, current;
::Oyster::Math::Float3 gravityNormal;
- bool subscribeCollision, ignoreGravity;
+ EventAction_Collision collisionAction;
+ bool ignoreGravity;
::Oyster::Collision3D::Sphere body;
};
} }
diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h
index bf80e6fa..dd36a9ee 100644
--- a/Code/GamePhysics/PhysicsAPI.h
+++ b/Code/GamePhysics/PhysicsAPI.h
@@ -19,8 +19,8 @@ namespace Oyster
enum UpdateState
{
- resting,
- altered
+ UpdateState_resting,
+ UpdateState_altered
};
namespace Constant
@@ -45,7 +45,9 @@ namespace Oyster
class PHYSICS_DLL_USAGE API
{
public:
- typedef void (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter );
+ struct SimpleBodyDescription;
+ struct SphericalBodyDescription;
+
typedef void (*EventAction_Destruction)( ::Utility::DynamicMemory::UniquePointer proto );
/** Gets the Physics instance. */
@@ -70,20 +72,15 @@ namespace Oyster
* @param g: Default is the real world Constant::gravity_constant [N(m/kg)^2]
********************************************************/
virtual void SetGravityConstant( float g ) = 0;
-
- /********************************************************
- * Sets the function that will be called by the engine
- * whenever a subscribed collision occurs.
- ********************************************************/
- virtual void SetAction( EventAction_Collision functionPointer ) = 0;
/********************************************************
* Sets the function that will be called by the engine
* whenever an object is being destroyed for some reason.
* - Because DestroyObject(...) were called.
* - Out of memory forced engine to destroy an object.
+ * @param functionPointer: If NULL, an empty default function will be set.
********************************************************/
- virtual void SetAction( EventAction_Destruction functionPointer ) = 0;
+ virtual void SetSubscription( EventAction_Destruction functionPointer ) = 0;
/********************************************************
* Triggers the engine to run next update frame.
@@ -213,10 +210,18 @@ namespace Oyster
/********************************************************
* Creates a new dynamically allocated object that can be used as a component for more complex ICustomBodies.
+ * @param desc: @see API::SimpleBodyDescription
* @return A pointer along with the responsibility to delete.
********************************************************/
- virtual ::Utility::DynamicMemory::UniquePointer CreateSimpleRigidBody() const = 0;
-
+ virtual ::Utility::DynamicMemory::UniquePointer CreateRigidBody( const SimpleBodyDescription &desc ) const = 0;
+
+ /********************************************************
+ * Creates a new dynamically allocated object that can be used as a component for more complex ICustomBodies.
+ * @param desc: @see API::SphericalBodyDescription
+ * @return A pointer along with the responsibility to delete.
+ ********************************************************/
+ virtual ::Utility::DynamicMemory::UniquePointer CreateRigidBody( const SphericalBodyDescription &desc ) const = 0;
+
protected:
virtual ~API() {}
};
@@ -225,6 +230,14 @@ namespace Oyster
class PHYSICS_DLL_USAGE ICustomBody
{
public:
+ enum SubscriptMessage
+ {
+ SubscriptMessage_none,
+ SubscriptMessage_ignore_collision_response
+ };
+
+ typedef SubscriptMessage (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter );
+
virtual ~ICustomBody() {};
/********************************************************
@@ -232,11 +245,6 @@ namespace Oyster
* @return An ICustomBody pointer along with the responsibility to delete.
********************************************************/
virtual ::Utility::DynamicMemory::UniquePointer Clone() const = 0;
-
- /********************************************************
- * @return true if Engine should call the EventAction_Collision function.
- ********************************************************/
- virtual bool IsSubscribingCollisions() const = 0;
/********************************************************
* @return true if Engine should apply gravity on this object.
@@ -312,6 +320,13 @@ namespace Oyster
********************************************************/
virtual UpdateState Update( ::Oyster::Math::Float timeStepLength ) = 0;
+ /********************************************************
+ * Sets the function that will be called by the engine
+ * whenever a collision occurs.
+ * @param functionPointer: If NULL, an empty default function will be set.
+ ********************************************************/
+ virtual void SetSubscription( EventAction_Collision functionPointer ) = 0;
+
/********************************************************
* @param ignore: True if Engine should not apply Gravity.
********************************************************/
@@ -323,11 +338,6 @@ namespace Oyster
********************************************************/
virtual void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector ) = 0;
- /********************************************************
- * @param subscribeCollision: If is true, engine will call EventAction_Collision when this collides.
- ********************************************************/
- virtual void SetSubscription( bool subscribeCollision ) = 0;
-
/********************************************************
* To not be called if is in Engine
* Use API::SetMomentOfInertiaTensor_KeepVelocity(...) instead
@@ -376,6 +386,50 @@ namespace Oyster
********************************************************/
virtual void SetSize( const ::Oyster::Math::Float3 &size ) = 0;
};
+
+ struct API::SimpleBodyDescription
+ {
+ ::Oyster::Math::Float4x4 rotation;
+ ::Oyster::Math::Float3 centerPosition;
+ ::Oyster::Math::Float3 size;
+ ::Oyster::Math::Float mass;
+ ::Oyster::Math::Float4x4 inertiaTensor;
+ ICustomBody::EventAction_Collision subscription;
+ bool ignoreGravity;
+
+ SimpleBodyDescription()
+ {
+ this->rotation = ::Oyster::Math::Float4x4::identity;
+ this->centerPosition = ::Oyster::Math::Float3::null;
+ this->size = ::Oyster::Math::Float3( 1.0f );
+ this->mass = 12.0f;
+ this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
+ this->subscription = NULL;
+ this->ignoreGravity = false;
+ }
+ };
+
+ struct API::SphericalBodyDescription
+ {
+ ::Oyster::Math::Float4x4 rotation;
+ ::Oyster::Math::Float3 centerPosition;
+ ::Oyster::Math::Float radius;
+ ::Oyster::Math::Float mass;
+ ::Oyster::Math::Float4x4 inertiaTensor;
+ ICustomBody::EventAction_Collision subscription;
+ bool ignoreGravity;
+
+ SphericalBodyDescription()
+ {
+ this->rotation = ::Oyster::Math::Float4x4::identity;
+ this->centerPosition = ::Oyster::Math::Float3::null;
+ this->radius = 0.5f;
+ this->mass = 10.0f;
+ this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
+ this->subscription = NULL;
+ this->ignoreGravity = false;
+ }
+ };
}
}
#endif
\ No newline at end of file
diff --git a/Code/Misc/Utilities-InlineImpl.h b/Code/Misc/Utilities-InlineImpl.h
index c2bbd2a9..6cc99aab 100644
--- a/Code/Misc/Utilities-InlineImpl.h
+++ b/Code/Misc/Utilities-InlineImpl.h
@@ -98,6 +98,18 @@ namespace Utility
return this->ownedInstance != NULL;
}
+ template
+ bool UniquePointer::operator == ( Type *stray ) const
+ {
+ return this->ownedInstance == stray;
+ }
+
+ template
+ bool UniquePointer::operator != ( Type *stray ) const
+ {
+ return this->ownedInstance != stray;
+ }
+
template
Type* UniquePointer::Release()
{
@@ -165,6 +177,18 @@ namespace Utility
return this->ownedArray != NULL;
}
+ template
+ bool UniqueArray::operator == ( Type *stray ) const
+ {
+ return this->ownedArray == stray;
+ }
+
+ template
+ bool UniqueArray::operator != ( Type *stray ) const
+ {
+ return this->ownedArray != stray;
+ }
+
template
Type* UniqueArray::Release()
{
diff --git a/Code/Misc/Utilities.h b/Code/Misc/Utilities.h
index 66164e19..59d5042d 100644
--- a/Code/Misc/Utilities.h
+++ b/Code/Misc/Utilities.h
@@ -60,6 +60,12 @@ namespace Utility
//! If true, this UniquePointer have a current ownership/responsibility of a dynamic instance.
operator bool () const;
+ //! @return true if this ownedInstance matches with stray
+ bool operator == ( Type *stray ) const;
+
+ //! @return false if this ownedInstance matches with stray
+ bool operator != ( Type *stray ) const;
+
//! This UniquePointer drops all claims of ownership/responsibility and returns the dynamic instance. Now it is your responsibility to delete.
Type* Release();
@@ -104,6 +110,12 @@ namespace Utility
//! If true, this UniqueArray have a current ownership/responsibility of a dynamic instance.
operator bool () const;
+ //! @return true if this ownedInstance matches with stray
+ bool operator == ( Type *stray ) const;
+
+ //! @return false if this ownedInstance matches with stray
+ bool operator != ( Type *stray ) const;
+
//! This UniqueArray drops all claims of ownership/responsibility and returns the dynamic array. Now it is your responsibility to delete.
Type* Release();
diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp
index 24648999..182a5a17 100644
--- a/Code/OysterPhysics3D/RigidBody.cpp
+++ b/Code/OysterPhysics3D/RigidBody.cpp
@@ -9,9 +9,14 @@ using namespace ::Oyster::Collision3D;
using namespace ::Oyster::Physics3D;
using namespace ::Oyster::Math3D;
-RigidBody::RigidBody( const Box &b, Float m )
- : box(b), angularMomentum(0.0f), linearMomentum(0.0f), impulseTorqueSum(0.0f), impulseForceSum(0.0f)
+RigidBody::RigidBody( const Box &b, Float m, const Float4x4 &inertiaTensor )
{ // by Dan Andersson
+ this->box = b;
+ this->angularMomentum = Float3::null;
+ this->linearMomentum = Float3::null;
+ this->impulseTorqueSum = Float3::null;
+ this->impulseForceSum = Float3::null;
+
if( m != 0.0f )
{
this->mass = m;
@@ -21,7 +26,14 @@ RigidBody::RigidBody( const Box &b, Float m )
this->mass = ::Utility::Value::numeric_limits::epsilon();
}
- this->momentOfInertiaTensor = Float4x4::identity;
+ if( inertiaTensor.GetDeterminant() != 0.0f )
+ {
+ this->momentOfInertiaTensor = inertiaTensor;
+ }
+ else
+ {
+ this->momentOfInertiaTensor = Float4x4::identity;
+ }
}
RigidBody & RigidBody::operator = ( const RigidBody &body )
diff --git a/Code/OysterPhysics3D/RigidBody.h b/Code/OysterPhysics3D/RigidBody.h
index bff6acde..81c92ae0 100644
--- a/Code/OysterPhysics3D/RigidBody.h
+++ b/Code/OysterPhysics3D/RigidBody.h
@@ -20,7 +20,9 @@ namespace Oyster { namespace Physics3D
impulseTorqueSum, /** The impulse torque T (Nm) that will be consumed each update. (worldValue) */
impulseForceSum; /** The impulse force F (N) that will be consumed each update. (worldValue) */
- RigidBody( const ::Oyster::Collision3D::Box &box = ::Oyster::Collision3D::Box(), ::Oyster::Math::Float mass = 1.0f );
+ RigidBody( const ::Oyster::Collision3D::Box &box = ::Oyster::Collision3D::Box(),
+ ::Oyster::Math::Float mass = 12.0f,
+ const ::Oyster::Math::Float4x4 &inertiaTensor = ::Oyster::Math::Float4x4::identity );
RigidBody & operator = ( const RigidBody &body );