Simple Rigid Body implementation
Second Iteration [iteration 1]: stubs [iteration 2]: implementations with shortcuts [iteration final]: implementations with real solutions
This commit is contained in:
parent
311beaac14
commit
a869771ffa
|
@ -7,7 +7,8 @@ using namespace ::Oyster::Math;
|
|||
using namespace ::Oyster::Collision3D;
|
||||
using namespace ::Utility::DynamicMemory;
|
||||
|
||||
API_Impl instance;
|
||||
API_Impl API_instance;
|
||||
Float updateFrameLength = 1.0f / 120.0f;
|
||||
|
||||
::Oyster::Math::Float4x4 & MomentOfInertia::CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius)
|
||||
{
|
||||
|
@ -36,7 +37,7 @@ API_Impl instance;
|
|||
|
||||
API & API::Instance()
|
||||
{
|
||||
return instance;
|
||||
return API_instance;
|
||||
}
|
||||
|
||||
API_Impl::API_Impl()
|
||||
|
@ -51,7 +52,7 @@ API_Impl::~API_Impl()
|
|||
|
||||
void API_Impl::SetDeltaTime( float deltaTime )
|
||||
{
|
||||
/** @todo TODO: Fix this function.*/
|
||||
updateFrameLength = deltaTime;
|
||||
}
|
||||
void API_Impl::SetGravityConstant( float g )
|
||||
{
|
||||
|
|
|
@ -41,7 +41,6 @@ namespace Oyster
|
|||
|
||||
::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateSimpleRigidBody() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
#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
|
||||
}
|
||||
SimpleRigidBody::SimpleRigidBody() : previous(), current() {}
|
||||
|
||||
SimpleRigidBody::~SimpleRigidBody()
|
||||
{
|
||||
//! @todo TODO: implement stub
|
||||
}
|
||||
SimpleRigidBody::~SimpleRigidBody() {}
|
||||
|
||||
UniquePointer<ICustomBody> SimpleRigidBody::Clone() const
|
||||
{
|
||||
|
@ -21,96 +17,101 @@ UniquePointer<ICustomBody> SimpleRigidBody::Clone() const
|
|||
}
|
||||
|
||||
bool SimpleRigidBody::IsSubscribingCollisions() const
|
||||
{
|
||||
//! @todo TODO: implement stub
|
||||
return false;
|
||||
{ // Assumption
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float &deltaWhen, Float3 &worldPointOfContact ) const
|
||||
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const
|
||||
{
|
||||
//! @todo TODO: implement stub
|
||||
return false;
|
||||
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;
|
||||
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::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::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 );
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
#define OYSTER_PHYSICS_SIMPLE_RIGIDBODY_H
|
||||
|
||||
#include "..\PhysicsAPI.h"
|
||||
#include "RigidBody.h"
|
||||
|
||||
namespace Oyster { namespace Physics
|
||||
{
|
||||
|
@ -14,7 +15,7 @@ namespace Oyster { namespace Physics
|
|||
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
|
||||
|
||||
bool IsSubscribingCollisions() const;
|
||||
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) 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;
|
||||
|
@ -35,6 +36,7 @@ namespace Oyster { namespace Physics
|
|||
void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
||||
|
||||
private:
|
||||
::Oyster::Physics3D::RigidBody previous, current;
|
||||
};
|
||||
} }
|
||||
|
||||
|
|
|
@ -226,11 +226,12 @@ namespace Oyster
|
|||
/********************************************************
|
||||
* Performs a detailed Intersect test and returns if, when and where.
|
||||
* @param object: What this is intersect testing against.
|
||||
* @param deltaWhen: Time in seconds since last update frame til timeOfContact. 0.0f <= deltaWhen <= deltaTime
|
||||
* @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 &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const = 0;
|
||||
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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue