diff --git a/Code/GamePhysics/GamePhysics.vcxproj b/Code/GamePhysics/GamePhysics.vcxproj index 562fecb4..540002a1 100644 --- a/Code/GamePhysics/GamePhysics.vcxproj +++ b/Code/GamePhysics/GamePhysics.vcxproj @@ -152,13 +152,15 @@ + + - + diff --git a/Code/GamePhysics/GamePhysics.vcxproj.filters b/Code/GamePhysics/GamePhysics.vcxproj.filters index b971ed32..72b83568 100644 --- a/Code/GamePhysics/GamePhysics.vcxproj.filters +++ b/Code/GamePhysics/GamePhysics.vcxproj.filters @@ -30,6 +30,9 @@ Header Files\Implementation + + Header Files\Implementation + Header Files\Implementation @@ -41,7 +44,10 @@ Source Files - + + Source Files + + Source Files diff --git a/Code/GamePhysics/DLLMain.cpp b/Code/GamePhysics/Implementation/DLLMain.cpp similarity index 100% rename from Code/GamePhysics/DLLMain.cpp rename to Code/GamePhysics/Implementation/DLLMain.cpp diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 54af5084..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,27 +43,36 @@ 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() {} +void API_Impl::Init( unsigned int numObjects, unsigned int numGravityWells , const Float3 &worldSize ) +{ + //! @todo TODO: implement stub +} + 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() @@ -155,7 +156,25 @@ void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orient //! @todo TODO: implement stub } +void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size ) +{ + //! @todo TODO: implement stub +} + 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 c02ebdb2..28858da0 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h @@ -13,10 +13,11 @@ namespace Oyster API_Impl(); virtual ~API_Impl(); + void Init( unsigned int numObjects, unsigned int numGravityWells , const ::Oyster::Math::Float3 &worldSize ); + 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(); @@ -38,15 +39,20 @@ namespace Oyster void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos ); void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation ); 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; 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 7fd15e40..95256915 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -7,7 +7,11 @@ using namespace ::Oyster::Collision3D; using namespace ::Utility::DynamicMemory; using namespace ::Utility::Value; -SimpleRigidBody::SimpleRigidBody() : previous(), current() {} +SimpleRigidBody::SimpleRigidBody() + : previous(), current(), + gravityNormal(0.0f), + collisionAction(Default::EventAction_Collision), + ignoreGravity(false) {} SimpleRigidBody::~SimpleRigidBody() {} @@ -16,9 +20,9 @@ UniquePointer SimpleRigidBody::Clone() const return new SimpleRigidBody( *this ); } -bool SimpleRigidBody::IsSubscribingCollisions() const -{ // Assumption - return true; +bool SimpleRigidBody::IsAffectedByGravity() const +{ + return !this->ignoreGravity; } bool SimpleRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const @@ -51,6 +55,11 @@ Float3 & SimpleRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem return targetMem = (worldPos - this->current.box.center).GetNormalized(); } +Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const +{ + return targetMem = this->gravityNormal; +} + Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const { return targetMem = this->current.box.center; @@ -78,7 +87,30 @@ 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) +{ + this->ignoreGravity = ignore; + this->gravityNormal = Float3::null; +} + +void SimpleRigidBody::SetGravityNormal( const Float3 &normalizedVector ) +{ + this->gravityNormal = normalizedVector; } void SimpleRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI ) @@ -114,4 +146,9 @@ void SimpleRigidBody::SetRotation( const Float4x4 &rotation ) void SimpleRigidBody::SetOrientation( const Float4x4 &orientation ) { this->current.SetOrientation( orientation ); +} + +void SimpleRigidBody::SetSize( const Float3 &size ) +{ + this->current.SetSize( size ); } \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h index 99295e44..c19a1ddb 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -14,12 +14,13 @@ 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; ::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const; ::Oyster::Math::Float3 & GetNormalAt( const ::Oyster::Math::Float3 &worldPos, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; + ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const; ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const; @@ -27,6 +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 SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ); void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ); void SetMass_KeepVelocity( ::Oyster::Math::Float m ); @@ -34,9 +38,13 @@ namespace Oyster { namespace Physics void SetCenter( const ::Oyster::Math::Float3 &worldPos ); void SetRotation( const ::Oyster::Math::Float4x4 &rotation ); void SetOrientation( const ::Oyster::Math::Float4x4 &orientation ); + void SetSize( const ::Oyster::Math::Float3 &size ); private: ::Oyster::Physics3D::RigidBody previous, current; + ::Oyster::Math::Float3 gravityNormal; + EventAction_Collision collisionAction; + bool ignoreGravity; }; } } diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp new file mode 100644 index 00000000..6d50b386 --- /dev/null +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -0,0 +1,159 @@ +#include "SphericalRigidBody.h" +#include "PhysicsAPI_Impl.h" + +using namespace ::Oyster::Physics; +using namespace ::Oyster::Math3D; +using namespace ::Oyster::Collision3D; +using namespace ::Utility::DynamicMemory; +using namespace ::Utility::Value; + +SphericalRigidBody::SphericalRigidBody() + : previous(), current( Box(Float4x4::identity, Float3::null, Float3(1.0f)) ), + gravityNormal( 0.0f ), + collisionAction(Default::EventAction_Collision), + ignoreGravity( false ), + body( Float3::null, 0.5f ) {} + +SphericalRigidBody::~SphericalRigidBody() {} + +UniquePointer SphericalRigidBody::Clone() const +{ + return new SphericalRigidBody( *this ); +} + +bool SphericalRigidBody::IsAffectedByGravity() const +{ + return !this->ignoreGravity; +} + +bool SphericalRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const +{ + if( object.Intersects(this->body) ) + { //! @todo TODO: better implementation needed + deltaWhen = timeStepLength; + worldPointOfContact = Average( this->body.center, object.GetCenter() ); + return true; + } + else + { + return false; + } +} + +bool SphericalRigidBody::Intersects( const ICollideable &shape ) const +{ + return this->current.box.Intersects( shape ); +} + +Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const +{ + return targetMem = this->body; +} + +Float3 & SphericalRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const +{ + //! @todo TODO: better implementation needed + return targetMem = (worldPos - this->current.box.center).GetNormalized(); +} + +Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const +{ + return targetMem = this->gravityNormal; +} + +Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const +{ + return targetMem = this->current.box.center; +} + +Float4x4 & SphericalRigidBody::GetRotation( Float4x4 &targetMem ) const +{ + return targetMem = this->current.box.rotation; +} + +Float4x4 & SphericalRigidBody::GetOrientation( Float4x4 &targetMem ) const +{ + return targetMem = this->current.GetOrientation(); +} + +Float4x4 & SphericalRigidBody::GetView( Float4x4 &targetMem ) const +{ + return targetMem = this->current.GetView(); +} + +UpdateState SphericalRigidBody::Update( Float timeStepLength ) +{ + this->previous = this->current; // memorizing the old state + + this->current.Update_LeapFrog( timeStepLength ); + this->body.center = this->current.GetCenter(); + + // compare previous and new state and return result + 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) +{ + this->ignoreGravity = ignore; + this->gravityNormal = Float3::null; +} + +void SphericalRigidBody::SetGravityNormal( const Float3 &normalizedVector ) +{ + this->gravityNormal = normalizedVector; +} + +void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI ) +{ + this->current.SetMomentOfInertia_KeepVelocity( localI ); +} + +void SphericalRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI ) +{ + this->current.SetMomentOfInertia_KeepMomentum( localI ); +} + +void SphericalRigidBody::SetMass_KeepVelocity( Float m ) +{ + this->current.SetMass_KeepVelocity( m ); +} + +void SphericalRigidBody::SetMass_KeepMomentum( Float m ) +{ + this->current.SetMass_KeepMomentum( m ); +} + +void SphericalRigidBody::SetCenter( const Float3 &worldPos ) +{ + this->current.SetCenter( worldPos ); + this->body.center = worldPos; +} + +void SphericalRigidBody::SetRotation( const Float4x4 &rotation ) +{ + this->current.SetRotation( rotation ); +} + +void SphericalRigidBody::SetOrientation( const Float4x4 &orientation ) +{ + this->current.SetOrientation( orientation ); + this->body.center = orientation.v[3].xyz; +} + +void SphericalRigidBody::SetSize( const Float3 &size ) +{ + this->current.SetSize( size ); + this->body.radius = 0.5f * Min( Min( size.x, size.y ), size.z ); // inline Min( FloatN )? +} \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.h b/Code/GamePhysics/Implementation/SphericalRigidBody.h new file mode 100644 index 00000000..1540f7a1 --- /dev/null +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.h @@ -0,0 +1,54 @@ +#ifndef OYSTER_PHYSICS_SPHERICAL_RIGIDBODY_H +#define OYSTER_PHYSICS_SPHERICAL_RIGIDBODY_H + +#include "..\PhysicsAPI.h" +#include "RigidBody.h" +#include "Sphere.h" + +namespace Oyster { namespace Physics +{ + class SphericalRigidBody : public ICustomBody + { + public: + SphericalRigidBody(); + virtual ~SphericalRigidBody(); + + ::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; + + ::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const; + ::Oyster::Math::Float3 & GetNormalAt( const ::Oyster::Math::Float3 &worldPos, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; + ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; + ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; + ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const; + ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const; + ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const; + + UpdateState Update( ::Oyster::Math::Float timeStepLength ); + + void SetSubscription( EventAction_Collision functionPointer ); + void SetGravity( bool ignore); + void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector ); + void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ); + void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ); + void SetMass_KeepVelocity( ::Oyster::Math::Float m ); + void SetMass_KeepMomentum( ::Oyster::Math::Float m ); + void SetCenter( const ::Oyster::Math::Float3 &worldPos ); + void SetRotation( const ::Oyster::Math::Float4x4 &rotation ); + void SetOrientation( const ::Oyster::Math::Float4x4 &orientation ); + void SetSize( const ::Oyster::Math::Float3 &size ); + + private: + ::Oyster::Physics3D::RigidBody previous, current; + ::Oyster::Math::Float3 gravityNormal; + EventAction_Collision collisionAction; + bool ignoreGravity; + ::Oyster::Collision3D::Sphere body; + }; +} } + +#endif \ No newline at end of file diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index 0f4a80ee..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,12 +45,19 @@ 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. */ static API & Instance(); + /******************************************************** + * Clears all content and reset Engine assetts such as buffers. + * @param numObjects: The predicted max number of active objects. + * @param numGravityWells: The predicted max number of active gravity wells. + * @param worldSize: The size of acceptable physics space. + ********************************************************/ + virtual void Init( unsigned int numObjects, unsigned int numGravityWells , const ::Oyster::Math::Float3 &worldSize ) = 0; + /******************************************************** * Sets the time length of each physics update frame. ********************************************************/ @@ -62,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. @@ -133,7 +135,7 @@ namespace Oyster * @param worldF: Vector with the direction and magnitude of the force. [N] ********************************************************/ virtual void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ) = 0; - + /******************************************************** * Apply force on an object. * @param objRefA: A pointer to the ICustomBody representing a physical object. @@ -196,6 +198,13 @@ namespace Oyster ********************************************************/ virtual void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation ) = 0; + /******************************************************** + * Resizes the boundingBox. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param size: New size of this [m] + ********************************************************/ + virtual void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size ) = 0; + /******************************************************** * Creates a new dynamically allocated object that can be used as a component for more complex ICustomBodies. * @return A pointer along with the responsibility to delete. @@ -210,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() {}; /******************************************************** @@ -217,11 +234,11 @@ 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. + * @return true if Engine should apply gravity on this object. ********************************************************/ - virtual bool IsSubscribingCollisions() const = 0; + virtual bool IsAffectedByGravity() const = 0; /******************************************************** * Performs a detailed Intersect test and returns if, when and where. @@ -254,6 +271,13 @@ namespace Oyster ********************************************************/ virtual ::Oyster::Math::Float3 & GetNormalAt( const ::Oyster::Math::Float3 &worldPos, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0; + /******************************************************** + * The gravity normal will have same direction as the total gravity force pulling on this and have the magnitude of 1.0f. + * @param targetMem: Provided memory that written into and then returned. + * @return a normalized vector in worldSpace. Exception: Null vector if no gravity been applied. + ********************************************************/ + virtual ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0; + /******************************************************** * The world position of this center of gravity. * @param targetMem: Provided memory that written into and then returned. @@ -280,52 +304,76 @@ namespace Oyster virtual ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0; /******************************************************** - * To be only called by Engine + * To not be called if is in Engine * Is called during API::Update ********************************************************/ 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; /******************************************************** - * To be only called by Engine + * @param ignore: True if Engine should not apply Gravity. + ********************************************************/ + virtual void SetGravity( bool ignore) = 0; + + /******************************************************** + * Used by Engine + * @param normalizedVector: Should have same direction as the pullinggravity. + ********************************************************/ + virtual void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector ) = 0; + + /******************************************************** + * To not be called if is in Engine * Use API::SetMomentOfInertiaTensor_KeepVelocity(...) instead ********************************************************/ virtual void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ) = 0; /******************************************************** - * To be only called by Engine + * To not be called if is in Engine * Use API::SetMomentOfInertiaTensor_KeepMomentum(...) ********************************************************/ virtual void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ) = 0; /******************************************************** - * To be only called by Engine + * To not be called if is in Engine * Use API::SetMass_KeepVelocity(...) ********************************************************/ virtual void SetMass_KeepVelocity( ::Oyster::Math::Float m ) = 0; /******************************************************** - * To be only called by Engine + * To not be called if is in Engine * Use API::SetMass_KeepMomentum(...) ********************************************************/ virtual void SetMass_KeepMomentum( ::Oyster::Math::Float m ) = 0; /******************************************************** - * To be only called by Engine + * To not be called if is in Engine * Use API::SetCenter(...) ********************************************************/ virtual void SetCenter( const ::Oyster::Math::Float3 &worldPos ) = 0; /******************************************************** - * To be only called by Engine + * To not be called if is in Engine * Use API::SetRotation(...) ********************************************************/ virtual void SetRotation( const ::Oyster::Math::Float4x4 &rotation ) = 0; /******************************************************** - * To be only called by Engine + * To not be called if is in Engine * Use API::SetOrientation(...) ********************************************************/ virtual void SetOrientation( const ::Oyster::Math::Float4x4 &orientation ) = 0; + + /******************************************************** + * To not be called if is in Engine + * Use API::SetSize(...) + ********************************************************/ + virtual void SetSize( const ::Oyster::Math::Float3 &size ) = 0; }; } } diff --git a/Code/OysterMath/Matrix.h b/Code/OysterMath/Matrix.h index c5c8735e..c7b6b9e0 100644 --- a/Code/OysterMath/Matrix.h +++ b/Code/OysterMath/Matrix.h @@ -29,7 +29,7 @@ namespace LinearAlgebra Matrix2x2( ); Matrix2x2( const ScalarType &m11, const ScalarType &m12, const ScalarType &m21, const ScalarType &m22 ); - Matrix2x2( const Vector2 vec[2] ); + explicit Matrix2x2( const Vector2 vec[2] ); Matrix2x2( const Vector2 &vec1, const Vector2 &vec2 ); explicit Matrix2x2( const ScalarType element[4] ); Matrix2x2( const Matrix2x2 &matrix ); @@ -80,7 +80,7 @@ namespace LinearAlgebra Matrix3x3( const ScalarType &m11, const ScalarType &m12, const ScalarType &m13, const ScalarType &m21, const ScalarType &m22, const ScalarType &m23, const ScalarType &m31, const ScalarType &m32, const ScalarType &m33 ); - Matrix3x3( const Vector3 vec[3] ); + explicit Matrix3x3( const Vector3 vec[3] ); Matrix3x3( const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3 ); explicit Matrix3x3( const ScalarType element[9] ); Matrix3x3( const Matrix3x3 &matrix ); @@ -132,7 +132,7 @@ namespace LinearAlgebra const ScalarType &m21, const ScalarType &m22, const ScalarType &m23, const ScalarType &m24, const ScalarType &m31, const ScalarType &m32, const ScalarType &m33, const ScalarType &m34, const ScalarType &m41, const ScalarType &m42, const ScalarType &m43, const ScalarType &m44 ); - Matrix4x4( const Vector4 vec[4] ); + explicit Matrix4x4( const Vector4 vec[4] ); Matrix4x4( const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, const Vector4 &vec4 ); explicit Matrix4x4( const ScalarType element[16] ); Matrix4x4( const Matrix4x4 &matrix ); diff --git a/Code/OysterPhysics3D/Box.cpp b/Code/OysterPhysics3D/Box.cpp index e9f04b04..382c6732 100644 --- a/Code/OysterPhysics3D/Box.cpp +++ b/Code/OysterPhysics3D/Box.cpp @@ -8,13 +8,19 @@ using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; -Box::Box( ) - : ICollideable(Type_box), rotation(Float4x4::identity), center(0.0f), boundingOffset(0.5f) -{} +Box::Box( ) : ICollideable(Type_box) +{ + this->rotation = Float4x4::identity; + this->center =0.0f; + this->boundingOffset = Float3(0.5f); +} -Box::Box( const Float4x4 &r, const Float3 &p, const Float3 &s ) - : ICollideable(Type_box), rotation(r), center(p), boundingOffset(s*0.5) -{} +Box::Box( const Float4x4 &r, const Float3 &p, const Float3 &s ) : ICollideable(Type_box) +{ + this->rotation = r; + this->center = p; + this->boundingOffset = Float3(s*0.5); +} Box::~Box( ) {} diff --git a/Code/OysterPhysics3D/BoxAxisAligned.cpp b/Code/OysterPhysics3D/BoxAxisAligned.cpp index bdd9d0a9..f50f4b6d 100644 --- a/Code/OysterPhysics3D/BoxAxisAligned.cpp +++ b/Code/OysterPhysics3D/BoxAxisAligned.cpp @@ -8,10 +8,24 @@ using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; -BoxAxisAligned::BoxAxisAligned( ) : ICollideable(Type_box_axis_aligned), minVertex(-0.5f,-0.5f,-0.5f), maxVertex(0.5f,0.5f,0.5f) {} -BoxAxisAligned::BoxAxisAligned( const Float3 &_minVertex, const Float3 &_maxVertex ) : ICollideable(Type_box_axis_aligned), minVertex(_minVertex), maxVertex(_maxVertex) {} -BoxAxisAligned::BoxAxisAligned( const Float &leftClip, const Float &rightClip, const Float &topClip, const Float &bottomClip, const Float &nearClip, const Float &farClip ) - : ICollideable(Type_box_axis_aligned), minVertex(leftClip, bottomClip, nearClip), maxVertex(rightClip, topClip, farClip) {} +BoxAxisAligned::BoxAxisAligned( ) : ICollideable(Type_box_axis_aligned) +{ + this->minVertex = Float3(-0.5f,-0.5f,-0.5f ); + this->maxVertex = Float3( 0.5f, 0.5f, 0.5f ); +} + +BoxAxisAligned::BoxAxisAligned( const Float3 &_minVertex, const Float3 &_maxVertex ) : ICollideable(Type_box_axis_aligned) +{ + this->minVertex = _minVertex; + this->maxVertex = _maxVertex; +} + +BoxAxisAligned::BoxAxisAligned( const Float &leftClip, const Float &rightClip, const Float &topClip, const Float &bottomClip, const Float &nearClip, const Float &farClip ) : ICollideable(Type_box_axis_aligned) +{ + this->minVertex = Float3( leftClip, bottomClip, nearClip ); + this->maxVertex = Float3( rightClip, topClip, farClip ); +} + BoxAxisAligned::~BoxAxisAligned( ) {} BoxAxisAligned & BoxAxisAligned::operator = ( const BoxAxisAligned &box ) @@ -22,7 +36,9 @@ BoxAxisAligned & BoxAxisAligned::operator = ( const BoxAxisAligned &box ) } ::Utility::DynamicMemory::UniquePointer BoxAxisAligned::Clone( ) const -{ return ::Utility::DynamicMemory::UniquePointer( new BoxAxisAligned(*this) ); } +{ + return ::Utility::DynamicMemory::UniquePointer( new BoxAxisAligned(*this) ); +} bool BoxAxisAligned::Intersects( const ICollideable &target ) const { diff --git a/Code/OysterPhysics3D/Frustrum.cpp b/Code/OysterPhysics3D/Frustrum.cpp index a826a4e0..7099c2ce 100644 --- a/Code/OysterPhysics3D/Frustrum.cpp +++ b/Code/OysterPhysics3D/Frustrum.cpp @@ -74,13 +74,22 @@ namespace PrivateStatic } } -Frustrum::Frustrum() : ICollideable(Type_frustrum), - leftPlane(Float3::standard_unit_x, -0.5f), rightPlane(-Float3::standard_unit_x, 0.5f), - bottomPlane(Float3::standard_unit_y, -0.5f), topPlane(-Float3::standard_unit_y, 0.5f), - nearPlane(Float3::standard_unit_z, -0.5f), farPlane(-Float3::standard_unit_z, 0.5f) {} +Frustrum::Frustrum() : ICollideable(Type_frustrum) +{ + this->leftPlane = Plane( Float3::standard_unit_x, -0.5f ); + this->rightPlane = Plane(-Float3::standard_unit_x, 0.5f ), + this->bottomPlane = Plane( Float3::standard_unit_y, -0.5f ); + this->topPlane = Plane(-Float3::standard_unit_y, 0.5f ); + this->nearPlane = Plane( Float3::standard_unit_z, -0.5f ); + this->farPlane = Plane(-Float3::standard_unit_z, 0.5f ); +} Frustrum::Frustrum( const Float4x4 &vp ) : ICollideable(Type_frustrum) -{ PrivateStatic::VP_ToPlanes( this->leftPlane, this->rightPlane, this->bottomPlane, this->topPlane, this->nearPlane, this->farPlane, vp ); } +{ + PrivateStatic::VP_ToPlanes( this->leftPlane, this->rightPlane, this->bottomPlane, + this->topPlane, this->nearPlane, this->farPlane, + vp ); +} Frustrum::~Frustrum() {} diff --git a/Code/OysterPhysics3D/ICollideable.cpp b/Code/OysterPhysics3D/ICollideable.cpp index 89effa36..b0af99e4 100644 --- a/Code/OysterPhysics3D/ICollideable.cpp +++ b/Code/OysterPhysics3D/ICollideable.cpp @@ -6,7 +6,5 @@ using namespace ::Oyster::Collision3D; -ICollideable::ICollideable( Type _type ) - : type(_type) {} - +ICollideable::ICollideable( Type _type ) : type(_type) {} ICollideable::~ICollideable() {} \ No newline at end of file diff --git a/Code/OysterPhysics3D/Line.cpp b/Code/OysterPhysics3D/Line.cpp index 6258c9d9..17fe55f7 100644 --- a/Code/OysterPhysics3D/Line.cpp +++ b/Code/OysterPhysics3D/Line.cpp @@ -8,9 +8,24 @@ using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; -Line::Line( ) : ICollideable(Type_line), ray(), length(0.0f) {} -Line::Line( const class Ray &_ray, const Float &_length ) : ICollideable(Type_line), ray(_ray), length(_length) {} -Line::Line( const Float3 &origin, const Float3 &normalizedDirection, const Float &_length ) : ICollideable(Type_line), ray(origin, normalizedDirection), length(_length) {} +Line::Line( ) : ICollideable(Type_line) +{ + this->ray = Ray(); + this->length = 0.0f; +} + +Line::Line( const class Ray &_ray, const Float &_length ) : ICollideable(Type_line) +{ + this->ray = _ray; + this->length = _length; +} + +Line::Line( const Float3 &origin, const Float3 &normalizedDirection, const Float &_length ) : ICollideable(Type_line) +{ + this->ray = Ray( origin, normalizedDirection ); + this->length = _length; +} + Line::~Line( ) {} Line & Line::operator = ( const Line &line ) diff --git a/Code/OysterPhysics3D/Plane.cpp b/Code/OysterPhysics3D/Plane.cpp index 48a76883..a1a16b14 100644 --- a/Code/OysterPhysics3D/Plane.cpp +++ b/Code/OysterPhysics3D/Plane.cpp @@ -8,8 +8,18 @@ using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math; -Plane::Plane( ) : ICollideable(Type_plane), normal(), phasing(0.0f) {} -Plane::Plane( const Float3 &n, const Float &p ) : ICollideable(Type_plane), normal(n), phasing(p) {} +Plane::Plane( ) : ICollideable(Type_plane) +{ + this->normal = Float3::standard_unit_z; + this->phasing = 0.0f; +} + +Plane::Plane( const Float3 &n, const Float &p ) : ICollideable(Type_plane) +{ + this->normal = n; + this->phasing = p; +} + Plane::~Plane( ) {} Plane & Plane::operator = ( const Plane &plane ) diff --git a/Code/OysterPhysics3D/Point.cpp b/Code/OysterPhysics3D/Point.cpp index a100359b..cf1186c9 100644 --- a/Code/OysterPhysics3D/Point.cpp +++ b/Code/OysterPhysics3D/Point.cpp @@ -8,8 +8,16 @@ using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; -Point::Point( ) : ICollideable(Type_point), center() {} -Point::Point( const Float3 &pos ) : ICollideable(Type_point), center(pos) {} +Point::Point( ) : ICollideable(Type_point) +{ + this->center = Float3::null; +} + +Point::Point( const Float3 &pos ) : ICollideable(Type_point) +{ + this->center = pos; +} + Point::~Point( ) {} Point & Point::operator = ( const Point &point ) @@ -19,7 +27,9 @@ Point & Point::operator = ( const Point &point ) } ::Utility::DynamicMemory::UniquePointer Point::Clone( ) const -{ return ::Utility::DynamicMemory::UniquePointer( new Point(*this) ); } +{ + return ::Utility::DynamicMemory::UniquePointer( new Point(*this) ); +} bool Point::Intersects( const ICollideable &target ) const { diff --git a/Code/OysterPhysics3D/Ray.cpp b/Code/OysterPhysics3D/Ray.cpp index 6d501335..09fb13ec 100644 --- a/Code/OysterPhysics3D/Ray.cpp +++ b/Code/OysterPhysics3D/Ray.cpp @@ -8,8 +8,20 @@ using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math3D; -Ray::Ray( ) : ICollideable(Type_ray), origin(), direction(), collisionDistance(0.0f) {} -Ray::Ray( const Float3 &o, const ::Oyster::Math::Float3 &d ) : ICollideable(Type_ray), origin(o), direction(d), collisionDistance(0.0f) {} +Ray::Ray( ) : ICollideable(Type_ray) +{ + this->origin = Float3::null; + this->direction = Float3::standard_unit_z; + this->collisionDistance = 0.0f; +} + +Ray::Ray( const Float3 &o, const ::Oyster::Math::Float3 &d ) : ICollideable(Type_ray) +{ + this->origin = o; + this->direction = d; + this->collisionDistance = 0.0f; +} + Ray::~Ray( ) {} Ray & Ray::operator = ( const Ray &ray ) @@ -20,7 +32,9 @@ Ray & Ray::operator = ( const Ray &ray ) } ::Utility::DynamicMemory::UniquePointer Ray::Clone( ) const -{ return ::Utility::DynamicMemory::UniquePointer( new Ray(*this) ); } +{ + return ::Utility::DynamicMemory::UniquePointer( new Ray(*this) ); +} bool Ray::Intersects( const ICollideable &target ) const { diff --git a/Code/OysterPhysics3D/Sphere.cpp b/Code/OysterPhysics3D/Sphere.cpp index e30ad384..0cc8bc3b 100644 --- a/Code/OysterPhysics3D/Sphere.cpp +++ b/Code/OysterPhysics3D/Sphere.cpp @@ -4,8 +4,18 @@ using namespace ::Oyster::Collision3D; using namespace ::Oyster::Math; -Sphere::Sphere( ) : ICollideable(Type_sphere), center(), radius(0.0f) { } -Sphere::Sphere( const Float3 &_position, const Float &_radius ) : ICollideable(Type_sphere), center(_position), radius(_radius) {} +Sphere::Sphere( ) : ICollideable(Type_sphere) +{ + this->center = Float3::null; + this->radius = 0.0f; +} + +Sphere::Sphere( const Float3 &_position, const Float &_radius ) : ICollideable(Type_sphere) +{ + this->center = _position; + this->radius = _radius; +} + Sphere::~Sphere( ) {} Sphere & Sphere::operator = ( const Sphere &sphere )