Gravity implemented
This commit is contained in:
parent
337c92a5b8
commit
ff4a39cdac
|
@ -3,6 +3,7 @@
|
||||||
#include "SimpleRigidBody.h"
|
#include "SimpleRigidBody.h"
|
||||||
#include "SphericalRigidBody.h"
|
#include "SphericalRigidBody.h"
|
||||||
|
|
||||||
|
using namespace ::Oyster;
|
||||||
using namespace ::Oyster::Physics;
|
using namespace ::Oyster::Physics;
|
||||||
using namespace ::Oyster::Math;
|
using namespace ::Oyster::Math;
|
||||||
using namespace ::Oyster::Collision3D;
|
using namespace ::Oyster::Collision3D;
|
||||||
|
@ -113,6 +114,7 @@ API_Impl::API_Impl()
|
||||||
this->gravityConstant = Constant::gravity_constant;
|
this->gravityConstant = Constant::gravity_constant;
|
||||||
this->updateFrameLength = 1.0f / 120.0f;
|
this->updateFrameLength = 1.0f / 120.0f;
|
||||||
this->destructionAction = Default::EventAction_Destruction;
|
this->destructionAction = Default::EventAction_Destruction;
|
||||||
|
this->gravity = ::std::vector<Gravity>();
|
||||||
this->worldScene = Octree();
|
this->worldScene = Octree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +123,8 @@ API_Impl::~API_Impl() {}
|
||||||
void API_Impl::Init( unsigned int numObjects, unsigned int numGravityWells , const Float3 &worldSize )
|
void API_Impl::Init( unsigned int numObjects, unsigned int numGravityWells , const Float3 &worldSize )
|
||||||
{
|
{
|
||||||
unsigned char numLayers = 4; //!< @todo TODO: calc numLayers from worldSize
|
unsigned char numLayers = 4; //!< @todo TODO: calc numLayers from worldSize
|
||||||
|
this->gravity.resize( 0 );
|
||||||
|
this->gravity.reserve( numGravityWells );
|
||||||
this->worldScene = Octree( numObjects, numLayers, worldSize );
|
this->worldScene = Octree( numObjects, numLayers, worldSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,14 +157,39 @@ float API_Impl::GetFrameTimeLength() const
|
||||||
|
|
||||||
void API_Impl::Update()
|
void API_Impl::Update()
|
||||||
{ /** @todo TODO: Update is a temporary solution .*/
|
{ /** @todo TODO: Update is a temporary solution .*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
::std::vector<ICustomBody*> updateList;
|
::std::vector<ICustomBody*> updateList;
|
||||||
|
ICustomBody::State state;
|
||||||
auto proto = this->worldScene.Sample( Universe(), updateList ).begin();
|
auto proto = this->worldScene.Sample( Universe(), updateList ).begin();
|
||||||
for( ; proto != updateList.end(); ++proto )
|
for( ; proto != updateList.end(); ++proto )
|
||||||
{
|
{
|
||||||
// Step 1: @todo TODO: Apply Gravity
|
// Step 1: Apply Gravity
|
||||||
|
(*proto)->GetState( state );
|
||||||
|
for( ::std::vector<Gravity>::size_type i = 0; i < this->gravity.size(); ++i )
|
||||||
|
{
|
||||||
|
switch( this->gravity[i].gravityType )
|
||||||
|
{
|
||||||
|
case Gravity::GravityType_Well:
|
||||||
|
{
|
||||||
|
Float4 d = state.GetCenterPosition() - Float4( this->gravity[i].well.position, 1.0f );
|
||||||
|
Float rSquared = d.Dot( d );
|
||||||
|
if( rSquared != 0.0 )
|
||||||
|
{
|
||||||
|
Float force = Physics3D::Formula::ForceField( this->gravityConstant, state.GetMass(), this->gravity[i].well.mass, rSquared );
|
||||||
|
state.ApplyLinearImpulse( (this->updateFrameLength * force / ::std::sqrt(rSquared)) * d );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Gravity::GravityType_Directed:
|
||||||
|
state.ApplyLinearImpulse( Float4(this->gravity[i].directed.impulse, 0.0f) );
|
||||||
|
break;
|
||||||
|
// case Gravity::GravityType_DirectedField:
|
||||||
|
// //this->gravity[i].directedField.
|
||||||
|
// //! TODO: @todo rethink
|
||||||
|
// break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*proto)->SetState( state );
|
||||||
|
|
||||||
// Step 2: Apply Collision Response
|
// Step 2: Apply Collision Response
|
||||||
this->worldScene.Visit( *proto, OnPossibleCollision );
|
this->worldScene.Visit( *proto, OnPossibleCollision );
|
||||||
|
@ -213,6 +242,24 @@ void API_Impl::DestroyObject( const ICustomBody* objRef )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void API_Impl::AddGravity( const API::Gravity &g )
|
||||||
|
{
|
||||||
|
this->gravity.push_back( g );
|
||||||
|
}
|
||||||
|
|
||||||
|
void API_Impl::RemoveGravity( const API::Gravity &g )
|
||||||
|
{
|
||||||
|
for( ::std::vector<Gravity>::size_type i = this->gravity.size() - 1; i >= 0; --i )
|
||||||
|
{
|
||||||
|
if( g == this->gravity[i] )
|
||||||
|
{
|
||||||
|
int end = this->gravity.size() - 1;
|
||||||
|
this->gravity[i] = this->gravity[end];
|
||||||
|
this->gravity.resize( end );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//void API_Impl::ApplyForceAt( const ICustomBody* objRef, const Float3 &worldPos, const Float3 &worldF )
|
//void API_Impl::ApplyForceAt( const ICustomBody* objRef, const Float3 &worldPos, const Float3 &worldF )
|
||||||
//{
|
//{
|
||||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
|
|
@ -32,6 +32,9 @@ namespace Oyster
|
||||||
::Utility::DynamicMemory::UniquePointer<ICustomBody> ExtractObject( const ICustomBody* objRef );
|
::Utility::DynamicMemory::UniquePointer<ICustomBody> ExtractObject( const ICustomBody* objRef );
|
||||||
void DestroyObject( const ICustomBody* objRef );
|
void DestroyObject( const ICustomBody* objRef );
|
||||||
|
|
||||||
|
void AddGravity( const Gravity &g );
|
||||||
|
void RemoveGravity( const Gravity &g );
|
||||||
|
|
||||||
//void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF );
|
//void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF );
|
||||||
|
|
||||||
//void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
|
//void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
|
||||||
|
@ -49,6 +52,7 @@ namespace Oyster
|
||||||
private:
|
private:
|
||||||
::Oyster::Math::Float gravityConstant, updateFrameLength;
|
::Oyster::Math::Float gravityConstant, updateFrameLength;
|
||||||
EventAction_Destruction destructionAction;
|
EventAction_Destruction destructionAction;
|
||||||
|
::std::vector<Gravity> gravity;
|
||||||
Octree worldScene;
|
Octree worldScene;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace Oyster
|
||||||
struct SimpleBodyDescription;
|
struct SimpleBodyDescription;
|
||||||
struct SphericalBodyDescription;
|
struct SphericalBodyDescription;
|
||||||
struct CustomBodyState;
|
struct CustomBodyState;
|
||||||
|
struct Gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum UpdateState
|
enum UpdateState
|
||||||
|
@ -40,6 +41,7 @@ namespace Oyster
|
||||||
public:
|
public:
|
||||||
typedef Struct::SimpleBodyDescription SimpleBodyDescription;
|
typedef Struct::SimpleBodyDescription SimpleBodyDescription;
|
||||||
typedef Struct::SphericalBodyDescription SphericalBodyDescription;
|
typedef Struct::SphericalBodyDescription SphericalBodyDescription;
|
||||||
|
typedef Struct::Gravity Gravity;
|
||||||
|
|
||||||
typedef void (*EventAction_Destruction)( ::Utility::DynamicMemory::UniquePointer<ICustomBody> proto );
|
typedef void (*EventAction_Destruction)( ::Utility::DynamicMemory::UniquePointer<ICustomBody> proto );
|
||||||
|
|
||||||
|
@ -124,6 +126,16 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual void DestroyObject( const ICustomBody* objRef ) = 0;
|
virtual void DestroyObject( const ICustomBody* objRef ) = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* TODO: @todo doc
|
||||||
|
********************************************************/
|
||||||
|
virtual void AddGravity( const Gravity &g ) = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* TODO: @todo doc
|
||||||
|
********************************************************/
|
||||||
|
virtual void RemoveGravity( const Gravity &g ) = 0;
|
||||||
|
|
||||||
///********************************************************
|
///********************************************************
|
||||||
// * Apply force on an object.
|
// * Apply force on an object.
|
||||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||||
|
|
|
@ -273,6 +273,22 @@ namespace Oyster { namespace Physics3D
|
||||||
return momentOfInertia * angularImpulseAcceleration;
|
return momentOfInertia * angularImpulseAcceleration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* @todo TODO: doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float ForceField( ::Oyster::Math::Float g, ::Oyster::Math::Float massA, ::Oyster::Math::Float massB, ::Oyster::Math::Float radiusSquared )
|
||||||
|
{
|
||||||
|
return g * massA * massB / radiusSquared;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* @todo TODO: doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float ForceField( ::Oyster::Math::Float g, ::Oyster::Math::Float massA, ::Oyster::Math::Float massB, const ::Oyster::Math::Float4 &deltaPos )
|
||||||
|
{
|
||||||
|
return g * massA * massB / deltaPos.Dot( deltaPos );
|
||||||
|
}
|
||||||
|
|
||||||
namespace MomentOfInertia
|
namespace MomentOfInertia
|
||||||
{ /// Library of Formulas to calculate moment of inerta for simple shapes
|
{ /// Library of Formulas to calculate moment of inerta for simple shapes
|
||||||
/** @todo TODO: add MomentOfInertia tensor formulas */
|
/** @todo TODO: add MomentOfInertia tensor formulas */
|
||||||
|
|
Loading…
Reference in New Issue