Merge remote-tracking branch 'origin/Physics' into Sprint2
This commit is contained in:
commit
fba52398c3
|
@ -166,6 +166,8 @@
|
||||||
<ClInclude Include="Implementation\SimpleRigidBody.h" />
|
<ClInclude Include="Implementation\SimpleRigidBody.h" />
|
||||||
<ClInclude Include="Implementation\SphericalRigidBody.h" />
|
<ClInclude Include="Implementation\SphericalRigidBody.h" />
|
||||||
<ClInclude Include="PhysicsAPI.h" />
|
<ClInclude Include="PhysicsAPI.h" />
|
||||||
|
<ClInclude Include="PhysicsFormula-Impl.h" />
|
||||||
|
<ClInclude Include="PhysicsFormula.h" />
|
||||||
<ClInclude Include="PhysicsStructs-Impl.h" />
|
<ClInclude Include="PhysicsStructs-Impl.h" />
|
||||||
<ClInclude Include="PhysicsStructs.h" />
|
<ClInclude Include="PhysicsStructs.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -42,6 +42,12 @@
|
||||||
<ClInclude Include="PhysicsStructs-Impl.h">
|
<ClInclude Include="PhysicsStructs-Impl.h">
|
||||||
<Filter>Header Files\Include</Filter>
|
<Filter>Header Files\Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="PhysicsFormula.h">
|
||||||
|
<Filter>Header Files\Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="PhysicsFormula-Impl.h">
|
||||||
|
<Filter>Header Files\Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Implementation\PhysicsAPI_Impl.cpp">
|
<ClCompile Include="Implementation\PhysicsAPI_Impl.cpp">
|
||||||
|
|
|
@ -31,6 +31,7 @@ Octree& Octree::operator=(const Octree& orig)
|
||||||
|
|
||||||
void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
|
void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
|
||||||
{
|
{
|
||||||
|
customBodyRef->SetScene( this );
|
||||||
Data data;
|
Data data;
|
||||||
//Data* tempPtr = this->worldNode.dataPtr;
|
//Data* tempPtr = this->worldNode.dataPtr;
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
#include "SphericalRigidBody.h"
|
#include "SphericalRigidBody.h"
|
||||||
|
|
||||||
using namespace ::Oyster::Physics;
|
using namespace ::Oyster::Physics;
|
||||||
using namespace ::Oyster::Physics3D;
|
|
||||||
using namespace ::Oyster::Math;
|
using namespace ::Oyster::Math;
|
||||||
using namespace ::Oyster::Collision3D;
|
using namespace ::Oyster::Collision3D;
|
||||||
using namespace ::Utility::DynamicMemory;
|
using namespace ::Utility::DynamicMemory;
|
||||||
|
using namespace ::Utility::Value;
|
||||||
|
|
||||||
API_Impl API_instance;
|
API_Impl API_instance;
|
||||||
|
|
||||||
|
@ -18,38 +18,68 @@ namespace
|
||||||
auto proto = worldScene.GetCustomBody( protoTempRef );
|
auto proto = worldScene.GetCustomBody( protoTempRef );
|
||||||
auto deuter = worldScene.GetCustomBody( deuterTempRef );
|
auto deuter = worldScene.GetCustomBody( deuterTempRef );
|
||||||
|
|
||||||
float deltaWhen;
|
Float4 worldPointOfContact;
|
||||||
Float3 worldWhere;
|
if( proto->Intersects(*deuter, worldPointOfContact) )
|
||||||
if( proto->Intersects(*deuter, 1.0f, deltaWhen, worldWhere) )
|
|
||||||
{
|
{
|
||||||
proto->CallSubscription( proto, deuter );
|
switch( proto->CallSubscription(proto, deuter) )
|
||||||
|
{
|
||||||
|
case ICustomBody::SubscriptMessage_ignore_collision_response:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{ // Apply CollisionResponse in pure gather pattern
|
||||||
|
ICustomBody::State protoState; proto->GetState( protoState );
|
||||||
|
ICustomBody::State deuterState; deuter->GetState( deuterState );
|
||||||
|
|
||||||
|
Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact ),
|
||||||
|
deuterG = deuterState.GetLinearMomentum( worldPointOfContact );
|
||||||
|
|
||||||
|
// calc from perspective of deuter
|
||||||
|
Float4 normal; deuter->GetNormalAt( worldPointOfContact, normal );
|
||||||
|
Float protoG_Magnitude = protoG.Dot( normal ),
|
||||||
|
deuterG_Magnitude = deuterG.Dot( normal );
|
||||||
|
|
||||||
|
// bounce
|
||||||
|
Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(),
|
||||||
|
deuterState.GetMass(), deuterG_Magnitude,
|
||||||
|
protoState.GetMass(), protoG_Magnitude );
|
||||||
|
|
||||||
|
//sumJ -= Formula::CollisionResponse::Friction( impulse, normal,
|
||||||
|
// protoState.GetLinearMomentum(), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(),
|
||||||
|
// deuterState.GetLinearMomentum(), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass());
|
||||||
|
|
||||||
|
// calc from perspective of proto
|
||||||
|
proto->GetNormalAt( worldPointOfContact, normal );
|
||||||
|
protoG_Magnitude = protoG.Dot( normal ),
|
||||||
|
deuterG_Magnitude = deuterG.Dot( normal );
|
||||||
|
|
||||||
|
// bounce
|
||||||
|
Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(),
|
||||||
|
protoState.GetMass(), protoG_Magnitude,
|
||||||
|
deuterState.GetMass(), deuterG_Magnitude );
|
||||||
|
|
||||||
|
Float4 bounce = Average( bounceD, bounceP );
|
||||||
|
//Float4 bounce = bounceD + bounceP;
|
||||||
|
|
||||||
|
// FRICTION
|
||||||
|
// Apply
|
||||||
|
//sumJ += ( 1 / deuterState.GetMass() )*frictionImpulse;
|
||||||
|
// FRICTION END
|
||||||
|
|
||||||
|
Float4 forwardedDeltaPos, forwardedDeltaAxis;
|
||||||
|
{ // @todo TODO: is this right?
|
||||||
|
Float4 bounceAngularImpulse = ::Oyster::Math::Float4( (worldPointOfContact - protoState.GetCenterPosition()).xyz.Cross(bounce.xyz), 0.0f ),
|
||||||
|
bounceLinearImpulse = bounce - bounceAngularImpulse;
|
||||||
|
proto->Predict( forwardedDeltaPos, forwardedDeltaAxis, bounceLinearImpulse, bounceAngularImpulse, API_instance.GetFrameTimeLength() );
|
||||||
|
}
|
||||||
|
|
||||||
|
protoState.ApplyForwarding( forwardedDeltaPos, forwardedDeltaAxis );
|
||||||
|
protoState.ApplyImpulse( bounce, worldPointOfContact, normal );
|
||||||
|
proto->SetState( protoState );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Float4x4 & MomentOfInertia::CreateSphereMatrix( const Float mass, const Float radius, ::Oyster::Math::Float4x4 &targetMem )
|
|
||||||
{
|
|
||||||
return targetMem = Formula::MomentOfInertia::Sphere(mass, radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
Float4x4 & MomentOfInertia::CreateHollowSphereMatrix( const Float mass, const Float radius, ::Oyster::Math::Float4x4 &targetMem )
|
|
||||||
{
|
|
||||||
return targetMem = Formula::MomentOfInertia::HollowSphere(mass, radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
Float4x4 & MomentOfInertia::CreateCuboidMatrix( const Float mass, const Float height, const Float width, const Float depth, ::Oyster::Math::Float4x4 &targetMem )
|
|
||||||
{
|
|
||||||
return targetMem = Formula::MomentOfInertia::Cuboid(mass, height, width, depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
Float4x4 & MomentOfInertia::CreateCylinderMatrix( const Float mass, const Float height, const Float radius, ::Oyster::Math::Float4x4 &targetMem )
|
|
||||||
{
|
|
||||||
return targetMem = Formula::MomentOfInertia::Cylinder(mass, height, radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
Float4x4 & MomentOfInertia::CreateRodMatrix( const Float mass, const Float length, ::Oyster::Math::Float4x4 &targetMem )
|
|
||||||
{
|
|
||||||
return targetMem = Formula::MomentOfInertia::RodCenter(mass, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
API & API::Instance()
|
API & API::Instance()
|
||||||
|
@ -95,12 +125,23 @@ void API_Impl::SetSubscription( API::EventAction_Destruction functionPointer )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float API_Impl::GetFrameTimeLength() const
|
||||||
|
{
|
||||||
|
return this->updateFrameLength;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
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 2: Apply Collision Response
|
||||||
this->worldScene.Visit( *proto, OnPossibleCollision );
|
this->worldScene.Visit( *proto, OnPossibleCollision );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,101 +192,91 @@ void API_Impl::DestroyObject( const ICustomBody* objRef )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 );
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
{
|
// {
|
||||||
//this->worldScene.GetCustomBody( tempRef )->Apply //!< @todo TODO: need function
|
// //this->worldScene.GetCustomBody( tempRef )->Apply //!< @todo TODO: need function
|
||||||
this->worldScene.SetAsAltered( tempRef );
|
// this->worldScene.SetAsAltered( tempRef );
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void API_Impl::ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, Float &deltaWhen, Float3 &worldPointOfContact )
|
//void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI )
|
||||||
{
|
//{ // deprecated
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRefA );
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
{
|
// {
|
||||||
//! @todo TODO: implement stub
|
// this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepVelocity( localI );
|
||||||
this->worldScene.SetAsAltered( tempRef );
|
// }
|
||||||
}
|
//}
|
||||||
}
|
//
|
||||||
|
//void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const Float4x4 &localI )
|
||||||
void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI )
|
//{ // deprecated
|
||||||
{ // deprecated
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// {
|
||||||
{
|
// this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepMomentum( localI );
|
||||||
this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepVelocity( localI );
|
// }
|
||||||
}
|
//}
|
||||||
}
|
//
|
||||||
|
//void API_Impl::SetMass_KeepVelocity( const ICustomBody* objRef, Float m )
|
||||||
void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const Float4x4 &localI )
|
//{ // deprecated
|
||||||
{ // deprecated
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// {
|
||||||
{
|
// this->worldScene.GetCustomBody( tempRef )->SetMass_KeepVelocity( m );
|
||||||
this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepMomentum( localI );
|
// }
|
||||||
}
|
//}
|
||||||
}
|
//
|
||||||
|
//void API_Impl::SetMass_KeepMomentum( const ICustomBody* objRef, Float m )
|
||||||
void API_Impl::SetMass_KeepVelocity( const ICustomBody* objRef, Float m )
|
//{ // deprecated
|
||||||
{ // deprecated
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// {
|
||||||
{
|
// this->worldScene.GetCustomBody( tempRef )->SetMass_KeepMomentum( m );
|
||||||
this->worldScene.GetCustomBody( tempRef )->SetMass_KeepVelocity( m );
|
// }
|
||||||
}
|
//}
|
||||||
}
|
//
|
||||||
|
//void API_Impl::SetCenter( const ICustomBody* objRef, const Float3 &worldPos )
|
||||||
void API_Impl::SetMass_KeepMomentum( const ICustomBody* objRef, Float m )
|
//{
|
||||||
{ // deprecated
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// {
|
||||||
{
|
// //this->worldScene.GetCustomBody( tempRef )->Set //!< @todo TODO: need function
|
||||||
this->worldScene.GetCustomBody( tempRef )->SetMass_KeepMomentum( m );
|
// this->worldScene.EvaluatePosition( tempRef );
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void API_Impl::SetCenter( const ICustomBody* objRef, const Float3 &worldPos )
|
//void API_Impl::SetRotation( const ICustomBody* objRef, const Float4x4 &rotation )
|
||||||
{
|
//{
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
{
|
// {
|
||||||
//this->worldScene.GetCustomBody( tempRef )->Set //!< @todo TODO: need function
|
// this->worldScene.GetCustomBody( tempRef )->SetRotation( rotation );
|
||||||
this->worldScene.EvaluatePosition( tempRef );
|
// this->worldScene.EvaluatePosition( tempRef );
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void API_Impl::SetRotation( const ICustomBody* objRef, const Float4x4 &rotation )
|
//void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orientation )
|
||||||
{
|
//{
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
{
|
// {
|
||||||
this->worldScene.GetCustomBody( tempRef )->SetRotation( rotation );
|
// this->worldScene.GetCustomBody( tempRef )->SetOrientation( orientation );
|
||||||
this->worldScene.EvaluatePosition( tempRef );
|
// this->worldScene.EvaluatePosition( tempRef );
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orientation )
|
//void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size )
|
||||||
{
|
//{
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
// if( tempRef != this->worldScene.invalid_ref )
|
||||||
{
|
// {
|
||||||
this->worldScene.GetCustomBody( tempRef )->SetOrientation( orientation );
|
// this->worldScene.GetCustomBody( tempRef )->SetSize( size );
|
||||||
this->worldScene.EvaluatePosition( tempRef );
|
// this->worldScene.EvaluatePosition( tempRef );
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size )
|
|
||||||
{
|
|
||||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
|
||||||
if( tempRef != this->worldScene.invalid_ref )
|
|
||||||
{
|
|
||||||
this->worldScene.GetCustomBody( tempRef )->SetSize( size );
|
|
||||||
this->worldScene.EvaluatePosition( tempRef );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SimpleBodyDescription &desc ) const
|
UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SimpleBodyDescription &desc ) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,8 @@ namespace Oyster
|
||||||
void SetGravityConstant( float g );
|
void SetGravityConstant( float g );
|
||||||
void SetSubscription( EventAction_Destruction functionPointer );
|
void SetSubscription( EventAction_Destruction functionPointer );
|
||||||
|
|
||||||
|
float GetFrameTimeLength() const;
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
bool IsInLimbo( const ICustomBody* objRef );
|
bool IsInLimbo( const ICustomBody* objRef );
|
||||||
|
@ -30,17 +32,16 @@ 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 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 ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact );
|
|
||||||
|
|
||||||
void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
|
//void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
|
||||||
void SetMomentOfInertiaTensor_KeepMomentum( 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_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m );
|
||||||
void SetMass_KeepMomentum( 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 SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos );
|
||||||
void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation );
|
//void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation );
|
||||||
void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation );
|
//void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation );
|
||||||
void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size );
|
//void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size );
|
||||||
|
|
||||||
::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SimpleBodyDescription &desc ) const;
|
::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SimpleBodyDescription &desc ) const;
|
||||||
::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SphericalBodyDescription &desc ) const;
|
::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SphericalBodyDescription &desc ) const;
|
||||||
|
|
|
@ -8,19 +8,59 @@ using namespace ::Oyster::Collision3D;
|
||||||
using namespace ::Utility::DynamicMemory;
|
using namespace ::Utility::DynamicMemory;
|
||||||
using namespace ::Utility::Value;
|
using namespace ::Utility::Value;
|
||||||
|
|
||||||
|
namespace Private
|
||||||
|
{
|
||||||
|
const Float epsilon = (const Float)1e-20;
|
||||||
|
|
||||||
|
// Float calculations can suffer roundingerrors. Which is where epsilon = 1e-20 comes into the picture
|
||||||
|
inline bool EqualsZero( const Float &value )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
return Abs( value ) < epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Contains( const Plane &container, const Float4 &pos )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
return EqualsZero( container.normal.Dot( pos ) + container.phasing );
|
||||||
|
}
|
||||||
|
|
||||||
|
// revision of Ray Vs Plane intersect test, there ray is more of an axis
|
||||||
|
bool Intersects( const Ray &axis, const Plane &plane, Float &connectDistance )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
Float c = plane.normal.Dot(axis.direction);
|
||||||
|
if( EqualsZero(c) )
|
||||||
|
{ // axis is parallell with the plane. (axis direction orthogonal with the planar normal)
|
||||||
|
connectDistance = 0.0f;
|
||||||
|
return Contains( plane, axis.origin );
|
||||||
|
}
|
||||||
|
|
||||||
|
connectDistance = -plane.phasing;
|
||||||
|
connectDistance -= plane.normal.Dot( axis.origin );
|
||||||
|
connectDistance /= c;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SimpleRigidBody::SimpleRigidBody()
|
SimpleRigidBody::SimpleRigidBody()
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody( Box(Float4x4::identity, Float3::null, Float3(1.0f)), 16.0f, Float4x4::identity );
|
this->rigid = RigidBody();
|
||||||
|
this->rigid.SetMass_KeepMomentum( 16.0f );
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
this->collisionAction = Default::EventAction_Collision;
|
this->collisionAction = Default::EventAction_Collision;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = this->isForwarded = false;
|
||||||
|
this->scene = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody( Box( desc.rotation, desc.centerPosition, desc.size ),
|
this->rigid.SetRotation( desc.rotation );
|
||||||
desc.mass,
|
this->rigid.centerPos = desc.centerPosition;
|
||||||
desc.inertiaTensor );
|
this->rigid.SetSize( desc.size );
|
||||||
|
this->rigid.SetMass_KeepMomentum( desc.mass );
|
||||||
|
this->rigid.SetMomentOfInertia_KeepMomentum( desc.inertiaTensor );
|
||||||
|
this->deltaPos = Float4::null;
|
||||||
|
this->deltaAxis = Float4::null;
|
||||||
|
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
|
|
||||||
if( desc.subscription )
|
if( desc.subscription )
|
||||||
|
@ -33,6 +73,7 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
||||||
}
|
}
|
||||||
|
|
||||||
this->ignoreGravity = desc.ignoreGravity;
|
this->ignoreGravity = desc.ignoreGravity;
|
||||||
|
this->scene = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleRigidBody::~SimpleRigidBody() {}
|
SimpleRigidBody::~SimpleRigidBody() {}
|
||||||
|
@ -44,24 +85,60 @@ UniquePointer<ICustomBody> SimpleRigidBody::Clone() const
|
||||||
|
|
||||||
SimpleRigidBody::State SimpleRigidBody::GetState() const
|
SimpleRigidBody::State SimpleRigidBody::GetState() const
|
||||||
{
|
{
|
||||||
return State( this->rigid.box.boundingOffset, this->rigid.box.center, AngularAxis(this->rigid.box.rotation).xyz );
|
return State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
||||||
|
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
||||||
|
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
|
||||||
|
this->rigid.centerPos, this->rigid.axis,
|
||||||
|
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targetMem ) const
|
SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = State( this->rigid.box.boundingOffset, this->rigid.box.center, AngularAxis(this->rigid.box.rotation).xyz );
|
return targetMem = State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
||||||
|
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
||||||
|
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
|
||||||
|
this->rigid.centerPos, this->rigid.axis,
|
||||||
|
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
|
void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
|
||||||
{ /** @todo TODO: temporary solution! Need to know it's occtree */
|
{
|
||||||
this->rigid.box.boundingOffset = state.GetReach();
|
this->rigid.centerPos = state.GetCenterPosition();
|
||||||
this->rigid.box.center = state.GetCenterPosition();
|
this->rigid.SetRotation( state.GetRotation() );
|
||||||
this->rigid.box.rotation = state.GetRotation();
|
this->rigid.boundingReach = state.GetReach();
|
||||||
|
this->rigid.momentum_Linear = state.GetLinearMomentum();
|
||||||
|
this->rigid.momentum_Angular = state.GetAngularMomentum();
|
||||||
|
this->rigid.impulse_Linear += state.GetLinearImpulse();
|
||||||
|
this->rigid.impulse_Angular += state.GetAngularImpulse();
|
||||||
|
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
|
||||||
|
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
|
||||||
|
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
|
||||||
|
|
||||||
|
if( state.IsForwarded() )
|
||||||
|
{
|
||||||
|
this->deltaPos += state.GetForward_DeltaPos();
|
||||||
|
this->deltaAxis += state.GetForward_DeltaAxis();
|
||||||
|
this->isForwarded;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->scene )
|
||||||
|
{
|
||||||
|
if( state.IsSpatiallyAltered() )
|
||||||
|
{
|
||||||
|
unsigned int tempRef = this->scene->GetTemporaryReferenceOf( this );
|
||||||
|
this->scene->SetAsAltered( tempRef );
|
||||||
|
this->scene->EvaluatePosition( tempRef );
|
||||||
|
}
|
||||||
|
else if( state.IsDisturbed() )
|
||||||
|
{
|
||||||
|
this->scene->SetAsAltered( this->scene->GetTemporaryReferenceOf(this) );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
|
ICustomBody::SubscriptMessage SimpleRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
|
||||||
{
|
{
|
||||||
this->collisionAction( proto, deuter );
|
return this->collisionAction( proto, deuter );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SimpleRigidBody::IsAffectedByGravity() const
|
bool SimpleRigidBody::IsAffectedByGravity() const
|
||||||
|
@ -69,34 +146,76 @@ bool SimpleRigidBody::IsAffectedByGravity() const
|
||||||
return !this->ignoreGravity;
|
return !this->ignoreGravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const
|
|
||||||
{
|
|
||||||
if( object.Intersects(this->rigid.box) )
|
|
||||||
{ //! @todo TODO: better implementation needed
|
|
||||||
deltaWhen = timeStepLength;
|
|
||||||
worldPointOfContact = Average( this->rigid.box.center, object.GetCenter() );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SimpleRigidBody::Intersects( const ICollideable &shape ) const
|
bool SimpleRigidBody::Intersects( const ICollideable &shape ) const
|
||||||
{
|
{
|
||||||
return this->rigid.box.Intersects( shape );
|
return Box( this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize() ).Intersects( shape );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
return Box( this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize() ).Intersects( shape, worldPointOfContact );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
return object.Intersects( Box(this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize()), worldPointOfContact );
|
||||||
}
|
}
|
||||||
|
|
||||||
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = Sphere( this->rigid.box.center, this->rigid.box.boundingOffset.GetMagnitude() );
|
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.GetMagnitude() );
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 & SimpleRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const
|
Float4 & SimpleRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
|
||||||
{
|
{
|
||||||
//! @todo TODO: better implementation needed
|
Float4 offset = worldPos - this->rigid.centerPos;
|
||||||
return targetMem = (worldPos - this->rigid.box.center).GetNormalized();
|
Float distance = offset.Dot( offset );
|
||||||
|
Float3 normal = Float3::null;
|
||||||
|
|
||||||
|
if( distance != 0.0f )
|
||||||
|
{ // sanity check
|
||||||
|
Ray axis( Float4::standard_unit_w, offset / (Float)::std::sqrt(distance) );
|
||||||
|
Float minDistance = numeric_limits<Float>::max();
|
||||||
|
Float4x4 rotationMatrix = this->rigid.GetRotationMatrix();
|
||||||
|
|
||||||
|
if( Private::Intersects(axis, Plane(rotationMatrix.v[0], -this->rigid.boundingReach.x), axis.collisionDistance) )
|
||||||
|
{ // check along x-axis
|
||||||
|
if( axis.collisionDistance < 0.0f )
|
||||||
|
normal = -rotationMatrix.v[0].xyz;
|
||||||
|
else
|
||||||
|
normal = rotationMatrix.v[0].xyz;
|
||||||
|
|
||||||
|
minDistance = Abs( axis.collisionDistance );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Private::Intersects(axis, Plane(rotationMatrix.v[1], -this->rigid.boundingReach.y), axis.collisionDistance) )
|
||||||
|
{ // check along y-axis
|
||||||
|
distance = Abs( axis.collisionDistance ); // recycling memory
|
||||||
|
if( minDistance > distance )
|
||||||
|
{
|
||||||
|
if( axis.collisionDistance < 0.0f )
|
||||||
|
normal = -rotationMatrix.v[1].xyz;
|
||||||
|
else
|
||||||
|
normal = rotationMatrix.v[1].xyz;
|
||||||
|
|
||||||
|
minDistance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Private::Intersects(axis, Plane(rotationMatrix.v[2], -this->rigid.boundingReach.z), axis.collisionDistance) )
|
||||||
|
{ // check along z-axis
|
||||||
|
if( minDistance > Abs( axis.collisionDistance ) )
|
||||||
|
{
|
||||||
|
if( axis.collisionDistance < 0.0f )
|
||||||
|
normal = -rotationMatrix.v[2].xyz;
|
||||||
|
else
|
||||||
|
normal = rotationMatrix.v[2].xyz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
targetMem.xyz = normal;
|
||||||
|
targetMem.w = 0.0f;
|
||||||
|
return targetMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||||
|
@ -104,41 +223,59 @@ Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||||
return targetMem = this->gravityNormal;
|
return targetMem = this->gravityNormal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const
|
//Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const
|
||||||
{
|
//{
|
||||||
return targetMem = this->rigid.box.center;
|
// return targetMem = this->rigid.centerPos;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
|
//Float4x4 & SimpleRigidBody::GetRotation( Float4x4 &targetMem ) const
|
||||||
|
//{
|
||||||
|
// return targetMem = this->rigid.box.rotation;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//Float4x4 & SimpleRigidBody::GetOrientation( Float4x4 &targetMem ) const
|
||||||
|
//{
|
||||||
|
// return targetMem = this->rigid.GetOrientation();
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//Float4x4 & SimpleRigidBody::GetView( Float4x4 &targetMem ) const
|
||||||
|
//{
|
||||||
|
// return targetMem = this->rigid.GetView();
|
||||||
|
//}
|
||||||
|
|
||||||
Float4x4 & SimpleRigidBody::GetRotation( Float4x4 &targetMem ) const
|
//Float3 SimpleRigidBody::GetRigidLinearVelocity() const
|
||||||
{
|
//{
|
||||||
return targetMem = this->rigid.box.rotation;
|
// return this->rigid.GetLinearVelocity();
|
||||||
}
|
//}
|
||||||
|
|
||||||
Float4x4 & SimpleRigidBody::GetOrientation( Float4x4 &targetMem ) const
|
|
||||||
{
|
|
||||||
return targetMem = this->rigid.GetOrientation();
|
|
||||||
}
|
|
||||||
|
|
||||||
Float4x4 & SimpleRigidBody::GetView( Float4x4 &targetMem ) const
|
|
||||||
{
|
|
||||||
return targetMem = this->rigid.GetView();
|
|
||||||
}
|
|
||||||
|
|
||||||
Float3 SimpleRigidBody::GetRigidLinearVelocity() const
|
|
||||||
{
|
|
||||||
return this->rigid.GetLinearVelocity();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
UpdateState SimpleRigidBody::Update( Float timeStepLength )
|
UpdateState SimpleRigidBody::Update( Float timeStepLength )
|
||||||
{
|
{
|
||||||
|
if( this->isForwarded )
|
||||||
|
{
|
||||||
|
this->rigid.Move( this->deltaPos, this->deltaAxis );
|
||||||
|
this->deltaPos = Float4::null;
|
||||||
|
this->deltaAxis = Float4::null;
|
||||||
|
this->isForwarded = false;
|
||||||
|
}
|
||||||
|
|
||||||
this->rigid.Update_LeapFrog( timeStepLength );
|
this->rigid.Update_LeapFrog( timeStepLength );
|
||||||
|
|
||||||
// compare previous and new state and return result
|
//! @todo TODO: compare previous and new state and return result
|
||||||
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
||||||
return UpdateState_altered;
|
return UpdateState_altered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SimpleRigidBody::Predict( Float4 &outDeltaPos, Float4 &outDeltaAxis, const Float4 &actingLinearImpulse, const Float4 &actingAngularImpulse, Float deltaTime )
|
||||||
|
{
|
||||||
|
this->rigid.Predict_LeapFrog( outDeltaPos, outDeltaAxis, actingLinearImpulse, actingAngularImpulse, deltaTime );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimpleRigidBody::SetScene( void *scene )
|
||||||
|
{
|
||||||
|
this->scene = (Octree*)scene;
|
||||||
|
}
|
||||||
|
|
||||||
void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer )
|
void SimpleRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer )
|
||||||
{
|
{
|
||||||
if( functionPointer )
|
if( functionPointer )
|
||||||
|
@ -162,47 +299,47 @@ void SimpleRigidBody::SetGravityNormal( const Float3 &normalizedVector )
|
||||||
this->gravityNormal = normalizedVector;
|
this->gravityNormal = normalizedVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
//void SimpleRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
||||||
{
|
//{
|
||||||
this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
// this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SimpleRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
//void SimpleRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
||||||
{
|
//{
|
||||||
this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
// this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SimpleRigidBody::SetMass_KeepVelocity( Float m )
|
//void SimpleRigidBody::SetMass_KeepVelocity( Float m )
|
||||||
{
|
//{
|
||||||
this->rigid.SetMass_KeepVelocity( m );
|
// this->rigid.SetMass_KeepVelocity( m );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SimpleRigidBody::SetMass_KeepMomentum( Float m )
|
//void SimpleRigidBody::SetMass_KeepMomentum( Float m )
|
||||||
{
|
//{
|
||||||
this->rigid.SetMass_KeepMomentum( m );
|
// this->rigid.SetMass_KeepMomentum( m );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SimpleRigidBody::SetCenter( const Float3 &worldPos )
|
//void SimpleRigidBody::SetCenter( const Float3 &worldPos )
|
||||||
{
|
//{
|
||||||
this->rigid.SetCenter( worldPos );
|
// this->rigid.SetCenter( worldPos );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SimpleRigidBody::SetRotation( const Float4x4 &rotation )
|
//void SimpleRigidBody::SetRotation( const Float4x4 &rotation )
|
||||||
{
|
//{
|
||||||
this->rigid.SetRotation( rotation );
|
// this->rigid.SetRotation( rotation );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SimpleRigidBody::SetOrientation( const Float4x4 &orientation )
|
//void SimpleRigidBody::SetOrientation( const Float4x4 &orientation )
|
||||||
{
|
//{
|
||||||
this->rigid.SetOrientation( orientation );
|
// this->rigid.SetOrientation( orientation );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SimpleRigidBody::SetSize( const Float3 &size )
|
//void SimpleRigidBody::SetSize( const Float3 &size )
|
||||||
{
|
//{
|
||||||
this->rigid.SetSize( size );
|
// this->rigid.SetSize( size );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SimpleRigidBody::SetMomentum( const Float3 &worldG )
|
//void SimpleRigidBody::SetMomentum( const Float3 &worldG )
|
||||||
{
|
//{
|
||||||
this->rigid.SetLinearMomentum( worldG );
|
// this->rigid.SetLinearMomentum( worldG );
|
||||||
}
|
//}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "..\PhysicsAPI.h"
|
#include "..\PhysicsAPI.h"
|
||||||
#include "RigidBody.h"
|
#include "RigidBody.h"
|
||||||
|
#include "Octree.h"
|
||||||
|
|
||||||
namespace Oyster { namespace Physics
|
namespace Oyster { namespace Physics
|
||||||
{
|
{
|
||||||
|
@ -18,41 +19,46 @@ namespace Oyster { namespace Physics
|
||||||
State GetState() const;
|
State GetState() const;
|
||||||
State & GetState( State &targetMem ) const;
|
State & GetState( State &targetMem ) const;
|
||||||
void SetState( const State &state );
|
void SetState( const State &state );
|
||||||
::Oyster::Math::Float3 GetRigidLinearVelocity() const;
|
//::Oyster::Math::Float3 GetRigidLinearVelocity() const;
|
||||||
|
|
||||||
void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
|
SubscriptMessage CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
|
||||||
bool IsAffectedByGravity() 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;
|
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
|
||||||
|
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
|
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
|
|
||||||
::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) 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::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const;
|
||||||
::Oyster::Math::Float3 & GetGravityNormal( ::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::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 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||||
::Oyster::Math::Float4x4 & GetOrientation( ::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;
|
//::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||||
|
|
||||||
UpdateState Update( ::Oyster::Math::Float timeStepLength );
|
UpdateState Update( ::Oyster::Math::Float timeStepLength );
|
||||||
|
void Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime );
|
||||||
|
|
||||||
|
void SetScene( void *scene );
|
||||||
void SetSubscription( EventAction_Collision functionPointer );
|
void SetSubscription( EventAction_Collision functionPointer );
|
||||||
void SetGravity( bool ignore);
|
void SetGravity( bool ignore);
|
||||||
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
|
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
|
||||||
void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
//void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
||||||
void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
//void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
||||||
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
//void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
||||||
void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
//void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
||||||
void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
//void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
||||||
void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
//void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
||||||
void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
//void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
||||||
void SetSize( const ::Oyster::Math::Float3 &size );
|
//void SetSize( const ::Oyster::Math::Float3 &size );
|
||||||
void SetMomentum( const ::Oyster::Math::Float3 &worldG );
|
//void SetMomentum( const ::Oyster::Math::Float3 &worldG );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Oyster::Physics3D::RigidBody rigid;
|
::Oyster::Physics3D::RigidBody rigid;
|
||||||
|
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||||
::Oyster::Math::Float3 gravityNormal;
|
::Oyster::Math::Float3 gravityNormal;
|
||||||
EventAction_Collision collisionAction;
|
EventAction_Collision collisionAction;
|
||||||
bool ignoreGravity;
|
Octree *scene;
|
||||||
|
bool ignoreGravity, isForwarded;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
|
@ -10,18 +10,26 @@ using namespace ::Utility::Value;
|
||||||
|
|
||||||
SphericalRigidBody::SphericalRigidBody()
|
SphericalRigidBody::SphericalRigidBody()
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody( Box(Float4x4::identity, Float3::null, Float3(1.0f)), 10.0f, Float4x4::identity );
|
this->rigid = RigidBody();
|
||||||
|
this->rigid.SetMass_KeepMomentum( 10.0f );
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
this->collisionAction = Default::EventAction_Collision;
|
this->collisionAction = Default::EventAction_Collision;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = this->isForwarded = false;
|
||||||
|
this->scene = nullptr;
|
||||||
this->body = Sphere( Float3::null, 0.5f );
|
this->body = Sphere( Float3::null, 0.5f );
|
||||||
}
|
}
|
||||||
|
|
||||||
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody( Box( desc.rotation, desc.centerPosition, Float3(2.0f * desc.radius) ),
|
this->rigid = RigidBody();
|
||||||
desc.mass,
|
this->rigid.SetRotation( desc.rotation );
|
||||||
MomentOfInertia::CreateSphereMatrix( desc.mass, desc.radius ) );
|
this->rigid.centerPos = desc.centerPosition;
|
||||||
|
this->rigid.boundingReach = Float4( desc.radius, desc.radius, desc.radius, 0.0f );
|
||||||
|
this->rigid.SetMass_KeepMomentum( desc.mass );
|
||||||
|
this->rigid.SetMomentOfInertia_KeepMomentum( Formula::MomentOfInertia::CreateSphereMatrix( desc.mass, desc.radius ) );
|
||||||
|
this->deltaPos = Float4::null;
|
||||||
|
this->deltaAxis = Float4::null;
|
||||||
|
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
|
|
||||||
if( desc.subscription )
|
if( desc.subscription )
|
||||||
|
@ -34,6 +42,7 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des
|
||||||
}
|
}
|
||||||
|
|
||||||
this->ignoreGravity = desc.ignoreGravity;
|
this->ignoreGravity = desc.ignoreGravity;
|
||||||
|
this->scene = nullptr;
|
||||||
this->body = Sphere( desc.centerPosition, desc.radius );
|
this->body = Sphere( desc.centerPosition, desc.radius );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,24 +55,60 @@ UniquePointer<ICustomBody> SphericalRigidBody::Clone() const
|
||||||
|
|
||||||
SphericalRigidBody::State SphericalRigidBody::GetState() const
|
SphericalRigidBody::State SphericalRigidBody::GetState() const
|
||||||
{
|
{
|
||||||
return State( this->rigid.box.boundingOffset, this->rigid.box.center, AngularAxis(this->rigid.box.rotation).xyz );
|
return State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
||||||
|
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
||||||
|
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
|
||||||
|
this->rigid.centerPos, this->rigid.axis,
|
||||||
|
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
SphericalRigidBody::State & SphericalRigidBody::GetState( SphericalRigidBody::State &targetMem ) const
|
SphericalRigidBody::State & SphericalRigidBody::GetState( SphericalRigidBody::State &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = State( this->rigid.box.boundingOffset, this->rigid.box.center, AngularAxis(this->rigid.box.rotation).xyz );
|
return targetMem = State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
||||||
|
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
||||||
|
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
|
||||||
|
this->rigid.centerPos, this->rigid.axis,
|
||||||
|
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
|
void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
|
||||||
{ /** @todo TODO: temporary solution! Need to know it's occtree */
|
{
|
||||||
this->rigid.box.boundingOffset = state.GetReach();
|
this->rigid.centerPos = state.GetCenterPosition();
|
||||||
this->rigid.box.center = state.GetCenterPosition();
|
this->rigid.SetRotation( state.GetRotation() );
|
||||||
this->rigid.box.rotation = state.GetRotation();
|
this->rigid.boundingReach = state.GetReach();
|
||||||
|
this->rigid.momentum_Linear = state.GetLinearMomentum();
|
||||||
|
this->rigid.momentum_Angular = state.GetAngularMomentum();
|
||||||
|
this->rigid.impulse_Linear += state.GetLinearImpulse();
|
||||||
|
this->rigid.impulse_Angular += state.GetAngularImpulse();
|
||||||
|
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
|
||||||
|
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
|
||||||
|
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
|
||||||
|
|
||||||
|
if( state.IsForwarded() )
|
||||||
|
{
|
||||||
|
this->deltaPos += state.GetForward_DeltaPos();
|
||||||
|
this->deltaAxis += state.GetForward_DeltaAxis();
|
||||||
|
this->isForwarded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->scene )
|
||||||
|
{
|
||||||
|
if( state.IsSpatiallyAltered() )
|
||||||
|
{
|
||||||
|
unsigned int tempRef = this->scene->GetTemporaryReferenceOf( this );
|
||||||
|
this->scene->SetAsAltered( tempRef );
|
||||||
|
this->scene->EvaluatePosition( tempRef );
|
||||||
|
}
|
||||||
|
else if( state.IsDisturbed() )
|
||||||
|
{
|
||||||
|
this->scene->SetAsAltered( this->scene->GetTemporaryReferenceOf(this) );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
|
ICustomBody::SubscriptMessage SphericalRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
|
||||||
{
|
{
|
||||||
this->collisionAction( proto, deuter );
|
return this->collisionAction( proto, deuter );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SphericalRigidBody::IsAffectedByGravity() const
|
bool SphericalRigidBody::IsAffectedByGravity() const
|
||||||
|
@ -71,23 +116,19 @@ bool SphericalRigidBody::IsAffectedByGravity() const
|
||||||
return !this->ignoreGravity;
|
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
|
bool SphericalRigidBody::Intersects( const ICollideable &shape ) const
|
||||||
{
|
{
|
||||||
return this->rigid.box.Intersects( shape );
|
return Sphere( this->rigid.centerPos, this->rigid.boundingReach.x ).Intersects( shape );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SphericalRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
return Sphere( this->rigid.centerPos, this->rigid.boundingReach.x ).Intersects( shape, worldPointOfContact );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SphericalRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
return object.Intersects( Sphere(this->rigid.centerPos, this->rigid.boundingReach.x), worldPointOfContact );
|
||||||
}
|
}
|
||||||
|
|
||||||
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
|
@ -95,10 +136,16 @@ Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
return targetMem = this->body;
|
return targetMem = this->body;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 & SphericalRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const
|
Float4 & SphericalRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
|
||||||
{
|
{
|
||||||
//! @todo TODO: better implementation needed
|
targetMem = worldPos - this->rigid.centerPos;
|
||||||
return targetMem = (worldPos - this->rigid.box.center).GetNormalized();
|
Float magnitude = targetMem.GetMagnitude();
|
||||||
|
if( magnitude != 0.0f )
|
||||||
|
{ // sanity check
|
||||||
|
targetMem.Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||||
|
@ -106,41 +153,54 @@ Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||||
return targetMem = this->gravityNormal;
|
return targetMem = this->gravityNormal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
|
//Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
|
||||||
{
|
//{
|
||||||
return targetMem = this->rigid.box.center;
|
// return targetMem = this->rigid.centerPos;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
|
//Float4x4 & SphericalRigidBody::GetRotation( Float4x4 &targetMem ) const
|
||||||
|
//{
|
||||||
|
// return targetMem = this->rigid.box.rotation;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//Float4x4 & SphericalRigidBody::GetOrientation( Float4x4 &targetMem ) const
|
||||||
|
//{
|
||||||
|
// return targetMem = this->rigid.GetOrientation();
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//Float4x4 & SphericalRigidBody::GetView( Float4x4 &targetMem ) const
|
||||||
|
//{
|
||||||
|
// return targetMem = this->rigid.GetView();
|
||||||
|
//}
|
||||||
|
|
||||||
Float4x4 & SphericalRigidBody::GetRotation( Float4x4 &targetMem ) const
|
//Float3 SphericalRigidBody::GetRigidLinearVelocity() const
|
||||||
{
|
//{
|
||||||
return targetMem = this->rigid.box.rotation;
|
// return this->rigid.GetLinearVelocity();
|
||||||
}
|
//}
|
||||||
|
|
||||||
Float4x4 & SphericalRigidBody::GetOrientation( Float4x4 &targetMem ) const
|
|
||||||
{
|
|
||||||
return targetMem = this->rigid.GetOrientation();
|
|
||||||
}
|
|
||||||
|
|
||||||
Float4x4 & SphericalRigidBody::GetView( Float4x4 &targetMem ) const
|
|
||||||
{
|
|
||||||
return targetMem = this->rigid.GetView();
|
|
||||||
}
|
|
||||||
|
|
||||||
Float3 SphericalRigidBody::GetRigidLinearVelocity() const
|
|
||||||
{
|
|
||||||
return this->rigid.GetLinearVelocity();
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateState SphericalRigidBody::Update( Float timeStepLength )
|
UpdateState SphericalRigidBody::Update( Float timeStepLength )
|
||||||
{
|
{
|
||||||
|
if( this->isForwarded )
|
||||||
|
{
|
||||||
|
this->rigid.Move( this->deltaPos, this->deltaAxis );
|
||||||
|
this->deltaPos = Float4::null;
|
||||||
|
this->deltaAxis = Float4::null;
|
||||||
|
this->isForwarded = false;
|
||||||
|
}
|
||||||
|
|
||||||
this->rigid.Update_LeapFrog( timeStepLength );
|
this->rigid.Update_LeapFrog( timeStepLength );
|
||||||
this->body.center = this->rigid.GetCenter();
|
this->body.center = this->rigid.centerPos;
|
||||||
|
|
||||||
// compare previous and new state and return result
|
// compare previous and new state and return result
|
||||||
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
||||||
return UpdateState_altered;
|
return UpdateState_altered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SphericalRigidBody::Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime )
|
||||||
|
{
|
||||||
|
this->rigid.Predict_LeapFrog( outDeltaPos, outDeltaAxis, actingLinearImpulse, actingAngularImpulse, deltaTime );
|
||||||
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer )
|
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer )
|
||||||
{
|
{
|
||||||
if( functionPointer )
|
if( functionPointer )
|
||||||
|
@ -153,7 +213,12 @@ void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision fun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetGravity( bool ignore)
|
void SphericalRigidBody::SetScene( void *scene )
|
||||||
|
{
|
||||||
|
this->scene = (Octree*)scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SphericalRigidBody::SetGravity( bool ignore )
|
||||||
{
|
{
|
||||||
this->ignoreGravity = ignore;
|
this->ignoreGravity = ignore;
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
|
@ -164,50 +229,50 @@ void SphericalRigidBody::SetGravityNormal( const Float3 &normalizedVector )
|
||||||
this->gravityNormal = normalizedVector;
|
this->gravityNormal = normalizedVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
//void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
||||||
{
|
//{
|
||||||
this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
// this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
//void SphericalRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
||||||
{
|
//{
|
||||||
this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
// this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SphericalRigidBody::SetMass_KeepVelocity( Float m )
|
//void SphericalRigidBody::SetMass_KeepVelocity( Float m )
|
||||||
{
|
//{
|
||||||
this->rigid.SetMass_KeepVelocity( m );
|
// this->rigid.SetMass_KeepVelocity( m );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SphericalRigidBody::SetMass_KeepMomentum( Float m )
|
//void SphericalRigidBody::SetMass_KeepMomentum( Float m )
|
||||||
{
|
//{
|
||||||
this->rigid.SetMass_KeepMomentum( m );
|
// this->rigid.SetMass_KeepMomentum( m );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SphericalRigidBody::SetCenter( const Float3 &worldPos )
|
//void SphericalRigidBody::SetCenter( const Float3 &worldPos )
|
||||||
{
|
//{
|
||||||
this->rigid.SetCenter( worldPos );
|
// this->rigid.SetCenter( worldPos );
|
||||||
this->body.center = worldPos;
|
// this->body.center = worldPos;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SphericalRigidBody::SetRotation( const Float4x4 &rotation )
|
//void SphericalRigidBody::SetRotation( const Float4x4 &rotation )
|
||||||
{
|
//{
|
||||||
this->rigid.SetRotation( rotation );
|
// this->rigid.SetRotation( rotation );
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SphericalRigidBody::SetOrientation( const Float4x4 &orientation )
|
//void SphericalRigidBody::SetOrientation( const Float4x4 &orientation )
|
||||||
{
|
//{
|
||||||
this->rigid.SetOrientation( orientation );
|
// this->rigid.SetOrientation( orientation );
|
||||||
this->body.center = orientation.v[3].xyz;
|
// this->body.center = orientation.v[3].xyz;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SphericalRigidBody::SetSize( const Float3 &size )
|
//void SphericalRigidBody::SetSize( const Float3 &size )
|
||||||
{
|
//{
|
||||||
this->rigid.SetSize( size );
|
// this->rigid.SetSize( size );
|
||||||
this->body.radius = 0.5f * Min( Min( size.x, size.y ), size.z ); // inline Min( FloatN )?
|
// this->body.radius = 0.5f * Min( Min( size.x, size.y ), size.z ); // inline Min( FloatN )?
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void SphericalRigidBody::SetMomentum( const Float3 &worldG )
|
//void SphericalRigidBody::SetMomentum( const Float3 &worldG )
|
||||||
{
|
//{
|
||||||
this->rigid.SetLinearMomentum( worldG );
|
// this->rigid.SetLinearMomentum( worldG );
|
||||||
}
|
//}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "..\PhysicsAPI.h"
|
#include "..\PhysicsAPI.h"
|
||||||
#include "RigidBody.h"
|
#include "RigidBody.h"
|
||||||
#include "Sphere.h"
|
#include "Sphere.h"
|
||||||
|
#include "Octree.h"
|
||||||
|
|
||||||
namespace Oyster { namespace Physics
|
namespace Oyster { namespace Physics
|
||||||
{
|
{
|
||||||
|
@ -19,41 +20,46 @@ namespace Oyster { namespace Physics
|
||||||
State GetState() const;
|
State GetState() const;
|
||||||
State & GetState( State &targetMem = State() ) const;
|
State & GetState( State &targetMem = State() ) const;
|
||||||
void SetState( const State &state );
|
void SetState( const State &state );
|
||||||
::Oyster::Math::Float3 GetRigidLinearVelocity() const;
|
//::Oyster::Math::Float3 GetRigidLinearVelocity() const;
|
||||||
|
|
||||||
void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
|
SubscriptMessage CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
|
||||||
bool IsAffectedByGravity() 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;
|
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
|
||||||
|
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
|
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
|
|
||||||
::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) 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::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const;
|
||||||
::Oyster::Math::Float3 & GetGravityNormal( ::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::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 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||||
::Oyster::Math::Float4x4 & GetOrientation( ::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;
|
//::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||||
|
|
||||||
UpdateState Update( ::Oyster::Math::Float timeStepLength );
|
UpdateState Update( ::Oyster::Math::Float timeStepLength );
|
||||||
|
void Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime );
|
||||||
|
|
||||||
|
void SetScene( void *scene );
|
||||||
void SetSubscription( EventAction_Collision functionPointer );
|
void SetSubscription( EventAction_Collision functionPointer );
|
||||||
void SetGravity( bool ignore);
|
void SetGravity( bool ignore);
|
||||||
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
|
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
|
||||||
void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
//void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
||||||
void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
//void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
||||||
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
//void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
||||||
void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
//void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
||||||
void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
//void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
||||||
void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
//void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
||||||
void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
//void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
||||||
void SetSize( const ::Oyster::Math::Float3 &size );
|
//void SetSize( const ::Oyster::Math::Float3 &size );
|
||||||
void SetMomentum( const ::Oyster::Math::Float3 &worldG );
|
//void SetMomentum( const ::Oyster::Math::Float3 &worldG );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Oyster::Physics3D::RigidBody rigid;
|
::Oyster::Physics3D::RigidBody rigid;
|
||||||
|
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||||
::Oyster::Math::Float3 gravityNormal;
|
::Oyster::Math::Float3 gravityNormal;
|
||||||
EventAction_Collision collisionAction;
|
EventAction_Collision collisionAction;
|
||||||
bool ignoreGravity;
|
bool ignoreGravity, isForwarded;
|
||||||
|
Octree *scene;
|
||||||
::Oyster::Collision3D::Sphere body;
|
::Oyster::Collision3D::Sphere body;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -35,20 +35,6 @@ namespace Oyster
|
||||||
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 PHYSICS_DLL_USAGE MomentOfInertia
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static ::Oyster::Math::Float4x4 & CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius, ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() );
|
|
||||||
|
|
||||||
static ::Oyster::Math::Float4x4 & CreateHollowSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius, ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() );
|
|
||||||
|
|
||||||
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, ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() );
|
|
||||||
|
|
||||||
static ::Oyster::Math::Float4x4 & CreateCylinderMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius, ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() );
|
|
||||||
|
|
||||||
static ::Oyster::Math::Float4x4 & CreateRodMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length, ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() );
|
|
||||||
};
|
|
||||||
|
|
||||||
class PHYSICS_DLL_USAGE API
|
class PHYSICS_DLL_USAGE API
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -138,82 +124,73 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual void DestroyObject( const ICustomBody* objRef ) = 0;
|
virtual void DestroyObject( const ICustomBody* objRef ) = 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.
|
||||||
* @param worldPos: Relative to the world origo. (Not relative to object) [m]
|
// * @param worldPos: Relative to the world origo. (Not relative to object) [m]
|
||||||
* @param worldF: Vector with the direction and magnitude of the force. [N]
|
// * @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;
|
//virtual void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
///********************************************************
|
||||||
* Apply force on an object.
|
// * Sets the MomentOfInertia tensor matrix of an object without changing it's angular velocity.
|
||||||
* @param objRefA: A pointer to the ICustomBody representing a physical object.
|
// * Noticeable effect: The angular momentum will change. Changing the amount of kinetic energy.
|
||||||
* @param objRefB: A pointer to the ICustomBody representing a physical object.
|
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||||
* @param deltaWhen: The elapsed simulation time since last update frame. [s]
|
// * @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace.
|
||||||
* @param worldPointOfContact: Point of Collision, relative to the world origo. (Not relative to the objects) [m]
|
// ********************************************************/
|
||||||
********************************************************/
|
//virtual void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0;
|
||||||
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 momentum.
|
||||||
* Sets the MomentOfInertia tensor matrix of an object without changing it's angular velocity.
|
// * Noticeable effect: The angular velocity will change. Can be used to create slow effects.
|
||||||
* 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 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.
|
||||||
* @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;
|
||||||
virtual void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0;
|
//
|
||||||
|
///********************************************************
|
||||||
/********************************************************
|
// * Sets the mass of an object without changing it's linear velocity.
|
||||||
* Sets the MomentOfInertia tensor matrix of an object without changing it's angular momentum.
|
// * Noticeable effect: The linear momentum will change. Changing the amount of kinetic energy.
|
||||||
* 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 objRef: A pointer to the ICustomBody representing a physical object.
|
// * @param m: [kg]
|
||||||
* @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace.
|
// ********************************************************/
|
||||||
********************************************************/
|
//virtual void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
|
||||||
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.
|
||||||
* 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.
|
||||||
* 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 objRef: A pointer to the ICustomBody representing a physical object.
|
// * @param m: [kg]
|
||||||
* @param m: [kg]
|
// ********************************************************/
|
||||||
********************************************************/
|
//virtual void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
|
||||||
virtual void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
|
//
|
||||||
|
///********************************************************
|
||||||
/********************************************************
|
// * Instantly moves an object.
|
||||||
* Sets the mass of an object without changing it's linear velocity.
|
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||||
* Noticeable effect: The linear velocity will change. Can be used to create slow effects.
|
// * @param worldPos: Relative to the world origo. (Not relative to object) [m]
|
||||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
// ********************************************************/
|
||||||
* @param m: [kg]
|
//virtual void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos ) = 0;
|
||||||
********************************************************/
|
//
|
||||||
virtual void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
|
///********************************************************
|
||||||
|
// * Instantly redirects object.
|
||||||
/********************************************************
|
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||||
* Instantly moves an object.
|
// * @param rotation: New rotation.
|
||||||
* @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 SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation ) = 0;
|
||||||
********************************************************/
|
//
|
||||||
virtual void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos ) = 0;
|
///********************************************************
|
||||||
|
// * Instantly moves and redirects object.
|
||||||
/********************************************************
|
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||||
* Instantly redirects object.
|
// * @param orientation: New orientation.
|
||||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
// ********************************************************/
|
||||||
* @param rotation: New rotation.
|
//virtual void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation ) = 0;
|
||||||
********************************************************/
|
//
|
||||||
virtual void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation ) = 0;
|
///********************************************************
|
||||||
|
// * Resizes the boundingBox.
|
||||||
/********************************************************
|
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||||
* Instantly moves and redirects object.
|
// * @param size: New size of this [m]
|
||||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
// ********************************************************/
|
||||||
* @param orientation: New orientation.
|
//virtual void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size ) = 0;
|
||||||
********************************************************/
|
|
||||||
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.
|
* Creates a new dynamically allocated object that can be used as a component for more complex ICustomBodies.
|
||||||
|
@ -245,11 +222,6 @@ namespace Oyster
|
||||||
SubscriptMessage_ignore_collision_response
|
SubscriptMessage_ignore_collision_response
|
||||||
};
|
};
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* @param gameObjectRef: a pointer to the object in the game owning the rigid body.
|
|
||||||
********************************************************/
|
|
||||||
void* gameObjectRef;
|
|
||||||
|
|
||||||
typedef SubscriptMessage (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter );
|
typedef SubscriptMessage (*EventAction_Collision)( const ICustomBody *proto, const ICustomBody *deuter );
|
||||||
typedef Struct::SimpleBodyDescription SimpleBodyDescription;
|
typedef Struct::SimpleBodyDescription SimpleBodyDescription;
|
||||||
typedef Struct::SphericalBodyDescription SphericalBodyDescription;
|
typedef Struct::SphericalBodyDescription SphericalBodyDescription;
|
||||||
|
@ -266,7 +238,7 @@ namespace Oyster
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* @todo TODO: need doc
|
* @todo TODO: need doc
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter ) = 0;
|
virtual SubscriptMessage CallSubscription( const ICustomBody *proto, const ICustomBody *deuter ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* @todo TODO: need doc
|
* @todo TODO: need doc
|
||||||
|
@ -281,7 +253,7 @@ namespace Oyster
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* @return the linear velocity of the rigid body in a vector.
|
* @return the linear velocity of the rigid body in a vector.
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual Math::Float3 GetRigidLinearVelocity() const = 0;
|
//virtual Math::Float3 GetRigidLinearVelocity() const = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* @todo TODO: need doc
|
* @todo TODO: need doc
|
||||||
|
@ -293,22 +265,28 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual bool IsAffectedByGravity() const = 0;
|
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.
|
* param shape: Any defined sample shape.
|
||||||
* @return true if this truly intersects with shape.
|
* @return true if this truly intersects with shape.
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const = 0;
|
virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* Performs a detailed Intersect test and returns if, when and where.
|
||||||
|
* @param shape: Any defined sample shape.
|
||||||
|
* @param worldPointOfContact: Where at timeOfContact, this and object touches eachother.
|
||||||
|
* @return true if this truly intersects with object.
|
||||||
|
********************************************************/
|
||||||
|
virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* Performs a detailed Intersect test and returns if, when and where.
|
||||||
|
* @param object: What this is intersect testing against.
|
||||||
|
* @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::Float4 &worldPointOfContact ) const = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Required by Engine's Collision Search.
|
* Required by Engine's Collision Search.
|
||||||
* @param targetMem: Provided memory that written into and then returned.
|
* @param targetMem: Provided memory that written into and then returned.
|
||||||
|
@ -322,7 +300,7 @@ namespace Oyster
|
||||||
* @param targetMem: Provided memory that written into and then returned.
|
* @param targetMem: Provided memory that written into and then returned.
|
||||||
* @return a surface normal in worldSpace.
|
* @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;
|
virtual ::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* The gravity normal will have same direction as the total gravity force pulling on this and have the magnitude of 1.0f.
|
* The gravity normal will have same direction as the total gravity force pulling on this and have the magnitude of 1.0f.
|
||||||
|
@ -331,30 +309,30 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
|
virtual ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
|
||||||
|
|
||||||
/********************************************************
|
///********************************************************
|
||||||
* The world position of this center of gravity.
|
// * The world position of this center of gravity.
|
||||||
* @param targetMem: Provided memory that written into and then returned.
|
// * @param targetMem: Provided memory that written into and then returned.
|
||||||
* @return a position in worldSpace.
|
// * @return a position in worldSpace.
|
||||||
********************************************************/
|
// ********************************************************/
|
||||||
virtual ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
|
//virtual ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
|
||||||
|
//
|
||||||
/********************************************************
|
///********************************************************
|
||||||
* @param targetMem: Provided memory that written into and then returned.
|
// * @param targetMem: Provided memory that written into and then returned.
|
||||||
* @return a copy of this's rotation matrix.
|
// * @return a copy of this's rotation matrix.
|
||||||
********************************************************/
|
// ********************************************************/
|
||||||
virtual ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
//virtual ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||||
|
//
|
||||||
/********************************************************
|
///********************************************************
|
||||||
* @param targetMem: Provided memory that written into and then returned.
|
// * @param targetMem: Provided memory that written into and then returned.
|
||||||
* @return a copy of this's orientation matrix.
|
// * @return a copy of this's orientation matrix.
|
||||||
********************************************************/
|
// ********************************************************/
|
||||||
virtual ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
//virtual ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||||
|
//
|
||||||
/********************************************************
|
///********************************************************
|
||||||
* @param targetMem: Provided memory that written into and then returned.
|
// * @param targetMem: Provided memory that written into and then returned.
|
||||||
* @return a copy of this's view matrix.
|
// * @return a copy of this's view matrix.
|
||||||
********************************************************/
|
// ********************************************************/
|
||||||
virtual ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
//virtual ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* To not be called if is in Engine
|
* To not be called if is in Engine
|
||||||
|
@ -362,6 +340,18 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual UpdateState Update( ::Oyster::Math::Float timeStepLength ) = 0;
|
virtual UpdateState Update( ::Oyster::Math::Float timeStepLength ) = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* @todo TODO: add doc
|
||||||
|
********************************************************/
|
||||||
|
virtual void Predict( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime ) = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* Sets which scene this ICustomBody is within.
|
||||||
|
* Reserved to only be used by the scene.
|
||||||
|
* @todo TODO: create an IScene interface
|
||||||
|
********************************************************/
|
||||||
|
virtual void SetScene( void *scene ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Sets the function that will be called by the engine
|
* Sets the function that will be called by the engine
|
||||||
* whenever a collision occurs.
|
* whenever a collision occurs.
|
||||||
|
@ -380,63 +370,64 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector ) = 0;
|
virtual void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
///********************************************************
|
||||||
* To not be called if is in Engine
|
// * To not be called if is in Engine
|
||||||
* Use API::SetMomentOfInertiaTensor_KeepVelocity(...) instead
|
// * Use API::SetMomentOfInertiaTensor_KeepVelocity(...) instead
|
||||||
********************************************************/
|
// ********************************************************/
|
||||||
virtual void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ) = 0;
|
//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
|
// * To not be called if is in Engine
|
||||||
* Use API::SetMomentOfInertiaTensor_KeepMomentum(...)
|
// * Use API::SetSize(...)
|
||||||
********************************************************/
|
// ********************************************************/
|
||||||
virtual void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ) = 0;
|
//virtual void SetSize( const ::Oyster::Math::Float3 &size ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
///********************************************************
|
||||||
* To not be called if is in Engine
|
// * To not be called if is in Engine
|
||||||
* Use API::SetMass_KeepVelocity(...)
|
// * Use API::?? @todo TODO:
|
||||||
********************************************************/
|
// ********************************************************/
|
||||||
virtual void SetMass_KeepVelocity( ::Oyster::Math::Float m ) = 0;
|
//virtual void SetMomentum( const ::Oyster::Math::Float3 &worldG ) = 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;
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* To not be called if is in Engine
|
|
||||||
* Use API::?? @todo TODO:
|
|
||||||
********************************************************/
|
|
||||||
virtual void SetMomentum( const ::Oyster::Math::Float3 &worldG ) = 0;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "PhysicsStructs.h"
|
#include "PhysicsStructs.h"
|
||||||
|
#include "PhysicsFormula.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1,76 @@
|
||||||
|
#ifndef PHYSICS_FORMULA_IMPL_H
|
||||||
|
#define PHYSICS_FORMULA_IMPL_H
|
||||||
|
|
||||||
|
#include "PhysicsFormula.h"
|
||||||
|
#include "OysterPhysics3D.h"
|
||||||
|
|
||||||
|
namespace Oyster { namespace Physics { namespace Formula
|
||||||
|
{
|
||||||
|
namespace MomentOfInertia
|
||||||
|
{
|
||||||
|
inline ::Oyster::Math::Float4x4 CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius )
|
||||||
|
{
|
||||||
|
return ::Oyster::Physics3D::Formula::MomentOfInertia::Sphere(mass, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 CreateHollowSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius )
|
||||||
|
{
|
||||||
|
return ::Oyster::Physics3D::Formula::MomentOfInertia::HollowSphere(mass, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 CreateCuboidMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth )
|
||||||
|
{
|
||||||
|
return ::Oyster::Physics3D::Formula::MomentOfInertia::Cuboid(mass, height, width, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 CreateCylinderMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius )
|
||||||
|
{
|
||||||
|
return ::Oyster::Physics3D::Formula::MomentOfInertia::Cylinder(mass, height, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 CreateRodMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length )
|
||||||
|
{
|
||||||
|
return ::Oyster::Physics3D::Formula::MomentOfInertia::RodCenter(mass, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CollisionResponse
|
||||||
|
{
|
||||||
|
inline ::Oyster::Math::Float Bounce( ::Oyster::Math::Float e, ::Oyster::Math::Float mA, ::Oyster::Math::Float gA, ::Oyster::Math::Float mB, ::Oyster::Math::Float gB )
|
||||||
|
{
|
||||||
|
//return (e + 1) * (mB*gA - mA*gB) / (mA + mB);
|
||||||
|
return (e + 1) * (mA*gB - mB*gA) / (mA + mB);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4 Friction( ::Oyster::Math::Float i, ::Oyster::Math::Float4 iN, ::Oyster::Math::Float4 momA, ::Oyster::Math::Float sFA, ::Oyster::Math::Float dFA, ::Oyster::Math::Float mA, ::Oyster::Math::Float4 momB, ::Oyster::Math::Float sFB, ::Oyster::Math::Float dFB, ::Oyster::Math::Float mB )
|
||||||
|
{
|
||||||
|
// FRICTION
|
||||||
|
// Relative momentum after normal impulse
|
||||||
|
::Oyster::Math::Float4 relativeMomentum = momB - momA;
|
||||||
|
|
||||||
|
::Oyster::Math::Float4 tanFriction = relativeMomentum - relativeMomentum.Dot( iN )*iN;
|
||||||
|
tanFriction.Normalize();
|
||||||
|
|
||||||
|
::Oyster::Math::Float magnitudeFriction = -relativeMomentum.Dot( tanFriction );
|
||||||
|
magnitudeFriction = magnitudeFriction*mA*mB/( mA + mB );
|
||||||
|
|
||||||
|
::Oyster::Math::Float mu = 0.5f*( sFA + sFB );
|
||||||
|
|
||||||
|
::Oyster::Math::Float4 frictionImpulse;
|
||||||
|
if( abs(magnitudeFriction) < i*mu )
|
||||||
|
{
|
||||||
|
frictionImpulse = magnitudeFriction*tanFriction;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float dynamicFriction = 0.5f*( dFA + dFB );
|
||||||
|
frictionImpulse = -i*tanFriction*dynamicFriction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( 1 / mA )*frictionImpulse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef PHYSICS_FORMULA_H
|
||||||
|
#define PHYSICS_FORMULA_H
|
||||||
|
|
||||||
|
#include "OysterMath.h"
|
||||||
|
#include "OysterPhysics3D.h"
|
||||||
|
|
||||||
|
namespace Oyster { namespace Physics { namespace Formula
|
||||||
|
{
|
||||||
|
namespace MomentOfInertia
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float4x4 CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius );
|
||||||
|
::Oyster::Math::Float4x4 CreateHollowSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius );
|
||||||
|
::Oyster::Math::Float4x4 CreateCuboidMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth );
|
||||||
|
::Oyster::Math::Float4x4 CreateCylinderMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius );
|
||||||
|
::Oyster::Math::Float4x4 CreateRodMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length );
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CollisionResponse
|
||||||
|
{
|
||||||
|
::Oyster::Math::Float Bounce( ::Oyster::Math::Float coeffOfRestitution,
|
||||||
|
::Oyster::Math::Float massA, ::Oyster::Math::Float momentumA,
|
||||||
|
::Oyster::Math::Float massB, ::Oyster::Math::Float momentumB );
|
||||||
|
|
||||||
|
::Oyster::Math::Float4 Friction( ::Oyster::Math::Float impulse, ::Oyster::Math::Float4 impulseNormal,
|
||||||
|
::Oyster::Math::Float4 momentumA, ::Oyster::Math::Float staticFrictionA,
|
||||||
|
::Oyster::Math::Float dynamicFrictionA, ::Oyster::Math::Float massA,
|
||||||
|
::Oyster::Math::Float4 momentumB, ::Oyster::Math::Float staticFrictionB,
|
||||||
|
::Oyster::Math::Float dynamicFrictionB, ::Oyster::Math::Float massB );
|
||||||
|
|
||||||
|
}
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#include "PhysicsFormula-Impl.h"
|
||||||
|
|
||||||
|
#endif
|
|
@ -10,8 +10,8 @@ namespace Oyster { namespace Physics
|
||||||
inline SimpleBodyDescription::SimpleBodyDescription()
|
inline SimpleBodyDescription::SimpleBodyDescription()
|
||||||
{
|
{
|
||||||
this->rotation = ::Oyster::Math::Float4x4::identity;
|
this->rotation = ::Oyster::Math::Float4x4::identity;
|
||||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
this->centerPosition = ::Oyster::Math::Float4::null;
|
||||||
this->size = ::Oyster::Math::Float3( 1.0f );
|
this->size = ::Oyster::Math::Float4( 1.0f );
|
||||||
this->mass = 12.0f;
|
this->mass = 12.0f;
|
||||||
this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
|
this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
|
||||||
this->subscription = NULL;
|
this->subscription = NULL;
|
||||||
|
@ -21,33 +21,77 @@ namespace Oyster { namespace Physics
|
||||||
inline SphericalBodyDescription::SphericalBodyDescription()
|
inline SphericalBodyDescription::SphericalBodyDescription()
|
||||||
{
|
{
|
||||||
this->rotation = ::Oyster::Math::Float4x4::identity;
|
this->rotation = ::Oyster::Math::Float4x4::identity;
|
||||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
this->centerPosition = ::Oyster::Math::Float4::null;
|
||||||
this->radius = 0.5f;
|
this->radius = 0.5f;
|
||||||
this->mass = 10.0f;
|
this->mass = 10.0f;
|
||||||
this->subscription = NULL;
|
this->subscription = NULL;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float kineticFrictionCoeff, const ::Oyster::Math::Float4x4 &inertiaTensor, const ::Oyster::Math::Float4 &reach, const ::Oyster::Math::Float4 ¢erPos, const ::Oyster::Math::Float4 &rotation, const ::Oyster::Math::Float4 &linearMomentum, const ::Oyster::Math::Float4 &angularMomentum )
|
||||||
inline CustomBodyState::CustomBodyState( const ::Oyster::Math::Float3 &reach, const ::Oyster::Math::Float3 ¢erPos, const ::Oyster::Math::Float3 &rotation )
|
|
||||||
{
|
{
|
||||||
this->reach = ::Oyster::Math::Float4( reach, 0.0f );
|
this->mass = mass;
|
||||||
this->centerPos = ::Oyster::Math::Float4( centerPos, 1.0f );
|
this->restitutionCoeff = restitutionCoeff;
|
||||||
this->angularAxis = ::Oyster::Math::Float4( rotation, 0.0f );
|
this->staticFrictionCoeff = staticFrictionCoeff;
|
||||||
this->isSpatiallyAltered = this->isDisturbed = false;
|
this->kineticFrictionCoeff = kineticFrictionCoeff;
|
||||||
|
this->inertiaTensor = inertiaTensor;
|
||||||
|
this->reach = reach;
|
||||||
|
this->centerPos = centerPos;
|
||||||
|
this->angularAxis = rotation;
|
||||||
|
this->linearMomentum = linearMomentum;
|
||||||
|
this->angularMomentum = angularMomentum;
|
||||||
|
this->linearImpulse = this->angularImpulse = ::Oyster::Math::Float4::null;
|
||||||
|
this->deltaPos = this->deltaAxis = ::Oyster::Math::Float4::null;
|
||||||
|
this->isSpatiallyAltered = this->isDisturbed = this->isForwarded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CustomBodyState & CustomBodyState::operator = ( const CustomBodyState &state )
|
inline CustomBodyState & CustomBodyState::operator = ( const CustomBodyState &state )
|
||||||
{
|
{
|
||||||
|
this->mass = state.mass;
|
||||||
|
this->restitutionCoeff = state.restitutionCoeff;
|
||||||
|
this->staticFrictionCoeff = state.staticFrictionCoeff;
|
||||||
|
this->kineticFrictionCoeff = state.kineticFrictionCoeff;
|
||||||
|
this->inertiaTensor = state.inertiaTensor;
|
||||||
this->reach = state.reach;
|
this->reach = state.reach;
|
||||||
this->centerPos = state.centerPos;
|
this->centerPos = state.centerPos;
|
||||||
this->angularAxis = state.angularAxis;
|
this->angularAxis = state.angularAxis;
|
||||||
|
this->linearMomentum = state.linearMomentum;
|
||||||
|
this->angularMomentum = state.angularMomentum;
|
||||||
|
this->linearImpulse = state.linearImpulse;
|
||||||
|
this->angularImpulse = state.angularImpulse;
|
||||||
|
this->deltaPos = state.deltaPos;
|
||||||
|
this->deltaAxis = state.deltaAxis;
|
||||||
this->isSpatiallyAltered = state.isSpatiallyAltered;
|
this->isSpatiallyAltered = state.isSpatiallyAltered;
|
||||||
this->isDisturbed = state.isDisturbed;
|
this->isDisturbed = state.isDisturbed;
|
||||||
|
this->isForwarded = state.isForwarded;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float CustomBodyState::GetMass() const
|
||||||
|
{
|
||||||
|
return this->mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float CustomBodyState::GetRestitutionCoeff() const
|
||||||
|
{
|
||||||
|
return this->restitutionCoeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float CustomBodyState::GetFrictionCoeff_Static() const
|
||||||
|
{
|
||||||
|
return this->staticFrictionCoeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float CustomBodyState::GetFrictionCoeff_Kinetic() const
|
||||||
|
{
|
||||||
|
return this->kineticFrictionCoeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float4x4 & CustomBodyState::GetMomentOfInertia() const
|
||||||
|
{
|
||||||
|
return this->inertiaTensor;
|
||||||
|
}
|
||||||
|
|
||||||
inline const ::Oyster::Math::Float4 & CustomBodyState::GetReach() const
|
inline const ::Oyster::Math::Float4 & CustomBodyState::GetReach() const
|
||||||
{
|
{
|
||||||
return this->reach;
|
return this->reach;
|
||||||
|
@ -73,25 +117,116 @@ namespace Oyster { namespace Physics
|
||||||
return ::Oyster::Math3D::RotationMatrix( this->GetAngularAxis().xyz );
|
return ::Oyster::Math3D::RotationMatrix( this->GetAngularAxis().xyz );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CustomBodyState::SetSize( const ::Oyster::Math::Float3 &size )
|
inline ::Oyster::Math::Float4x4 CustomBodyState::GetOrientation() const
|
||||||
|
{
|
||||||
|
return ::Oyster::Math3D::OrientationMatrix( this->angularAxis.xyz, this->centerPos.xyz );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 CustomBodyState::GetView() const
|
||||||
|
{
|
||||||
|
return ::Oyster::Math3D::ViewMatrix( this->angularAxis.xyz, this->centerPos.xyz );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float4 & CustomBodyState::GetLinearMomentum() const
|
||||||
|
{
|
||||||
|
return this->linearMomentum;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float4 &at ) const
|
||||||
|
{
|
||||||
|
//return this->linearMomentum + ::Oyster::Physics3D::Formula::TangentialLinearMomentum( this->angularMomentum, at - this->centerPos ); // C3083 error?
|
||||||
|
return this->linearMomentum + ::Oyster::Math::Float4( this->angularMomentum.xyz.Cross((at - this->centerPos).xyz), 0.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularMomentum() const
|
||||||
|
{
|
||||||
|
return this->angularMomentum;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float4 & CustomBodyState::GetLinearImpulse() const
|
||||||
|
{
|
||||||
|
return this->linearImpulse;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularImpulse() const
|
||||||
|
{
|
||||||
|
return this->angularImpulse;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float4 & CustomBodyState::GetForward_DeltaPos() const
|
||||||
|
{
|
||||||
|
return this->deltaPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const ::Oyster::Math::Float4 & CustomBodyState::GetForward_DeltaAxis() const
|
||||||
|
{
|
||||||
|
return this->deltaAxis;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetMass_KeepMomentum( ::Oyster::Math::Float m )
|
||||||
|
{
|
||||||
|
this->mass = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetMass_KeepVelocity( ::Oyster::Math::Float m )
|
||||||
|
{
|
||||||
|
if( m != 0.0f )
|
||||||
|
{ // sanity block!
|
||||||
|
// Formula::LinearMomentum( m, Formula::LinearVelocity(this->mass, this->linearMomentum) )
|
||||||
|
// is the same as (this->linearMomentum / this->mass) * m = (m / this->mass) * this->linearMomentum
|
||||||
|
this->linearMomentum *= (m / this->mass);
|
||||||
|
this->mass = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetRestitutionCoeff( ::Oyster::Math::Float e )
|
||||||
|
{
|
||||||
|
this->restitutionCoeff = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetFrictionCoeff( ::Oyster::Math::Float staticU, ::Oyster::Math::Float kineticU )
|
||||||
|
{
|
||||||
|
this->staticFrictionCoeff = staticU;
|
||||||
|
this->kineticFrictionCoeff = kineticU;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &tensor )
|
||||||
|
{
|
||||||
|
this->inertiaTensor = tensor;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &tensor )
|
||||||
|
{
|
||||||
|
if( tensor.GetDeterminant() != 0.0f )
|
||||||
|
{ // sanity block!
|
||||||
|
::Oyster::Math::Float4x4 rotation = ::Oyster::Math3D::RotationMatrix(this->angularAxis.xyz);
|
||||||
|
//::Oyster::Math::Float4 w = ::Oyster::Physics3D::Formula::AngularVelocity( (rotation * this->inertiaTensor).GetInverse(), this->angularMomentum ); // C3083 error?
|
||||||
|
::Oyster::Math::Float4 w = (rotation * this->inertiaTensor).GetInverse() * this->angularMomentum;
|
||||||
|
this->inertiaTensor = tensor;
|
||||||
|
//this->angularMomentum = ::Oyster::Physics3D::Formula::AngularMomentum( rotation * tensor, w ); // C3083 error?
|
||||||
|
this->angularMomentum = rotation * tensor * w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetSize( const ::Oyster::Math::Float4 &size )
|
||||||
{
|
{
|
||||||
this->SetReach( 0.5f * size );
|
this->SetReach( 0.5f * size );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CustomBodyState::SetReach( const ::Oyster::Math::Float3 &halfSize )
|
inline void CustomBodyState::SetReach( const ::Oyster::Math::Float4 &halfSize )
|
||||||
{
|
{
|
||||||
this->reach.xyz = halfSize;
|
this->reach.xyz = halfSize;
|
||||||
this->reach = ::Utility::Value::Max( this->reach, ::Oyster::Math::Float4::null );
|
this->reach = ::Utility::Value::Max( this->reach, ::Oyster::Math::Float4::null );
|
||||||
this->isSpatiallyAltered = this->isDisturbed = true;
|
this->isSpatiallyAltered = this->isDisturbed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CustomBodyState::SetCenterPosition( const ::Oyster::Math::Float3 ¢erPos )
|
inline void CustomBodyState::SetCenterPosition( const ::Oyster::Math::Float4 ¢erPos )
|
||||||
{
|
{
|
||||||
this->centerPos.xyz = centerPos;
|
this->centerPos.xyz = centerPos;
|
||||||
this->isSpatiallyAltered = this->isDisturbed = true;
|
this->isSpatiallyAltered = this->isDisturbed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float3 &angularAxis )
|
inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float4 &angularAxis )
|
||||||
{
|
{
|
||||||
this->angularAxis.xyz = angularAxis;
|
this->angularAxis.xyz = angularAxis;
|
||||||
this->isSpatiallyAltered = this->isDisturbed = true;
|
this->isSpatiallyAltered = this->isDisturbed = true;
|
||||||
|
@ -99,7 +234,78 @@ namespace Oyster { namespace Physics
|
||||||
|
|
||||||
inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float4x4 &rotation )
|
inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float4x4 &rotation )
|
||||||
{
|
{
|
||||||
this->SetRotation( ::Oyster::Math3D::AngularAxis(rotation).xyz );
|
this->SetRotation( ::Oyster::Math3D::AngularAxis(rotation) );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetOrientation( const ::Oyster::Math::Float4x4 &orientation )
|
||||||
|
{
|
||||||
|
this->SetRotation( ::Oyster::Math3D::ExtractAngularAxis(orientation) );
|
||||||
|
this->SetCenterPosition( orientation.v[3] );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetLinearMomentum( const ::Oyster::Math::Float4 &g )
|
||||||
|
{
|
||||||
|
this->linearMomentum.xyz = g;
|
||||||
|
this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetAngularMomentum( const ::Oyster::Math::Float4 &h )
|
||||||
|
{
|
||||||
|
this->angularMomentum.xyz = h;
|
||||||
|
this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetLinearImpulse( const ::Oyster::Math::Float4 &j )
|
||||||
|
{
|
||||||
|
this->linearImpulse.xyz = j;
|
||||||
|
this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::SetAngularImpulse( const ::Oyster::Math::Float4 &j )
|
||||||
|
{
|
||||||
|
this->angularImpulse.xyz = j;
|
||||||
|
this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::AddRotation( const ::Oyster::Math::Float4 &angularAxis )
|
||||||
|
{
|
||||||
|
this->angularAxis += angularAxis;
|
||||||
|
this->isSpatiallyAltered = this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::AddTranslation( const ::Oyster::Math::Float4 &deltaPos )
|
||||||
|
{
|
||||||
|
this->centerPos += deltaPos;
|
||||||
|
this->isSpatiallyAltered = this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::ApplyLinearImpulse( const ::Oyster::Math::Float4 &j )
|
||||||
|
{
|
||||||
|
this->linearImpulse += j;
|
||||||
|
this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::ApplyAngularImpulse( const ::Oyster::Math::Float4 &j )
|
||||||
|
{
|
||||||
|
this->angularImpulse += j;
|
||||||
|
this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float4 &j, const ::Oyster::Math::Float4 &at, const ::Oyster::Math::Float4 &normal )
|
||||||
|
{
|
||||||
|
//::Oyster::Math::Float4 tangentialImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, at - this->centerPos ); // C3083 error?
|
||||||
|
::Oyster::Math::Float4 tangentialImpulse = ::Oyster::Math::Float4( (at - this->centerPos).xyz.Cross(j.xyz), 0.0f );
|
||||||
|
this->linearImpulse += j - tangentialImpulse;
|
||||||
|
this->angularImpulse += tangentialImpulse;
|
||||||
|
|
||||||
|
this->isDisturbed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomBodyState::ApplyForwarding( const ::Oyster::Math::Float4 &deltaPos, const ::Oyster::Math::Float4 &deltaAxis )
|
||||||
|
{
|
||||||
|
this->deltaPos += deltaPos;
|
||||||
|
this->deltaAxis += deltaAxis;
|
||||||
|
this->isDisturbed = this->isForwarded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool CustomBodyState::IsSpatiallyAltered() const
|
inline bool CustomBodyState::IsSpatiallyAltered() const
|
||||||
|
@ -111,6 +317,11 @@ namespace Oyster { namespace Physics
|
||||||
{
|
{
|
||||||
return this->isDisturbed;
|
return this->isDisturbed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool CustomBodyState::IsForwarded() const
|
||||||
|
{
|
||||||
|
return this->isForwarded;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ namespace Oyster { namespace Physics
|
||||||
struct SimpleBodyDescription
|
struct SimpleBodyDescription
|
||||||
{
|
{
|
||||||
::Oyster::Math::Float4x4 rotation;
|
::Oyster::Math::Float4x4 rotation;
|
||||||
::Oyster::Math::Float3 centerPosition;
|
::Oyster::Math::Float4 centerPosition;
|
||||||
::Oyster::Math::Float3 size;
|
::Oyster::Math::Float4 size;
|
||||||
::Oyster::Math::Float mass;
|
::Oyster::Math::Float mass;
|
||||||
::Oyster::Math::Float4x4 inertiaTensor;
|
::Oyster::Math::Float4x4 inertiaTensor;
|
||||||
::Oyster::Physics::ICustomBody::EventAction_Collision subscription;
|
::Oyster::Physics::ICustomBody::EventAction_Collision subscription;
|
||||||
|
@ -24,7 +24,7 @@ namespace Oyster { namespace Physics
|
||||||
struct SphericalBodyDescription
|
struct SphericalBodyDescription
|
||||||
{
|
{
|
||||||
::Oyster::Math::Float4x4 rotation;
|
::Oyster::Math::Float4x4 rotation;
|
||||||
::Oyster::Math::Float3 centerPosition;
|
::Oyster::Math::Float4 centerPosition;
|
||||||
::Oyster::Math::Float radius;
|
::Oyster::Math::Float radius;
|
||||||
::Oyster::Math::Float mass;
|
::Oyster::Math::Float mass;
|
||||||
::Oyster::Physics::ICustomBody::EventAction_Collision subscription;
|
::Oyster::Physics::ICustomBody::EventAction_Collision subscription;
|
||||||
|
@ -36,31 +36,77 @@ namespace Oyster { namespace Physics
|
||||||
struct CustomBodyState
|
struct CustomBodyState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CustomBodyState( const ::Oyster::Math::Float3 &reach = ::Oyster::Math::Float3::null,
|
CustomBodyState( ::Oyster::Math::Float mass = 1.0f,
|
||||||
const ::Oyster::Math::Float3 ¢erPos = ::Oyster::Math::Float3::null,
|
::Oyster::Math::Float restitutionCoeff = 1.0f,
|
||||||
const ::Oyster::Math::Float3 &rotation = ::Oyster::Math::Float3::null );
|
::Oyster::Math::Float staticFrictionCoeff = 1.0f,
|
||||||
|
::Oyster::Math::Float kineticFrictionCoeff = 1.0f,
|
||||||
|
const ::Oyster::Math::Float4x4 &inertiaTensor = ::Oyster::Math::Float4x4::identity,
|
||||||
|
const ::Oyster::Math::Float4 &reach = ::Oyster::Math::Float4::null,
|
||||||
|
const ::Oyster::Math::Float4 ¢erPos = ::Oyster::Math::Float4::standard_unit_w,
|
||||||
|
const ::Oyster::Math::Float4 &rotation = ::Oyster::Math::Float4::null,
|
||||||
|
const ::Oyster::Math::Float4 &linearMomentum = ::Oyster::Math::Float4::null,
|
||||||
|
const ::Oyster::Math::Float4 &angularMomentum = ::Oyster::Math::Float4::null );
|
||||||
|
|
||||||
CustomBodyState & operator = ( const CustomBodyState &state );
|
CustomBodyState & operator = ( const CustomBodyState &state );
|
||||||
|
|
||||||
|
const ::Oyster::Math::Float GetMass() const;
|
||||||
|
const ::Oyster::Math::Float GetRestitutionCoeff() const;
|
||||||
|
const ::Oyster::Math::Float GetFrictionCoeff_Static() const;
|
||||||
|
const ::Oyster::Math::Float GetFrictionCoeff_Kinetic() const;
|
||||||
|
const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const;
|
||||||
const ::Oyster::Math::Float4 & GetReach() const;
|
const ::Oyster::Math::Float4 & GetReach() const;
|
||||||
::Oyster::Math::Float4 GetSize() const;
|
::Oyster::Math::Float4 GetSize() const;
|
||||||
const ::Oyster::Math::Float4 & GetCenterPosition() const;
|
const ::Oyster::Math::Float4 & GetCenterPosition() const;
|
||||||
const ::Oyster::Math::Float4 & GetAngularAxis() const;
|
const ::Oyster::Math::Float4 & GetAngularAxis() const;
|
||||||
::Oyster::Math::Float4x4 GetRotation() const;
|
::Oyster::Math::Float4x4 GetRotation() const;
|
||||||
|
::Oyster::Math::Float4x4 GetOrientation() const;
|
||||||
|
::Oyster::Math::Float4x4 GetView() const;
|
||||||
|
const ::Oyster::Math::Float4 & GetLinearMomentum() const;
|
||||||
|
::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float4 &at ) const;
|
||||||
|
const ::Oyster::Math::Float4 & GetAngularMomentum() const;
|
||||||
|
const ::Oyster::Math::Float4 & GetLinearImpulse() const;
|
||||||
|
const ::Oyster::Math::Float4 & GetAngularImpulse() const;
|
||||||
|
const ::Oyster::Math::Float4 & GetForward_DeltaPos() const;
|
||||||
|
const ::Oyster::Math::Float4 & GetForward_DeltaAxis() const;
|
||||||
|
|
||||||
void SetSize( const ::Oyster::Math::Float3 &size );
|
void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
||||||
void SetReach( const ::Oyster::Math::Float3 &halfSize );
|
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
||||||
void SetCenterPosition( const ::Oyster::Math::Float3 ¢erPos );
|
void SetRestitutionCoeff( ::Oyster::Math::Float e );
|
||||||
void SetRotation( const ::Oyster::Math::Float3 &angularAxis );
|
void SetFrictionCoeff( ::Oyster::Math::Float staticU, ::Oyster::Math::Float kineticU );
|
||||||
|
void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &tensor );
|
||||||
|
void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &tensor );
|
||||||
|
void SetSize( const ::Oyster::Math::Float4 &size );
|
||||||
|
void SetReach( const ::Oyster::Math::Float4 &halfSize );
|
||||||
|
void SetCenterPosition( const ::Oyster::Math::Float4 ¢erPos );
|
||||||
|
void SetRotation( const ::Oyster::Math::Float4 &angularAxis );
|
||||||
void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
||||||
|
void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
||||||
|
void SetLinearMomentum( const ::Oyster::Math::Float4 &g );
|
||||||
|
void SetAngularMomentum( const ::Oyster::Math::Float4 &h );
|
||||||
|
void SetLinearImpulse( const ::Oyster::Math::Float4 &j );
|
||||||
|
void SetAngularImpulse( const ::Oyster::Math::Float4 &j );
|
||||||
|
|
||||||
|
void AddRotation( const ::Oyster::Math::Float4 &angularAxis );
|
||||||
|
void AddTranslation( const ::Oyster::Math::Float4 &deltaPos );
|
||||||
|
|
||||||
|
void ApplyLinearImpulse( const ::Oyster::Math::Float4 &j );
|
||||||
|
void ApplyAngularImpulse( const ::Oyster::Math::Float4 &j );
|
||||||
|
void ApplyImpulse( const ::Oyster::Math::Float4 &j, const ::Oyster::Math::Float4 &at, const ::Oyster::Math::Float4 &normal );
|
||||||
|
void ApplyForwarding( const ::Oyster::Math::Float4 &deltaPos, const ::Oyster::Math::Float4 &deltaAxis );
|
||||||
|
|
||||||
bool IsSpatiallyAltered() const;
|
bool IsSpatiallyAltered() const;
|
||||||
bool IsDisturbed() const;
|
bool IsDisturbed() const;
|
||||||
|
bool IsForwarded() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, kineticFrictionCoeff;
|
||||||
|
::Oyster::Math::Float4x4 inertiaTensor;
|
||||||
::Oyster::Math::Float4 reach, centerPos, angularAxis;
|
::Oyster::Math::Float4 reach, centerPos, angularAxis;
|
||||||
|
::Oyster::Math::Float4 linearMomentum, angularMomentum;
|
||||||
|
::Oyster::Math::Float4 linearImpulse, angularImpulse;
|
||||||
|
::Oyster::Math::Float4 deltaPos, deltaAxis; // Forwarding data sum
|
||||||
|
|
||||||
bool isSpatiallyAltered, isDisturbed;
|
bool isSpatiallyAltered, isDisturbed, isForwarded;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -266,6 +266,12 @@ namespace LinearAlgebra3D
|
||||||
return ::std::asin( ::LinearAlgebra::Vector4<ScalarType>(rotationMatrix.v[1].z, rotationMatrix.v[2].x, rotationMatrix.v[0].y, 1) );
|
return ::std::asin( ::LinearAlgebra::Vector4<ScalarType>(rotationMatrix.v[1].z, rotationMatrix.v[2].x, rotationMatrix.v[0].y, 1) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Vector4<ScalarType> ExtractAngularAxis( const ::LinearAlgebra::Matrix4x4<ScalarType> &orientationMatrix )
|
||||||
|
{
|
||||||
|
return ::std::asin( ::LinearAlgebra::Vector4<ScalarType>(orientationMatrix.v[1].z, orientationMatrix.v[2].x, orientationMatrix.v[0].y, 0) );
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline ::LinearAlgebra::Matrix4x4<ScalarType> & TranslationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &position, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & TranslationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &position, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
{
|
{
|
||||||
|
@ -275,6 +281,106 @@ namespace LinearAlgebra3D
|
||||||
0, 0, 0, 1 );
|
0, 0, 0, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Quaternion<ScalarType> Rotation( const ScalarType &radian, const ::LinearAlgebra::Vector3<ScalarType> &normalizedAxis )
|
||||||
|
{
|
||||||
|
ScalarType r = radian * 0.5f,
|
||||||
|
s = std::sin( r ),
|
||||||
|
c = std::cos( r );
|
||||||
|
|
||||||
|
return ::LinearAlgebra::Quaternion<ScalarType>( normalizedAxis * s, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Quaternion<ScalarType> Rotation( const ScalarType &radian, const ::LinearAlgebra::Vector4<ScalarType> &normalizedAxis )
|
||||||
|
{
|
||||||
|
ScalarType r = radian * 0.5f,
|
||||||
|
s = std::sin( r ),
|
||||||
|
c = std::cos( r );
|
||||||
|
|
||||||
|
return ::LinearAlgebra::Quaternion<ScalarType>( (normalizedAxis * s).xyz, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Quaternion<ScalarType> Rotation( const ::LinearAlgebra::Vector3<ScalarType> &angularAxis )
|
||||||
|
{
|
||||||
|
ScalarType radius = angularAxis.Dot( angularAxis );
|
||||||
|
if( radius != 0 )
|
||||||
|
{
|
||||||
|
radius = (ScalarType)::std::sqrt( radius );
|
||||||
|
return Rotation( radius, angularAxis / radius );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra::Quaternion<ScalarType>::identity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Quaternion<ScalarType> Rotation( const ::LinearAlgebra::Vector4<ScalarType> &angularAxis )
|
||||||
|
{
|
||||||
|
ScalarType radius = angularAxis.Dot( angularAxis );
|
||||||
|
if( radius != 0 )
|
||||||
|
{
|
||||||
|
radius = (ScalarType)::std::sqrt( radius );
|
||||||
|
return Rotation( radius, angularAxis / radius );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra::Quaternion<ScalarType>::identity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & RotationMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
::LinearAlgebra::Quaternion<ScalarType> conjugate = rotationQuaternion.GetConjugate();
|
||||||
|
|
||||||
|
targetMem.v[0] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(1,0,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[1] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,1,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[2] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,0,1)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[3] = ::LinearAlgebra::Vector4<ScalarType>::standard_unit_w;
|
||||||
|
return targetMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, const ::LinearAlgebra::Vector3<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
::LinearAlgebra::Quaternion<ScalarType> conjugate = rotationQuaternion.GetConjugate();
|
||||||
|
|
||||||
|
targetMem.v[0] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(1,0,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[1] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,1,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[2] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,0,1)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[3] = ::LinearAlgebra::Vector4<ScalarType>( translation, 1 );
|
||||||
|
return targetMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, const ::LinearAlgebra::Vector4<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
::LinearAlgebra::Quaternion<ScalarType> conjugate = rotationQuaternion.GetConjugate();
|
||||||
|
|
||||||
|
targetMem.v[0] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(1,0,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[1] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,1,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[2] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,0,1)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[3] = translation;
|
||||||
|
return targetMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & ViewMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, const ::LinearAlgebra::Vector3<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
OrientationMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
return InverseOrientationMatrix( targetMem, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & ViewMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, const ::LinearAlgebra::Vector4<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
OrientationMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
return InverseOrientationMatrix( targetMem, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline ::LinearAlgebra::Matrix3x3<ScalarType> & RotationMatrix_AxisX( const ScalarType &radian, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
|
inline ::LinearAlgebra::Matrix3x3<ScalarType> & RotationMatrix_AxisX( const ScalarType &radian, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
|
||||||
{
|
{
|
||||||
|
@ -400,18 +506,35 @@ namespace LinearAlgebra3D
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &sumDeltaAngularAxis, const ::LinearAlgebra::Vector3<ScalarType> &sumTranslation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &angularAxis, const ::LinearAlgebra::Vector3<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
{ /** @todo TODO: not tested */
|
{
|
||||||
ScalarType radian = sumDeltaAngularAxis.Dot( sumDeltaAngularAxis );
|
ScalarType radian = angularAxis.Dot( angularAxis );
|
||||||
if( radian > 0 )
|
if( radian > 0 )
|
||||||
{
|
{
|
||||||
radian = ::std::sqrt( radian );
|
radian = ::std::sqrt( radian );
|
||||||
return OrientationMatrix( sumDeltaAngularAxis / radian, radian, sumTranslation, targetMem );
|
return OrientationMatrix( angularAxis / radian, radian, translation, targetMem );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>::identity;
|
targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>::identity;
|
||||||
targetMem.v[3].xyz = sumTranslation;
|
targetMem.v[3].xyz = translation;
|
||||||
|
return targetMem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
::LinearAlgebra::Matrix4x4<ScalarType> & ViewMatrix( const ::LinearAlgebra::Vector3<ScalarType> &angularAxis, const ::LinearAlgebra::Vector3<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
ScalarType radian = angularAxis.Dot( angularAxis );
|
||||||
|
if( radian > 0 )
|
||||||
|
{
|
||||||
|
radian = ::std::sqrt( radian );
|
||||||
|
return InverseOrientationMatrix( OrientationMatrix(angularAxis / radian, radian, translation, targetMem) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>::identity;
|
||||||
|
targetMem.v[3].xyz = -translation;
|
||||||
return targetMem;
|
return targetMem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -534,9 +657,17 @@ namespace LinearAlgebra3D
|
||||||
inline ::LinearAlgebra::Vector3<ScalarType> VectorProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &axis )
|
inline ::LinearAlgebra::Vector3<ScalarType> VectorProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &axis )
|
||||||
{ return axis * ( vector.Dot(axis) / axis.Dot(axis) ); }
|
{ return axis * ( vector.Dot(axis) / axis.Dot(axis) ); }
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Vector4<ScalarType> VectorProjection( const ::LinearAlgebra::Vector4<ScalarType> &vector, const ::LinearAlgebra::Vector4<ScalarType> &axis )
|
||||||
|
{ return axis * ( vector.Dot(axis) / axis.Dot(axis) ); }
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline ::LinearAlgebra::Vector3<ScalarType> NormalProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &normalizedAxis )
|
inline ::LinearAlgebra::Vector3<ScalarType> NormalProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &normalizedAxis )
|
||||||
{ return normalizedAxis * ( vector.Dot(normalizedAxis) ); }
|
{ return normalizedAxis * ( vector.Dot(normalizedAxis) ); }
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Vector4<ScalarType> NormalProjection( const ::LinearAlgebra::Vector4<ScalarType> &vector, const ::LinearAlgebra::Vector4<ScalarType> &normalizedAxis )
|
||||||
|
{ return normalizedAxis * ( vector.Dot(normalizedAxis) ); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
|
|
|
@ -91,11 +91,61 @@ namespace Oyster { namespace Math3D
|
||||||
return ::LinearAlgebra3D::AngularAxis( rotationMatrix );
|
return ::LinearAlgebra3D::AngularAxis( rotationMatrix );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Float4 ExtractAngularAxis( const Float4x4 &orientationMatrix )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::ExtractAngularAxis( orientationMatrix );
|
||||||
|
}
|
||||||
|
|
||||||
Float4x4 & TranslationMatrix( const Float3 &position, Float4x4 &targetMem )
|
Float4x4 & TranslationMatrix( const Float3 &position, Float4x4 &targetMem )
|
||||||
{
|
{
|
||||||
return ::LinearAlgebra3D::TranslationMatrix( position, targetMem );
|
return ::LinearAlgebra3D::TranslationMatrix( position, targetMem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quaternion Rotation( Float radian, const Float3 &normalizedAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::Rotation( radian, normalizedAxis );
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Rotation( Float radian, const Float4 &normalizedAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::Rotation( radian, normalizedAxis );
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Rotation( const Float3 &angularAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::Rotation( angularAxis );
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Rotation( const Float4 &angularAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::Rotation( angularAxis );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & RotationMatrix( const Quaternion &rotationQuaternion, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::RotationMatrix( rotationQuaternion, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & OrientationMatrix( const Quaternion &rotationQuaternion, const Float3 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::OrientationMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & OrientationMatrix( const Quaternion &rotationQuaternion, const Float4 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::OrientationMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & ViewMatrix( const Quaternion &rotationQuaternion, const Float3 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::ViewMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & ViewMatrix( const Quaternion &rotationQuaternion, const Float4 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::ViewMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem )
|
Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem )
|
||||||
{
|
{
|
||||||
return ::LinearAlgebra3D::RotationMatrix_AxisX( radian, targetMem );
|
return ::LinearAlgebra3D::RotationMatrix_AxisX( radian, targetMem );
|
||||||
|
@ -147,9 +197,14 @@ namespace Oyster { namespace Math3D
|
||||||
return ::LinearAlgebra3D::OrientationMatrix( normalizedAxis, deltaRadian, sumTranslation, targetMem );
|
return ::LinearAlgebra3D::OrientationMatrix( normalizedAxis, deltaRadian, sumTranslation, targetMem );
|
||||||
}
|
}
|
||||||
|
|
||||||
Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, Float4x4 &targetMem )
|
Float4x4 & OrientationMatrix( const Float3 &angularAxis, const Float3 &translation, Float4x4 &targetMem )
|
||||||
{
|
{
|
||||||
return ::LinearAlgebra3D::OrientationMatrix( sumDeltaAngularAxis, sumTranslation, targetMem );
|
return ::LinearAlgebra3D::OrientationMatrix( angularAxis, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & ViewMatrix( const Float3 &angularAxis, const Float3 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::ViewMatrix( angularAxis, translation, targetMem );
|
||||||
}
|
}
|
||||||
|
|
||||||
Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, const Float3 ¢erOfMass, Float4x4 &targetMem )
|
Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, const Float3 ¢erOfMass, Float4x4 &targetMem )
|
||||||
|
@ -207,8 +262,18 @@ namespace Oyster { namespace Math3D
|
||||||
return ::LinearAlgebra3D::VectorProjection( vector, axis );
|
return ::LinearAlgebra3D::VectorProjection( vector, axis );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Float4 VectorProjection( const Float4 &vector, const Float4 &axis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::VectorProjection( vector, axis );
|
||||||
|
}
|
||||||
|
|
||||||
Float3 NormalProjection( const Float3 &vector, const Float3 &normalizedAxis )
|
Float3 NormalProjection( const Float3 &vector, const Float3 &normalizedAxis )
|
||||||
{
|
{
|
||||||
return ::LinearAlgebra3D::NormalProjection( vector, normalizedAxis );
|
return ::LinearAlgebra3D::NormalProjection( vector, normalizedAxis );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Float4 NormalProjection( const Float4 &vector, const Float4 &normalizedAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::NormalProjection( vector, normalizedAxis );
|
||||||
|
}
|
||||||
} }
|
} }
|
|
@ -9,17 +9,19 @@
|
||||||
#include "LinearMath.h"
|
#include "LinearMath.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace Oyster { namespace Math /// Oyster's native math library
|
namespace Oyster { namespace Math //! Oyster's native math library
|
||||||
{
|
{
|
||||||
typedef float Float; /// Oyster's native scalar is float
|
typedef float Float; //!< Oyster's native scalar is float
|
||||||
|
|
||||||
typedef ::LinearAlgebra::Vector2<Float> Float2; /// 2D Linear Vector for Oyster
|
typedef ::LinearAlgebra::Vector2<Float> Float2; //!< 2D Linear Vector for Oyster
|
||||||
typedef ::LinearAlgebra::Vector3<Float> Float3; /// 3D Linear Vector for Oyster
|
typedef ::LinearAlgebra::Vector3<Float> Float3; //!< 3D Linear Vector for Oyster
|
||||||
typedef ::LinearAlgebra::Vector4<Float> Float4; /// 4D Linear Vector for Oyster
|
typedef ::LinearAlgebra::Vector4<Float> Float4; //!< 4D Linear Vector for Oyster
|
||||||
|
|
||||||
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2; /// 2x2 Linear Matrix for Oyster
|
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2; //!< 2x2 Linear Matrix for Oyster
|
||||||
typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3; /// 3x3 Linear Matrix for Oyster
|
typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3; //!< 3x3 Linear Matrix for Oyster
|
||||||
typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4; /// 4x4 Linear Matrix for Oyster
|
typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4; //!< 4x4 Linear Matrix for Oyster
|
||||||
|
|
||||||
|
typedef ::LinearAlgebra::Quaternion<Float> Quaternion; //!< Quaternion for Oyster
|
||||||
|
|
||||||
typedef Float4x4 Matrix; // by popular demand
|
typedef Float4x4 Matrix; // by popular demand
|
||||||
typedef Float2 Vector2; // by popular demand
|
typedef Float2 Vector2; // by popular demand
|
||||||
|
@ -28,20 +30,20 @@ namespace Oyster { namespace Math /// Oyster's native math library
|
||||||
|
|
||||||
const Float pi = 3.1415926535897932384626433832795f;
|
const Float pi = 3.1415926535897932384626433832795f;
|
||||||
|
|
||||||
/// Function Highly recommended to check at start, just in case current version is using a feature that might be available.
|
//! Function Highly recommended to check at start, just in case current version is using a feature that might be available.
|
||||||
/// @todo TODO: create a template UniquePointer to use here
|
//! @todo TODO: create a template UniquePointer to use here
|
||||||
bool IsSupported();
|
bool IsSupported();
|
||||||
|
|
||||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||||
/// Returns false if there is no explicit solution.
|
//! Returns false if there is no explicit solution.
|
||||||
bool SuperpositionMatrix( const Float2x2 &in, const Float2x2 &out, Float2x2 &targetMem );
|
bool SuperpositionMatrix( const Float2x2 &in, const Float2x2 &out, Float2x2 &targetMem );
|
||||||
|
|
||||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||||
/// Returns false if there is no explicit solution.
|
//! Returns false if there is no explicit solution.
|
||||||
bool SuperpositionMatrix( const Float3x3 &in, const Float3x3 &out, Float3x3 &targetMem );
|
bool SuperpositionMatrix( const Float3x3 &in, const Float3x3 &out, Float3x3 &targetMem );
|
||||||
|
|
||||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||||
/// Returns false if there is no explicit solution.
|
//! Returns false if there is no explicit solution.
|
||||||
bool SuperpositionMatrix( const Float4x4 &in, const Float4x4 &out, Float4x4 &targetMem );
|
bool SuperpositionMatrix( const Float4x4 &in, const Float4x4 &out, Float4x4 &targetMem );
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
@ -96,54 +98,54 @@ inline ::Oyster::Math::Float3x3 operator * ( const ::Oyster::Math::Float &left,
|
||||||
inline ::Oyster::Math::Float4x4 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float4x4 &right )
|
inline ::Oyster::Math::Float4x4 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float4x4 &right )
|
||||||
{ return ::Oyster::Math::Float4x4(right) *= left; }
|
{ return ::Oyster::Math::Float4x4(right) *= left; }
|
||||||
|
|
||||||
namespace Oyster { namespace Math2D /// Oyster's native math library specialized for 2D
|
namespace Oyster { namespace Math2D //! Oyster's native math library specialized for 2D
|
||||||
{
|
{
|
||||||
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
|
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
|
||||||
|
|
||||||
/// If there is an Y-axis on a 2D plane, then there is an explicit X-axis on and that is what is returned.
|
//! If there is an Y-axis on a 2D plane, then there is an explicit X-axis on and that is what is returned.
|
||||||
/// Recommended too make sure that yAxis is normalized.
|
//! Recommended too make sure that yAxis is normalized.
|
||||||
Float2 X_AxisTo( const Float2 &yAxis );
|
Float2 X_AxisTo( const Float2 &yAxis );
|
||||||
|
|
||||||
/// If there is an X-axis on a 2D plane, then there is an explicit Y-axis and that is what is returned.
|
//! If there is an X-axis on a 2D plane, then there is an explicit Y-axis and that is what is returned.
|
||||||
/// Recommended too make sure that yAxis is normalized.
|
//! Recommended too make sure that yAxis is normalized.
|
||||||
Float2 Y_AxisTo( const Float2 &xAxis );
|
Float2 Y_AxisTo( const Float2 &xAxis );
|
||||||
|
|
||||||
/// Sets and returns targetMem to a translationMatrix with position as translation.
|
//! Sets and returns targetMem to a translationMatrix with position as translation.
|
||||||
Float3x3 & TranslationMatrix( const Float2 &position, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & TranslationMatrix( const Float2 &position, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as a counterclockwise rotationMatrix
|
//! Sets and returns targetMem as a counterclockwise rotationMatrix
|
||||||
Float3x3 & RotationMatrix( const Float &radian, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & RotationMatrix( const Float &radian, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
//! If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
||||||
Float2x2 & InverseRotationMatrix( const Float2x2 &rotation, Float2x2 &targetMem = Float2x2() );
|
Float2x2 & InverseRotationMatrix( const Float2x2 &rotation, Float2x2 &targetMem = Float2x2() );
|
||||||
|
|
||||||
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
//! If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
||||||
Float3x3 & InverseRotationMatrix( const Float3x3 &rotation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & InverseRotationMatrix( const Float3x3 &rotation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
//! Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
||||||
Float3x3 & OrientationMatrix( const Float2x2 &rotation, const Float2 &translation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float2x2 &rotation, const Float2 &translation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
//! Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
||||||
Float3x3 & OrientationMatrix( const Float3x3 &rotation, const Float2 &translation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float3x3 &rotation, const Float2 &translation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix with position as translation and radian rotation
|
//! Sets and returns targetMem as an orientation Matrix with position as translation and radian rotation
|
||||||
Float3x3 & OrientationMatrix( const Float2 &position, const Float &radian, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float2 &position, const Float &radian, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix with position as translation and local y-axis directed at lookAt
|
//! Sets and returns targetMem as an orientation Matrix with position as translation and local y-axis directed at lookAt
|
||||||
Float3x3 & OrientationMatrix( const Float2 &position, const Float2 &lookAt, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float2 &position, const Float2 &lookAt, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix that is rotated around localCenterOfRotation and then translated with position.
|
//! Sets and returns targetMem as an orientation Matrix that is rotated around localCenterOfRotation and then translated with position.
|
||||||
/// TODO: not tested
|
//! TODO: not tested
|
||||||
Float3x3 & OrientationMatrix( const Float2 &position, Float radian, const Float2 &localCenterOfRotation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float2 &position, Float radian, const Float2 &localCenterOfRotation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
|
//! If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
|
||||||
Float3x3 & InverseOrientationMatrix( const Float3x3 &orientationMatrix, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & InverseOrientationMatrix( const Float3x3 &orientationMatrix, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Returns targetmem after writing the rotation data from orientation, into it.
|
//! Returns targetmem after writing the rotation data from orientation, into it.
|
||||||
Float3x3 & ExtractRotationMatrix( const Float3x3 &orientation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & ExtractRotationMatrix( const Float3x3 &orientation, Float3x3 &targetMem = Float3x3() );
|
||||||
} }
|
} }
|
||||||
|
|
||||||
namespace Oyster { namespace Math3D /// Oyster's native math library specialized for 3D
|
namespace Oyster { namespace Math3D //! Oyster's native math library specialized for 3D
|
||||||
{
|
{
|
||||||
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
|
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
|
||||||
|
|
||||||
|
@ -153,35 +155,65 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
//! Extracts the angularAxis from rotationMatrix
|
//! Extracts the angularAxis from rotationMatrix
|
||||||
Float4 AngularAxis( const Float4x4 &rotationMatrix );
|
Float4 AngularAxis( const Float4x4 &rotationMatrix );
|
||||||
|
|
||||||
/// Sets and returns targetMem to a translationMatrix with position as translation.
|
//! Extracts the angularAxis from orientationMatrix
|
||||||
|
Float4 ExtractAngularAxis( const Float4x4 &orientationMatrix );
|
||||||
|
|
||||||
|
//! Sets and returns targetMem to a translationMatrix with position as translation.
|
||||||
Float4x4 & TranslationMatrix( const Float3 &position, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & TranslationMatrix( const Float3 &position, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global X-axis
|
/** @todo TODO: add doc */
|
||||||
|
Quaternion Rotation( Float radian, const Float3 &normalizedAxis );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Quaternion Rotation( Float radian, const Float3 &normalizedAxis );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Quaternion Rotation( const Float3 &angularAxis );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Quaternion Rotation( const Float4 &angularAxis );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & RotationMatrix( const Quaternion &rotationQuaternion, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & OrientationMatrix( const Quaternion &rotationQuaternion, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & OrientationMatrix( const Quaternion &rotationQuaternion, const Float4 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & ViewMatrix( const Quaternion &rotationQuaternion, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & ViewMatrix( const Quaternion &rotationQuaternion, const Float4 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the global X-axis
|
||||||
Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global Y-axis
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the global Y-axis
|
||||||
Float4x4 & RotationMatrix_AxisY( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix_AxisY( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global Z-axis
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the global Z-axis
|
||||||
Float4x4 & RotationMatrix_AxisZ( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix_AxisZ( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the angularAxis.
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the angularAxis.
|
||||||
Float4x4 & RotationMatrix( const Float3 &angularAxis, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix( const Float3 &angularAxis, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the normalizedAxis.
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the normalizedAxis.
|
||||||
/// Please make sure normalizedAxis is normalized.
|
//! Please make sure normalizedAxis is normalized.
|
||||||
Float4x4 & RotationMatrix( const Float &radian, const Float3 &normalizedAxis, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix( const Float &radian, const Float3 &normalizedAxis, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
//! If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
||||||
Float3x3 & InverseRotationMatrix( const Float3x3 &rotation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & InverseRotationMatrix( const Float3x3 &rotation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
//! If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
||||||
Float4x4 & InverseRotationMatrix( const Float4x4 &rotation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & InverseRotationMatrix( const Float4x4 &rotation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
//! Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
||||||
Float4x4 & OrientationMatrix( const Float3x3 &rotation, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & OrientationMatrix( const Float3x3 &rotation, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
//! Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
||||||
Float4x4 & OrientationMatrix( const Float4x4 &rotation, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & OrientationMatrix( const Float4x4 &rotation, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
@ -191,19 +223,26 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
* @param sumTranslation: sum of all the translation vectors.
|
* @param sumTranslation: sum of all the translation vectors.
|
||||||
* @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates.
|
* @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates.
|
||||||
* @return targetMem
|
* @return targetMem
|
||||||
* @todo TODO: not tested
|
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
Float4x4 & OrientationMatrix( const Float3 &normalizedAxis, const Float & deltaRadian, const Float3 &sumTranslation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & OrientationMatrix( const Float3 &normalizedAxis, const Float & deltaRadian, const Float3 &sumTranslation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* Sets and returns targetMem as an orientation Matrix
|
* Sets and returns targetMem as an orientation Matrix
|
||||||
* @param sumDeltaAngularAxis: sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector".
|
* @param angularAxis: sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector".
|
||||||
* @param sumTranslation: sum of all the translation vectors.
|
* @param translation: sum of all the translation vectors.
|
||||||
* @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates.
|
* @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates.
|
||||||
* @return targetMem
|
* @return targetMem
|
||||||
* @todo TODO: not tested
|
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & OrientationMatrix( const Float3 &angularAxis, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* Sets and returns targetMem as a view Matrix
|
||||||
|
* @param angularAxis: sum of all ( (1/I) * ( L x D ) )-vectorproducts. There I is known as "moment of inertia", L as "angular momentum vector" and D the "lever vector".
|
||||||
|
* @param translation: sum of all the translation vectors.
|
||||||
|
* @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates.
|
||||||
|
* @return targetMem
|
||||||
|
*******************************************************************/
|
||||||
|
Float4x4 & ViewMatrix( const Float3 &angularAxis, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* Sets and returns targetMem as an orientation Matrix
|
* Sets and returns targetMem as an orientation Matrix
|
||||||
|
@ -228,14 +267,14 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
//! @todo TODO: Add documentation and not tested
|
//! @todo TODO: Add documentation and not tested
|
||||||
Float4x4 & ViewMatrix_LookAtPos( const Float3 &worldLookAt, const Float3 &normalizedUpVector, const Float3 &worldPos, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & ViewMatrix_LookAtPos( const Float3 &worldLookAt, const Float3 &normalizedUpVector, const Float3 &worldPos, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
|
//! If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
|
||||||
Float4x4 & InverseOrientationMatrix( const Float4x4 &orientationMatrix, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & InverseOrientationMatrix( const Float4x4 &orientationMatrix, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
// O0 = T0 * R0
|
// O0 = T0 * R0
|
||||||
// O1 = T1 * T0 * R1 * R0
|
// O1 = T1 * T0 * R1 * R0
|
||||||
Float4x4 & UpdateOrientationMatrix( const Float3 &deltaPosition, const Float4x4 &deltaRotationMatrix, Float4x4 &orientationMatrix );
|
Float4x4 & UpdateOrientationMatrix( const Float3 &deltaPosition, const Float4x4 &deltaRotationMatrix, Float4x4 &orientationMatrix );
|
||||||
|
|
||||||
/// Returns targetmem after writing the rotation data from orientation, into it.
|
//! Returns targetmem after writing the rotation data from orientation, into it.
|
||||||
Float4x4 & ExtractRotationMatrix( const Float4x4 &orientation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & ExtractRotationMatrix( const Float4x4 &orientation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
@ -262,13 +301,19 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
Float4x4 & ProjectionMatrix_Perspective( const Float &verticalFoV, const Float &aspectRatio, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max(), Float4x4 &targetMem = Float4x4() );
|
Float4x4 & ProjectionMatrix_Perspective( const Float &verticalFoV, const Float &aspectRatio, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max(), Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// returns the component vector of vector that is parallell with axis
|
//! returns the component vector of vector that is parallell with axis
|
||||||
Float3 VectorProjection( const Float3 &vector, const Float3 &axis );
|
Float3 VectorProjection( const Float3 &vector, const Float3 &axis );
|
||||||
|
|
||||||
/// returns the component vector of vector that is parallell with axis. Faster than VectorProjection.
|
//! returns the component vector of vector that is parallell with axis
|
||||||
|
Float4 VectorProjection( const Float4 &vector, const Float4 &axis );
|
||||||
|
|
||||||
|
//! returns the component vector of vector that is parallell with axis. Faster than VectorProjection.
|
||||||
Float3 NormalProjection( const Float3 &vector, const Float3 &normalizedAxis );
|
Float3 NormalProjection( const Float3 &vector, const Float3 &normalizedAxis );
|
||||||
|
|
||||||
/// Helper inline function that sets and then returns targetMem = projection * view
|
//! returns the component vector of vector that is parallell with axis. Faster than VectorProjection.
|
||||||
|
Float4 NormalProjection( const Float4 &vector, const Float4 &normalizedAxis );
|
||||||
|
|
||||||
|
//! Helper inline function that sets and then returns targetMem = projection * view
|
||||||
inline Float4x4 & ViewProjectionMatrix( const Float4x4 &view, const Float4x4 &projection, Float4x4 &targetMem = Float4x4() )
|
inline Float4x4 & ViewProjectionMatrix( const Float4x4 &view, const Float4x4 &projection, Float4x4 &targetMem = Float4x4() )
|
||||||
{ return targetMem = projection * view; }
|
{ return targetMem = projection * view; }
|
||||||
|
|
||||||
|
@ -280,7 +325,7 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
inline Float4x4 TransformMatrix( const Float4x4 &transformer, const Float4x4 &transformee )
|
inline Float4x4 TransformMatrix( const Float4x4 &transformer, const Float4x4 &transformee )
|
||||||
{ return transformer * transformee; }
|
{ return transformer * transformee; }
|
||||||
|
|
||||||
/// Helper inline function that sets and then returns targetMem = transformer * transformee
|
//! Helper inline function that sets and then returns targetMem = transformer * transformee
|
||||||
inline Float4 & TransformVector( const Float4x4 &transformer, const Float4 &transformee, Float4 &targetMem = Float4() )
|
inline Float4 & TransformVector( const Float4x4 &transformer, const Float4 &transformee, Float4 &targetMem = Float4() )
|
||||||
{ return targetMem = transformer * transformee; }
|
{ return targetMem = transformer * transformee; }
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -22,8 +22,10 @@ namespace LinearAlgebra
|
||||||
char byte[sizeof(ScalarType[2])];
|
char byte[sizeof(ScalarType[2])];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const Quaternion<ScalarType> null;
|
||||||
|
static const Quaternion<ScalarType> identity;
|
||||||
|
|
||||||
Quaternion( );
|
Quaternion( );
|
||||||
Quaternion( const Quaternion &quaternion );
|
|
||||||
Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real );
|
Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real );
|
||||||
|
|
||||||
operator ScalarType* ( );
|
operator ScalarType* ( );
|
||||||
|
@ -53,40 +55,54 @@ namespace LinearAlgebra
|
||||||
// Body
|
// Body
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<typename ScalarType> const Quaternion<ScalarType> Quaternion<ScalarType>::null = Quaternion<ScalarType>( Vector3<ScalarType>((ScalarType)0), (ScalarType)0 );
|
||||||
|
template<typename ScalarType> const Quaternion<ScalarType> Quaternion<ScalarType>::identity = Quaternion<ScalarType>( Vector3<ScalarType>((ScalarType)0), (ScalarType)1 );
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
Quaternion<ScalarType>::Quaternion( ) : imaginary(), real() {}
|
Quaternion<ScalarType>::Quaternion( ) : imaginary(), real() {}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
Quaternion<ScalarType>::Quaternion( const Quaternion &quaternion )
|
Quaternion<ScalarType>::Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real )
|
||||||
{ this->imaginary = quaternion.imaginary; this->real = quaternion.real; }
|
{
|
||||||
|
this->imaginary = imaginary;
|
||||||
template<typename ScalarType>
|
this->real = real;
|
||||||
Quaternion<ScalarType>::Quaternion( const Vector3<ScalarType> &_imaginary, const ScalarType &_real )
|
}
|
||||||
{ this->imaginary = _imaginary; this->real = _real; }
|
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType>::operator ScalarType* ( )
|
inline Quaternion<ScalarType>::operator ScalarType* ( )
|
||||||
{ return this->element; }
|
{
|
||||||
|
return this->element;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType>::operator const ScalarType* ( ) const
|
inline Quaternion<ScalarType>::operator const ScalarType* ( ) const
|
||||||
{ return this->element; }
|
{
|
||||||
|
return this->element;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType>::operator char* ( )
|
inline Quaternion<ScalarType>::operator char* ( )
|
||||||
{ return this->byte; }
|
{
|
||||||
|
return this->byte;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType>::operator const char* ( ) const
|
inline Quaternion<ScalarType>::operator const char* ( ) const
|
||||||
{ return this->byte; }
|
{
|
||||||
|
return this->byte;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline ScalarType & Quaternion<ScalarType>::operator [] ( int i )
|
inline ScalarType & Quaternion<ScalarType>::operator [] ( int i )
|
||||||
{ return this->element[i]; }
|
{
|
||||||
|
return this->element[i];
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline const ScalarType & Quaternion<ScalarType>::operator [] ( int i ) const
|
inline const ScalarType & Quaternion<ScalarType>::operator [] ( int i ) const
|
||||||
{ return this->element[i]; }
|
{
|
||||||
|
return this->element[i];
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
Quaternion<ScalarType> & Quaternion<ScalarType>::operator = ( const Quaternion<ScalarType> &quaternion )
|
Quaternion<ScalarType> & Quaternion<ScalarType>::operator = ( const Quaternion<ScalarType> &quaternion )
|
||||||
|
@ -154,27 +170,39 @@ namespace LinearAlgebra
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const ScalarType &scalar ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const ScalarType &scalar ) const
|
||||||
{ return Quaternion<ScalarType>(*this) *= scalar; }
|
{
|
||||||
|
return Quaternion<ScalarType>(*this) *= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator / ( const ScalarType &scalar ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator / ( const ScalarType &scalar ) const
|
||||||
{ return Quaternion<ScalarType>(*this) /= scalar; }
|
{
|
||||||
|
return Quaternion<ScalarType>(*this) /= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator + ( const Quaternion<ScalarType> &quaternion ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator + ( const Quaternion<ScalarType> &quaternion ) const
|
||||||
{ return Quaternion<ScalarType>(*this) += quaternion; }
|
{
|
||||||
|
return Quaternion<ScalarType>(*this) += quaternion;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( const Quaternion<ScalarType> &quaternion ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( const Quaternion<ScalarType> &quaternion ) const
|
||||||
{ return Quaternion<ScalarType>(*this) -= quaternion; }
|
{
|
||||||
|
return Quaternion<ScalarType>(*this) -= quaternion;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( ) const
|
||||||
{ return Quaternion<ScalarType>(-this->imaginary, -this->real); }
|
{
|
||||||
|
return Quaternion<ScalarType>(-this->imaginary, -this->real);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::GetConjugate( ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::GetConjugate( ) const
|
||||||
{ return Quaternion<ScalarType>(-this->imaginary, this->real ); }
|
{
|
||||||
|
return Quaternion<ScalarType>(-this->imaginary, this->real );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -16,10 +16,17 @@ Box::Box( ) : ICollideable(Type_box)
|
||||||
}
|
}
|
||||||
|
|
||||||
Box::Box( const Float4x4 &r, const Float3 &p, const Float3 &s ) : ICollideable(Type_box)
|
Box::Box( const Float4x4 &r, const Float3 &p, const Float3 &s ) : ICollideable(Type_box)
|
||||||
|
{
|
||||||
|
this->rotation = r;
|
||||||
|
this->center = Float4( p, 1.0f );
|
||||||
|
this->boundingOffset = Float4( s * 0.5f , 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::Box( const Float4x4 &r, const Float4 &p, const Float4 &s ) : ICollideable(Type_box)
|
||||||
{
|
{
|
||||||
this->rotation = r;
|
this->rotation = r;
|
||||||
this->center = p;
|
this->center = p;
|
||||||
this->boundingOffset = Float3(s*0.5);
|
this->boundingOffset = s * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Box::~Box( ) {}
|
Box::~Box( ) {}
|
||||||
|
@ -42,13 +49,32 @@ bool Box::Intersects( const ICollideable &target ) const
|
||||||
switch( target.type )
|
switch( target.type )
|
||||||
{
|
{
|
||||||
case Type_universe: return true;
|
case Type_universe: return true;
|
||||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||||
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target );
|
case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
|
||||||
// case Type_triangle: return false; // TODO: :
|
// 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, (const BoxAxisAligned&)target );
|
||||||
case Type_box: return Utility::Intersect( *this, *(Box*)&target );
|
case Type_box: return Utility::Intersect( *this, (const Box&)target );
|
||||||
|
// case Type_frustrum: return false; // TODO: :
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Box::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
switch( target.type )
|
||||||
|
{
|
||||||
|
case Type_universe:
|
||||||
|
worldPointOfContact = this->center;
|
||||||
|
return true;
|
||||||
|
case Type_point: return Utility::Intersect( *this, (const Point&)target, worldPointOfContact );
|
||||||
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance, worldPointOfContact );
|
||||||
|
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target, worldPointOfContact );
|
||||||
|
case Type_plane: return Utility::Intersect( *this, (const Plane&)target, worldPointOfContact );
|
||||||
|
// case Type_triangle: return false; // TODO: :
|
||||||
|
case Type_box_axis_aligned: return Utility::Intersect( *this, (const BoxAxisAligned&)target, worldPointOfContact );
|
||||||
|
case Type_box: return Utility::Intersect( *this, (const Box&)target, worldPointOfContact );
|
||||||
// case Type_frustrum: return false; // TODO: :
|
// case Type_frustrum: return false; // TODO: :
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
@ -58,12 +84,12 @@ 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, (const Point&)target );
|
||||||
// case Type_sphere: return false; // TODO:
|
//case Type_sphere: return false; // TODO:
|
||||||
// case Type_triangle: return false; // TODO:
|
//case Type_triangle: return false; // TODO:
|
||||||
// case Type_box_axis_aligned: return false; // TODO:
|
//case Type_box_axis_aligned: return false; // TODO:
|
||||||
// case Type_box: return false; // TODO:
|
//case Type_box: return false; // TODO:
|
||||||
// case Type_frustrum: return false; // TODO:
|
//case Type_frustrum: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,24 +16,26 @@ namespace Oyster { namespace Collision3D
|
||||||
public:
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct{ ::Oyster::Math::Float4x4 rotation; ::Oyster::Math::Float3 center, boundingOffset; };
|
struct{ ::Oyster::Math::Float4x4 rotation; ::Oyster::Math::Float4 center, boundingOffset; };
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
::Oyster::Math::Float3 xAxis; ::Oyster::Math::Float paddingA;
|
::Oyster::Math::Float4 xAxis;
|
||||||
::Oyster::Math::Float3 yAxis; ::Oyster::Math::Float paddingB;
|
::Oyster::Math::Float4 yAxis;
|
||||||
::Oyster::Math::Float3 zAxis; ::Oyster::Math::Float paddingC;
|
::Oyster::Math::Float4 zAxis;
|
||||||
};
|
};
|
||||||
char byte[sizeof(::Oyster::Math::Float4x4) + 2*sizeof(::Oyster::Math::Float3)];
|
char byte[sizeof(::Oyster::Math::Float4x4) + 2*sizeof(::Oyster::Math::Float4)];
|
||||||
};
|
};
|
||||||
|
|
||||||
Box( );
|
Box( );
|
||||||
Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &size );
|
Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &size );
|
||||||
|
Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float4 &worldPos, const ::Oyster::Math::Float4 &size );
|
||||||
virtual ~Box( );
|
virtual ~Box( );
|
||||||
|
|
||||||
Box & operator = ( const Box &box );
|
Box & operator = ( const Box &box );
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -14,16 +14,16 @@ BoxAxisAligned::BoxAxisAligned( ) : ICollideable(Type_box_axis_aligned)
|
||||||
this->maxVertex = Float3( 0.5f, 0.5f, 0.5f );
|
this->maxVertex = Float3( 0.5f, 0.5f, 0.5f );
|
||||||
}
|
}
|
||||||
|
|
||||||
BoxAxisAligned::BoxAxisAligned( const Float3 &_minVertex, const Float3 &_maxVertex ) : ICollideable(Type_box_axis_aligned)
|
BoxAxisAligned::BoxAxisAligned( const Float3 &minVertex, const Float3 &maxVertex ) : ICollideable(Type_box_axis_aligned)
|
||||||
{
|
{
|
||||||
this->minVertex = _minVertex;
|
this->minVertex = Float4( minVertex, 1.0f );
|
||||||
this->maxVertex = _maxVertex;
|
this->maxVertex = Float4( maxVertex, 1.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
BoxAxisAligned::BoxAxisAligned( const Float &leftClip, const Float &rightClip, const Float &topClip, const Float &bottomClip, const Float &nearClip, const Float &farClip ) : ICollideable(Type_box_axis_aligned)
|
BoxAxisAligned::BoxAxisAligned( const Float &leftClip, const Float &rightClip, const Float &topClip, const Float &bottomClip, const Float &nearClip, const Float &farClip ) : ICollideable(Type_box_axis_aligned)
|
||||||
{
|
{
|
||||||
this->minVertex = Float3( leftClip, bottomClip, nearClip );
|
this->minVertex = Float4( leftClip, bottomClip, nearClip, 1.0f );
|
||||||
this->maxVertex = Float3( rightClip, topClip, farClip );
|
this->maxVertex = Float4( rightClip, topClip, farClip, 1.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
BoxAxisAligned::~BoxAxisAligned( ) {}
|
BoxAxisAligned::~BoxAxisAligned( ) {}
|
||||||
|
@ -45,28 +45,35 @@ bool BoxAxisAligned::Intersects( const ICollideable &target ) const
|
||||||
switch( target.type )
|
switch( target.type )
|
||||||
{
|
{
|
||||||
case Type_universe: return true;
|
case Type_universe: return true;
|
||||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||||
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target );
|
case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
|
||||||
// case Type_triangle: return false; // TODO:
|
// 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, (const BoxAxisAligned&)target );
|
||||||
// case Type_box: return false; // TODO:
|
// case Type_box: return false; // TODO:
|
||||||
// case Type_frustrum: return false; // TODO:
|
// case Type_frustrum: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BoxAxisAligned::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement stub properly
|
||||||
|
return this->Intersects( target );
|
||||||
|
}
|
||||||
|
|
||||||
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_point: return false; // TODO:
|
||||||
// case Type_sphere: return false; // TODO:
|
////case Type_sphere: return false; // TODO:
|
||||||
// case Type_triangle: return false; // TODO:
|
////case Type_triangle: return false; // TODO:
|
||||||
// case Type_box_axis_aligned: return false; // TODO:
|
////case Type_box_axis_aligned: return false; // TODO:
|
||||||
// case Type_box: return false; // TODO:
|
////case Type_box: return false; // TODO:
|
||||||
// case Type_frustrum: return false; // TODO:
|
////case Type_frustrum: return false; // TODO:
|
||||||
default: return false;
|
//default: return false;
|
||||||
}
|
//}
|
||||||
|
return false;
|
||||||
}
|
}
|
|
@ -16,8 +16,8 @@ namespace Oyster { namespace Collision3D
|
||||||
public:
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct{ ::Oyster::Math::Float3 minVertex, maxVertex; };
|
struct{ ::Oyster::Math::Float4 minVertex, maxVertex; };
|
||||||
char byte[2*sizeof(::Oyster::Math::Float3)];
|
char byte[2*sizeof(::Oyster::Math::Float4)];
|
||||||
};
|
};
|
||||||
|
|
||||||
BoxAxisAligned( );
|
BoxAxisAligned( );
|
||||||
|
@ -29,6 +29,7 @@ namespace Oyster { namespace Collision3D
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#include "Frustrum.h"
|
#include "Frustrum.h"
|
||||||
#include "OysterCollision3D.h"
|
#include "OysterCollision3D.h"
|
||||||
|
|
||||||
using namespace Oyster::Math;
|
using namespace ::Oyster::Math;
|
||||||
using namespace Oyster::Collision3D;
|
using namespace ::Oyster::Collision3D;
|
||||||
|
|
||||||
namespace PrivateStatic
|
namespace PrivateStatic
|
||||||
{
|
{
|
||||||
|
@ -76,12 +76,12 @@ namespace PrivateStatic
|
||||||
|
|
||||||
Frustrum::Frustrum() : ICollideable(Type_frustrum)
|
Frustrum::Frustrum() : ICollideable(Type_frustrum)
|
||||||
{
|
{
|
||||||
this->leftPlane = Plane( Float3::standard_unit_x, -0.5f );
|
this->leftPlane = Plane( Float4::standard_unit_x, -0.5f );
|
||||||
this->rightPlane = Plane(-Float3::standard_unit_x, 0.5f ),
|
this->rightPlane = Plane(-Float4::standard_unit_x, 0.5f ),
|
||||||
this->bottomPlane = Plane( Float3::standard_unit_y, -0.5f );
|
this->bottomPlane = Plane( Float4::standard_unit_y, -0.5f );
|
||||||
this->topPlane = Plane(-Float3::standard_unit_y, 0.5f );
|
this->topPlane = Plane(-Float4::standard_unit_y, 0.5f );
|
||||||
this->nearPlane = Plane( Float3::standard_unit_z, -0.5f );
|
this->nearPlane = Plane( Float4::standard_unit_z, -0.5f );
|
||||||
this->farPlane = Plane(-Float3::standard_unit_z, 0.5f );
|
this->farPlane = Plane(-Float4::standard_unit_z, 0.5f );
|
||||||
}
|
}
|
||||||
|
|
||||||
Frustrum::Frustrum( const Float4x4 &vp ) : ICollideable(Type_frustrum)
|
Frustrum::Frustrum( const Float4x4 &vp ) : ICollideable(Type_frustrum)
|
||||||
|
@ -198,39 +198,47 @@ void Frustrum::WriteToByte( unsigned int &nextIndex, unsigned char targetMem[] )
|
||||||
}
|
}
|
||||||
|
|
||||||
::Utility::DynamicMemory::UniquePointer<ICollideable> Frustrum::Clone( ) const
|
::Utility::DynamicMemory::UniquePointer<ICollideable> Frustrum::Clone( ) const
|
||||||
{ return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Frustrum(*this) ); }
|
{
|
||||||
|
return ::Utility::DynamicMemory::UniquePointer<ICollideable>( 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_universe: return true;
|
||||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||||
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target );
|
case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
|
||||||
// case Type_triangle: return false; // TODO:
|
//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, (const BoxAxisAligned&)target );
|
||||||
case Type_box: return Utility::Intersect( *this, *(Box*)&target );
|
case Type_box: return Utility::Intersect( *this, (const Box&)target );
|
||||||
case Type_frustrum: return Utility::Intersect( *this, *(Frustrum*)&target );
|
case Type_frustrum: return Utility::Intersect( *this, (const Frustrum&)target );
|
||||||
// case Type_line: return false; // TODO:
|
//case Type_line: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Frustrum::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement stub properly
|
||||||
|
return this->Intersects( target );
|
||||||
|
}
|
||||||
|
|
||||||
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, (const Point&)target );
|
||||||
// case Type_ray: return false; // TODO:
|
//case Type_ray: return false; // TODO:
|
||||||
// case Type_sphere: return false; // TODO:
|
//case Type_sphere: return false; // TODO:
|
||||||
// case Type_plane: return false; // TODO:
|
//case Type_plane: return false; // TODO:
|
||||||
// case Type_triangle: return false; // TODO:
|
//case Type_triangle: return false; // TODO:
|
||||||
// case Type_box_axis_aligned: return false; // TODO:
|
//case Type_box_axis_aligned: return false; // TODO:
|
||||||
// case Type_box: return false; // TODO:
|
//case Type_box: return false; // TODO:
|
||||||
// case Type_frustrum: return false; // TODO:
|
//case Type_frustrum: return false; // TODO:
|
||||||
// case Type_line: return false; // TODO:
|
//case Type_line: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -39,6 +39,7 @@ namespace Oyster { namespace Collision3D
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#ifndef OYSTER_COLLISION_3D_ICOLLIDEABLE_H
|
#ifndef OYSTER_COLLISION_3D_ICOLLIDEABLE_H
|
||||||
#define OYSTER_COLLISION_3D_ICOLLIDEABLE_H
|
#define OYSTER_COLLISION_3D_ICOLLIDEABLE_H
|
||||||
|
|
||||||
|
#include "OysterMath.h"
|
||||||
#include "Utilities.h"
|
#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.
|
||||||
|
@ -34,6 +35,7 @@ namespace Oyster { namespace Collision3D //! Contains a collection of 3D shapes
|
||||||
virtual ~ICollideable();
|
virtual ~ICollideable();
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const = 0;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const = 0;
|
||||||
|
virtual bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
|
||||||
virtual bool Intersects( const ICollideable &target ) const = 0;
|
virtual bool Intersects( const ICollideable &target ) const = 0;
|
||||||
virtual bool Contains( const ICollideable &target ) const = 0;
|
virtual bool Contains( const ICollideable &target ) const = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,8 +46,29 @@ bool Line::Intersects( const ICollideable &target ) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( this->ray.Intersects( target ) ) if( this->ray.collisionDistance >= 0.0f ) if( this->ray.collisionDistance <= this->length )
|
if( this->ray.Intersects(target) ) if( this->ray.collisionDistance >= 0.0f ) if( this->ray.collisionDistance <= this->length )
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->ray.collisionDistance = 0.0f;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Line::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
if( target.type == Type_universe )
|
||||||
|
{
|
||||||
|
this->ray.collisionDistance = 0.0f;
|
||||||
|
worldPointOfContact = this->ray.origin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this->ray.Intersects(target) ) if( this->ray.collisionDistance >= 0.0f ) if( this->ray.collisionDistance <= this->length )
|
||||||
|
{
|
||||||
|
worldPointOfContact = this->ray.origin + this->ray.direction * this->ray.collisionDistance;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
this->ray.collisionDistance = 0.0f;
|
this->ray.collisionDistance = 0.0f;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace Oyster { namespace Collision3D
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if miss/reject
|
// returns true if miss/reject
|
||||||
bool BoxVsRayPerSlabCheck( const Float3 &axis, const Float &boundingOffset, const Float3 &deltaPos, const Float3 rayDirection, Float &tMin, Float &tMax )
|
bool BoxVsRayPerSlabCheck( const Float4 &axis, const Float &boundingOffset, const Float4 &deltaPos, const Float4 rayDirection, Float &tMin, Float &tMax )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float e = axis.Dot( deltaPos ),
|
Float e = axis.Dot( deltaPos ),
|
||||||
f = axis.Dot( rayDirection );
|
f = axis.Dot( rayDirection );
|
||||||
|
@ -51,12 +51,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Contains( const Plane &container, const Float3 &pos )
|
inline bool Contains( const Plane &container, const Float4 &pos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return EqualsZero( container.normal.Dot( pos ) + container.phasing );
|
return EqualsZero( container.normal.Dot( pos ) + container.phasing );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Compare( Float &connectOffset, const Plane &plane, const Float3 &pos )
|
inline void Compare( Float &connectOffset, const Plane &plane, const Float4 &pos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
connectOffset = plane.normal.Dot(pos);
|
connectOffset = plane.normal.Dot(pos);
|
||||||
connectOffset += plane.phasing;
|
connectOffset += plane.phasing;
|
||||||
|
@ -64,7 +64,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
|
|
||||||
void Compare( Float &boxExtend, Float ¢erDistance, const Plane &plane, const BoxAxisAligned &box )
|
void Compare( Float &boxExtend, Float ¢erDistance, const Plane &plane, const BoxAxisAligned &box )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float3 c = (box.maxVertex + box.minVertex) * 0.5f, // box.Center
|
Float4 c = (box.maxVertex + box.minVertex) * 0.5f, // box.Center
|
||||||
h = (box.maxVertex - box.minVertex) * 0.5f; // box.halfSize
|
h = (box.maxVertex - box.minVertex) * 0.5f; // box.halfSize
|
||||||
boxExtend = h.x * Abs(plane.normal.x); // Box max extending towards plane
|
boxExtend = h.x * Abs(plane.normal.x); // Box max extending towards plane
|
||||||
boxExtend += h.y * Abs(plane.normal.y);
|
boxExtend += h.y * Abs(plane.normal.y);
|
||||||
|
@ -81,7 +81,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
centerDistance = box.center.Dot(plane.normal) + plane.phasing; // distance between box center and plane
|
centerDistance = box.center.Dot(plane.normal) + plane.phasing; // distance between box center and plane
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SeperatingAxisTest_AxisAlignedVsTransformedBox( const Float3 &boundingOffsetA, const Float3 &boundingOffsetB, const Float4x4 &rotationB, const Float3 &worldOffset )
|
bool SeperatingAxisTest_AxisAlignedVsTransformedBox( const Float4 &boundingOffsetA, const Float4 &boundingOffsetB, const Float4x4 &rotationB, const Float4 &worldOffset )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
|
@ -103,37 +103,37 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
Float3 absWorldOffset = Abs(worldOffset); // |t|: [absWorldOffset]
|
Float3 absWorldOffset = Abs(worldOffset); // |t|: [absWorldOffset]
|
||||||
|
|
||||||
// s = { 1, 0, 0 } [ RA.v[0] ]
|
// s = { 1, 0, 0 } [ RA.v[0] ]
|
||||||
if( absWorldOffset.x > boundingOffsetA.x + boundingOffsetB.Dot(Float3(absRotationB.v[0].x, absRotationB.v[1].x, absRotationB.v[2].x)) )
|
if( absWorldOffset.x > boundingOffsetA.x + boundingOffsetB.Dot(Float4(absRotationB.v[0].x, absRotationB.v[1].x, absRotationB.v[2].x, 0.0f)) )
|
||||||
{ // |t dot s| > hA dot |s| + hB dot |s * RB| -->> t.x > hA.x + hB dot |{RB.v[0].x, RB.v[1].x, RB.v[2].x}|
|
{ // |t dot s| > hA dot |s| + hB dot |s * RB| -->> t.x > hA.x + hB dot |{RB.v[0].x, RB.v[1].x, RB.v[2].x}|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// s = { 0, 1, 0 } [ RA.v[1] ]
|
// s = { 0, 1, 0 } [ RA.v[1] ]
|
||||||
if( absWorldOffset.y > boundingOffsetA.y + boundingOffsetB.Dot(Float3(absRotationB.v[0].y, absRotationB.v[1].y, absRotationB.v[2].y)) )
|
if( absWorldOffset.y > boundingOffsetA.y + boundingOffsetB.Dot(Float4(absRotationB.v[0].y, absRotationB.v[1].y, absRotationB.v[2].y, 0.0f)) )
|
||||||
{ // t.y > hA.y + hB dot |{RB.v[0].y, RB.v[1].y, RB.v[2].y}|
|
{ // t.y > hA.y + hB dot |{RB.v[0].y, RB.v[1].y, RB.v[2].y}|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// s = { 0, 0, 1 } [ RA.v[2] ]
|
// s = { 0, 0, 1 } [ RA.v[2] ]
|
||||||
if( absWorldOffset.z > boundingOffsetA.z + boundingOffsetB.Dot(Float3(absRotationB.v[0].z, absRotationB.v[1].z, absRotationB.v[2].z)) )
|
if( absWorldOffset.z > boundingOffsetA.z + boundingOffsetB.Dot(Float4(absRotationB.v[0].z, absRotationB.v[1].z, absRotationB.v[2].z, 0.0f)) )
|
||||||
{ // t.z > hA.z + hB dot |{RB.v[0].z, RB.v[1].z, RB.v[2].z}|
|
{ // t.z > hA.z + hB dot |{RB.v[0].z, RB.v[1].z, RB.v[2].z}|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// s = RB.v[0].xyz
|
// s = RB.v[0].xyz
|
||||||
if( Abs(worldOffset.Dot(rotationB.v[0].xyz)) > boundingOffsetA.Dot(absRotationB.v[0].xyz) + boundingOffsetB.x )
|
if( Abs(worldOffset.Dot(rotationB.v[0])) > boundingOffsetA.Dot(absRotationB.v[0]) + boundingOffsetB.x )
|
||||||
{ // |t dot s| > hA dot |s| + hB dot |s * RB| -->> |t dot s| > hA dot |s| + hB dot |{1, 0, 0}| -->> |t dot s| > hA dot |s| + hB.x
|
{ // |t dot s| > hA dot |s| + hB dot |s * RB| -->> |t dot s| > hA dot |s| + hB dot |{1, 0, 0}| -->> |t dot s| > hA dot |s| + hB.x
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// s = RB.v[1].xyz
|
// s = RB.v[1].xyz
|
||||||
if( Abs(worldOffset.Dot(rotationB.v[1].xyz)) > boundingOffsetA.Dot(absRotationB.v[1].xyz) + boundingOffsetB.y )
|
if( Abs(worldOffset.Dot(rotationB.v[1])) > boundingOffsetA.Dot(absRotationB.v[1]) + boundingOffsetB.y )
|
||||||
{ // |t dot s| > hA dot |s| + hB.y
|
{ // |t dot s| > hA dot |s| + hB.y
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// s = RB.v[2].xyz
|
// s = RB.v[2].xyz
|
||||||
if( Abs(worldOffset.Dot(rotationB.v[2].xyz)) > boundingOffsetA.Dot(absRotationB.v[2].xyz) + boundingOffsetB.z )
|
if( Abs(worldOffset.Dot(rotationB.v[2])) > boundingOffsetA.Dot(absRotationB.v[2]) + boundingOffsetB.z )
|
||||||
{ // |t dot s| > hA dot |s| + hB.z
|
{ // |t dot s| > hA dot |s| + hB.z
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -203,13 +203,187 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SeperatingAxisTest_AxisAlignedVsTransformedBox( const Float4 &boundingOffsetA, const Float4 &boundingOffsetB, const Float4x4 &rotationB, const Float4 &worldOffset, Float4 &worldPointOfContact )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
|
||||||
|
/*****************************************************************
|
||||||
|
* Uses the Seperating Axis Theorem
|
||||||
|
* if( |t dot s| > hA dot |s * RA| + hB dot |s * RB| ) then not intersecting
|
||||||
|
* |t dot s| > hA dot |s| + hB dot |s * RB| .. as RA = I
|
||||||
|
*
|
||||||
|
* t: objectB's offset from objectA [worldOffset]
|
||||||
|
* s: current comparison axis
|
||||||
|
* hA: boundingReach vector of objectA. Only absolute values is assumed. [boundingOffsetA]
|
||||||
|
* hB: boundingReach vector of objectB. Only absolute values is assumed. [boundingOffsetB]
|
||||||
|
* RA: rotation matrix of objectA. Is identity matrix here, thus omitted.
|
||||||
|
* RB: rotation matrix of objectB. Is transformed into objectA's view at this point. [rotationB]
|
||||||
|
*
|
||||||
|
* Note: s * RB = (RB^T * s)^T = (RB^-1 * s)^T .... vector == vector^T
|
||||||
|
*****************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************
|
||||||
|
* Distance Alghorithm based on .. something Dan came up with
|
||||||
|
* pi = si * ( (t dot si) * (hA dot |si|) / (hA dot |si| + hB dot |si * RB|) )
|
||||||
|
* p = estimated point of contact
|
||||||
|
* = ( p1 + p2 + ... + p5 + p6 ) / 2
|
||||||
|
*****************************************************************/
|
||||||
|
|
||||||
|
const Float4 &t = worldOffset,
|
||||||
|
&hA = boundingOffsetA,
|
||||||
|
&hB = boundingOffsetB;
|
||||||
|
Float4 s = Float4::standard_unit_x;
|
||||||
|
|
||||||
|
Float centerSeperation = t.Dot(s),
|
||||||
|
eA = hA.Dot( Abs(s) ),
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
worldPointOfContact = s * ( centerSeperation * eA / edgeSeperation );
|
||||||
|
|
||||||
|
s = Float4::standard_unit_y;
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
worldPointOfContact += s * ( centerSeperation * eA / edgeSeperation );
|
||||||
|
|
||||||
|
s = Float4::standard_unit_z;
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
worldPointOfContact += s * ( centerSeperation * eA / edgeSeperation );
|
||||||
|
|
||||||
|
s = rotationB.v[0];
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
worldPointOfContact += s * ( centerSeperation * eA / edgeSeperation );
|
||||||
|
|
||||||
|
s = rotationB.v[1];
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
worldPointOfContact += s * ( centerSeperation * eA / edgeSeperation );
|
||||||
|
|
||||||
|
s = rotationB.v[2];
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
worldPointOfContact += s * ( centerSeperation * eA / edgeSeperation ); // enough point of contact data gathered for approximative result.
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_x.Cross(rotationB.v[0].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_x.Cross(rotationB.v[1].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_x.Cross(rotationB.v[2].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_y.Cross(rotationB.v[0].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_y.Cross(rotationB.v[1].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_y.Cross(rotationB.v[2].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_z.Cross(rotationB.v[0].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_z.Cross(rotationB.v[1].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = Float4( Float3::standard_unit_z.Cross(rotationB.v[2].xyz), 0.0f );
|
||||||
|
centerSeperation = t.Dot(s);
|
||||||
|
eA = hA.Dot( Abs(s) );
|
||||||
|
edgeSeperation = eA + hB.Dot( Abs(s * rotationB) );
|
||||||
|
if( Abs(centerSeperation) > edgeSeperation )
|
||||||
|
{ // no intersection
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
worldPointOfContact *= 0.5f;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUBLIC BODY //////////////////////////////////////////////////////
|
// PUBLIC BODY //////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Compare( Float &connectDistance, Float &connectOffsetSquared, const Ray &ray, const Point &point )
|
void Compare( Float &connectDistance, Float &connectOffsetSquared, const Ray &ray, const Point &point )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float3 dP = point.center - ray.origin;
|
Float4 dP = point.center - ray.origin;
|
||||||
|
|
||||||
connectDistance = dP.Dot( ray.direction );
|
connectDistance = dP.Dot( ray.direction );
|
||||||
connectDistance /= ray.direction.Dot( ray.direction );
|
connectDistance /= ray.direction.Dot( ray.direction );
|
||||||
|
@ -220,7 +394,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
|
|
||||||
void Compare( Float &connectDistanceA, Float &connectDistanceB, Float &connectOffsetSquared, const Ray &rayA, const Ray &rayB )
|
void Compare( Float &connectDistanceA, Float &connectDistanceB, Float &connectOffsetSquared, const Ray &rayA, const Ray &rayB )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float3 dP = rayB.origin - rayA.origin;
|
Float4 dP = rayB.origin - rayA.origin;
|
||||||
connectDistanceA = rayA.direction.Dot( dP );
|
connectDistanceA = rayA.direction.Dot( dP );
|
||||||
connectDistanceA /= rayA.direction.Dot( rayA.direction );
|
connectDistanceA /= rayA.direction.Dot( rayA.direction );
|
||||||
|
|
||||||
|
@ -249,6 +423,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true; // Passed all tests, is in same position
|
return true; // Passed all tests, is in same position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Point &pointA, const Point &pointB, ::Oyster::Math::Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Ray &ray, const Point &point, Float &connectDistance )
|
bool Intersect( const Ray &ray, const Point &point, Float &connectDistance )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float connectOffsetSquared;
|
Float connectOffsetSquared;
|
||||||
|
@ -264,6 +444,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Ray &rayA, const Ray &rayB, Float &connectDistanceA, Float &connectDistanceB )
|
bool Intersect( const Ray &rayA, const Ray &rayB, Float &connectDistanceA, Float &connectDistanceB )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float connectOffsetSquared;
|
Float connectOffsetSquared;
|
||||||
|
@ -279,6 +465,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB, ::Oyster::Math::Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Sphere &sphere, const Point &point )
|
bool Intersect( const Sphere &sphere, const Point &point )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float3 dP = point.center - sphere.center;
|
Float3 dP = point.center - sphere.center;
|
||||||
|
@ -287,9 +479,15 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Sphere &sphere, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Sphere &sphere, const Ray &ray, Float &connectDistance )
|
bool Intersect( const Sphere &sphere, const Ray &ray, Float &connectDistance )
|
||||||
{// by Dan Andersson
|
{// by Dan Andersson
|
||||||
Float3 dP = sphere.center - ray.origin;
|
Float4 dP = sphere.center - ray.origin;
|
||||||
Float s = dP.Dot( ray.direction ),
|
Float s = dP.Dot( ray.direction ),
|
||||||
dSquared = dP.Dot( dP ),
|
dSquared = dP.Dot( dP ),
|
||||||
rSquared = sphere.radius * sphere.radius;
|
rSquared = sphere.radius * sphere.radius;
|
||||||
|
@ -307,9 +505,15 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Sphere &sphereA, const Sphere &sphereB )
|
bool Intersect( const Sphere &sphereA, const Sphere &sphereB )
|
||||||
{ // by Fredrick Johansson
|
{ // by Fredrick Johansson
|
||||||
Float3 C = sphereA.center;
|
Float4 C = sphereA.center;
|
||||||
C -= sphereB.center;
|
C -= sphereB.center;
|
||||||
Float r = (sphereA.radius + sphereB.radius);
|
Float r = (sphereA.radius + sphereB.radius);
|
||||||
|
|
||||||
|
@ -321,6 +525,27 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Sphere &sphereA, const Sphere &sphereB, ::Oyster::Math::Float4 &worldPointOfContact )
|
||||||
|
{ // by Robin Engman
|
||||||
|
Float4 C = sphereA.center;
|
||||||
|
C -= sphereB.center;
|
||||||
|
Float r = sphereA.radius + sphereB.radius;
|
||||||
|
|
||||||
|
if ( r*r >= C.Dot(C) )
|
||||||
|
{
|
||||||
|
Float distance;
|
||||||
|
Ray ray(sphereB.center, C.Normalize());
|
||||||
|
|
||||||
|
Intersect( sphereA, ray, distance );
|
||||||
|
|
||||||
|
worldPointOfContact = ray.origin + ray.direction*distance;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Plane &plane, const Point &point )
|
bool Intersect( const Plane &plane, const Point &point )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float connectOffset;
|
Float connectOffset;
|
||||||
|
@ -328,6 +553,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return Private::EqualsZero(connectOffset);
|
return Private::EqualsZero(connectOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Plane &plane, const Point &point, Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Plane &plane, const Ray &ray, Float &connectDistance )
|
bool Intersect( const Plane &plane, const Ray &ray, Float &connectDistance )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float c = plane.normal.Dot(ray.direction);
|
Float c = plane.normal.Dot(ray.direction);
|
||||||
|
@ -348,6 +579,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Plane &plane, const Ray &ray, Float &connectDistance, Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Plane &plane, const Sphere &sphere )
|
bool Intersect( const Plane &plane, const Sphere &sphere )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float connectOffset;
|
Float connectOffset;
|
||||||
|
@ -355,6 +592,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return (connectOffset <= sphere.radius);
|
return (connectOffset <= sphere.radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Plane &plane, const Sphere &sphere, Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Plane &planeA, const Plane &planeB )
|
bool Intersect( const Plane &planeA, const Plane &planeB )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
if( planeA.normal == planeB.normal ) // they are parallell
|
if( planeA.normal == planeB.normal ) // they are parallell
|
||||||
|
@ -364,6 +607,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true; // none parallell planes ALWAYS intersects somewhere
|
return true; // none parallell planes ALWAYS intersects somewhere
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Plane &planeA, const Plane &planeB, Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement Stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const BoxAxisAligned &box, const Point &point )
|
bool Intersect( const BoxAxisAligned &box, const Point &point )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
if( point.center.x < box.minVertex.x ) return false;
|
if( point.center.x < box.minVertex.x ) return false;
|
||||||
|
@ -375,31 +624,66 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const BoxAxisAligned &box, const Point &point, Float4 &worldPointOfContact )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
if( Intersect(box, point) )
|
||||||
|
{
|
||||||
|
worldPointOfContact = point.center;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const BoxAxisAligned &box, const Ray &ray, Float &connectDistance )
|
bool Intersect( const BoxAxisAligned &box, const Ray &ray, Float &connectDistance )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float tMin = ::std::numeric_limits<Float>::max(),
|
Float tMin = ::std::numeric_limits<Float>::max(),
|
||||||
tMax = -tMin; // initiating to extremevalues
|
tMax = -tMin; // initiating to extremevalues
|
||||||
|
|
||||||
Float3 boundingOffset = ((box.maxVertex - box.minVertex) * 0.5f),
|
Float4 boundingOffset = ((box.maxVertex - box.minVertex) * 0.5f),
|
||||||
dP = ((box.maxVertex + box.minVertex) * 0.5f) - ray.origin;
|
dP = ((box.maxVertex + box.minVertex) * 0.5f) - ray.origin;
|
||||||
if( Private::BoxVsRayPerSlabCheck( Float3::standard_unit_x, boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
if( Private::BoxVsRayPerSlabCheck( Float4::standard_unit_x, boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
||||||
if( Private::BoxVsRayPerSlabCheck( Float3::standard_unit_y, boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
if( Private::BoxVsRayPerSlabCheck( Float4::standard_unit_y, boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
||||||
if( Private::BoxVsRayPerSlabCheck( Float3::standard_unit_z, boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
if( Private::BoxVsRayPerSlabCheck( Float4::standard_unit_z, boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
||||||
|
|
||||||
if( tMin > 0.0f ) connectDistance = tMin;
|
if( tMin > 0.0f ) connectDistance = tMin;
|
||||||
else connectDistance = tMax;
|
else connectDistance = tMax;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const BoxAxisAligned &box, const Ray &ray, Float &connectDistance, Float4 &worldPointOfContact )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
if( Intersect(box, ray, connectDistance) )
|
||||||
|
{
|
||||||
|
worldPointOfContact = ray.origin + ray.direction * connectDistance;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere )
|
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float4 e = Max( Float4(box.minVertex - sphere.center, 0.0f), Float4::null );
|
Float4 e = Max( box.minVertex - sphere.center, Float4::null );
|
||||||
e += Max( Float4(sphere.center - box.maxVertex, 0.0f), Float4::null );
|
e += Max( sphere.center - box.maxVertex, Float4::null );
|
||||||
|
|
||||||
if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
|
if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere, Float4 &worldPointOfContact )
|
||||||
|
{ // by Robin Engman
|
||||||
|
if( Intersect(box, sphere) )
|
||||||
|
{
|
||||||
|
Float distance;
|
||||||
|
Float4 boxMiddle = (box.maxVertex - box.minVertex) * 0.5f;
|
||||||
|
Ray ray( boxMiddle, (sphere.center - boxMiddle).Normalize() );
|
||||||
|
Intersect( sphere, ray, distance );
|
||||||
|
worldPointOfContact = ray.origin + ray.direction * distance;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const BoxAxisAligned &box, const Plane &plane )
|
bool Intersect( const BoxAxisAligned &box, const Plane &plane )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float e, d;
|
Float e, d;
|
||||||
|
@ -409,6 +693,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const BoxAxisAligned &box, const Plane &plane, Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement stub
|
||||||
|
return Intersect( box, plane );
|
||||||
|
}
|
||||||
|
|
||||||
// bool Intersect( const BoxAxisAligned &box, const Triangle &triangle )
|
// bool Intersect( const BoxAxisAligned &box, const Triangle &triangle )
|
||||||
// { return false; /* TODO: */ }
|
// { return false; /* TODO: */ }
|
||||||
|
|
||||||
|
@ -425,7 +715,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
|
|
||||||
bool Intersect( const Box &box, const Point &point )
|
bool Intersect( const Box &box, const Point &point )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float3 dPos = point.center - box.center;
|
Float4 dPos = point.center - box.center;
|
||||||
|
|
||||||
Float coordinate = dPos.Dot( box.xAxis );
|
Float coordinate = dPos.Dot( box.xAxis );
|
||||||
if( coordinate > box.boundingOffset.x ) return false;
|
if( coordinate > box.boundingOffset.x ) return false;
|
||||||
|
@ -442,12 +732,22 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Box &box, const Point &point, Float4 &worldPointOfContact )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
if( Intersect(box, point) )
|
||||||
|
{
|
||||||
|
worldPointOfContact = point.center;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Box &box, const Ray &ray, Float &connectDistance )
|
bool Intersect( const Box &box, const Ray &ray, Float &connectDistance )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float tMin = ::std::numeric_limits<Float>::max(),
|
Float tMin = ::std::numeric_limits<Float>::max(),
|
||||||
tMax = -tMin; // initiating to extremevalues
|
tMax = -tMin; // initiating to extremevalues
|
||||||
|
|
||||||
Float3 dP = box.center - ray.origin;
|
Float4 dP = box.center - ray.origin;
|
||||||
if( Private::BoxVsRayPerSlabCheck( box.xAxis, box.boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
if( Private::BoxVsRayPerSlabCheck( box.xAxis, box.boundingOffset.x, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
||||||
if( Private::BoxVsRayPerSlabCheck( box.yAxis, box.boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
if( Private::BoxVsRayPerSlabCheck( box.yAxis, box.boundingOffset.y, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
||||||
if( Private::BoxVsRayPerSlabCheck( box.zAxis, box.boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
if( Private::BoxVsRayPerSlabCheck( box.zAxis, box.boundingOffset.z, dP, ray.direction, tMin, tMax ) ) { connectDistance = 0.0f; return false; }
|
||||||
|
@ -457,18 +757,43 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Box &box, const Ray &ray, Float &connectDistance, Float4 &worldPointOfContact )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
if( Intersect(box, ray, connectDistance) )
|
||||||
|
{
|
||||||
|
worldPointOfContact = ray.origin + ray.direction * connectDistance;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Box &box, const Sphere &sphere )
|
bool Intersect( const Box &box, const Sphere &sphere )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
// center: sphere's center in the box's view space
|
// center: sphere's center in the box's view space
|
||||||
Float4 center = TransformVector( InverseRotationMatrix(box.rotation), Float4(sphere.center - box.center, 0.0f) );
|
Float4 center = TransformVector( InverseRotationMatrix(box.rotation), sphere.center - box.center );
|
||||||
|
|
||||||
Float4 e = Max( Float4(-box.boundingOffset, 0.0f) - center, Float4::null );
|
Float4 e = Max( -box.boundingOffset - center, Float4::null );
|
||||||
e += Max( center - Float4(box.boundingOffset, 0.0f), Float4::null );
|
e += Max( center - box.boundingOffset, Float4::null );
|
||||||
|
|
||||||
if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
|
if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Box &box, const Sphere &sphere, Float4 &worldPointOfContact )
|
||||||
|
{ // by Robin Engman
|
||||||
|
if( Intersect(box, sphere) )
|
||||||
|
{
|
||||||
|
Float distance;
|
||||||
|
Ray ray( box.center, sphere.center - box.center );
|
||||||
|
|
||||||
|
Intersect( sphere, ray, distance );
|
||||||
|
worldPointOfContact = ray.origin + ray.direction*distance;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Box &box, const Plane &plane )
|
bool Intersect( const Box &box, const Plane &plane )
|
||||||
{// by Dan Andersson
|
{// by Dan Andersson
|
||||||
Float e, d;
|
Float e, d;
|
||||||
|
@ -478,22 +803,53 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Box &box, const Plane &plane, Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement stub
|
||||||
|
return Intersect( box, plane );
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB )
|
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float3 alignedOffsetBoundaries = (boxB.maxVertex - boxB.minVertex) * 0.5f,
|
Float4 alignedOffsetBoundaries = (boxB.maxVertex - boxB.minVertex) * 0.5f,
|
||||||
offset = boxA.center - Average( boxB.minVertex, boxB.maxVertex );
|
offset = boxA.center- Average( boxB.maxVertex, boxB.minVertex );
|
||||||
return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries, boxA.boundingOffset, boxA.rotation, offset );
|
return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries, boxA.boundingOffset, boxA.rotation, offset );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB, ::Oyster::Math::Float4 &worldPointOfContact )
|
||||||
|
{ // by Dan Andersson
|
||||||
|
Float4 alignedOffsetBoundaries = (boxB.maxVertex - boxB.minVertex) * 0.5f,
|
||||||
|
offset = boxA.center - Average( boxB.maxVertex, boxB.minVertex );
|
||||||
|
|
||||||
|
Float4 pointOfContact;
|
||||||
|
if( Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( alignedOffsetBoundaries, boxA.boundingOffset, boxA.rotation, offset, pointOfContact ) )
|
||||||
|
{
|
||||||
|
worldPointOfContact = pointOfContact.xyz;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Intersect( const Box &boxA, const Box &boxB )
|
bool Intersect( const Box &boxA, const Box &boxB )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float4x4 orientationA = OrientationMatrix(boxA.rotation, boxA.center),
|
Float4x4 rotationB = TransformMatrix( InverseRotationMatrix(boxA.rotation), boxB.rotation );
|
||||||
orientationB = OrientationMatrix(boxB.rotation, boxB.center),
|
Float4 posB = boxB.center - boxA.center;
|
||||||
invOrientationA = InverseOrientationMatrix( orientationA );
|
|
||||||
|
|
||||||
orientationB = TransformMatrix( invOrientationA, orientationB );
|
return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( boxA.boundingOffset, boxB.boundingOffset, rotationB, posB );
|
||||||
|
}
|
||||||
|
|
||||||
return Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( boxA.boundingOffset, boxB.boundingOffset, ExtractRotationMatrix(orientationB), orientationB.v[3].xyz );
|
bool Intersect( const Box &boxA, const Box &boxB, Float4 &worldPointOfContact )
|
||||||
|
{
|
||||||
|
Float4x4 rotationB = TransformMatrix( InverseRotationMatrix(boxA.rotation), boxB.rotation );
|
||||||
|
Float4 posB = boxB.center - boxA.center;
|
||||||
|
|
||||||
|
Float4 pointOfContact;
|
||||||
|
if( Private::SeperatingAxisTest_AxisAlignedVsTransformedBox( boxA.boundingOffset, boxB.boundingOffset, rotationB, posB, pointOfContact ) )
|
||||||
|
{
|
||||||
|
worldPointOfContact = TransformVector( boxA.rotation, pointOfContact, pointOfContact ).xyz;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Intersect( const Frustrum &frustrum, const Point &point )
|
bool Intersect( const Frustrum &frustrum, const Point &point )
|
||||||
|
|
|
@ -25,18 +25,28 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
void Compare( ::Oyster::Math::Float &connectOffset, const Plane &plane, const Point &point );
|
void Compare( ::Oyster::Math::Float &connectOffset, const Plane &plane, const Point &point );
|
||||||
|
|
||||||
bool Intersect( const Point &pointA, const Point &pointB );
|
bool Intersect( const Point &pointA, const Point &pointB );
|
||||||
|
bool Intersect( const Point &pointA, const Point &pointB, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
|
|
||||||
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance );
|
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance );
|
||||||
|
bool Intersect( const Ray &ray, const Point &point, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB );
|
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB );
|
||||||
|
bool Intersect( const Ray &rayA, const Ray &rayB, ::Oyster::Math::Float &connectDistanceA, ::Oyster::Math::Float &connectDistanceB, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
|
|
||||||
bool Intersect( const Sphere &sphere, const Point &point );
|
bool Intersect( const Sphere &sphere, const Point &point );
|
||||||
|
bool Intersect( const Sphere &sphere, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
||||||
|
bool Intersect( const Sphere &sphere, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Sphere &sphereA, const Sphere &sphereB );
|
bool Intersect( const Sphere &sphereA, const Sphere &sphereB );
|
||||||
|
bool Intersect( const Sphere &sphereA, const Sphere &sphereB, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
|
|
||||||
bool Intersect( const Plane &plane, const Point &point );
|
bool Intersect( const Plane &plane, const Point &point );
|
||||||
|
bool Intersect( const Plane &plane, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
bool Intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
||||||
|
bool Intersect( const Plane &plane, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Plane &plane, const Sphere &sphere );
|
bool Intersect( const Plane &plane, const Sphere &sphere );
|
||||||
|
bool Intersect( const Plane &plane, const Sphere &sphere, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Plane &planeA, const Plane &planeB );
|
bool Intersect( const Plane &planeA, const Plane &planeB );
|
||||||
|
bool Intersect( const Plane &planeA, const Plane &planeB, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
|
|
||||||
// bool Intersect( const Triangle &triangle, const Point &point, ? );
|
// bool Intersect( const Triangle &triangle, const Point &point, ? );
|
||||||
// bool Intersect( const Triangle &triangle, const Ray &ray, ? );
|
// bool Intersect( const Triangle &triangle, const Ray &ray, ? );
|
||||||
|
@ -45,19 +55,29 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
// bool Intersect( const Triangle &triangleA, const Triangle &triangleB, ? );
|
// bool Intersect( const Triangle &triangleA, const Triangle &triangleB, ? );
|
||||||
|
|
||||||
bool Intersect( const BoxAxisAligned &box, const Point &point );
|
bool Intersect( const BoxAxisAligned &box, const Point &point );
|
||||||
|
bool Intersect( const BoxAxisAligned &box, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const BoxAxisAligned &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
bool Intersect( const BoxAxisAligned &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
||||||
|
bool Intersect( const BoxAxisAligned &box, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere );
|
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere );
|
||||||
|
bool Intersect( const BoxAxisAligned &box, const Sphere &sphere, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const BoxAxisAligned &box, const Plane &plane );
|
bool Intersect( const BoxAxisAligned &box, const Plane &plane );
|
||||||
|
bool Intersect( const BoxAxisAligned &box, const Plane &plane, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
// bool Intersect( const BoxAxisAligned &box, const Triangle &triangle );
|
// bool Intersect( const BoxAxisAligned &box, const Triangle &triangle );
|
||||||
bool Intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB );
|
bool Intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB );
|
||||||
|
|
||||||
bool Intersect( const Box &box, const Point &point );
|
bool Intersect( const Box &box, const Point &point );
|
||||||
|
bool Intersect( const Box &box, const Point &point, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Box &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
bool Intersect( const Box &box, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
||||||
|
bool Intersect( const Box &box, const Ray &ray, ::Oyster::Math::Float &connectDistance, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Box &box, const Sphere &sphere );
|
bool Intersect( const Box &box, const Sphere &sphere );
|
||||||
|
bool Intersect( const Box &box, const Sphere &sphere, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Box &box, const Plane &plane );
|
bool Intersect( const Box &box, const Plane &plane );
|
||||||
|
bool Intersect( const Box &box, const Plane &plane, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
// bool Intersect( const Box &box, const Triangle &triangle, ? );
|
// bool Intersect( const Box &box, const Triangle &triangle, ? );
|
||||||
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB );
|
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB );
|
||||||
|
bool Intersect( const Box &boxA, const BoxAxisAligned &boxB, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
bool Intersect( const Box &boxA, const Box &boxB );
|
bool Intersect( const Box &boxA, const Box &boxB );
|
||||||
|
bool Intersect( const Box &boxA, const Box &boxB, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||||
|
|
||||||
bool Intersect( const Frustrum &frustrum, const Point &point );
|
bool Intersect( const Frustrum &frustrum, const Point &point );
|
||||||
bool Intersect( const Frustrum &frustrum, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
bool Intersect( const Frustrum &frustrum, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
||||||
|
|
|
@ -12,6 +12,60 @@ namespace Oyster { namespace Physics3D
|
||||||
namespace Formula
|
namespace Formula
|
||||||
{ /// Library of 3D physics related formulas
|
{ /// Library of 3D physics related formulas
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Returns the linear momentum of a mass in motion.
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 LinearMomentum( const ::Oyster::Math::Float &mass, const ::Oyster::Math::Float4 &linearVelocity )
|
||||||
|
{
|
||||||
|
return linearVelocity * mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Returns the linear momentum of a mass in motion.
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 LinearVelocity( const ::Oyster::Math::Float &mass, const ::Oyster::Math::Float4 &linearMomentum )
|
||||||
|
{
|
||||||
|
return linearMomentum / mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Returns the world angular momentum of a mass in rotation.
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 AngularMomentum( const ::Oyster::Math::Float4 linearMomentum, const ::Oyster::Math::Float4 &worldOffset )
|
||||||
|
{
|
||||||
|
return ::Oyster::Math::Float4( worldOffset.xyz.Cross(linearMomentum.xyz), 0.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Returns the world angular momentum of a mass in rotation.
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 AngularMomentum( const ::Oyster::Math::Float4x4 &worldMomentOfInertia, const ::Oyster::Math::Float4 &angularVelocity )
|
||||||
|
{
|
||||||
|
return worldMomentOfInertia * angularVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Returns the world angular velocity of a mass in rotation.
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 AngularVelocity( const ::Oyster::Math::Float4x4 &worldMomentOfInertiaInversed, const ::Oyster::Math::Float4 &angularMomentum )
|
||||||
|
{
|
||||||
|
return worldMomentOfInertiaInversed * angularMomentum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Returns the world tangential momentum at worldPos, of a mass in rotation.
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 TangentialLinearMomentum( const ::Oyster::Math::Float4 &angularMomentum, const ::Oyster::Math::Float4 &worldOffset )
|
||||||
|
{
|
||||||
|
return ::Oyster::Math::Float4( angularMomentum.xyz.Cross(worldOffset.xyz), 0.0f );
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* Returns the linear kinetic energy of a mass in motion.
|
* Returns the linear kinetic energy of a mass in motion.
|
||||||
* @todo TODO: improve doc
|
* @todo TODO: improve doc
|
||||||
|
@ -138,6 +192,15 @@ namespace Oyster { namespace Physics3D
|
||||||
return worldOffset.Cross( linearVelocity );
|
return worldOffset.Cross( linearVelocity );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Returns the world angular velocity of a mass in rotation.
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 AngularVelocity( const ::Oyster::Math::Float4 &linearVelocity, const ::Oyster::Math::Float4 &worldOffset )
|
||||||
|
{
|
||||||
|
return ::Oyster::Math::Float4( worldOffset.xyz.Cross( linearVelocity.xyz ), 0.0f );
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* Returns the world tangential velocity at worldPos, of a mass in rotation.
|
* Returns the world tangential velocity at worldPos, of a mass in rotation.
|
||||||
* @todo TODO: improve doc
|
* @todo TODO: improve doc
|
||||||
|
@ -183,6 +246,15 @@ namespace Oyster { namespace Physics3D
|
||||||
return worldOffset.Cross( impulseForce );
|
return worldOffset.Cross( impulseForce );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
*
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 ImpulseTorque( const ::Oyster::Math::Float4 & impulseForce, const ::Oyster::Math::Float4 &worldOffset )
|
||||||
|
{
|
||||||
|
return ::Oyster::Math::Float4( worldOffset.xyz.Cross(impulseForce.xyz), 0.0f );
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* T = I*a
|
* T = I*a
|
||||||
* @todo TODO: improve doc
|
* @todo TODO: improve doc
|
||||||
|
@ -192,10 +264,13 @@ namespace Oyster { namespace Physics3D
|
||||||
return ( momentOfInertia * ::Oyster::Math::Float4(angularImpulseAcceleration, 0.0f) ).xyz;
|
return ( momentOfInertia * ::Oyster::Math::Float4(angularImpulseAcceleration, 0.0f) ).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ::Oyster::Math::Float3 Impulse( )
|
/******************************************************************
|
||||||
|
* T = I*a
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 ImpulseTorque( const ::Oyster::Math::Float4x4 & momentOfInertia, const ::Oyster::Math::Float4 &angularImpulseAcceleration )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement calculation for impulse. Hijack Mattias Eriksson
|
return momentOfInertia * angularImpulseAcceleration;
|
||||||
return ::Oyster::Math::Float3::null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MomentOfInertia
|
namespace MomentOfInertia
|
||||||
|
|
|
@ -163,6 +163,7 @@
|
||||||
<ClInclude Include="Point.h" />
|
<ClInclude Include="Point.h" />
|
||||||
<ClInclude Include="Ray.h" />
|
<ClInclude Include="Ray.h" />
|
||||||
<ClInclude Include="RigidBody.h" />
|
<ClInclude Include="RigidBody.h" />
|
||||||
|
<ClInclude Include="RigidBody_Inline.h" />
|
||||||
<ClInclude Include="Sphere.h" />
|
<ClInclude Include="Sphere.h" />
|
||||||
<ClInclude Include="Spring.h" />
|
<ClInclude Include="Spring.h" />
|
||||||
<ClInclude Include="Universe.h" />
|
<ClInclude Include="Universe.h" />
|
||||||
|
|
|
@ -75,6 +75,9 @@
|
||||||
<ClInclude Include="RigidBody.h">
|
<ClInclude Include="RigidBody.h">
|
||||||
<Filter>Header Files\Physics</Filter>
|
<Filter>Header Files\Physics</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="RigidBody_Inline.h">
|
||||||
|
<Filter>Header Files\Physics</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Box.cpp">
|
<ClCompile Include="Box.cpp">
|
||||||
|
|
|
@ -34,7 +34,7 @@ Particle & Particle::operator = ( const Particle &particle )
|
||||||
void Particle::Update_LeapFrog( Float deltaTime )
|
void Particle::Update_LeapFrog( Float deltaTime )
|
||||||
{ // Euler leap frog update when Runga Kutta is not needed
|
{ // Euler leap frog update when Runga Kutta is not needed
|
||||||
this->impulseForceSum *= (deltaTime / this->mass); // is now deltaLinearVelocity ( dt * a = dt * F / m )
|
this->impulseForceSum *= (deltaTime / this->mass); // is now deltaLinearVelocity ( dt * a = dt * F / m )
|
||||||
this->sphere.center += deltaTime * ::Utility::Value::AverageWithDelta( Formula::LinearVelocity(this->mass, this->linearMomentum), this->impulseForceSum );
|
this->sphere.center.xyz += deltaTime * ::Utility::Value::AverageWithDelta( Formula::LinearVelocity(this->mass, this->linearMomentum), this->impulseForceSum );
|
||||||
this->linearMomentum += Formula::LinearMomentum( this->mass, this->impulseForceSum );
|
this->linearMomentum += Formula::LinearMomentum( this->mass, this->impulseForceSum );
|
||||||
this->impulseForceSum = Float3::null;
|
this->impulseForceSum = Float3::null;
|
||||||
|
|
||||||
|
@ -66,12 +66,12 @@ void Particle::ApplyLinearImpulseAcceleration( const Float3 &a )
|
||||||
|
|
||||||
Float3 & Particle::AccessCenter()
|
Float3 & Particle::AccessCenter()
|
||||||
{
|
{
|
||||||
return this->sphere.center;
|
return this->sphere.center.xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float3 & Particle::AccessCenter() const
|
const Float3 & Particle::AccessCenter() const
|
||||||
{
|
{
|
||||||
return this->sphere.center;
|
return this->sphere.center.xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float & Particle::AccessRadius()
|
Float & Particle::AccessRadius()
|
||||||
|
@ -91,7 +91,7 @@ const Float & Particle::GetMass() const
|
||||||
|
|
||||||
const Float3 & Particle::GetCenter() const
|
const Float3 & Particle::GetCenter() const
|
||||||
{
|
{
|
||||||
return this->sphere.center;
|
return this->sphere.center.xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float & Particle::GetRadius() const
|
const Float & Particle::GetRadius() const
|
||||||
|
|
|
@ -10,11 +10,11 @@ using namespace ::Oyster::Math;
|
||||||
|
|
||||||
Plane::Plane( ) : ICollideable(Type_plane)
|
Plane::Plane( ) : ICollideable(Type_plane)
|
||||||
{
|
{
|
||||||
this->normal = Float3::standard_unit_z;
|
this->normal = Float4::standard_unit_z;
|
||||||
this->phasing = 0.0f;
|
this->phasing = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Plane::Plane( const Float3 &n, const Float &p ) : ICollideable(Type_plane)
|
Plane::Plane( const Float4 &n, const Float &p ) : ICollideable(Type_plane)
|
||||||
{
|
{
|
||||||
this->normal = n;
|
this->normal = n;
|
||||||
this->phasing = p;
|
this->phasing = p;
|
||||||
|
@ -30,34 +30,57 @@ Plane & Plane::operator = ( const Plane &plane )
|
||||||
}
|
}
|
||||||
|
|
||||||
::Utility::DynamicMemory::UniquePointer<ICollideable> Plane::Clone( ) const
|
::Utility::DynamicMemory::UniquePointer<ICollideable> Plane::Clone( ) const
|
||||||
{ return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Plane(*this) ); }
|
{
|
||||||
|
return ::Utility::DynamicMemory::UniquePointer<ICollideable>( 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_universe: return true;
|
||||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||||
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target );
|
case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
|
||||||
// case Type_triangle: return false; // TODO:
|
//case Type_triangle: return false; // TODO:
|
||||||
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this );
|
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
|
||||||
case Type_box: return Utility::Intersect( *(Box*)&target, *this );
|
case Type_box: return Utility::Intersect( (const Box&)target, *this );
|
||||||
case Type_frustrum: return false; // TODO:
|
//case Type_frustrum: return false; // TODO:
|
||||||
case Type_line: return false; // TODO:
|
//case Type_line: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Plane::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
switch( target.type )
|
||||||
|
{
|
||||||
|
case Type_universe:
|
||||||
|
worldPointOfContact = this->normal * this->phasing;
|
||||||
|
return true;
|
||||||
|
case Type_point: return Utility::Intersect( *this, (const Point&)target, worldPointOfContact );
|
||||||
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance, worldPointOfContact );
|
||||||
|
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target, worldPointOfContact );
|
||||||
|
case Type_plane: return Utility::Intersect( (const Plane&)target, *this, worldPointOfContact );
|
||||||
|
//case Type_triangle: return false; // TODO:
|
||||||
|
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, worldPointOfContact );
|
||||||
|
case Type_box: return Utility::Intersect( (const Box&)target, *this, worldPointOfContact );
|
||||||
|
//case Type_frustrum: return false; // TODO:
|
||||||
|
default:
|
||||||
|
worldPointOfContact = Float3::null;
|
||||||
|
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_point: return Utility::Intersect( *this, (const Point&)target );
|
||||||
case Type_ray: return Utility::Contains( *this, *(Ray*)&target );
|
case Type_ray: return Utility::Contains( *this, (const Ray&)target );
|
||||||
case Type_plane: return Utility::Contains( *this, *(Plane*)&target );
|
case Type_plane: return Utility::Contains( *this, (const Plane&)target );
|
||||||
// case Type_triangle: return false; // TODO:
|
//case Type_triangle: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,19 +16,20 @@ namespace Oyster { namespace Collision3D
|
||||||
public:
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct{ ::Oyster::Math::Float3 normal; ::Oyster::Math::Float phasing; };
|
struct{ ::Oyster::Math::Float4 normal; ::Oyster::Math::Float phasing; };
|
||||||
::Oyster::Math::Float element[4];
|
::Oyster::Math::Float element[5];
|
||||||
char byte[sizeof(::Oyster::Math::Float3) + sizeof(::Oyster::Math::Float)];
|
char byte[sizeof(::Oyster::Math::Float4) + sizeof(::Oyster::Math::Float)];
|
||||||
};
|
};
|
||||||
|
|
||||||
Plane( );
|
Plane( );
|
||||||
Plane( const ::Oyster::Math::Float3 &normal, const ::Oyster::Math::Float &phasing );
|
Plane( const ::Oyster::Math::Float4 &normal, const ::Oyster::Math::Float &phasing );
|
||||||
virtual ~Plane( );
|
virtual ~Plane( );
|
||||||
|
|
||||||
Plane & operator = ( const Plane &plane );
|
Plane & operator = ( const Plane &plane );
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -10,10 +10,15 @@ using namespace ::Oyster::Math3D;
|
||||||
|
|
||||||
Point::Point( ) : ICollideable(Type_point)
|
Point::Point( ) : ICollideable(Type_point)
|
||||||
{
|
{
|
||||||
this->center = Float3::null;
|
this->center = Float4::standard_unit_w;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point::Point( const Float3 &pos ) : ICollideable(Type_point)
|
Point::Point( const Float3 &pos ) : ICollideable(Type_point)
|
||||||
|
{
|
||||||
|
this->center = Float4( pos, 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
Point::Point( const Float4 &pos ) : ICollideable(Type_point)
|
||||||
{
|
{
|
||||||
this->center = pos;
|
this->center = pos;
|
||||||
}
|
}
|
||||||
|
@ -36,23 +41,44 @@ bool Point::Intersects( const ICollideable &target ) const
|
||||||
switch( target.type )
|
switch( target.type )
|
||||||
{
|
{
|
||||||
case Type_universe: return true;
|
case Type_universe: return true;
|
||||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||||
case Type_ray: return Utility::Intersect( *(Ray*)&target, *this, ((Ray*)&target)->collisionDistance );
|
case Type_ray: return Utility::Intersect( (const Ray&)target, *this, ((const Ray&)target).collisionDistance );
|
||||||
case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this );
|
case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this );
|
||||||
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this );
|
case Type_plane: return Utility::Intersect( (const Plane&)target, *this );
|
||||||
//case Type_triangle: return false; // TODO:
|
//case Type_triangle: return false; // TODO:
|
||||||
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this );
|
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
|
||||||
case Type_box: return Utility::Intersect( *(Box*)&target, *this );
|
case Type_box: return Utility::Intersect( (const Box&)target, *this );
|
||||||
case Type_frustrum: return false; // TODO:
|
//case Type_frustrum: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Point::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
switch( target.type )
|
||||||
|
{
|
||||||
|
case Type_universe:
|
||||||
|
worldPointOfContact = this->center;
|
||||||
|
return true;
|
||||||
|
case Type_point: return Utility::Intersect( *this, (const Point&)target, worldPointOfContact );
|
||||||
|
case Type_ray: return Utility::Intersect( (const Ray&)target, *this, ((const Ray&)target).collisionDistance, worldPointOfContact );
|
||||||
|
case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this, worldPointOfContact );
|
||||||
|
case Type_plane: return Utility::Intersect( (const Plane&)target, *this, worldPointOfContact );
|
||||||
|
//case Type_triangle: return false; // TODO:
|
||||||
|
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, worldPointOfContact );
|
||||||
|
case Type_box: return Utility::Intersect( (const Box&)target, *this, worldPointOfContact );
|
||||||
|
case Type_frustrum: return false; // TODO:
|
||||||
|
default:
|
||||||
|
worldPointOfContact = Float3::null;
|
||||||
|
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, (const Point&)target );
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,18 +16,20 @@ namespace Oyster { namespace Collision3D
|
||||||
public:
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct{ ::Oyster::Math::Float3 center; };
|
struct{ ::Oyster::Math::Float4 center; };
|
||||||
char byte[sizeof(::Oyster::Math::Float3)];
|
char byte[sizeof(::Oyster::Math::Float4)];
|
||||||
};
|
};
|
||||||
|
|
||||||
Point( );
|
Point( );
|
||||||
Point( const ::Oyster::Math::Float3 &position );
|
Point( const ::Oyster::Math::Float3 &position );
|
||||||
|
Point( const ::Oyster::Math::Float4 &position );
|
||||||
virtual ~Point( );
|
virtual ~Point( );
|
||||||
|
|
||||||
Point & operator = ( const Point &point );
|
Point & operator = ( const Point &point );
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -10,12 +10,19 @@ using namespace ::Oyster::Math3D;
|
||||||
|
|
||||||
Ray::Ray( ) : ICollideable(Type_ray)
|
Ray::Ray( ) : ICollideable(Type_ray)
|
||||||
{
|
{
|
||||||
this->origin = Float3::null;
|
this->origin = Float4::standard_unit_w;
|
||||||
this->direction = Float3::standard_unit_z;
|
this->direction = Float4::standard_unit_z;
|
||||||
this->collisionDistance = 0.0f;
|
this->collisionDistance = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ray::Ray( const Float3 &o, const ::Oyster::Math::Float3 &d ) : ICollideable(Type_ray)
|
Ray::Ray( const Float3 &o, const Float3 &d ) : ICollideable(Type_ray)
|
||||||
|
{
|
||||||
|
this->origin = Float4( o, 1.0f );
|
||||||
|
this->direction = Float4( d, 0.0f );
|
||||||
|
this->collisionDistance = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ray::Ray( const Float4 &o, const Float4 &d ) : ICollideable(Type_ray)
|
||||||
{
|
{
|
||||||
this->origin = o;
|
this->origin = o;
|
||||||
this->direction = d;
|
this->direction = d;
|
||||||
|
@ -43,24 +50,46 @@ bool Ray::Intersects( const ICollideable &target ) const
|
||||||
case Type_universe:
|
case Type_universe:
|
||||||
this->collisionDistance = 0.0f;
|
this->collisionDistance = 0.0f;
|
||||||
return true;
|
return true;
|
||||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target, this->collisionDistance );
|
case Type_point: return Utility::Intersect( *this, (const Point&)target, this->collisionDistance );
|
||||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, this->collisionDistance, ((Ray*)&target)->collisionDistance );
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, this->collisionDistance, ((const Ray&)target).collisionDistance );
|
||||||
case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this, this->collisionDistance );
|
case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this, this->collisionDistance );
|
||||||
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this, this->collisionDistance );
|
case Type_plane: return Utility::Intersect( (const Plane&)target, *this, this->collisionDistance );
|
||||||
// case Type_triangle: return false; // TODO:
|
//case Type_triangle: return false; // TODO:
|
||||||
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this, this->collisionDistance );
|
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, this->collisionDistance );
|
||||||
case Type_box: return Utility::Intersect( *(Box*)&target, *this, this->collisionDistance );
|
case Type_box: return Utility::Intersect( (const Box&)target, *this, this->collisionDistance );
|
||||||
case Type_frustrum: return false; // TODO:
|
//case Type_frustrum: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Ray::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
switch( target.type )
|
||||||
|
{
|
||||||
|
case Type_universe:
|
||||||
|
this->collisionDistance = 0.0f;
|
||||||
|
worldPointOfContact = this->origin;
|
||||||
|
return true;
|
||||||
|
case Type_point: return Utility::Intersect( *this, (const Point&)target, this->collisionDistance, worldPointOfContact );
|
||||||
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, this->collisionDistance, ((const Ray&)target).collisionDistance, worldPointOfContact );
|
||||||
|
case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this, this->collisionDistance, worldPointOfContact );
|
||||||
|
case Type_plane: return Utility::Intersect( (const Plane&)target, *this, this->collisionDistance, worldPointOfContact );
|
||||||
|
//case Type_triangle: return false; // TODO:
|
||||||
|
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, this->collisionDistance, worldPointOfContact );
|
||||||
|
case Type_box: return Utility::Intersect( (const Box&)target, *this, this->collisionDistance, worldPointOfContact );
|
||||||
|
//case Type_frustrum: return false; // TODO:
|
||||||
|
default:
|
||||||
|
worldPointOfContact = Float3::null;
|
||||||
|
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_point: return Utility::Intersect( *this, (const Point&)target, this->collisionDistance );
|
||||||
case Type_ray: return Utility::Contains( *this, *(Ray*)&target );
|
case Type_ray: return Utility::Contains( *this, (const Ray&)target );
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,7 +10,6 @@
|
||||||
#ifndef OYSTER_COLLISION_3D_RAY_H
|
#ifndef OYSTER_COLLISION_3D_RAY_H
|
||||||
#define OYSTER_COLLISION_3D_RAY_H
|
#define OYSTER_COLLISION_3D_RAY_H
|
||||||
|
|
||||||
#include "OysterMath.h"
|
|
||||||
#include "ICollideable.h"
|
#include "ICollideable.h"
|
||||||
|
|
||||||
namespace Oyster { namespace Collision3D
|
namespace Oyster { namespace Collision3D
|
||||||
|
@ -22,21 +21,23 @@ namespace Oyster { namespace Collision3D
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
::Oyster::Math::Float3 origin,
|
::Oyster::Math::Float4 origin,
|
||||||
direction; /// Assumed to be normalized
|
direction; /// Assumed to be normalized
|
||||||
};
|
};
|
||||||
char byte[2*sizeof(::Oyster::Math::Float3)];
|
char byte[2*sizeof(::Oyster::Math::Float4)];
|
||||||
};
|
};
|
||||||
mutable float collisionDistance;
|
mutable float collisionDistance;
|
||||||
|
|
||||||
Ray( );
|
Ray( );
|
||||||
Ray( const ::Oyster::Math::Float3 &origin, const ::Oyster::Math::Float3 &normalizedDirection );
|
Ray( const ::Oyster::Math::Float3 &origin, const ::Oyster::Math::Float3 &normalizedDirection );
|
||||||
|
Ray( const ::Oyster::Math::Float4 &origin, const ::Oyster::Math::Float4 &normalizedDirection );
|
||||||
virtual ~Ray( );
|
virtual ~Ray( );
|
||||||
|
|
||||||
Ray & operator = ( const Ray &ray );
|
Ray & operator = ( const Ray &ray );
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -8,413 +8,224 @@
|
||||||
using namespace ::Oyster::Collision3D;
|
using namespace ::Oyster::Collision3D;
|
||||||
using namespace ::Oyster::Physics3D;
|
using namespace ::Oyster::Physics3D;
|
||||||
using namespace ::Oyster::Math3D;
|
using namespace ::Oyster::Math3D;
|
||||||
|
using namespace ::Utility::Value;
|
||||||
|
|
||||||
RigidBody::RigidBody( const Box &b, Float m, const Float4x4 &inertiaTensor )
|
RigidBody::RigidBody( )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->box = b;
|
this->centerPos = Float4::standard_unit_w;
|
||||||
this->angularMomentum = Float3::null;
|
this->axis = Float4::null;
|
||||||
this->linearMomentum = Float3::null;
|
this->boundingReach = Float4( 0.5f, 0.5f, 0.5f, 0.0f );
|
||||||
this->impulseTorqueSum = Float3::null;
|
this->momentum_Linear = Float4::null;
|
||||||
this->impulseForceSum = Float3::null;
|
this->momentum_Angular = Float4::null;
|
||||||
|
this->impulse_Linear = Float4::null;
|
||||||
if( m != 0.0f )
|
this->impulse_Angular = Float4::null;
|
||||||
{
|
this->restitutionCoeff = 1.0f;
|
||||||
this->mass = m;
|
this->frictionCoeff_Static = 0.5f;
|
||||||
}
|
this->frictionCoeff_Kinetic = 1.0f;
|
||||||
else
|
this->mass = 10;
|
||||||
{
|
|
||||||
this->mass = ::Utility::Value::numeric_limits<Float>::epsilon();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( inertiaTensor.GetDeterminant() != 0.0f )
|
|
||||||
{
|
|
||||||
this->momentOfInertiaTensor = inertiaTensor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->momentOfInertiaTensor = Float4x4::identity;
|
this->momentOfInertiaTensor = Float4x4::identity;
|
||||||
}
|
this->rotation = Quaternion::identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBody & RigidBody::operator = ( const RigidBody &body )
|
RigidBody & RigidBody::operator = ( const RigidBody &body )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->box = body.box;
|
this->centerPos = body.centerPos;
|
||||||
this->angularMomentum = body.angularMomentum;
|
this->axis = body.axis;
|
||||||
this->linearMomentum = body.linearMomentum;
|
this->boundingReach = body.boundingReach;
|
||||||
this->impulseTorqueSum = body.impulseTorqueSum;
|
this->momentum_Linear = body.momentum_Linear;
|
||||||
this->impulseForceSum = body.impulseForceSum;
|
this->momentum_Angular = body.momentum_Angular;
|
||||||
|
this->impulse_Linear = body.impulse_Linear;
|
||||||
|
this->impulse_Angular = body.impulse_Angular;
|
||||||
|
this->restitutionCoeff = body.restitutionCoeff;
|
||||||
|
this->frictionCoeff_Static = body.frictionCoeff_Static;
|
||||||
|
this->frictionCoeff_Kinetic = body.frictionCoeff_Kinetic;
|
||||||
this->mass = body.mass;
|
this->mass = body.mass;
|
||||||
this->momentOfInertiaTensor = body.momentOfInertiaTensor;
|
this->momentOfInertiaTensor = body.momentOfInertiaTensor;
|
||||||
|
this->rotation = body.rotation;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RigidBody::operator == ( const RigidBody &body )
|
void RigidBody::Update_LeapFrog( Float updateFrameLength )
|
||||||
{
|
|
||||||
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
|
{ // by Dan Andersson: Euler leap frog update when Runga Kutta is not needed
|
||||||
|
|
||||||
// Important! The member data is all world data except the Inertia tensor. Thus a new InertiaTensor needs to be created to be compatible with the rest of the world data.
|
|
||||||
Float4x4 wMomentOfInertiaTensor = TransformMatrix( this->box.rotation, this->momentOfInertiaTensor ); // RI
|
|
||||||
|
|
||||||
// updating the linear
|
// updating the linear
|
||||||
// dG = F * dt
|
|
||||||
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
|
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
|
||||||
Float3 linearImpulse = this->impulseForceSum * deltaTime; // aka deltaLinearMomentum
|
this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
|
||||||
Float3 deltaPos = ( deltaTime / this->mass ) * ::Utility::Value::AverageWithDelta( this->linearMomentum, linearImpulse );
|
|
||||||
|
|
||||||
// updating the angular
|
// updating the angular
|
||||||
// dH = T * dt
|
Float4x4 rotationMatrix; ::Oyster::Math3D::RotationMatrix( this->rotation, rotationMatrix );
|
||||||
|
// Important! The member data is all world data except the Inertia tensor. Thus a new InertiaTensor needs to be created to be compatible with the rest of the world data.
|
||||||
|
Float4x4 wMomentOfInertiaTensor = TransformMatrix( rotationMatrix, this->momentOfInertiaTensor ); // RI
|
||||||
|
|
||||||
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
|
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
|
||||||
Float3 angularImpulse = this->impulseTorqueSum * deltaTime; // aka deltaAngularMomentum
|
this->axis += Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, this->impulse_Angular) );
|
||||||
Float3 rotationAxis = Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(),
|
this->rotation = Rotation( this->axis );
|
||||||
::Utility::Value::AverageWithDelta(this->angularMomentum, angularImpulse) );
|
|
||||||
|
|
||||||
Float deltaRadian = rotationAxis.Dot( rotationAxis );
|
// update momentums and clear impulse_Linear and impulse_Angular
|
||||||
if( deltaRadian != 0.0f )
|
this->momentum_Linear += this->impulse_Linear;
|
||||||
{ // branch depending if there is rotation
|
this->impulse_Linear = Float4::null;
|
||||||
deltaRadian = ::std::sqrt( deltaRadian );
|
this->momentum_Angular += this->impulse_Angular;
|
||||||
rotationAxis /= deltaRadian;
|
this->impulse_Angular = Float4::null;
|
||||||
|
|
||||||
// using rotationAxis, deltaRadian and deltaPos to create a matrix to update the box
|
|
||||||
this->box.center += deltaPos;
|
|
||||||
TransformMatrix( RotationMatrix(deltaRadian, rotationAxis), this->box.rotation, this->box.rotation );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // no rotation, only use deltaPos to translate the RigidBody
|
|
||||||
this->box.center += deltaPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update momentums and clear impulseForceSum and impulseTorqueSum
|
|
||||||
this->linearMomentum += linearImpulse;
|
|
||||||
this->impulseForceSum = Float3::null;
|
|
||||||
this->angularMomentum += angularImpulse;
|
|
||||||
this->impulseTorqueSum = Float3::null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::ApplyImpulseForce( const Float3 &worldF )
|
void RigidBody::Predict_LeapFrog( Float4 &outDeltaPos, Float4 &outDeltaAxis, const Float4 &actingLinearImpulse, const Float4 &actingAngularImpulse, Float deltaTime )
|
||||||
{ // by Dan Andersson
|
{
|
||||||
this->impulseForceSum += worldF;
|
// updating the linear
|
||||||
|
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
|
||||||
|
outDeltaPos = ( deltaTime / this->mass ) * AverageWithDelta( this->momentum_Linear, actingLinearImpulse );
|
||||||
|
|
||||||
|
// updating the angular
|
||||||
|
Float4x4 rotationMatrix; ::Oyster::Math3D::RotationMatrix( this->rotation, rotationMatrix );
|
||||||
|
Float4x4 wMomentOfInertiaTensor = TransformMatrix( rotationMatrix, this->momentOfInertiaTensor ); // RI
|
||||||
|
|
||||||
|
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
|
||||||
|
outDeltaAxis = Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, actingAngularImpulse) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::ApplyImpulseForceAt( const Float3 &worldF, const Float3 &worldPos )
|
void RigidBody::Move( const Float4 &deltaPos, const Float4 &deltaAxis )
|
||||||
|
{
|
||||||
|
this->centerPos += deltaPos;
|
||||||
|
this->axis += deltaAxis;
|
||||||
|
this->rotation = Rotation( this->axis );
|
||||||
|
}
|
||||||
|
|
||||||
|
void RigidBody::ApplyImpulse( const Float4 &worldJ, const Float4 &atWorldPos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float3 worldOffset = worldPos - this->box.center;
|
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||||
if( worldOffset != Float3::null )
|
if( worldOffset != Float4::null )
|
||||||
{
|
{
|
||||||
this->impulseForceSum += VectorProjection( worldF, worldOffset );
|
this->impulse_Linear += VectorProjection( worldJ, atWorldPos );
|
||||||
this->impulseTorqueSum += Formula::ImpulseTorque( worldF, worldOffset );
|
this->impulse_Angular += Formula::ImpulseTorque( worldJ, atWorldPos );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->impulseForceSum += worldF;
|
this->impulse_Linear += worldJ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::ApplyLinearImpulseAcceleration( const Float3 &worldA )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->impulseForceSum += Formula::ImpulseForce( this->mass, worldA );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::ApplyLinearImpulseAccelerationAt( const Float3 &worldA, const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center;
|
|
||||||
if( worldOffset != Float3::null )
|
|
||||||
{
|
|
||||||
this->impulseForceSum += Formula::ImpulseForce( this->mass, VectorProjection(worldA, worldOffset) );
|
|
||||||
|
|
||||||
// tanAcc = angularAcc x localPosition
|
|
||||||
// angularAcc = localPosition x tanAcc = localPosition x linearAcc
|
|
||||||
// T = I * angularAcc
|
|
||||||
this->impulseTorqueSum += Formula::ImpulseTorque( this->momentOfInertiaTensor, Formula::AngularImpulseAcceleration(worldA, worldOffset) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->impulseForceSum += Formula::ImpulseForce( this->mass, worldA );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::ApplyImpulseTorque( const Float3 &worldT )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->impulseTorqueSum += worldT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::ApplyAngularImpulseAcceleration( const Float3 &worldA )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->impulseTorqueSum += Formula::ImpulseTorque( this->momentOfInertiaTensor, worldA );
|
|
||||||
}
|
|
||||||
|
|
||||||
Float3 & RigidBody::AccessBoundingReach()
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->box.boundingOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Float3 & RigidBody::AccessBoundingReach() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->box.boundingOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
Float3 & RigidBody::AccessCenter()
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->box.center;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Float3 & RigidBody::AccessCenter() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->box.center;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Float4x4 & RigidBody::GetMomentOfInertia() const
|
const Float4x4 & RigidBody::GetMomentOfInertia() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->momentOfInertiaTensor;
|
return this->momentOfInertiaTensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float & RigidBody::GetMass() const
|
Float RigidBody::GetMass() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->mass;
|
return this->mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float4x4 RigidBody::GetOrientation() const
|
const Quaternion & RigidBody::GetRotation() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return OrientationMatrix( this->box.rotation, this->box.center );
|
return this->rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 RigidBody::GetRotationMatrix() const
|
||||||
|
{ // by Dan Andersson
|
||||||
|
return RotationMatrix( this->rotation );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 RigidBody::GetOrientation() const
|
||||||
|
{ // by Dan Andersson
|
||||||
|
return ::Oyster::Math3D::OrientationMatrix( this->rotation, this->centerPos );
|
||||||
}
|
}
|
||||||
|
|
||||||
Float4x4 RigidBody::GetView() const
|
Float4x4 RigidBody::GetView() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return InverseOrientationMatrix( this->GetOrientation() );
|
return ViewMatrix( this->rotation, this->centerPos );
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float3 & RigidBody::GetBoundingReach() const
|
Float4 RigidBody::GetVelocity_Linear() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->box.boundingOffset;
|
return Formula::LinearVelocity( this->mass, this->momentum_Linear );
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 RigidBody::GetSize() const
|
Float4 RigidBody::GetVelocity_Angular() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return 2.0f * this->box.boundingOffset;
|
return Formula::AngularVelocity( this->momentOfInertiaTensor.GetInverse(), this->momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float3 & RigidBody::GetCenter() const
|
Float4 RigidBody::GetLinearMomentum( const Float4 &atWorldPos ) const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->box.center;
|
return this->momentum_Linear + Formula::TangentialLinearMomentum( this->momentum_Angular, atWorldPos - this->centerPos );
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float3 & RigidBody::GetImpulsTorque() const
|
void RigidBody::SetMomentOfInertia_KeepVelocity( const Float4x4 &localTensorI )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->impulseTorqueSum;
|
if( localTensorI.GetDeterminant() != 0.0f )
|
||||||
}
|
{ // insanity check! MomentOfInertiaTensor must be invertable
|
||||||
|
Float4x4 rotationMatrix; RotationMatrix( this->rotation, rotationMatrix );
|
||||||
|
|
||||||
const Float3 & RigidBody::GetAngularMomentum() const
|
Float4 w = Formula::AngularVelocity( (rotationMatrix * this->momentOfInertiaTensor).GetInverse(), this->momentum_Angular );
|
||||||
{ // by Dan Andersson
|
this->momentOfInertiaTensor = localTensorI;
|
||||||
return this->angularMomentum;
|
this->momentum_Angular = Formula::AngularMomentum( rotationMatrix * localTensorI, w );
|
||||||
}
|
|
||||||
|
|
||||||
Float3 RigidBody::GetAngularImpulseAcceleration() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return Formula::AngularImpulseAcceleration( this->momentOfInertiaTensor.GetInverse(), this->impulseTorqueSum );
|
|
||||||
}
|
|
||||||
|
|
||||||
Float3 RigidBody::GetAngularVelocity() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return Formula::AngularVelocity( this->momentOfInertiaTensor.GetInverse(), this->angularMomentum );
|
|
||||||
}
|
|
||||||
|
|
||||||
const Float3 & RigidBody::GetImpulseForce() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->impulseForceSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Float3 & RigidBody::GetLinearMomentum() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->linearMomentum;
|
|
||||||
}
|
|
||||||
|
|
||||||
Float3 RigidBody::GetLinearImpulseAcceleration() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return Formula::LinearImpulseAcceleration( this->mass, this->impulseForceSum );
|
|
||||||
}
|
|
||||||
|
|
||||||
Float3 RigidBody::GetLinearVelocity() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return Formula::LinearVelocity( this->mass, this->linearMomentum );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::GetMomentumAt( const Float3 &worldPos, const Float3 &surfaceNormal, Float3 &normalMomentum, Float3 &tangentialMomentum ) const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center;
|
|
||||||
Float3 momentum = Formula::TangentialLinearMomentum( this->angularMomentum, worldOffset );
|
|
||||||
momentum += this->linearMomentum;
|
|
||||||
|
|
||||||
normalMomentum = NormalProjection( momentum, surfaceNormal );
|
|
||||||
tangentialMomentum = momentum - normalMomentum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localI )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
if( localI.GetDeterminant() != 0.0f ) // insanitycheck! momentOfInertiaTensor must be invertable
|
|
||||||
{
|
|
||||||
Float3 w = Formula::AngularVelocity( (this->box.rotation * this->momentOfInertiaTensor).GetInverse(),
|
|
||||||
this->angularMomentum );
|
|
||||||
this->momentOfInertiaTensor = localI;
|
|
||||||
this->angularMomentum = Formula::AngularMomentum( this->box.rotation*localI, w );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetMomentOfInertia_KeepMomentum( const Float4x4 &localI )
|
void RigidBody::SetMomentOfInertia_KeepMomentum( const Float4x4 &localTensorI )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
if( localI.GetDeterminant() != 0.0f ) // insanitycheck! momentOfInertiaTensor must be invertable
|
if( localTensorI.GetDeterminant() != 0.0f )
|
||||||
{
|
{ // insanity check! MomentOfInertiaTensor must be invertable
|
||||||
this->momentOfInertiaTensor = localI;
|
this->momentOfInertiaTensor = localTensorI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetMass_KeepVelocity( const Float &m )
|
void RigidBody::SetMass_KeepVelocity( const Float &m )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
if( m != 0.0f ) // insanitycheck! mass must be invertable
|
if( m != 0.0f )
|
||||||
{
|
{ // insanity check! Mass must be invertable
|
||||||
Float3 v = Formula::LinearVelocity( this->mass, this->linearMomentum );
|
Float4 v = Formula::LinearVelocity( this->mass, this->momentum_Linear );
|
||||||
this->mass = m;
|
this->mass = m;
|
||||||
this->linearMomentum = Formula::LinearMomentum( this->mass, v );
|
this->momentum_Linear = Formula::LinearMomentum( this->mass, v );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetMass_KeepMomentum( const Float &m )
|
void RigidBody::SetMass_KeepMomentum( const Float &m )
|
||||||
{ // by Dan Anderson
|
{ // by Dan Anderson
|
||||||
if( m != 0.0f ) // insanitycheck! mass must be invertable
|
if( m != 0.0f )
|
||||||
{
|
{ // insanity check! Mass must be invertable
|
||||||
this->mass = m;
|
this->mass = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetOrientation( const Float4x4 &o )
|
void RigidBody::SetOrientation( const Float4x4 &o )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
ExtractRotationMatrix( o, this->box.rotation );
|
this->axis = ExtractAngularAxis( o );
|
||||||
this->box.center = o.v[3].xyz;
|
this->rotation = Rotation( this->axis );
|
||||||
}
|
this->centerPos = o.v[3].xyz;
|
||||||
|
|
||||||
void RigidBody::SetSize( const Float3 &widthHeight )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->box.boundingOffset = 0.5f * widthHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetCenter( const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->box.center = worldPos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetRotation( const Float4x4 &r )
|
void RigidBody::SetRotation( const Float4x4 &r )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->box.rotation = r;
|
this->axis = ExtractAngularAxis( r );
|
||||||
|
this->rotation = Rotation( this->axis );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetImpulseTorque( const Float3 &worldT )
|
void RigidBody::SetMomentum_Linear( const Float4 &worldG, const Float4 &atWorldPos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->impulseTorqueSum = worldT;
|
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||||
|
this->momentum_Linear = VectorProjection( worldG, worldOffset );
|
||||||
|
this->momentum_Angular = Formula::AngularMomentum( worldG, worldOffset );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetAngularMomentum( const Float3 &worldH )
|
void RigidBody::SetVelocity_Linear( const Float4 &worldV )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->angularMomentum = worldH;
|
this->momentum_Linear = Formula::LinearMomentum( this->mass, worldV );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetAngularImpulseAcceleration( const Float3 &worldA )
|
void RigidBody::SetVelocity_Linear( const Float4 &worldV, const Float4 &atWorldPos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->impulseTorqueSum = Formula::ImpulseTorque( this->momentOfInertiaTensor, worldA );
|
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||||
|
this->momentum_Linear = Formula::LinearMomentum( this->mass, VectorProjection(worldV, worldOffset) );
|
||||||
|
this->momentum_Angular = Formula::AngularMomentum( RotationMatrix(this->rotation) * this->momentOfInertiaTensor, Formula::AngularVelocity(worldV, worldOffset) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetAngularVelocity( const Float3 &worldW )
|
void RigidBody::SetVelocity_Angular( const Float4 &worldW )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->angularMomentum = Formula::AngularMomentum( this->momentOfInertiaTensor, worldW );
|
this->momentum_Angular = Formula::AngularMomentum( this->momentOfInertiaTensor, worldW );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetImpulseForce( const Float3 &worldF )
|
void RigidBody::SetImpulse_Linear( const Float4 &worldJ, const Float4 &atWorldPos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->impulseForceSum = worldF;
|
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||||
}
|
this->impulse_Linear = VectorProjection( worldJ, worldOffset );
|
||||||
|
this->impulse_Angular = Formula::ImpulseTorque( worldJ, worldOffset );
|
||||||
void RigidBody::SetLinearMomentum( const Float3 &worldG )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->linearMomentum = worldG;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetLinearImpulseAcceleration( const Float3 &worldA )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->impulseForceSum = Formula::ImpulseForce( this->mass, worldA );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetLinearVelocity( const Float3 &worldV )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->linearMomentum = Formula::LinearMomentum( this->mass, worldV );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetImpulseForceAt( const Float3 &worldForce, const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center;
|
|
||||||
this->impulseForceSum = VectorProjection( worldForce, worldOffset );
|
|
||||||
this->impulseTorqueSum = Formula::ImpulseTorque( worldForce, worldOffset );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetLinearMomentumAt( const Float3 &worldG, const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center;
|
|
||||||
this->linearMomentum = VectorProjection( worldG, worldOffset );
|
|
||||||
this->angularMomentum = Formula::AngularMomentum( worldG, worldOffset );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetImpulseAccelerationAt( const Float3 &worldA, const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center;
|
|
||||||
this->impulseForceSum = Formula::ImpulseForce( this->mass, VectorProjection(worldA, worldOffset) );
|
|
||||||
this->impulseTorqueSum = Formula::ImpulseTorque( this->box.rotation * this->momentOfInertiaTensor,
|
|
||||||
Formula::AngularImpulseAcceleration(worldA, worldOffset) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetLinearVelocityAt( const Float3 &worldV, const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center;
|
|
||||||
this->linearMomentum = Formula::LinearMomentum( this->mass, VectorProjection(worldV, worldOffset) );
|
|
||||||
this->angularMomentum = Formula::AngularMomentum( this->box.rotation * this->momentOfInertiaTensor,
|
|
||||||
Formula::AngularVelocity(worldV, worldOffset) );
|
|
||||||
}
|
}
|
|
@ -12,109 +12,76 @@
|
||||||
namespace Oyster { namespace Physics3D
|
namespace Oyster { namespace Physics3D
|
||||||
{
|
{
|
||||||
struct RigidBody
|
struct RigidBody
|
||||||
{ /// A struct of a simple rigid body.
|
{ //! A struct of a simple rigid body.
|
||||||
public:
|
public:
|
||||||
::Oyster::Collision3D::Box box; /** Contains data representing physical presence. (worldValue) */
|
::Oyster::Math::Float4 centerPos, //!< Location of the body's center in the world.
|
||||||
::Oyster::Math::Float3 angularMomentum, /** The angular momentum H (Nm*s) around an parallell axis. (worldValue) */
|
axis, //!< Euler rotationAxis of the body.
|
||||||
linearMomentum, /** The linear momentum G (kg*m/s). (worldValue) */
|
boundingReach, //!<
|
||||||
impulseTorqueSum, /** The impulse torque T (Nm) that will be consumed each update. (worldValue) */
|
momentum_Linear, //!< The linear momentum G (kg*m/s).
|
||||||
impulseForceSum; /** The impulse force F (N) that will be consumed each update. (worldValue) */
|
momentum_Angular, //!< The angular momentum H (Nm*s) around an parallell axis.
|
||||||
|
impulse_Linear, //!< The linear impulse sum Jl (kg*m/s) that will be consumed each update.
|
||||||
|
impulse_Angular; //!< The angular impulse sum Ja (kg*m^2/s) that will be consumed each update.
|
||||||
|
::Oyster::Math::Float restitutionCoeff, //!<
|
||||||
|
frictionCoeff_Static, //!<
|
||||||
|
frictionCoeff_Kinetic; //!<
|
||||||
|
|
||||||
RigidBody( const ::Oyster::Collision3D::Box &box = ::Oyster::Collision3D::Box(),
|
RigidBody();
|
||||||
::Oyster::Math::Float mass = 12.0f,
|
|
||||||
const ::Oyster::Math::Float4x4 &inertiaTensor = ::Oyster::Math::Float4x4::identity );
|
|
||||||
|
|
||||||
RigidBody & operator = ( const RigidBody &body );
|
RigidBody & operator = ( const RigidBody &body );
|
||||||
|
|
||||||
bool operator == ( const RigidBody &body );
|
void Update_LeapFrog( ::Oyster::Math::Float updateFrameLength );
|
||||||
bool operator != ( const RigidBody &body );
|
void Predict_LeapFrog( ::Oyster::Math::Float4 &outDeltaPos, ::Oyster::Math::Float4 &outDeltaAxis, const ::Oyster::Math::Float4 &actingLinearImpulse, const ::Oyster::Math::Float4 &actingAngularImpulse, ::Oyster::Math::Float deltaTime );
|
||||||
|
|
||||||
void Update_LeapFrog( ::Oyster::Math::Float deltaTime );
|
void Move( const ::Oyster::Math::Float4 &deltaPos, const ::Oyster::Math::Float4 &deltaAxis );
|
||||||
void ApplyImpulseForce( const ::Oyster::Math::Float3 &worldF );
|
void ApplyImpulse( const ::Oyster::Math::Float4 &worldJ, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void ApplyImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos );
|
void ApplyImpulse_Linear( const ::Oyster::Math::Float4 &worldJ );
|
||||||
void ApplyLinearImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
void ApplyImpulse_Angular( const ::Oyster::Math::Float4 &worldJ );
|
||||||
void ApplyLinearImpulseAccelerationAt( const ::Oyster::Math::Float3 &worldA, const ::Oyster::Math::Float3 &worldPos );
|
void ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength );
|
||||||
void ApplyImpulseTorque( const ::Oyster::Math::Float3 &worldT );
|
void ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void ApplyAngularImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
|
||||||
|
|
||||||
// ACCESS METHODS /////////////////////////////
|
|
||||||
|
|
||||||
::Oyster::Math::Float3 & AccessBoundingReach();
|
|
||||||
const ::Oyster::Math::Float3 & AccessBoundingReach() const;
|
|
||||||
::Oyster::Math::Float3 & AccessCenter();
|
|
||||||
const ::Oyster::Math::Float3 & AccessCenter() const;
|
|
||||||
|
|
||||||
// GET METHODS ////////////////////////////////
|
// GET METHODS ////////////////////////////////
|
||||||
|
|
||||||
const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const;
|
const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const;
|
||||||
const ::Oyster::Math::Float & GetMass() const;
|
::Oyster::Math::Float GetMass() const;
|
||||||
|
const ::Oyster::Math::Quaternion & GetRotation() const;
|
||||||
const ::Oyster::Math::Float4x4 GetOrientation() const;
|
::Oyster::Math::Float4x4 GetRotationMatrix() const;
|
||||||
|
::Oyster::Math::Float4x4 GetOrientation() const;
|
||||||
::Oyster::Math::Float4x4 GetView() const;
|
::Oyster::Math::Float4x4 GetView() const;
|
||||||
const ::Oyster::Math::Float4x4 & GetToWorldMatrix() const;
|
::Oyster::Math::Float4x4 GetToWorldMatrix() const;
|
||||||
::Oyster::Math::Float4x4 GetToLocalMatrix() const;
|
::Oyster::Math::Float4x4 GetToLocalMatrix() const;
|
||||||
|
::Oyster::Math::Float4 GetSize() const;
|
||||||
const ::Oyster::Math::Float3 & GetBoundingReach() const;
|
::Oyster::Math::Float4 GetVelocity_Linear() const;
|
||||||
::Oyster::Math::Float3 GetSize() const;
|
::Oyster::Math::Float4 GetVelocity_Angular() const;
|
||||||
|
::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float4 &atWorldPos ) const;
|
||||||
const ::Oyster::Math::Float3 & GetCenter() const;
|
|
||||||
|
|
||||||
const ::Oyster::Math::Float3 & GetImpulsTorque() const;
|
|
||||||
const ::Oyster::Math::Float3 & GetAngularMomentum() const;
|
|
||||||
::Oyster::Math::Float3 GetAngularImpulseAcceleration() const;
|
|
||||||
::Oyster::Math::Float3 GetAngularVelocity() const;
|
|
||||||
|
|
||||||
const ::Oyster::Math::Float3 & GetImpulseForce() const;
|
|
||||||
const ::Oyster::Math::Float3 & GetLinearMomentum() const;
|
|
||||||
::Oyster::Math::Float3 GetLinearImpulseAcceleration() const;
|
|
||||||
::Oyster::Math::Float3 GetLinearVelocity() const;
|
|
||||||
|
|
||||||
void GetMomentumAt( const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &surfaceNormal, ::Oyster::Math::Float3 &normalMomentum, ::Oyster::Math::Float3 &tangentialMomentum ) const;
|
|
||||||
|
|
||||||
// SET METHODS ////////////////////////////////
|
// SET METHODS ////////////////////////////////
|
||||||
|
|
||||||
void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localTensorI );
|
||||||
void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &localTensorI );
|
||||||
void SetMass_KeepVelocity( const ::Oyster::Math::Float &m );
|
void SetMass_KeepVelocity( const ::Oyster::Math::Float &m );
|
||||||
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
|
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
|
||||||
|
|
||||||
void SetOrientation( const ::Oyster::Math::Float4x4 &o );
|
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 SetRotation( const ::Oyster::Math::Float4x4 &r );
|
||||||
|
void SetSize( const ::Oyster::Math::Float4 &widthHeight );
|
||||||
|
|
||||||
void SetImpulseTorque( const ::Oyster::Math::Float3 &worldT );
|
void SetMomentum_Linear( const ::Oyster::Math::Float4 &worldG, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void SetAngularMomentum( const ::Oyster::Math::Float3 &worldH );
|
|
||||||
void SetAngularImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
|
||||||
void SetAngularVelocity( const ::Oyster::Math::Float3 &worldW );
|
|
||||||
|
|
||||||
void SetImpulseForce( const ::Oyster::Math::Float3 &worldF );
|
void SetVelocity_Linear( const ::Oyster::Math::Float4 &worldV );
|
||||||
void SetLinearMomentum( const ::Oyster::Math::Float3 &worldG );
|
void SetVelocity_Linear( const ::Oyster::Math::Float4 &worldV, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void SetLinearImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
void SetVelocity_Angular( const ::Oyster::Math::Float4 &worldW );
|
||||||
void SetLinearVelocity( const ::Oyster::Math::Float3 &worldV );
|
|
||||||
|
|
||||||
void SetImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos );
|
void SetImpulse_Linear( const ::Oyster::Math::Float4 &worldJ, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void SetLinearMomentumAt( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &worldPos );
|
void SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength );
|
||||||
void SetImpulseAccelerationAt( const ::Oyster::Math::Float3 &worldA, const ::Oyster::Math::Float3 &worldPos );
|
void SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void SetLinearVelocityAt( const ::Oyster::Math::Float3 &worldV, const ::Oyster::Math::Float3 &worldPos );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Oyster::Math::Float mass; /** m (kg) */
|
::Oyster::Math::Float mass; //!< m (kg)
|
||||||
::Oyster::Math::Float4x4 momentOfInertiaTensor; /** I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue) */
|
::Oyster::Math::Float4x4 momentOfInertiaTensor; //!< I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue)
|
||||||
|
::Oyster::Math::Quaternion rotation; //!< RotationAxis of the body.
|
||||||
};
|
};
|
||||||
|
|
||||||
// INLINE IMPLEMENTATIONS ///////////////////////////////////////
|
|
||||||
|
|
||||||
inline const ::Oyster::Math::Float4x4 & RigidBody::GetToWorldMatrix() const
|
|
||||||
{
|
|
||||||
return this->GetOrientation();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ::Oyster::Math::Float4x4 RigidBody::GetToLocalMatrix() const
|
|
||||||
{
|
|
||||||
return this->GetView();
|
|
||||||
}
|
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
#include "RigidBody_Inline.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// INLINE IMPLEMENTATIONS
|
||||||
|
// Created by Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef OYSTER_PHYSICS_3D_RIGIDBODY_INLINE_H
|
||||||
|
#define OYSTER_PHYSICS_3D_RIGIDBODY_INLINE_H
|
||||||
|
|
||||||
|
#include "RigidBody.h"
|
||||||
|
|
||||||
|
namespace Oyster { namespace Physics3D
|
||||||
|
{
|
||||||
|
inline void RigidBody::ApplyImpulse_Linear( const ::Oyster::Math::Float4 &worldJ )
|
||||||
|
{
|
||||||
|
this->impulse_Linear += worldJ;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::ApplyImpulse_Angular( const ::Oyster::Math::Float4 &worldJ )
|
||||||
|
{
|
||||||
|
this->impulse_Angular += worldJ;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength )
|
||||||
|
{
|
||||||
|
this->impulse_Linear += worldF * updateFrameLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos )
|
||||||
|
{
|
||||||
|
this->ApplyImpulse( worldF * updateFrameLength, atWorldPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 RigidBody::GetToWorldMatrix() const
|
||||||
|
{
|
||||||
|
return this->GetOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 RigidBody::GetToLocalMatrix() const
|
||||||
|
{
|
||||||
|
return this->GetView();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4 RigidBody::GetSize() const
|
||||||
|
{
|
||||||
|
return 2.0f * this->boundingReach;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::SetSize( const ::Oyster::Math::Float4 &widthHeight )
|
||||||
|
{
|
||||||
|
this->boundingReach = ::Utility::Value::Abs( 0.5f * widthHeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength )
|
||||||
|
{
|
||||||
|
this->impulse_Linear = worldF * updateFrameLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos )
|
||||||
|
{
|
||||||
|
this->SetImpulse_Linear( worldF * updateFrameLength, atWorldPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
|
@ -6,14 +6,20 @@ using namespace ::Oyster::Math;
|
||||||
|
|
||||||
Sphere::Sphere( ) : ICollideable(Type_sphere)
|
Sphere::Sphere( ) : ICollideable(Type_sphere)
|
||||||
{
|
{
|
||||||
this->center = Float3::null;
|
this->center = Float4::standard_unit_w;
|
||||||
this->radius = 0.0f;
|
this->radius = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sphere::Sphere( const Float3 &_position, const Float &_radius ) : ICollideable(Type_sphere)
|
Sphere::Sphere( const Float3 &p, const Float &r ) : ICollideable(Type_sphere)
|
||||||
{
|
{
|
||||||
this->center = _position;
|
this->center = Float4( p, 1.0f );
|
||||||
this->radius = _radius;
|
this->radius = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sphere::Sphere( const Float4 &p, const Float &r ) : ICollideable(Type_sphere)
|
||||||
|
{
|
||||||
|
this->center = p;
|
||||||
|
this->radius = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sphere::~Sphere( ) {}
|
Sphere::~Sphere( ) {}
|
||||||
|
@ -26,35 +32,58 @@ Sphere & Sphere::operator = ( const Sphere &sphere )
|
||||||
}
|
}
|
||||||
|
|
||||||
::Utility::DynamicMemory::UniquePointer<ICollideable> Sphere::Clone( ) const
|
::Utility::DynamicMemory::UniquePointer<ICollideable> Sphere::Clone( ) const
|
||||||
{ return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Sphere(*this) ); }
|
{
|
||||||
|
return ::Utility::DynamicMemory::UniquePointer<ICollideable>( 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_universe: return true;
|
||||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||||
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this );
|
case Type_plane: return Utility::Intersect( (const Plane&)target, *this );
|
||||||
// case Type_triangle: return false; // TODO:
|
//case Type_triangle: return false; // TODO:
|
||||||
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this );
|
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
|
||||||
case Type_box: return Utility::Intersect( *(Box*)&target, *this );
|
case Type_box: return Utility::Intersect( (const Box&)target, *this );
|
||||||
case Type_frustrum: return false; // TODO:
|
//case Type_frustrum: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sphere::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
|
{
|
||||||
|
switch( target.type )
|
||||||
|
{
|
||||||
|
case Type_universe:
|
||||||
|
worldPointOfContact = this->center;
|
||||||
|
return true;
|
||||||
|
case Type_point: return Utility::Intersect( *this, (const Point&)target, worldPointOfContact );
|
||||||
|
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance, worldPointOfContact );
|
||||||
|
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target, worldPointOfContact );
|
||||||
|
case Type_plane: return Utility::Intersect( (const Plane&)target, *this, worldPointOfContact );
|
||||||
|
//case Type_triangle: return false; // TODO:
|
||||||
|
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, worldPointOfContact );
|
||||||
|
case Type_box: return Utility::Intersect( (const Box&)target, *this, worldPointOfContact );
|
||||||
|
//case Type_frustrum: return false; // TODO:
|
||||||
|
default:
|
||||||
|
worldPointOfContact = Float3::null;
|
||||||
|
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_point: return Utility::Intersect( *this, (const Point&)target );
|
||||||
case Type_sphere: return Utility::Contains( *this, *(Sphere*)&target );
|
case Type_sphere: return Utility::Contains( *this, (const Sphere&)target );
|
||||||
// case Type_triangle: return false; // TODO:
|
//case Type_triangle: return false; // TODO:
|
||||||
case Type_box_axis_aligned: return false; // TODO:
|
//case Type_box_axis_aligned: return false; // TODO:
|
||||||
case Type_box: return false; // TODO:
|
//case Type_box: return false; // TODO:
|
||||||
case Type_frustrum: return false; // TODO:
|
//case Type_frustrum: return false; // TODO:
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,18 +16,20 @@ namespace Oyster { namespace Collision3D
|
||||||
public:
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct{ ::Oyster::Math::Float3 center; ::Oyster::Math::Float radius; };
|
struct{ ::Oyster::Math::Float4 center; ::Oyster::Math::Float radius; };
|
||||||
char byte[sizeof(::Oyster::Math::Float3) + sizeof(::Oyster::Math::Float)];
|
char byte[sizeof(::Oyster::Math::Float4) + sizeof(::Oyster::Math::Float)];
|
||||||
};
|
};
|
||||||
|
|
||||||
Sphere( );
|
Sphere( );
|
||||||
Sphere( const ::Oyster::Math::Float3 ¢er, const ::Oyster::Math::Float &radius );
|
Sphere( const ::Oyster::Math::Float3 ¢er, const ::Oyster::Math::Float &radius );
|
||||||
|
Sphere( const ::Oyster::Math::Float4 ¢er, const ::Oyster::Math::Float &radius );
|
||||||
virtual ~Sphere( );
|
virtual ~Sphere( );
|
||||||
|
|
||||||
Sphere & operator = ( const Sphere &sphere );
|
Sphere & operator = ( const Sphere &sphere );
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "Universe.h"
|
#include "Universe.h"
|
||||||
#include "OysterCollision3D.h"
|
#include "OysterCollision3D.h"
|
||||||
|
|
||||||
|
using namespace ::Utility::Value;
|
||||||
|
using namespace ::Oyster::Math;
|
||||||
using namespace ::Oyster::Collision3D;
|
using namespace ::Oyster::Collision3D;
|
||||||
using namespace ::Utility::DynamicMemory;
|
using namespace ::Utility::DynamicMemory;
|
||||||
|
|
||||||
|
@ -8,20 +10,24 @@ Universe::Universe() : ICollideable(Type_universe) {}
|
||||||
Universe::~Universe() {}
|
Universe::~Universe() {}
|
||||||
|
|
||||||
Universe & Universe::operator = ( const Universe &universe )
|
Universe & Universe::operator = ( const Universe &universe )
|
||||||
{ return *this; }
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
UniquePointer<ICollideable> Universe::Clone( ) const
|
UniquePointer<ICollideable> Universe::Clone( ) const
|
||||||
{ return UniquePointer<ICollideable>( new Universe(*this) ); }
|
{
|
||||||
|
return UniquePointer<ICollideable>( new Universe(*this) );
|
||||||
|
}
|
||||||
|
|
||||||
bool Universe::Intersects( const ICollideable &target ) const
|
bool Universe::Intersects( const ICollideable &target ) const
|
||||||
{ // universe touches everything
|
{ // universe touches everything
|
||||||
switch( target.type )
|
switch( target.type )
|
||||||
{
|
{
|
||||||
case Type_ray:
|
case Type_ray:
|
||||||
((Ray*)&target)->collisionDistance = 0.0f;
|
((const Ray&)target).collisionDistance = 0.0f;
|
||||||
break;
|
break;
|
||||||
case Type_line:
|
case Type_line:
|
||||||
((Line*)&target)->ray.collisionDistance = 0.0f;
|
((const Line&)target).ray.collisionDistance = 0.0f;
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +35,47 @@ bool Universe::Intersects( const ICollideable &target ) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Universe::Contains( const ICollideable &target ) const
|
bool Universe::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||||
{ return true; } // universe contains everything
|
{ // universe touches everything
|
||||||
|
switch( target.type )
|
||||||
|
{
|
||||||
|
case Type_point:
|
||||||
|
worldPointOfContact = ((const Point&)target).center;
|
||||||
|
break;
|
||||||
|
case Type_sphere:
|
||||||
|
worldPointOfContact = ((const Sphere&)target).center;
|
||||||
|
break;
|
||||||
|
case Type_plane:
|
||||||
|
worldPointOfContact = ((const Plane&)target).normal * ((const Plane&)target).phasing;
|
||||||
|
break;
|
||||||
|
case Type_box_axis_aligned:
|
||||||
|
worldPointOfContact = Average( ((const BoxAxisAligned&)target).minVertex, ((const BoxAxisAligned&)target).maxVertex );
|
||||||
|
break;
|
||||||
|
case Type_box:
|
||||||
|
worldPointOfContact = ((const Box&)target).center;
|
||||||
|
break;
|
||||||
|
case Type_frustrum:
|
||||||
|
worldPointOfContact = Average( ((const Frustrum&)target).leftPlane.normal * ((const Frustrum&)target).leftPlane.phasing, ((const Frustrum&)target).rightPlane.normal * ((const Frustrum&)target).rightPlane.phasing );
|
||||||
|
worldPointOfContact = Average( worldPointOfContact, Average( ((const Frustrum&)target).bottomPlane.normal * ((const Frustrum&)target).bottomPlane.phasing, ((const Frustrum&)target).topPlane.normal * ((const Frustrum&)target).topPlane.phasing ) );
|
||||||
|
worldPointOfContact = Average( worldPointOfContact, Average( ((const Frustrum&)target).nearPlane.normal * ((const Frustrum&)target).nearPlane.phasing, ((const Frustrum&)target).farPlane.normal * ((const Frustrum&)target).farPlane.phasing ) );
|
||||||
|
break;
|
||||||
|
case Type_ray:
|
||||||
|
((const Ray&)target).collisionDistance = 0.0f;
|
||||||
|
worldPointOfContact = ((const Ray&)target).origin;
|
||||||
|
break;
|
||||||
|
case Type_line:
|
||||||
|
((const Line&)target).ray.collisionDistance = 0.0f;
|
||||||
|
worldPointOfContact = ((const Line&)target).ray.origin;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
worldPointOfContact = Float3::null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Universe::Contains( const ICollideable &target ) const
|
||||||
|
{ // universe contains everything
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
#define OYSTER_COLLISION_3D_UNIVERSE_H
|
#define OYSTER_COLLISION_3D_UNIVERSE_H
|
||||||
|
|
||||||
#include "ICollideable.h"
|
#include "ICollideable.h"
|
||||||
|
#include "OysterMath.h"
|
||||||
|
|
||||||
namespace Oyster { namespace Collision3D
|
namespace Oyster { namespace Collision3D
|
||||||
{
|
{
|
||||||
|
@ -20,6 +21,7 @@ namespace Oyster { namespace Collision3D
|
||||||
|
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
Loading…
Reference in New Issue