From b06a03a54302a83ccfa2be63b136044d8e0930ea Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Thu, 28 Nov 2013 10:26:29 +0100 Subject: [PATCH] Improved Collision Event Subscription From now on, will each ICustomBody instance have it's own collisionAction function. --- .../Implementation/PhysicsAPI_Impl.cpp | 43 +++++++++++-------- .../Implementation/PhysicsAPI_Impl.h | 11 +++-- .../Implementation/SimpleRigidBody.cpp | 26 +++++------ .../Implementation/SimpleRigidBody.h | 6 +-- .../Implementation/SphericalRigidBody.cpp | 26 +++++------ .../Implementation/SphericalRigidBody.h | 5 ++- Code/GamePhysics/PhysicsAPI.h | 39 ++++++++--------- 7 files changed, 86 insertions(+), 70 deletions(-) diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 6c3e4a27..13184ce5 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -10,14 +10,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 +43,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 +57,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() @@ -168,4 +164,17 @@ void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size ) UniquePointer API_Impl::CreateSimpleRigidBody() const { return new SimpleRigidBody(); -} \ No newline at end of file +} + +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..28858da0 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(); @@ -45,11 +44,15 @@ namespace Oyster ::Utility::DynamicMemory::UniquePointer CreateSimpleRigidBody() 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..95256915 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -10,7 +10,7 @@ using namespace ::Utility::Value; SimpleRigidBody::SimpleRigidBody() : previous(), current(), gravityNormal(0.0f), - subscribeCollision(true), + collisionAction(Default::EventAction_Collision), ignoreGravity(false) {} SimpleRigidBody::~SimpleRigidBody() {} @@ -20,11 +20,6 @@ UniquePointer SimpleRigidBody::Clone() const return new SimpleRigidBody( *this ); } -bool SimpleRigidBody::IsSubscribingCollisions() const -{ // Assumption - return this->subscribeCollision; -} - bool SimpleRigidBody::IsAffectedByGravity() const { return !this->ignoreGravity; @@ -92,7 +87,19 @@ UpdateState SimpleRigidBody::Update( Float timeStepLength ) this->current.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; +} + +void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer ) +{ + if( functionPointer ) + { + this->collisionAction = functionPointer; + } + else + { + this->collisionAction = Default::EventAction_Collision; + } } void SimpleRigidBody::SetGravity( bool ignore) @@ -106,11 +113,6 @@ 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 ); diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h index 41be919b..c19a1ddb 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -14,7 +14,6 @@ namespace Oyster { namespace Physics ::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 +28,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 ); @@ -44,7 +43,8 @@ namespace Oyster { namespace Physics private: ::Oyster::Physics3D::RigidBody previous, current; ::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..6d50b386 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -10,7 +10,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 +21,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 +89,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 +115,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..71bebc1f 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,6 @@ namespace Oyster class PHYSICS_DLL_USAGE API { public: - typedef void (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter ); typedef void (*EventAction_Destruction)( ::Utility::DynamicMemory::UniquePointer proto ); /** Gets the Physics instance. */ @@ -70,20 +69,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. @@ -225,6 +219,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 +234,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 +309,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 +327,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