diff --git a/Code/GamePhysics/GamePhysics.vcxproj b/Code/GamePhysics/GamePhysics.vcxproj index c9f6513c..232bc3ed 100644 --- a/Code/GamePhysics/GamePhysics.vcxproj +++ b/Code/GamePhysics/GamePhysics.vcxproj @@ -24,7 +24,7 @@ - StaticLibrary + DynamicLibrary true v110 MultiByte @@ -66,22 +66,22 @@ - $(SolutionDir)..\External\Bin\DLL\ + $(SolutionDir)..\Bin\DLL\ $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ $(ProjectName)_$(PlatformShortName)D - $(SolutionDir)..\External\Bin\DLL\ + $(SolutionDir)..\Bin\DLL\ $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ $(ProjectName)_$(PlatformShortName) - $(SolutionDir)..\External\Bin\DLL\ + $(SolutionDir)..\Bin\DLL\ $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ $(ProjectName)_$(PlatformShortName)D - $(SolutionDir)..\External\Bin\DLL\ + $(SolutionDir)..\Bin\DLL\ $(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\ $(ProjectName)_$(PlatformShortName) @@ -90,6 +90,7 @@ Level3 Disabled $(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories) + _WINDLL;PHYSICS_DLL_EXPORT;%(PreprocessorDefinitions) true @@ -100,6 +101,7 @@ Level3 Disabled $(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories) + _WINDLL;PHYSICS_DLL_EXPORT;%(PreprocessorDefinitions) true @@ -112,6 +114,7 @@ true true $(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories) + _WINDLL;PHYSICS_DLL_EXPORT;%(PreprocessorDefinitions) true @@ -126,6 +129,7 @@ true true $(SolutionDir)Misc;$(SolutionDir)OysterMath;$(SolutionDir)OysterPhysics3D;%(AdditionalIncludeDirectories) + _WINDLL;PHYSICS_DLL_EXPORT;%(PreprocessorDefinitions) true @@ -145,14 +149,17 @@ + + - + + diff --git a/Code/GamePhysics/GamePhysics.vcxproj.filters b/Code/GamePhysics/GamePhysics.vcxproj.filters index 7118c2b5..4c0fd5f3 100644 --- a/Code/GamePhysics/GamePhysics.vcxproj.filters +++ b/Code/GamePhysics/GamePhysics.vcxproj.filters @@ -30,6 +30,9 @@ Header Files\Implementation + + Header Files\Implementation + @@ -38,7 +41,10 @@ Source Files - + + Source Files + + Source Files diff --git a/Code/GamePhysics/Implementation/DLLMain.cpp b/Code/GamePhysics/Implementation/DLLMain.cpp new file mode 100644 index 00000000..e46d1c83 --- /dev/null +++ b/Code/GamePhysics/Implementation/DLLMain.cpp @@ -0,0 +1,11 @@ +#define NOMINMAX + +#include +#include "OysterMath.h" + +BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, + _In_ DWORD fdwReason, + _In_ LPVOID lpvReserved ) +{ + return ::Oyster::Math::IsSupported(); +} \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/NullBody.cpp b/Code/GamePhysics/Implementation/NullBody.cpp deleted file mode 100644 index 76d2471d..00000000 --- a/Code/GamePhysics/Implementation/NullBody.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "..\PhysicsAPI.h" - -using namespace ::Oyster::Physics; -using namespace ::Oyster::Physics::Error; -using namespace ::Oyster::Math; -using namespace ::Oyster::Collision3D; -using namespace ::Utility::DynamicMemory; - -NullBody::~NullBody() {} - -UniquePointer NullBody::Clone() const -{ - return new NullBody( *this ); -} - -bool NullBody::IsSubscribingCollisions() const -{ - return false; -} - -bool NullBody::Intersects( const ICustomBody &object, Float &deltaWhen, Float3 &worldPointOfContact ) const -{ - return false; -} - -bool NullBody::Intersects( const ICollideable &shape ) const -{ - return false; -} - -unsigned int NullBody::GetReference() const -{ - return not_a_reference; -} - -Sphere & NullBody::GetBoundingSphere( Sphere &targetMem ) const -{ - return targetMem = Sphere( Float3::null, 0.0f ); -} - -Float3 & NullBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const -{ - return targetMem = Float3::standard_unit_z; -} - -Float3 & NullBody::GetCenter( Float3 &targetMem ) const -{ - return targetMem = Float3::null; -} - -Float4x4 & NullBody::GetRotation( Float4x4 &targetMem ) const -{ - return targetMem = Float4x4::identity; -} - -Float4x4 & NullBody::GetOrientation( Float4x4 &targetMem ) const -{ - return targetMem = Float4x4::identity; -} - -Float4x4 & NullBody::GetView( Float4x4 &targetMem ) const -{ - return targetMem = Float4x4::identity; -} - -UpdateState NullBody::Update( Float timeStepLength ) -{ - return resting; -} - -void NullBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI ) {} - -void NullBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI ) {} - -void NullBody::SetMass_KeepVelocity( Float m ) {} - -void NullBody::SetMass_KeepMomentum( Float m ) {} - -void NullBody::SetCenter( const Float3 &worldPos ) {} - -void NullBody::SetRotation( const Float4x4 &rotation ) {} - -void NullBody::SetOrientation( const Float4x4 &orientation ) {} \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/Octree.h b/Code/GamePhysics/Implementation/Octree.h new file mode 100644 index 00000000..22385dc6 --- /dev/null +++ b/Code/GamePhysics/Implementation/Octree.h @@ -0,0 +1,57 @@ +#ifndef OCTREE_H +#define OCTREE_H + +#include +#include +#include "Sphere.h" +#include "BoxAxisAligned.h" +#include "Utilities.h" +#include "../PhysicsAPI.h" + +namespace Oyster +{ + namespace Physics + { + class Octree + { + public: + struct Data + { + Data* prev; + Data* next; + + Collision3D::Sphere container; + + Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef; + + unsigned int queueRef; + }; + + struct OctreeNode + { + + }; + + Octree(unsigned int bufferSize, unsigned char numLayers, Math::Float3 worldSize); + virtual ~Octree(); + + void AddObject(Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef); + + void MoveToUpdateQueue(Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef); + + void Update(); + + void DestroyObject(Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef); + + void Sample(Collision3D::ICollideable& collideable); + private: + std::vector < Data > leafData; + + std::map< ICustomBody*, unsigned int > mapReferences; + + }; + } + +} + +#endif \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index c1816a0b..6c3e4a27 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -1,43 +1,82 @@ #include "PhysicsAPI_Impl.h" #include "SimpleRigidBody.h" +#include "OysterPhysics3D.h" using namespace ::Oyster::Physics; +using namespace ::Oyster::Physics3D; using namespace ::Oyster::Math; using namespace ::Oyster::Collision3D; using namespace ::Utility::DynamicMemory; -API_Impl instance; +API_Impl API_instance; -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 instance; + return Formula::MomentOfInertia::Sphere(mass, radius); +} + +Float4x4 & MomentOfInertia::CreateHollowSphereMatrix( const Float mass, const Float radius) +{ + return Formula::MomentOfInertia::HollowSphere(mass, radius); +} + +Float4x4 & MomentOfInertia::CreateCuboidMatrix( const Float mass, const Float height, const Float width, const Float depth ) +{ + return Formula::MomentOfInertia::Cuboid(mass, height, width, depth); +} + +Float4x4 & MomentOfInertia::CreateCylinderMatrix( const Float mass, const Float height, const Float radius ) +{ + return Formula::MomentOfInertia::Cylinder(mass, height, radius); +} + +Float4x4 & MomentOfInertia::CreateRodMatrix( const Float mass, const Float length ) +{ + return Formula::MomentOfInertia::RodCenter(mass, length); +} + +API & API::Instance() +{ + return API_instance; } API_Impl::API_Impl() -{ - /** @todo TODO: Fix this constructor.*/ -} + : gravityConstant( Constant::gravity_constant ), + updateFrameLength( 1.0f / 120.0f ), + collisionAction( defaultCollisionAction ), + destructionAction( defaultDestructionAction ) +{} -API_Impl::~API_Impl() +API_Impl::~API_Impl() {} + +void API_Impl::Init( unsigned int numObjects, unsigned int numGravityWells , const Float3 &worldSize ) { - /** @todo TODO: Fix this destructor.*/ + //! @todo TODO: implement stub } void API_Impl::SetDeltaTime( float deltaTime ) { - /** @todo TODO: Fix this function.*/ + updateFrameLength = deltaTime; } void API_Impl::SetGravityConstant( float g ) { - /** @todo TODO: Fix this function.*/ + this->gravityConstant = g; } -void API_Impl::SetAction( EventAction_Collision functionPointer ) +void API_Impl::SetAction( API::EventAction_Collision functionPointer ) { - /** @todo TODO: Fix this function.*/ + this->collisionAction = functionPointer; } -void API_Impl::SetAction( EventAction_Destruction functionPointer ) +void API_Impl::SetAction( API::EventAction_Destruction functionPointer ) { - /** @todo TODO: Fix this function.*/ + this->destructionAction = functionPointer; } void API_Impl::Update() @@ -45,80 +84,83 @@ void API_Impl::Update() /** @todo TODO: Fix this function.*/ } -bool API_Impl::IsInLimbo( unsigned int objRef ) +bool API_Impl::IsInLimbo( const ICustomBody* objRef ) { //! @todo TODO: implement stub return true; } -void API_Impl::MoveToLimbo( unsigned int objRef ) +void API_Impl::MoveToLimbo( const ICustomBody* objRef ) { /** @todo TODO: Fix this function.*/ } -void API_Impl::ReleaseFromLimbo( unsigned int objRef ) +void API_Impl::ReleaseFromLimbo( const ICustomBody* objRef ) { /** @todo TODO: Fix this function.*/ } -unsigned int API_Impl::AddObject( ::Utility::DynamicMemory::UniquePointer handle ) +void API_Impl::AddObject( ::Utility::DynamicMemory::UniquePointer handle ) { /** @todo TODO: Fix this function.*/ - - return 0; } -::Utility::DynamicMemory::UniquePointer ExtractObject( unsigned int objRef ) +::Utility::DynamicMemory::UniquePointer API_Impl::ExtractObject( const ICustomBody* objRef ) { //! @todo TODO: implement stub return NULL; } -void API_Impl::DestroyObject( unsigned int objRef ) +void API_Impl::DestroyObject( const ICustomBody* objRef ) { /** @todo TODO: Fix this function.*/ } -void API_Impl::ApplyForceAt( unsigned int objRef, const Float3 &worldPos, const Float3 &worldF ) +void API_Impl::ApplyForceAt( const ICustomBody* objRef, const Float3 &worldPos, const Float3 &worldF ) { //! @todo TODO: implement stub } -void API_Impl::ApplyCollisionResponse( unsigned int objRefA, unsigned int objRefB, Float &deltaWhen, Float3 &worldPointOfContact ) +void API_Impl::ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, Float &deltaWhen, Float3 &worldPointOfContact ) { //! @todo TODO: implement stub } -void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( unsigned int objRef, const Float4x4 &localI ) +void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI ) { //! @todo TODO: implement stub } -void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( unsigned int objRef, const Float4x4 &localI ) +void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const Float4x4 &localI ) { //! @todo TODO: implement stub } -void API_Impl::SetMass_KeepVelocity( unsigned int objRef, Float m ) +void API_Impl::SetMass_KeepVelocity( const ICustomBody* objRef, Float m ) { //! @todo TODO: implement stub } -void API_Impl::SetMass_KeepMomentum( unsigned int objRef, Float m ) +void API_Impl::SetMass_KeepMomentum( const ICustomBody* objRef, Float m ) { //! @todo TODO: implement stub } -void API_Impl::SetCenter( unsigned int objRef, const Float3 &worldPos ) +void API_Impl::SetCenter( const ICustomBody* objRef, const Float3 &worldPos ) { //! @todo TODO: implement stub } -void API_Impl::SetRotation( unsigned int objRef, const Float4x4 &rotation ) +void API_Impl::SetRotation( const ICustomBody* objRef, const Float4x4 &rotation ) { //! @todo TODO: implement stub } -void API_Impl::SetOrientation( unsigned int objRef, const Float4x4 &orientation ) +void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orientation ) +{ + //! @todo TODO: implement stub +} + +void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size ) { //! @todo TODO: implement stub } diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h index 3b1f217c..5a2e3ef6 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h @@ -13,6 +13,8 @@ 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 ); @@ -20,30 +22,32 @@ namespace Oyster void Update(); - bool IsInLimbo( unsigned int objRef ); - void MoveToLimbo( unsigned int objRef ); - void ReleaseFromLimbo( unsigned int objRef ); + bool IsInLimbo( const ICustomBody* objRef ); + void MoveToLimbo( const ICustomBody* objRef ); + void ReleaseFromLimbo( const ICustomBody* objRef ); - unsigned int AddObject( ::Utility::DynamicMemory::UniquePointer handle ); - ::Utility::DynamicMemory::UniquePointer ExtractObject( unsigned int objRef ); - void DestroyObject( unsigned int objRef ); + void AddObject( ::Utility::DynamicMemory::UniquePointer handle ); + ::Utility::DynamicMemory::UniquePointer ExtractObject( const ICustomBody* objRef ); + void DestroyObject( const ICustomBody* objRef ); - const ICustomBody & Peek( unsigned int objRef ) const; + void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ); + void ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ); - void ApplyForceAt( unsigned int objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ); - void ApplyCollisionResponse( unsigned int objRefA, unsigned int objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ); - - void SetMomentOfInertiaTensor_KeepVelocity( unsigned int objRef, const ::Oyster::Math::Float4x4 &localI ); - void SetMomentOfInertiaTensor_KeepMomentum( unsigned int objRef, const ::Oyster::Math::Float4x4 &localI ); - void SetMass_KeepVelocity( unsigned int objRef, ::Oyster::Math::Float m ); - void SetMass_KeepMomentum( unsigned int objRef, ::Oyster::Math::Float m ); - void SetCenter( unsigned int objRef, const ::Oyster::Math::Float3 &worldPos ); - void SetRotation( unsigned int objRef, const ::Oyster::Math::Float4x4 &rotation ); - void SetOrientation( unsigned int objRef, const ::Oyster::Math::Float4x4 &orientation ); + void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ); + void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ); + void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m ); + void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m ); + 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; }; - } } diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 59d501b4..cc1f847b 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -1,19 +1,19 @@ #include "SimpleRigidBody.h" +#include "PhysicsAPI_Impl.h" using namespace ::Oyster::Physics; -using namespace ::Oyster::Math; +using namespace ::Oyster::Math3D; using namespace ::Oyster::Collision3D; using namespace ::Utility::DynamicMemory; +using namespace ::Utility::Value; SimpleRigidBody::SimpleRigidBody() -{ - //! @todo TODO: implement stub -} + : previous(), current(), + gravityNormal(0.0f), + subscribeCollision(true), + ignoreGravity(false) {} -SimpleRigidBody::~SimpleRigidBody() -{ - //! @todo TODO: implement stub -} +SimpleRigidBody::~SimpleRigidBody() {} UniquePointer SimpleRigidBody::Clone() const { @@ -21,102 +21,132 @@ UniquePointer SimpleRigidBody::Clone() const } bool SimpleRigidBody::IsSubscribingCollisions() const -{ - //! @todo TODO: implement stub - return false; +{ // Assumption + return this->subscribeCollision; } -bool SimpleRigidBody::Intersects( const ICustomBody &object, Float &deltaWhen, Float3 &worldPointOfContact ) const +bool SimpleRigidBody::IsAffectedByGravity() const { - //! @todo TODO: implement stub - return false; + return !this->ignoreGravity; +} + +bool SimpleRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const +{ + if( object.Intersects(this->current.box) ) + { //! @todo TODO: better implementation needed + deltaWhen = timeStepLength; + worldPointOfContact = Average( this->current.box.center, object.GetCenter() ); + return true; + } + else + { + return false; + } } bool SimpleRigidBody::Intersects( const ICollideable &shape ) const { - //! @todo TODO: implement stub - return false; -} - -unsigned int SimpleRigidBody::GetReference() const -{ - //! @todo TODO: implement stub - return Error::not_a_reference; + return this->current.box.Intersects( shape ); } Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const { - //! @todo TODO: implement stub - return targetMem = Sphere( Float3::null, 0.0f ); + return targetMem = Sphere( this->current.box.center, this->current.box.boundingOffset.GetMagnitude() ); } Float3 & SimpleRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const { - //! @todo TODO: implement stub - return targetMem = Float3::standard_unit_z; + //! @todo TODO: better implementation needed + return targetMem = (worldPos - this->current.box.center).GetNormalized(); +} + +Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const +{ + return targetMem = this->gravityNormal; } Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const { - //! @todo TODO: implement stub - return targetMem = Float3::null; + return targetMem = this->current.box.center; } Float4x4 & SimpleRigidBody::GetRotation( Float4x4 &targetMem ) const { - //! @todo TODO: implement stub - return targetMem = Float4x4::identity; + return targetMem = this->current.box.rotation; } Float4x4 & SimpleRigidBody::GetOrientation( Float4x4 &targetMem ) const { - //! @todo TODO: implement stub - return targetMem = Float4x4::identity; + return targetMem = this->current.GetOrientation(); } Float4x4 & SimpleRigidBody::GetView( Float4x4 &targetMem ) const { - //! @todo TODO: implement stub - return targetMem = Float4x4::identity; + return targetMem = this->current.GetView(); } UpdateState SimpleRigidBody::Update( Float timeStepLength ) { - //! @todo TODO: implement stub - return resting; + this->previous = this->current; // memorizing the old state + + this->current.Update_LeapFrog( timeStepLength ); + + // compare previous and new state and return result + return this->current == this->previous ? resting : altered; +} + +void SimpleRigidBody::SetGravity( bool ignore) +{ + this->ignoreGravity = ignore; + this->gravityNormal = Float3::null; +} + +void SimpleRigidBody::SetGravityNormal( const Float3 &normalizedVector ) +{ + this->gravityNormal = normalizedVector; +} + +void SimpleRigidBody::SetSubscription( bool subscribeCollision ) +{ + this->subscribeCollision = subscribeCollision; } void SimpleRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI ) { - //! @todo TODO: implement stub + this->current.SetMomentOfInertia_KeepVelocity( localI ); } void SimpleRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI ) { - //! @todo TODO: implement stub + this->current.SetMomentOfInertia_KeepMomentum( localI ); } void SimpleRigidBody::SetMass_KeepVelocity( Float m ) { - //! @todo TODO: implement stub + this->current.SetMass_KeepVelocity( m ); } void SimpleRigidBody::SetMass_KeepMomentum( Float m ) { - //! @todo TODO: implement stub + this->current.SetMass_KeepMomentum( m ); } void SimpleRigidBody::SetCenter( const Float3 &worldPos ) { - //! @todo TODO: implement stub + this->current.SetCenter( worldPos ); } void SimpleRigidBody::SetRotation( const Float4x4 &rotation ) { - //! @todo TODO: implement stub + this->current.SetRotation( rotation ); } void SimpleRigidBody::SetOrientation( const Float4x4 &orientation ) { - //! @todo TODO: implement stub + 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 dd6531e6..41be919b 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -2,6 +2,7 @@ #define OYSTER_PHYSICS_SIMPLE_RIGIDBODY_H #include "..\PhysicsAPI.h" +#include "RigidBody.h" namespace Oyster { namespace Physics { @@ -14,12 +15,13 @@ namespace Oyster { namespace Physics ::Utility::DynamicMemory::UniquePointer Clone() const; bool IsSubscribingCollisions() const; - bool Intersects( const ICustomBody &object, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) 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; - unsigned int GetReference() 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 +29,9 @@ namespace Oyster { namespace Physics UpdateState Update( ::Oyster::Math::Float timeStepLength ); + 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 ); @@ -34,8 +39,12 @@ 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; + bool subscribeCollision, ignoreGravity; }; } } diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp new file mode 100644 index 00000000..20d806c9 --- /dev/null +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -0,0 +1,157 @@ +#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 ), + subscribeCollision( true ), + ignoreGravity( false ), + body( Float3::null, 0.5f ) {} + +SphericalRigidBody::~SphericalRigidBody() {} + +UniquePointer SphericalRigidBody::Clone() const +{ + return new SphericalRigidBody( *this ); +} + +bool SphericalRigidBody::IsSubscribingCollisions() const +{ // Assumption + return this->subscribeCollision; +} + +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 ? resting : altered; +} + +void SphericalRigidBody::SetGravity( bool ignore) +{ + this->ignoreGravity = ignore; + this->gravityNormal = Float3::null; +} + +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 ); +} + +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..7a727ee8 --- /dev/null +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.h @@ -0,0 +1,53 @@ +#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 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 ); + 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; + bool subscribeCollision, 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 c1f6ef43..bf80e6fa 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -3,7 +3,12 @@ #include "OysterCollision3D.h" #include "OysterMath.h" -#include "Utilities.h" + +#if defined PHYSICS_DLL_EXPORT + #define PHYSICS_DLL_USAGE __declspec(dllexport) +#else + #define PHYSICS_DLL_USAGE __declspec(dllimport) +#endif namespace Oyster { @@ -20,116 +25,357 @@ namespace Oyster namespace Constant { - const float gravity_constant = (const float)6.67284e-11; // The _big_G_! ( N(m/kg)^2 ) Used in real gravityforcefields. + const float gravity_constant = (const float)6.67284e-11; //!< The _big_G_! ( N(m/kg)^2 ) Used in real gravityforcefields. } - class API + class PHYSICS_DLL_USAGE MomentOfInertia { public: - typedef void (*EventAction_Collision)( unsigned int, unsigned int ); - typedef void (*EventAction_Destruction)( unsigned int, ::Utility::DynamicMemory::UniquePointer ); + static ::Oyster::Math::Float4x4 & CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius); + + static ::Oyster::Math::Float4x4 & CreateHollowSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius); + static ::Oyster::Math::Float4x4 & CreateCuboidMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth ); + + static ::Oyster::Math::Float4x4 & CreateCylinderMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius ); + + static ::Oyster::Math::Float4x4 & CreateRodMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length ); + }; + + 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(); - virtual void SetDeltaTime( float deltaTime ) = 0; + /******************************************************** + * 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. + ********************************************************/ + virtual void SetDeltaTime( float seconds ) = 0; + + /******************************************************** + * Sets the Gravityconstant in the physics that will be + * used in ForceField calculations. + * @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. + ********************************************************/ virtual void SetAction( EventAction_Destruction functionPointer ) = 0; + /******************************************************** + * Triggers the engine to run next update frame. + * All accumulated forces and changes will be consumed. + * EventAction functions might be called. + ********************************************************/ virtual void Update() = 0; - virtual bool IsInLimbo( unsigned int objRef ) = 0; - virtual void MoveToLimbo( unsigned int objRef ) = 0; - virtual void ReleaseFromLimbo( unsigned int objRef ) = 0; + /******************************************************** + * An object in limbo state will be ignored during the physics frame Update. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @return true if object is in limbo state. + ********************************************************/ + virtual bool IsInLimbo( const ICustomBody* objRef ) = 0; + + /******************************************************** + * An object in limbo state will be ignored during the physics frame Update. + * This will put an object in Limbo state. + * @param objRef: A pointer to the ICustomBody representing a physical object. + ********************************************************/ + virtual void MoveToLimbo( const ICustomBody* objRef ) = 0; + + /******************************************************** + * An object in limbo state will be ignored during the physics frame Update. + * This will clear the accumulated force/torque and remove the Limbo state. + * @param objRef: A pointer to the ICustomBody representing a physical object. + ********************************************************/ + virtual void ReleaseFromLimbo( const ICustomBody* objRef ) = 0; - virtual unsigned int AddObject( ::Utility::DynamicMemory::UniquePointer handle ) = 0; - virtual ::Utility::DynamicMemory::UniquePointer ExtractObject( unsigned int objRef ) = 0; - virtual void DestroyObject( unsigned int objRef ) = 0; + /******************************************************** + * Introduces a new object into the engine. + * @param handle: A pointer along with the responsibility to delete. + ********************************************************/ + virtual void AddObject( ::Utility::DynamicMemory::UniquePointer handle ) = 0; - virtual const ICustomBody & Peek( unsigned int objRef ) const = 0; + /******************************************************** + * Fetches and removes an object from the engine. + * Will not call the provided EventAction_Destruction method. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @return A pointer along with the responsibility to delete. NULL if faulty objRef. + ********************************************************/ + virtual ::Utility::DynamicMemory::UniquePointer ExtractObject( const ICustomBody* objRef ) = 0; - virtual void ApplyForceAt( unsigned int objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ) = 0; - virtual void ApplyCollisionResponse( unsigned int objRefA, unsigned int objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) = 0; + /******************************************************** + * Removes an object from the engine. + * Will call the provided EventAction_Destruction method. Not if objRef is faulty. + * @param objRef: A pointer to the ICustomBody representing a physical object. + ********************************************************/ + virtual void DestroyObject( const ICustomBody* objRef ) = 0; - virtual void SetMomentOfInertiaTensor_KeepVelocity( unsigned int objRef, const ::Oyster::Math::Float4x4 &localI ) = 0; - virtual void SetMomentOfInertiaTensor_KeepMomentum( unsigned int objRef, const ::Oyster::Math::Float4x4 &localI ) = 0; - virtual void SetMass_KeepVelocity( unsigned int objRef, ::Oyster::Math::Float m ) = 0; - virtual void SetMass_KeepMomentum( unsigned int objRef, ::Oyster::Math::Float m ) = 0; - virtual void SetCenter( unsigned int objRef, const ::Oyster::Math::Float3 &worldPos ) = 0; - virtual void SetRotation( unsigned int objRef, const ::Oyster::Math::Float4x4 &rotation ) = 0; - virtual void SetOrientation( unsigned int objRef, const ::Oyster::Math::Float4x4 &orientation ) = 0; + /******************************************************** + * Apply force on an object. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param worldPos: Relative to the world origo. (Not relative to object) [m] + * @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. + * @param objRefB: A pointer to the ICustomBody representing a physical object. + * @param deltaWhen: The elapsed simulation time since last update frame. [s] + * @param worldPointOfContact: Point of Collision, relative to the world origo. (Not relative to the objects) [m] + ********************************************************/ + virtual void ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) = 0; + + /******************************************************** + * Sets the MomentOfInertia tensor matrix of an object without changing it's angular velocity. + * Noticeable effect: The angular momentum will change. Changing the amount of kinetic energy. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace. + ********************************************************/ + virtual void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0; + + /******************************************************** + * Sets the MomentOfInertia tensor matrix of an object without changing it's angular momentum. + * Noticeable effect: The angular velocity will change. Can be used to create slow effects. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace. + ********************************************************/ + virtual void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0; + + /******************************************************** + * Sets the mass of an object without changing it's linear velocity. + * Noticeable effect: The linear momentum will change. Changing the amount of kinetic energy. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param m: [kg] + ********************************************************/ + virtual void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0; + + /******************************************************** + * Sets the mass of an object without changing it's linear velocity. + * Noticeable effect: The linear velocity will change. Can be used to create slow effects. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param m: [kg] + ********************************************************/ + virtual void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0; + + /******************************************************** + * Instantly moves an object. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param worldPos: Relative to the world origo. (Not relative to object) [m] + ********************************************************/ + virtual void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos ) = 0; + + /******************************************************** + * Instantly redirects object. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param rotation: New rotation. + ********************************************************/ + virtual void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation ) = 0; + + /******************************************************** + * Instantly moves and redirects object. + * @param objRef: A pointer to the ICustomBody representing a physical object. + * @param orientation: New orientation. + ********************************************************/ + 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. + ********************************************************/ virtual ::Utility::DynamicMemory::UniquePointer CreateSimpleRigidBody() const = 0; protected: virtual ~API() {} }; - class ICustomBody + //! The root interface for all physical representations processable by the engine. + class PHYSICS_DLL_USAGE ICustomBody { public: virtual ~ICustomBody() {}; + /******************************************************** + * Creates a complete copy of the current (type)object. + * @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; - virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const = 0; + + /******************************************************** + * @return true if Engine should apply gravity on this object. + ********************************************************/ + virtual bool IsAffectedByGravity() const = 0; + + /******************************************************** + * Performs a detailed Intersect test and returns if, when and where. + * @param object: What this is intersect testing against. + * @param timeStepLength: The value set by API::SetDeltaTime(...) + * @param deltaWhen: Time in seconds since last update frame til timeOfContact. 0.0f <= deltaWhen <= timeStepLength + * @param worldPointOfContact: Where at timeOfContact, this and object touches eachother. + * @return true if this truly intersects with object. + ********************************************************/ + virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const = 0; + + /******************************************************** + * param shape: Any defined sample shape. + * @return true if this truly intersects with shape. + ********************************************************/ virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const = 0; - virtual unsigned int GetReference() const = 0; - virtual ::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const = 0; - virtual ::Oyster::Math::Float3 & GetNormalAt( const ::Oyster::Math::Float3 &worldPos, ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0; - virtual ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0; - virtual ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0; - virtual ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0; - virtual ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0; - - virtual UpdateState Update( ::Oyster::Math::Float timeStepLength ) = 0; - - virtual void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ) = 0; - virtual void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ) = 0; - virtual void SetMass_KeepVelocity( ::Oyster::Math::Float m ) = 0; - virtual void SetMass_KeepMomentum( ::Oyster::Math::Float m ) = 0; - virtual void SetCenter( const ::Oyster::Math::Float3 &worldPos ) = 0; - virtual void SetRotation( const ::Oyster::Math::Float4x4 &rotation ) = 0; - virtual void SetOrientation( const ::Oyster::Math::Float4x4 &orientation ) = 0; - }; - - namespace Error - { - const unsigned int not_a_reference = ::Utility::Value::numeric_limits::max(); - - class NullBody : public ICustomBody - { - public: - virtual ~NullBody(); - - ::Utility::DynamicMemory::UniquePointer Clone() const; + /******************************************************** + * Required by Engine's Collision Search. + * @param targetMem: Provided memory that written into and then returned. + * @return a sphere shape that contains the ICustomBody. + ********************************************************/ + virtual ::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const = 0; - bool IsSubscribingCollisions() const; - bool Intersects( const ICustomBody &object, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const; - bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const; + /******************************************************** + * Required by Engine's Collision Responsing. + * @param worldPos: Should be worldPointOfContact from Intersects( ... ) + * @param targetMem: Provided memory that written into and then returned. + * @return a surface normal in worldSpace. + ********************************************************/ + 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; - unsigned int GetReference() 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 & 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; + /******************************************************** + * The world position of this center of gravity. + * @param targetMem: Provided memory that written into and then returned. + * @return a position in worldSpace. + ********************************************************/ + virtual ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0; + + /******************************************************** + * @param targetMem: Provided memory that written into and then returned. + * @return a copy of this's rotation matrix. + ********************************************************/ + virtual ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0; + + /******************************************************** + * @param targetMem: Provided memory that written into and then returned. + * @return a copy of this's orientation matrix. + ********************************************************/ + virtual ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0; + + /******************************************************** + * @param targetMem: Provided memory that written into and then returned. + * @return a copy of this's view matrix. + ********************************************************/ + virtual ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0; - UpdateState Update( ::Oyster::Math::Float timeStepLength ); + /******************************************************** + * To not be called if is in Engine + * Is called during API::Update + ********************************************************/ + virtual UpdateState Update( ::Oyster::Math::Float timeStepLength ) = 0; + + /******************************************************** + * @param ignore: True if Engine should not apply Gravity. + ********************************************************/ + virtual void SetGravity( bool ignore) = 0; - 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 ); + /******************************************************** + * Used by Engine + * @param normalizedVector: Should have same direction as the pullinggravity. + ********************************************************/ + virtual void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector ) = 0; - } const nobody; - } + /******************************************************** + * @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 + ********************************************************/ + virtual void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ) = 0; + + /******************************************************** + * To not be called if is in Engine + * Use API::SetMomentOfInertiaTensor_KeepMomentum(...) + ********************************************************/ + virtual void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ) = 0; + + /******************************************************** + * To not be called if is in Engine + * Use API::SetMass_KeepVelocity(...) + ********************************************************/ + virtual void SetMass_KeepVelocity( ::Oyster::Math::Float m ) = 0; + + /******************************************************** + * To not be called if is in Engine + * Use API::SetMass_KeepMomentum(...) + ********************************************************/ + virtual void SetMass_KeepMomentum( ::Oyster::Math::Float m ) = 0; + + /******************************************************** + * To not be called if is in Engine + * Use API::SetCenter(...) + ********************************************************/ + virtual void SetCenter( const ::Oyster::Math::Float3 &worldPos ) = 0; + + /******************************************************** + * To not be called if is in Engine + * Use API::SetRotation(...) + ********************************************************/ + virtual void SetRotation( const ::Oyster::Math::Float4x4 &rotation ) = 0; + + /******************************************************** + * 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; + }; } } #endif \ No newline at end of file diff --git a/Code/Misc/Utilities.h b/Code/Misc/Utilities.h index b01ab2c4..6a48ad7e 100644 --- a/Code/Misc/Utilities.h +++ b/Code/Misc/Utilities.h @@ -1,7 +1,7 @@ -///////////////////////////////////////////////////////////////////// +//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//! // Utility Collection of Miscellanious Handy Functions // © Dan Andersson 2013 -///////////////////////////////////////////////////////////////////// +//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//! #ifndef UTILITIES_H #define UTILITIES_H @@ -16,50 +16,50 @@ namespace Utility { namespace DynamicMemory { - /// If dynamicInstance is not NULL, then delete + //! If dynamicInstance is not NULL, then delete template void SafeDeleteInstance( Type *dynamicInstance ); - /// If dynamicArray is not NULL, then delete [] + //! If dynamicArray is not NULL, then delete [] template void SafeDeleteArray( Type dynamicArray[] ); - template - struct UniquePointer - { /// Wrapper to safely transfer dynamic ownership/responsibility + //! Wrapper to safely transfer dynamic ownership/responsibility + template struct UniquePointer + { public: - /// Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. - /// If NULL is assigned is equavalent with clearing all responsibilities from this UniquePointer. + //! Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. + //! If NULL is assigned is equavalent with clearing all responsibilities from this UniquePointer. UniquePointer( Type *assignedInstance = NULL ); - /// Will auto delete assigned dynamic instance. + //! Will auto delete assigned dynamic instance. ~UniquePointer(); - /// Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. - /// If NULL is assigned is equavalent with clearing all responsibilities from this UniquePointer. + //! Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. + //! If NULL is assigned is equavalent with clearing all responsibilities from this UniquePointer. UniquePointer & operator = ( Type *assignedInstance ); - /// Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted. - /// If donor had nothing, is equavalent with clearing all responsibilities from this UniquePointer. + //! Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted. + //! If donor had nothing, is equavalent with clearing all responsibilities from this UniquePointer. UniquePointer & operator = ( const UniquePointer &donor ); - /// Access the assigned dynamic instance. Will crash if nothing there + //! Access the assigned dynamic instance. Will crash if nothing there operator Type* (); - /// Access the assigned dynamic instance. Will crash if nothing there + //! Access the assigned dynamic instance. Will crash if nothing there operator const Type* () const; - /// Access members of the assigned dynamic instance. Will crash if nothing there + //! Access members of the assigned dynamic instance. Will crash if nothing there Type * operator -> (); - /// Access members of the assigned dynamic instance. Will crash if nothing there + //! Access members of the assigned dynamic instance. Will crash if nothing there const Type * operator -> () const; - /// If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. + //! If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. operator bool () const; - /// This UniquePointer drops all claims of ownership/responsibility and returns the dynamic instance. Now it is your responsibility to delete. + //! This UniquePointer drops all claims of ownership/responsibility and returns the dynamic instance. Now it is your responsibility to delete. Type* Release(); - /// (inline) If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. + //! (inline) If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. bool HaveOwnership() const; private: @@ -68,38 +68,38 @@ namespace Utility template struct UniqueArray - { /// Wrapper to safely transfer dynamic ownership/responsibility + { //! Wrapper to safely transfer dynamic ownership/responsibility public: - /// Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. - /// If NULL is assigned is equavalent with clearing all responsibilities from this UniqueArray. + //! Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. + //! If NULL is assigned is equavalent with clearing all responsibilities from this UniqueArray. UniqueArray( Type assignedArray[] = NULL ); - /// Will auto delete assigned dynamic array. + //! Will auto delete assigned dynamic array. ~UniqueArray(); - /// Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. - /// If NULL is assigned is equavalent with clearing all responsibilities from this UniqueArray. + //! Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. + //! If NULL is assigned is equavalent with clearing all responsibilities from this UniqueArray. UniqueArray & operator = ( Type assignedArray[] ); - /// Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted. - /// If donor had nothing, is equavalent with clearing all responsibilities from this UniqueArray. + //! Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted. + //! If donor had nothing, is equavalent with clearing all responsibilities from this UniqueArray. UniqueArray & operator = ( const UniqueArray &donor ); - /// Accesses the instance at index i of this UniqeArray's owned dynamic array. - /// Will crash if out-of-bound or there is no assigned array. + //! Accesses the instance at index i of this UniqeArray's owned dynamic array. + //! Will crash if out-of-bound or there is no assigned array. template Type & operator [] ( Index i ); - /// Accesses the instance at index i of this UniqeArray's owned dynamic array. - /// Will crash if out-of-bound or there is no assigned array. + //! Accesses the instance at index i of this UniqeArray's owned dynamic array. + //! Will crash if out-of-bound or there is no assigned array. template const Type & operator [] ( Index i ) const; - /// If true, this UniqueArray have a current ownership/responsibility of a dynamic instance. + //! If true, this UniqueArray have a current ownership/responsibility of a dynamic instance. operator bool () const; - /// This UniqueArray drops all claims of ownership/responsibility and returns the dynamic array. Now it is your responsibility to delete. + //! This UniqueArray drops all claims of ownership/responsibility and returns the dynamic array. Now it is your responsibility to delete. Type* Release(); - /// (inline) If true, this UniqueArray have a current ownership/responsibility of a dynamic array. + //! (inline) If true, this UniqueArray have a current ownership/responsibility of a dynamic array. bool HaveOwnership() const; private: @@ -215,7 +215,7 @@ namespace Utility inline ValueType Degree( const ValueType &radian ) { return radian * (180.0f / 3.1415926535897932384626433832795f); } - // SPECIALIZATIONS ////////////////////////////////////////// + // SPECIALIZATIONS //!//!//!//!//!//!//!//!//!//!//!//!//!//! template<> inline char Average( const char &valueA, const char &valueB ) { return (valueA + valueB) >> 1; } diff --git a/Code/OysterPhysics3D/Box.cpp b/Code/OysterPhysics3D/Box.cpp index ba97c5c5..e9f04b04 100644 --- a/Code/OysterPhysics3D/Box.cpp +++ b/Code/OysterPhysics3D/Box.cpp @@ -31,28 +31,28 @@ Box & Box::operator = ( const Box &box ) return ::Utility::DynamicMemory::UniquePointer( new Box(*this) ); } -bool Box::Intersects( const ICollideable *target ) const +bool Box::Intersects( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { case Type_universe: return true; - case Type_point: return Utility::Intersect( *this, *(Point*)target ); - case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance ); - case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target ); - case Type_plane: return Utility::Intersect( *this, *(Plane*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); + case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); + case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); + case Type_plane: return Utility::Intersect( *this, *(Plane*)&target ); // case Type_triangle: return false; // TODO: : - case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target ); - case Type_box: return Utility::Intersect( *this, *(Box*)target ); + case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target ); + case Type_box: return Utility::Intersect( *this, *(Box*)&target ); // case Type_frustrum: return false; // TODO: : default: return false; } } -bool Box::Contains( const ICollideable *target ) const +bool Box::Contains( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { - case Type_point: return Utility::Intersect( *this, *(Point*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); // case Type_sphere: return false; // TODO: // case Type_triangle: return false; // TODO: // case Type_box_axis_aligned: return false; // TODO: diff --git a/Code/OysterPhysics3D/Box.h b/Code/OysterPhysics3D/Box.h index ee46d6b6..d40c9f30 100644 --- a/Code/OysterPhysics3D/Box.h +++ b/Code/OysterPhysics3D/Box.h @@ -33,8 +33,8 @@ namespace Oyster { namespace Collision3D Box & operator = ( const Box &box ); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; } } diff --git a/Code/OysterPhysics3D/BoxAxisAligned.cpp b/Code/OysterPhysics3D/BoxAxisAligned.cpp index 04bc53f1..bdd9d0a9 100644 --- a/Code/OysterPhysics3D/BoxAxisAligned.cpp +++ b/Code/OysterPhysics3D/BoxAxisAligned.cpp @@ -24,26 +24,26 @@ BoxAxisAligned & BoxAxisAligned::operator = ( const BoxAxisAligned &box ) ::Utility::DynamicMemory::UniquePointer BoxAxisAligned::Clone( ) const { return ::Utility::DynamicMemory::UniquePointer( new BoxAxisAligned(*this) ); } -bool BoxAxisAligned::Intersects( const ICollideable *target ) const +bool BoxAxisAligned::Intersects( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { case Type_universe: return true; - case Type_point: return Utility::Intersect( *this, *(Point*)target ); - case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance ); - case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target ); - case Type_plane: return Utility::Intersect( *this, *(Plane*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); + case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); + case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); + case Type_plane: return Utility::Intersect( *this, *(Plane*)&target ); // case Type_triangle: return false; // TODO: - case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target ); + case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target ); // case Type_box: return false; // TODO: // case Type_frustrum: return false; // TODO: default: return false; } } -bool BoxAxisAligned::Contains( const ICollideable *target ) const +bool BoxAxisAligned::Contains( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { // case Type_point: return false; // TODO: // case Type_sphere: return false; // TODO: diff --git a/Code/OysterPhysics3D/BoxAxisAligned.h b/Code/OysterPhysics3D/BoxAxisAligned.h index 9810c39a..a0e109b2 100644 --- a/Code/OysterPhysics3D/BoxAxisAligned.h +++ b/Code/OysterPhysics3D/BoxAxisAligned.h @@ -28,8 +28,8 @@ namespace Oyster { namespace Collision3D BoxAxisAligned & operator = ( const BoxAxisAligned &box ); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; } } diff --git a/Code/OysterPhysics3D/Frustrum.cpp b/Code/OysterPhysics3D/Frustrum.cpp index 9e45f579..a826a4e0 100644 --- a/Code/OysterPhysics3D/Frustrum.cpp +++ b/Code/OysterPhysics3D/Frustrum.cpp @@ -191,29 +191,29 @@ void Frustrum::WriteToByte( unsigned int &nextIndex, unsigned char targetMem[] ) ::Utility::DynamicMemory::UniquePointer Frustrum::Clone( ) const { return ::Utility::DynamicMemory::UniquePointer( new Frustrum(*this) ); } -bool Frustrum::Intersects( const ICollideable *target ) const +bool Frustrum::Intersects( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { case Type_universe: return true; - case Type_point: return Utility::Intersect( *this, *(Point*)target ); - case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance ); - case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target ); - case Type_plane: return Utility::Intersect( *this, *(Plane*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); + case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); + case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); + case Type_plane: return Utility::Intersect( *this, *(Plane*)&target ); // case Type_triangle: return false; // TODO: - case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)target ); - case Type_box: return Utility::Intersect( *this, *(Box*)target ); - case Type_frustrum: return Utility::Intersect( *this, *(Frustrum*)target ); + case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target ); + case Type_box: return Utility::Intersect( *this, *(Box*)&target ); + case Type_frustrum: return Utility::Intersect( *this, *(Frustrum*)&target ); // case Type_line: return false; // TODO: default: return false; } } -bool Frustrum::Contains( const ICollideable *target ) const +bool Frustrum::Contains( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { - case Type_point: return Utility::Intersect( *this, *(Point*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); // case Type_ray: return false; // TODO: // case Type_sphere: return false; // TODO: // case Type_plane: return false; // TODO: diff --git a/Code/OysterPhysics3D/Frustrum.h b/Code/OysterPhysics3D/Frustrum.h index c711c9af..afd8d8bd 100644 --- a/Code/OysterPhysics3D/Frustrum.h +++ b/Code/OysterPhysics3D/Frustrum.h @@ -38,8 +38,8 @@ namespace Oyster { namespace Collision3D void WriteToByte( unsigned char targetMem[], unsigned int &nextIndex ) const; /// DEPRECATED virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; // INLINE IMPLEMENTATIONS /////////////////////////////////////// diff --git a/Code/OysterPhysics3D/ICollideable.h b/Code/OysterPhysics3D/ICollideable.h index 4b620506..34a86f7b 100644 --- a/Code/OysterPhysics3D/ICollideable.h +++ b/Code/OysterPhysics3D/ICollideable.h @@ -8,7 +8,7 @@ #include "Utilities.h" -namespace Oyster { namespace Collision3D /// Contains a collection of 3D shapes and intercollission algorithms. +namespace Oyster { namespace Collision3D //! Contains a collection of 3D shapes and intercollission algorithms. { class ICollideable { @@ -34,8 +34,8 @@ namespace Oyster { namespace Collision3D /// Contains a collection of 3D shapes virtual ~ICollideable(); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const = 0; - virtual bool Intersects( const ICollideable *target ) const = 0; - virtual bool Contains( const ICollideable *target ) const = 0; + virtual bool Intersects( const ICollideable &target ) const = 0; + virtual bool Contains( const ICollideable &target ) const = 0; }; } } #endif \ No newline at end of file diff --git a/Code/OysterPhysics3D/Line.cpp b/Code/OysterPhysics3D/Line.cpp index 7093f6b2..6258c9d9 100644 --- a/Code/OysterPhysics3D/Line.cpp +++ b/Code/OysterPhysics3D/Line.cpp @@ -23,9 +23,9 @@ Line & Line::operator = ( const Line &line ) ::Utility::DynamicMemory::UniquePointer Line::Clone( ) const { return ::Utility::DynamicMemory::UniquePointer( new Line(*this) ); } -bool Line::Intersects( const ICollideable *target ) const +bool Line::Intersects( const ICollideable &target ) const { - if( target->type == Type_universe ) + if( target.type == Type_universe ) { this->ray.collisionDistance = 0.0f; return true; @@ -38,5 +38,5 @@ bool Line::Intersects( const ICollideable *target ) const return false; } -bool Line::Contains( const ICollideable *target ) const +bool Line::Contains( const ICollideable &target ) const { /* TODO: : */ return false; } diff --git a/Code/OysterPhysics3D/Line.h b/Code/OysterPhysics3D/Line.h index fecc0bd2..f062c0dc 100644 --- a/Code/OysterPhysics3D/Line.h +++ b/Code/OysterPhysics3D/Line.h @@ -29,8 +29,8 @@ namespace Oyster { namespace Collision3D Line & operator = ( const Line &line ); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; } } diff --git a/Code/OysterPhysics3D/Plane.cpp b/Code/OysterPhysics3D/Plane.cpp index d495584c..48a76883 100644 --- a/Code/OysterPhysics3D/Plane.cpp +++ b/Code/OysterPhysics3D/Plane.cpp @@ -22,31 +22,31 @@ Plane & Plane::operator = ( const Plane &plane ) ::Utility::DynamicMemory::UniquePointer Plane::Clone( ) const { return ::Utility::DynamicMemory::UniquePointer( new Plane(*this) ); } -bool Plane::Intersects( const ICollideable *target ) const +bool Plane::Intersects( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { case Type_universe: return true; - case Type_point: return Utility::Intersect( *this, *(Point*)target ); - case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance ); - case Type_sphere: return Utility::Intersect( *this, *(Sphere*)target ); - case Type_plane: return Utility::Intersect( *this, *(Plane*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); + case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); + case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target ); + case Type_plane: return Utility::Intersect( *this, *(Plane*)&target ); // case Type_triangle: return false; // TODO: - case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this ); - case Type_box: return Utility::Intersect( *(Box*)target, *this ); + case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this ); + case Type_box: return Utility::Intersect( *(Box*)&target, *this ); case Type_frustrum: return false; // TODO: case Type_line: return false; // TODO: default: return false; } } -bool Plane::Contains( const ICollideable *target ) const +bool Plane::Contains( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { - case Type_point: return Utility::Intersect( *this, *(Point*)target ); - case Type_ray: return Utility::Contains( *this, *(Ray*)target ); - case Type_plane: return Utility::Contains( *this, *(Plane*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); + case Type_ray: return Utility::Contains( *this, *(Ray*)&target ); + case Type_plane: return Utility::Contains( *this, *(Plane*)&target ); // case Type_triangle: return false; // TODO: default: return false; } diff --git a/Code/OysterPhysics3D/Plane.h b/Code/OysterPhysics3D/Plane.h index d44c92bd..b69c5c9f 100644 --- a/Code/OysterPhysics3D/Plane.h +++ b/Code/OysterPhysics3D/Plane.h @@ -28,8 +28,8 @@ namespace Oyster { namespace Collision3D Plane & operator = ( const Plane &plane ); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; } } diff --git a/Code/OysterPhysics3D/Point.cpp b/Code/OysterPhysics3D/Point.cpp index bf1057f3..a100359b 100644 --- a/Code/OysterPhysics3D/Point.cpp +++ b/Code/OysterPhysics3D/Point.cpp @@ -21,28 +21,28 @@ Point & Point::operator = ( const Point &point ) ::Utility::DynamicMemory::UniquePointer Point::Clone( ) const { return ::Utility::DynamicMemory::UniquePointer( new Point(*this) ); } -bool Point::Intersects( const ICollideable *target ) const +bool Point::Intersects( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { case Type_universe: return true; - case Type_point: return Utility::Intersect( *this, *(Point*)target ); - case Type_ray: return Utility::Intersect( *(Ray*)target, *this, ((Ray*)target)->collisionDistance ); - case Type_sphere: Utility::Intersect( *(Sphere*)target, *this ); - case Type_plane: return Utility::Intersect( *(Plane*)target, *this ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); + case Type_ray: return Utility::Intersect( *(Ray*)&target, *this, ((Ray*)&target)->collisionDistance ); + case Type_sphere: Utility::Intersect( *(Sphere*)&target, *this ); + case Type_plane: return Utility::Intersect( *(Plane*)&target, *this ); //case Type_triangle: return false; // TODO: - case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this ); - case Type_box: return Utility::Intersect( *(Box*)target, *this ); + case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this ); + case Type_box: return Utility::Intersect( *(Box*)&target, *this ); case Type_frustrum: return false; // TODO: default: return false; } } -bool Point::Contains( const ICollideable *target ) const +bool Point::Contains( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { - case Type_point: return Utility::Intersect( *this, *(Point*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); default: return false; } } \ No newline at end of file diff --git a/Code/OysterPhysics3D/Point.h b/Code/OysterPhysics3D/Point.h index 2529ae0c..42561909 100644 --- a/Code/OysterPhysics3D/Point.h +++ b/Code/OysterPhysics3D/Point.h @@ -27,8 +27,8 @@ namespace Oyster { namespace Collision3D Point & operator = ( const Point &point ); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; } } diff --git a/Code/OysterPhysics3D/Ray.cpp b/Code/OysterPhysics3D/Ray.cpp index 1983a9ba..6d501335 100644 --- a/Code/OysterPhysics3D/Ray.cpp +++ b/Code/OysterPhysics3D/Ray.cpp @@ -22,31 +22,31 @@ Ray & Ray::operator = ( const Ray &ray ) ::Utility::DynamicMemory::UniquePointer Ray::Clone( ) const { return ::Utility::DynamicMemory::UniquePointer( new Ray(*this) ); } -bool Ray::Intersects( const ICollideable *target ) const +bool Ray::Intersects( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { case Type_universe: this->collisionDistance = 0.0f; return true; - case Type_point: return Utility::Intersect( *this, *(Point*)target, this->collisionDistance ); - case Type_ray: return Utility::Intersect( *this, *(Ray*)target, this->collisionDistance, ((Ray*)target)->collisionDistance ); - case Type_sphere: return Utility::Intersect( *(Sphere*)target, *this, this->collisionDistance ); - case Type_plane: return Utility::Intersect( *(Plane*)target, *this, this->collisionDistance ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target, this->collisionDistance ); + case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, this->collisionDistance, ((Ray*)&target)->collisionDistance ); + case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this, this->collisionDistance ); + case Type_plane: return Utility::Intersect( *(Plane*)&target, *this, this->collisionDistance ); // case Type_triangle: return false; // TODO: - case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this, this->collisionDistance ); - case Type_box: return Utility::Intersect( *(Box*)target, *this, this->collisionDistance ); + case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this, this->collisionDistance ); + case Type_box: return Utility::Intersect( *(Box*)&target, *this, this->collisionDistance ); case Type_frustrum: return false; // TODO: default: return false; } } -bool Ray::Contains( const ICollideable *target ) const +bool Ray::Contains( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { - case Type_point: return Utility::Intersect( *this, *(Point*)target, this->collisionDistance ); - case Type_ray: Utility::Contains( *this, *(Ray*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target, this->collisionDistance ); + case Type_ray: Utility::Contains( *this, *(Ray*)&target ); default: return false; } } \ No newline at end of file diff --git a/Code/OysterPhysics3D/Ray.h b/Code/OysterPhysics3D/Ray.h index 4132c0b8..5f24ea81 100644 --- a/Code/OysterPhysics3D/Ray.h +++ b/Code/OysterPhysics3D/Ray.h @@ -36,8 +36,8 @@ namespace Oyster { namespace Collision3D Ray & operator = ( const Ray &ray ); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; } } diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index 748d2272..24648999 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -36,6 +36,51 @@ RigidBody & RigidBody::operator = ( const RigidBody &body ) return *this; } +bool RigidBody::operator == ( const RigidBody &body ) +{ + if( this->box.center != body.box.center ) + { + return false; + } + + if( this->box.rotation != body.box.rotation ) + { + return false; + } + + if( this->box.boundingOffset != body.box.boundingOffset ) + { + return false; + } + + if( this->angularMomentum != body.angularMomentum ) + { + return false; + } + + if( this->linearMomentum != body.linearMomentum ) + { + return false; + } + + if( this->impulseTorqueSum != body.impulseTorqueSum ) + { + return false; + } + + if( this->impulseForceSum != body.impulseForceSum ) + { + return false; + } + + return true; +} + +bool RigidBody::operator != ( const RigidBody &body ) +{ + return !this->operator==( body ); +} + void RigidBody::Update_LeapFrog( Float deltaTime ) { // by Dan Andersson: Euler leap frog update when Runga Kutta is not needed @@ -287,6 +332,11 @@ void RigidBody::SetCenter( const Float3 &worldPos ) this->box.center = worldPos; } +void RigidBody::SetRotation( const Float4x4 &r ) +{ // by Dan Andersson + this->box.rotation = r; +} + void RigidBody::SetImpulseTorque( const Float3 &worldT ) { // by Dan Andersson this->impulseTorqueSum = worldT; diff --git a/Code/OysterPhysics3D/RigidBody.h b/Code/OysterPhysics3D/RigidBody.h index b343ff07..bff6acde 100644 --- a/Code/OysterPhysics3D/RigidBody.h +++ b/Code/OysterPhysics3D/RigidBody.h @@ -24,6 +24,9 @@ namespace Oyster { namespace Physics3D RigidBody & operator = ( const RigidBody &body ); + bool operator == ( const RigidBody &body ); + bool operator != ( const RigidBody &body ); + void Update_LeapFrog( ::Oyster::Math::Float deltaTime ); void ApplyImpulseForce( const ::Oyster::Math::Float3 &worldF ); void ApplyImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos ); @@ -76,6 +79,7 @@ namespace Oyster { namespace Physics3D void SetOrientation( const ::Oyster::Math::Float4x4 &o ); void SetSize( const ::Oyster::Math::Float3 &widthHeight ); void SetCenter( const ::Oyster::Math::Float3 &worldPos ); + void SetRotation( const ::Oyster::Math::Float4x4 &r ); void SetImpulseTorque( const ::Oyster::Math::Float3 &worldT ); void SetAngularMomentum( const ::Oyster::Math::Float3 &worldH ); diff --git a/Code/OysterPhysics3D/Sphere.cpp b/Code/OysterPhysics3D/Sphere.cpp index 324abeeb..e30ad384 100644 --- a/Code/OysterPhysics3D/Sphere.cpp +++ b/Code/OysterPhysics3D/Sphere.cpp @@ -18,29 +18,29 @@ Sphere & Sphere::operator = ( const Sphere &sphere ) ::Utility::DynamicMemory::UniquePointer Sphere::Clone( ) const { return ::Utility::DynamicMemory::UniquePointer( new Sphere(*this) ); } -bool Sphere::Intersects( const ICollideable *target ) const +bool Sphere::Intersects( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { case Type_universe: return true; - case Type_point: return Utility::Intersect( *this, *(Point*)target ); - case Type_ray: return Utility::Intersect( *this, *(Ray*)target, ((Ray*)target)->collisionDistance ); - case Type_sphere: Utility::Intersect( *this, *(Sphere*)target ); - case Type_plane: return Utility::Intersect( *(Plane*)target, *this ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); + case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance ); + case Type_sphere: Utility::Intersect( *this, *(Sphere*)&target ); + case Type_plane: return Utility::Intersect( *(Plane*)&target, *this ); // case Type_triangle: return false; // TODO: - case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)target, *this ); - case Type_box: return Utility::Intersect( *(Box*)target, *this ); + case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this ); + case Type_box: return Utility::Intersect( *(Box*)&target, *this ); case Type_frustrum: return false; // TODO: default: return false; } } -bool Sphere::Contains( const ICollideable *target ) const +bool Sphere::Contains( const ICollideable &target ) const { - switch( target->type ) + switch( target.type ) { - case Type_point: return Utility::Intersect( *this, *(Point*)target ); - case Type_sphere: return Utility::Contains( *this, *(Sphere*)target ); + case Type_point: return Utility::Intersect( *this, *(Point*)&target ); + case Type_sphere: return Utility::Contains( *this, *(Sphere*)&target ); // case Type_triangle: return false; // TODO: case Type_box_axis_aligned: return false; // TODO: case Type_box: return false; // TODO: diff --git a/Code/OysterPhysics3D/Sphere.h b/Code/OysterPhysics3D/Sphere.h index 881c8928..8e73de0b 100644 --- a/Code/OysterPhysics3D/Sphere.h +++ b/Code/OysterPhysics3D/Sphere.h @@ -27,8 +27,8 @@ namespace Oyster { namespace Collision3D Sphere & operator = ( const Sphere &sphere ); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; } } diff --git a/Code/OysterPhysics3D/Universe.cpp b/Code/OysterPhysics3D/Universe.cpp index f473ff2c..725e2839 100644 --- a/Code/OysterPhysics3D/Universe.cpp +++ b/Code/OysterPhysics3D/Universe.cpp @@ -13,15 +13,15 @@ Universe & Universe::operator = ( const Universe &universe ) UniquePointer Universe::Clone( ) const { return UniquePointer( new Universe(*this) ); } -bool Universe::Intersects( const ICollideable *target ) const +bool Universe::Intersects( const ICollideable &target ) const { // universe touches everything - switch( target->type ) + switch( target.type ) { case Type_ray: - ((Ray*)target)->collisionDistance = 0.0f; + ((Ray*)&target)->collisionDistance = 0.0f; break; case Type_line: - ((Line*)target)->ray.collisionDistance = 0.0f; + ((Line*)&target)->ray.collisionDistance = 0.0f; break; default: break; } @@ -29,6 +29,6 @@ bool Universe::Intersects( const ICollideable *target ) const return true; } -bool Universe::Contains( const ICollideable *target ) const +bool Universe::Contains( const ICollideable &target ) const { return true; } // universe contains everything diff --git a/Code/OysterPhysics3D/Universe.h b/Code/OysterPhysics3D/Universe.h index fd06a454..ff8366be 100644 --- a/Code/OysterPhysics3D/Universe.h +++ b/Code/OysterPhysics3D/Universe.h @@ -19,8 +19,8 @@ namespace Oyster { namespace Collision3D Universe & operator = ( const Universe &universe ); virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable *target ) const; - bool Contains( const ICollideable *target ) const; + bool Intersects( const ICollideable &target ) const; + bool Contains( const ICollideable &target ) const; }; } }