diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 14c4d9e4..5ca06fce 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -22,92 +22,71 @@ namespace Float4 worldPointOfContact; if( proto->Intersects(*deuter, worldPointOfContact) ) { - switch( proto->CallSubscription_Collision(deuter) ) - { - case ICustomBody::SubscriptMessage_ignore_collision_response: - break; - default: - { // Apply CollisionResponse in pure gather pattern - ICustomBody::State protoState; proto->GetState( protoState ); - ICustomBody::State deuterState; deuter->GetState( deuterState ); + // Apply CollisionResponse in pure gather pattern + ICustomBody::State protoState; proto->GetState( protoState ); + ICustomBody::State deuterState; deuter->GetState( deuterState ); - Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ), - deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); + Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ), + deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); - // calc from perspective of deuter - Float4 normal; deuter->GetNormalAt( worldPointOfContact, normal ); - Float protoG_Magnitude = protoG.Dot( normal ), - deuterG_Magnitude = deuterG.Dot( normal ); - - // if they are not relatively moving towards eachother, there is no collision - Float deltaPos = normal.Dot( Float4(deuterState.GetCenterPosition(), 1) - Float4(protoState.GetCenterPosition(), 1) ); - if( deltaPos < 0.0f ) - { - if( protoG_Magnitude >= deuterG_Magnitude ) - { - break; - } - } - else if( deltaPos > 0.0f ) - { - if( protoG_Magnitude <= deuterG_Magnitude ) - { - break; - } - } - else - { - break; - } - - // bounce - Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(), - deuterState.GetMass(), deuterG_Magnitude, - protoState.GetMass(), protoG_Magnitude ); - - //sumJ -= Formula::CollisionResponse::Friction( impulse, normal, - // protoState.GetLinearMomentum(), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(), - // deuterState.GetLinearMomentum(), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass()); - - // calc from perspective of proto - proto->GetNormalAt( worldPointOfContact, normal ); - protoG_Magnitude = protoG.Dot( normal ), + // calc from perspective of deuter + Float4 normal; deuter->GetNormalAt( worldPointOfContact, normal ); + Float protoG_Magnitude = protoG.Dot( normal ), deuterG_Magnitude = deuterG.Dot( normal ); - - // bounce - Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(), - protoState.GetMass(), protoG_Magnitude, - deuterState.GetMass(), deuterG_Magnitude ); - Float4 bounce = Average( bounceD, bounceP ); - //Float4 bounce = bounceD + bounceP; - - // FRICTION - // Apply - //sumJ += ( 1 / deuterState.GetMass() )*frictionImpulse; - // FRICTION END - -// Float4 forwardedDeltaPos, forwardedDeltaAxis; -// { // @todo TODO: is this right? -// Float4 bounceAngularImpulse = ::Oyster::Math::Float4( (worldPointOfContact - protoState.GetCenterPosition()).xyz.Cross(bounce.xyz), 0.0f ), -// bounceLinearImpulse = bounce - bounceAngularImpulse; -// proto->Predict( forwardedDeltaPos, forwardedDeltaAxis, bounceLinearImpulse, bounceAngularImpulse, API_instance.GetFrameTimeLength() ); -// } - - - Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() ); - -// protoState.ApplyForwarding( forwardedDeltaPos, forwardedDeltaAxis ); - protoState.ApplyImpulse( bounce.xyz, worldPointOfContact.xyz, normal.xyz ); - proto->SetState( protoState ); - - Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() ); - - proto->CallSubscription_CollisionResponse( deuter, kineticEnergyPBefore - kineticEnergyPAFter ); - + // if they are not relatively moving towards eachother, there is no collision + Float deltaPos = normal.Dot( Float4(deuterState.GetCenterPosition(), 1) - Float4(protoState.GetCenterPosition(), 1) ); + if( deltaPos < 0.0f ) + { + if( protoG_Magnitude >= deuterG_Magnitude ) + { + return; } - break; } + else if( deltaPos > 0.0f ) + { + if( protoG_Magnitude <= deuterG_Magnitude ) + { + return; + } + } + else + { + return; + } + + if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_ignore_collision_response ) + { + return; + } + + + // bounce + Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(), + deuterState.GetMass(), deuterG_Magnitude, + protoState.GetMass(), protoG_Magnitude ); + + + // calc from perspective of proto + proto->GetNormalAt( worldPointOfContact, normal ); + protoG_Magnitude = protoG.Dot( normal ), + deuterG_Magnitude = deuterG.Dot( normal ); + + // bounce + Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(), + protoState.GetMass(), protoG_Magnitude, + deuterState.GetMass(), deuterG_Magnitude ); + + Float4 bounce = Average( bounceD, bounceP ); + + Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() ); + + protoState.ApplyImpulse( bounce.xyz, worldPointOfContact.xyz, normal.xyz ); + proto->SetState( protoState ); + + Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() ); + + proto->CallSubscription_AfterCollisionResponse( deuter, kineticEnergyPBefore - kineticEnergyPAFter ); } } } @@ -384,12 +363,12 @@ namespace Oyster { namespace Physics 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 ) + ::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_BeforeCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter ) { /* Do nothing except returning business as usual. */ return ::Oyster::Physics::ICustomBody::SubscriptMessage_none; } - void EventAction_CollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ) + void EventAction_AfterCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ) { /* Do nothing except returning business as usual. */ } diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h index 63d8ff08..9ea9a6fc 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h @@ -61,8 +61,8 @@ namespace Oyster 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 ); - void EventAction_CollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); + ::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_BeforeCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter ); + void EventAction_AfterCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); void EventAction_Move( const ::Oyster::Physics::ICustomBody *object ); } } diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 2f6a6c0c..ef3027ee 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -46,8 +46,8 @@ SimpleRigidBody::SimpleRigidBody() this->rigid = RigidBody(); this->rigid.SetMass_KeepMomentum( 16.0f ); this->gravityNormal = Float3::null; - this->onCollision = Default::EventAction_Collision; - this->onCollisionResponse = Default::EventAction_CollisionResponse; + this->onCollision = Default::EventAction_BeforeCollisionResponse; + this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; this->onMovement = Default::EventAction_Move; this->scene = nullptr; this->customTag = nullptr; @@ -72,7 +72,7 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc ) } else { - this->onCollision = Default::EventAction_Collision; + this->onCollision = Default::EventAction_BeforeCollisionResponse; } if( desc.subscription_onCollisionResponse ) @@ -81,7 +81,7 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc ) } else { - this->onCollisionResponse = Default::EventAction_CollisionResponse; + this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; } if( desc.subscription_onMovement ) @@ -163,12 +163,12 @@ void SimpleRigidBody::SetState( const SimpleRigidBody::State &state ) } } -ICustomBody::SubscriptMessage SimpleRigidBody::CallSubscription_Collision( const ICustomBody *deuter ) +ICustomBody::SubscriptMessage SimpleRigidBody::CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter ) { return this->onCollision( this, deuter ); } -void SimpleRigidBody::CallSubscription_CollisionResponse( const ICustomBody *deuter, Float kineticEnergyLoss ) +void SimpleRigidBody::CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, Float kineticEnergyLoss ) { return this->onCollisionResponse( this, deuter, kineticEnergyLoss ); } @@ -318,7 +318,7 @@ void SimpleRigidBody::SetScene( void *scene ) this->scene = (Octree*)scene; } -void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer ) +void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_BeforeCollisionResponse functionPointer ) { if( functionPointer ) { @@ -326,11 +326,11 @@ void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Collision functi } else { - this->onCollision = Default::EventAction_Collision; + this->onCollision = Default::EventAction_BeforeCollisionResponse; } } -void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_CollisionResponse functionPointer ) +void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_AfterCollisionResponse functionPointer ) { if( functionPointer ) { @@ -338,7 +338,7 @@ void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_CollisionRespons } else { - this->onCollisionResponse = Default::EventAction_CollisionResponse; + this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; } } diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h index 271c4362..9e61cee3 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -21,8 +21,8 @@ namespace Oyster { namespace Physics void SetState( const State &state ); //::Oyster::Math::Float3 GetRigidLinearVelocity() const; - SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter ); - void CallSubscription_CollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); + SubscriptMessage CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter ); + void CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); void CallSubscription_Move(); bool IsAffectedByGravity() const; @@ -44,8 +44,8 @@ namespace Oyster { namespace Physics void SetScene( void *scene ); - void SetSubscription( EventAction_Collision functionPointer ); - void SetSubscription( EventAction_CollisionResponse functionPointer ); + void SetSubscription( EventAction_BeforeCollisionResponse functionPointer ); + void SetSubscription( EventAction_AfterCollisionResponse functionPointer ); void SetSubscription( EventAction_Move functionPointer ); void SetGravity( bool ignore); @@ -65,8 +65,8 @@ namespace Oyster { namespace Physics ::Oyster::Physics3D::RigidBody rigid; ::Oyster::Math::Float4 deltaPos, deltaAxis; ::Oyster::Math::Float3 gravityNormal; - EventAction_Collision onCollision; - EventAction_CollisionResponse onCollisionResponse; + EventAction_BeforeCollisionResponse onCollision; + EventAction_AfterCollisionResponse onCollisionResponse; EventAction_Move onMovement; Octree *scene; void *customTag; diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index 3fb6b4ce..539093db 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -13,8 +13,8 @@ SphericalRigidBody::SphericalRigidBody() this->rigid = RigidBody(); this->rigid.SetMass_KeepMomentum( 10.0f ); this->gravityNormal = Float3::null; - this->onCollision = Default::EventAction_Collision; - this->onCollisionResponse = Default::EventAction_CollisionResponse; + this->onCollision = Default::EventAction_BeforeCollisionResponse; + this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; this->onMovement = Default::EventAction_Move; this->scene = nullptr; this->customTag = nullptr; @@ -40,7 +40,7 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des } else { - this->onCollision = Default::EventAction_Collision; + this->onCollision = Default::EventAction_BeforeCollisionResponse; } if( desc.subscription_onCollisionResponse ) @@ -49,7 +49,7 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des } else { - this->onCollisionResponse = Default::EventAction_CollisionResponse; + this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; } if( desc.subscription_onMovement ) @@ -128,12 +128,12 @@ void SphericalRigidBody::SetState( const SphericalRigidBody::State &state ) } } -ICustomBody::SubscriptMessage SphericalRigidBody::CallSubscription_Collision( const ICustomBody *deuter ) +ICustomBody::SubscriptMessage SphericalRigidBody::CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter ) { return this->onCollision( this, deuter ); } -void SphericalRigidBody::CallSubscription_CollisionResponse( const ICustomBody *deuter, Float kineticEnergyLoss ) +void SphericalRigidBody::CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, Float kineticEnergyLoss ) { this->onCollisionResponse( this, deuter, kineticEnergyLoss); } @@ -238,7 +238,7 @@ void SphericalRigidBody::Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster: this->rigid.Predict_LeapFrog( outDeltaPos.xyz, outDeltaAxis.xyz, actingLinearImpulse.xyz, actingAngularImpulse.xyz, deltaTime ); } -void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer ) +void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_BeforeCollisionResponse functionPointer ) { if( functionPointer ) { @@ -246,11 +246,11 @@ void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision fun } else { - this->onCollision = Default::EventAction_Collision; + this->onCollision = Default::EventAction_BeforeCollisionResponse; } } -void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_CollisionResponse functionPointer ) +void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_AfterCollisionResponse functionPointer ) { if( functionPointer ) { @@ -258,7 +258,7 @@ void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_CollisionResp } else { - this->onCollisionResponse = Default::EventAction_CollisionResponse; + this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; } } diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.h b/Code/GamePhysics/Implementation/SphericalRigidBody.h index 213e225b..390b7171 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.h +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.h @@ -22,8 +22,8 @@ namespace Oyster { namespace Physics void SetState( const State &state ); //::Oyster::Math::Float3 GetRigidLinearVelocity() const; - SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter ); - void CallSubscription_CollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); + SubscriptMessage CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter ); + void CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); void CallSubscription_Move(); bool IsAffectedByGravity() const; @@ -45,8 +45,8 @@ namespace Oyster { namespace Physics void SetScene( void *scene ); - void SetSubscription( EventAction_Collision functionPointer ); - void SetSubscription( EventAction_CollisionResponse functionPointer ); + void SetSubscription( EventAction_BeforeCollisionResponse functionPointer ); + void SetSubscription( EventAction_AfterCollisionResponse functionPointer ); void SetSubscription( EventAction_Move functionPointer ); void SetGravity( bool ignore); @@ -66,8 +66,8 @@ namespace Oyster { namespace Physics ::Oyster::Physics3D::RigidBody rigid; ::Oyster::Math::Float4 deltaPos, deltaAxis; ::Oyster::Math::Float3 gravityNormal; - EventAction_Collision onCollision; - EventAction_CollisionResponse onCollisionResponse; + EventAction_BeforeCollisionResponse onCollision; + EventAction_AfterCollisionResponse onCollisionResponse; EventAction_Move onMovement; Octree *scene; void *customTag; diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index 3ced2a55..353756eb 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -244,8 +244,8 @@ namespace Oyster SubscriptMessage_ignore_collision_response }; - typedef SubscriptMessage (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter ); - typedef void (*EventAction_CollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); + typedef SubscriptMessage (*EventAction_BeforeCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter ); + typedef void (*EventAction_AfterCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ); typedef void (*EventAction_Move)( const ICustomBody *object ); typedef Struct::SimpleBodyDescription SimpleBodyDescription; typedef Struct::SphericalBodyDescription SphericalBodyDescription; @@ -262,12 +262,12 @@ namespace Oyster /******************************************************** * @todo TODO: need doc ********************************************************/ - virtual SubscriptMessage CallSubscription_Collision( const ICustomBody *deuter ) = 0; + virtual SubscriptMessage CallSubscription_BeforeCollisionResponse( const ICustomBody *deuter ) = 0; /******************************************************** * @todo TODO: need doc ********************************************************/ - virtual void CallSubscription_CollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ) = 0; + virtual void CallSubscription_AfterCollisionResponse( const ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss ) = 0; /******************************************************** * @todo TODO: need doc @@ -397,14 +397,14 @@ namespace Oyster * whenever a collision occurs. * @param functionPointer: If NULL, an empty default function will be set. ********************************************************/ - virtual void SetSubscription( EventAction_Collision functionPointer ) = 0; + virtual void SetSubscription( EventAction_BeforeCollisionResponse functionPointer ) = 0; /******************************************************** * Sets the function that will be called by the engine * whenever a collision has finished. * @param functionPointer: If NULL, an empty default function will be set. ********************************************************/ - virtual void SetSubscription( EventAction_CollisionResponse functionPointer ) = 0; + virtual void SetSubscription( EventAction_AfterCollisionResponse functionPointer ) = 0; /******************************************************** * Sets the function that will be called by the engine diff --git a/Code/GamePhysics/PhysicsStructs.h b/Code/GamePhysics/PhysicsStructs.h index 49cf6993..00c07b2d 100644 --- a/Code/GamePhysics/PhysicsStructs.h +++ b/Code/GamePhysics/PhysicsStructs.h @@ -19,8 +19,8 @@ namespace Oyster { namespace Physics ::Oyster::Math::Float frictionCoeff_Static; ::Oyster::Math::Float frictionCoeff_Dynamic; ::Oyster::Physics3D::MomentOfInertia inertiaTensor; - ::Oyster::Physics::ICustomBody::EventAction_Collision subscription_onCollision; - ::Oyster::Physics::ICustomBody::EventAction_CollisionResponse subscription_onCollisionResponse; + ::Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse subscription_onCollision; + ::Oyster::Physics::ICustomBody::EventAction_AfterCollisionResponse subscription_onCollisionResponse; ::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement; bool ignoreGravity; @@ -36,8 +36,8 @@ namespace Oyster { namespace Physics ::Oyster::Math::Float restitutionCoeff; ::Oyster::Math::Float frictionCoeff_Static; ::Oyster::Math::Float frictionCoeff_Dynamic; - ::Oyster::Physics::ICustomBody::EventAction_Collision subscription_onCollision; - ::Oyster::Physics::ICustomBody::EventAction_CollisionResponse subscription_onCollisionResponse; + ::Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse subscription_onCollision; + ::Oyster::Physics::ICustomBody::EventAction_AfterCollisionResponse subscription_onCollisionResponse; ::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement; bool ignoreGravity;