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\SphericalRigidBody.h" />
|
||||
<ClInclude Include="PhysicsAPI.h" />
|
||||
<ClInclude Include="PhysicsFormula-Impl.h" />
|
||||
<ClInclude Include="PhysicsFormula.h" />
|
||||
<ClInclude Include="PhysicsStructs-Impl.h" />
|
||||
<ClInclude Include="PhysicsStructs.h" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -42,6 +42,12 @@
|
|||
<ClInclude Include="PhysicsStructs-Impl.h">
|
||||
<Filter>Header Files\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PhysicsFormula.h">
|
||||
<Filter>Header Files\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PhysicsFormula-Impl.h">
|
||||
<Filter>Header Files\Include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Implementation\PhysicsAPI_Impl.cpp">
|
||||
|
|
|
@ -31,6 +31,7 @@ Octree& Octree::operator=(const Octree& orig)
|
|||
|
||||
void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
|
||||
{
|
||||
customBodyRef->SetScene( this );
|
||||
Data data;
|
||||
//Data* tempPtr = this->worldNode.dataPtr;
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
#include "SphericalRigidBody.h"
|
||||
|
||||
using namespace ::Oyster::Physics;
|
||||
using namespace ::Oyster::Physics3D;
|
||||
using namespace ::Oyster::Math;
|
||||
using namespace ::Oyster::Collision3D;
|
||||
using namespace ::Utility::DynamicMemory;
|
||||
using namespace ::Utility::Value;
|
||||
|
||||
API_Impl API_instance;
|
||||
|
||||
|
@ -18,38 +18,68 @@ namespace
|
|||
auto proto = worldScene.GetCustomBody( protoTempRef );
|
||||
auto deuter = worldScene.GetCustomBody( deuterTempRef );
|
||||
|
||||
float deltaWhen;
|
||||
Float3 worldWhere;
|
||||
if( proto->Intersects(*deuter, 1.0f, deltaWhen, worldWhere) )
|
||||
Float4 worldPointOfContact;
|
||||
if( proto->Intersects(*deuter, worldPointOfContact) )
|
||||
{
|
||||
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()
|
||||
|
@ -95,12 +125,23 @@ void API_Impl::SetSubscription( API::EventAction_Destruction functionPointer )
|
|||
}
|
||||
}
|
||||
|
||||
float API_Impl::GetFrameTimeLength() const
|
||||
{
|
||||
return this->updateFrameLength;
|
||||
}
|
||||
|
||||
void API_Impl::Update()
|
||||
{ /** @todo TODO: Update is a temporary solution .*/
|
||||
|
||||
|
||||
|
||||
::std::vector<ICustomBody*> updateList;
|
||||
auto proto = this->worldScene.Sample( Universe(), updateList ).begin();
|
||||
for( ; proto != updateList.end(); ++proto )
|
||||
{
|
||||
// Step 1: @todo TODO: Apply Gravity
|
||||
|
||||
// Step 2: Apply Collision Response
|
||||
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 )
|
||||
{
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
//this->worldScene.GetCustomBody( tempRef )->Apply //!< @todo TODO: need function
|
||||
this->worldScene.SetAsAltered( tempRef );
|
||||
}
|
||||
}
|
||||
|
||||
void API_Impl::ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, Float &deltaWhen, Float3 &worldPointOfContact )
|
||||
{
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRefA );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
//! @todo TODO: implement stub
|
||||
this->worldScene.SetAsAltered( tempRef );
|
||||
}
|
||||
}
|
||||
|
||||
void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI )
|
||||
{ // deprecated
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepVelocity( localI );
|
||||
}
|
||||
}
|
||||
|
||||
void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const Float4x4 &localI )
|
||||
{ // deprecated
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepMomentum( localI );
|
||||
}
|
||||
}
|
||||
|
||||
void API_Impl::SetMass_KeepVelocity( const ICustomBody* objRef, Float m )
|
||||
{ // deprecated
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
this->worldScene.GetCustomBody( tempRef )->SetMass_KeepVelocity( m );
|
||||
}
|
||||
}
|
||||
|
||||
void API_Impl::SetMass_KeepMomentum( const ICustomBody* objRef, Float m )
|
||||
{ // deprecated
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
this->worldScene.GetCustomBody( tempRef )->SetMass_KeepMomentum( m );
|
||||
}
|
||||
}
|
||||
|
||||
void API_Impl::SetCenter( const ICustomBody* objRef, const Float3 &worldPos )
|
||||
{
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
//this->worldScene.GetCustomBody( tempRef )->Set //!< @todo TODO: need function
|
||||
this->worldScene.EvaluatePosition( tempRef );
|
||||
}
|
||||
}
|
||||
|
||||
void API_Impl::SetRotation( const ICustomBody* objRef, const Float4x4 &rotation )
|
||||
{
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
this->worldScene.GetCustomBody( tempRef )->SetRotation( rotation );
|
||||
this->worldScene.EvaluatePosition( tempRef );
|
||||
}
|
||||
}
|
||||
|
||||
void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orientation )
|
||||
{
|
||||
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
if( tempRef != this->worldScene.invalid_ref )
|
||||
{
|
||||
this->worldScene.GetCustomBody( tempRef )->SetOrientation( orientation );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
//void API_Impl::ApplyForceAt( const ICustomBody* objRef, const Float3 &worldPos, const Float3 &worldF )
|
||||
//{
|
||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
// if( tempRef != this->worldScene.invalid_ref )
|
||||
// {
|
||||
// //this->worldScene.GetCustomBody( tempRef )->Apply //!< @todo TODO: need function
|
||||
// this->worldScene.SetAsAltered( tempRef );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI )
|
||||
//{ // deprecated
|
||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
// if( tempRef != this->worldScene.invalid_ref )
|
||||
// {
|
||||
// this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepVelocity( localI );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const Float4x4 &localI )
|
||||
//{ // deprecated
|
||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
// if( tempRef != this->worldScene.invalid_ref )
|
||||
// {
|
||||
// this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepMomentum( localI );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void API_Impl::SetMass_KeepVelocity( const ICustomBody* objRef, Float m )
|
||||
//{ // deprecated
|
||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
// if( tempRef != this->worldScene.invalid_ref )
|
||||
// {
|
||||
// this->worldScene.GetCustomBody( tempRef )->SetMass_KeepVelocity( m );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void API_Impl::SetMass_KeepMomentum( const ICustomBody* objRef, Float m )
|
||||
//{ // deprecated
|
||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
// if( tempRef != this->worldScene.invalid_ref )
|
||||
// {
|
||||
// this->worldScene.GetCustomBody( tempRef )->SetMass_KeepMomentum( m );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void API_Impl::SetCenter( const ICustomBody* objRef, const Float3 &worldPos )
|
||||
//{
|
||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
// if( tempRef != this->worldScene.invalid_ref )
|
||||
// {
|
||||
// //this->worldScene.GetCustomBody( tempRef )->Set //!< @todo TODO: need function
|
||||
// this->worldScene.EvaluatePosition( tempRef );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void API_Impl::SetRotation( const ICustomBody* objRef, const Float4x4 &rotation )
|
||||
//{
|
||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
// if( tempRef != this->worldScene.invalid_ref )
|
||||
// {
|
||||
// this->worldScene.GetCustomBody( tempRef )->SetRotation( rotation );
|
||||
// this->worldScene.EvaluatePosition( tempRef );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orientation )
|
||||
//{
|
||||
// unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||
// if( tempRef != this->worldScene.invalid_ref )
|
||||
// {
|
||||
// this->worldScene.GetCustomBody( tempRef )->SetOrientation( orientation );
|
||||
// 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
|
||||
{
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace Oyster
|
|||
void SetGravityConstant( float g );
|
||||
void SetSubscription( EventAction_Destruction functionPointer );
|
||||
|
||||
float GetFrameTimeLength() const;
|
||||
|
||||
void Update();
|
||||
|
||||
bool IsInLimbo( const ICustomBody* objRef );
|
||||
|
@ -30,17 +32,16 @@ namespace Oyster
|
|||
::Utility::DynamicMemory::UniquePointer<ICustomBody> ExtractObject( const ICustomBody* objRef );
|
||||
void DestroyObject( const ICustomBody* objRef );
|
||||
|
||||
void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF );
|
||||
void ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact );
|
||||
//void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF );
|
||||
|
||||
void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
|
||||
void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
|
||||
void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m );
|
||||
void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m );
|
||||
void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos );
|
||||
void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation );
|
||||
void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation );
|
||||
void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size );
|
||||
//void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
|
||||
//void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI );
|
||||
//void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m );
|
||||
//void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m );
|
||||
//void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos );
|
||||
//void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation );
|
||||
//void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation );
|
||||
//void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size );
|
||||
|
||||
::Utility::DynamicMemory::UniquePointer<ICustomBody> CreateRigidBody( const SimpleBodyDescription &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::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()
|
||||
{
|
||||
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->collisionAction = Default::EventAction_Collision;
|
||||
this->ignoreGravity = false;
|
||||
this->ignoreGravity = this->isForwarded = false;
|
||||
this->scene = nullptr;
|
||||
}
|
||||
|
||||
SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
||||
{
|
||||
this->rigid = RigidBody( Box( desc.rotation, desc.centerPosition, desc.size ),
|
||||
desc.mass,
|
||||
desc.inertiaTensor );
|
||||
this->rigid.SetRotation( desc.rotation );
|
||||
this->rigid.centerPos = desc.centerPosition;
|
||||
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;
|
||||
|
||||
if( desc.subscription )
|
||||
|
@ -33,6 +73,7 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
|||
}
|
||||
|
||||
this->ignoreGravity = desc.ignoreGravity;
|
||||
this->scene = nullptr;
|
||||
}
|
||||
|
||||
SimpleRigidBody::~SimpleRigidBody() {}
|
||||
|
@ -44,24 +85,60 @@ UniquePointer<ICustomBody> SimpleRigidBody::Clone() 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
|
||||
{
|
||||
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 )
|
||||
{ /** @todo TODO: temporary solution! Need to know it's occtree */
|
||||
this->rigid.box.boundingOffset = state.GetReach();
|
||||
this->rigid.box.center = state.GetCenterPosition();
|
||||
this->rigid.box.rotation = state.GetRotation();
|
||||
{
|
||||
this->rigid.centerPos = state.GetCenterPosition();
|
||||
this->rigid.SetRotation( 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
|
||||
|
@ -69,34 +146,76 @@ bool SimpleRigidBody::IsAffectedByGravity() const
|
|||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
return targetMem = (worldPos - this->rigid.box.center).GetNormalized();
|
||||
Float4 offset = worldPos - this->rigid.centerPos;
|
||||
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
|
||||
|
@ -104,41 +223,59 @@ Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
|||
return targetMem = this->gravityNormal;
|
||||
}
|
||||
|
||||
Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const
|
||||
{
|
||||
return targetMem = this->rigid.box.center;
|
||||
}
|
||||
//Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const
|
||||
//{
|
||||
// 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
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
Float3 SimpleRigidBody::GetRigidLinearVelocity() const
|
||||
{
|
||||
return this->rigid.GetLinearVelocity();
|
||||
}
|
||||
//Float3 SimpleRigidBody::GetRigidLinearVelocity() const
|
||||
//{
|
||||
// return this->rigid.GetLinearVelocity();
|
||||
//}
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
// 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 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 )
|
||||
{
|
||||
if( functionPointer )
|
||||
|
@ -162,47 +299,47 @@ void SimpleRigidBody::SetGravityNormal( const Float3 &normalizedVector )
|
|||
this->gravityNormal = normalizedVector;
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
||||
{
|
||||
this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
||||
{
|
||||
this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetMass_KeepVelocity( Float m )
|
||||
{
|
||||
this->rigid.SetMass_KeepVelocity( m );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetMass_KeepMomentum( Float m )
|
||||
{
|
||||
this->rigid.SetMass_KeepMomentum( m );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetCenter( const Float3 &worldPos )
|
||||
{
|
||||
this->rigid.SetCenter( worldPos );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetRotation( const Float4x4 &rotation )
|
||||
{
|
||||
this->rigid.SetRotation( rotation );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetOrientation( const Float4x4 &orientation )
|
||||
{
|
||||
this->rigid.SetOrientation( orientation );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetSize( const Float3 &size )
|
||||
{
|
||||
this->rigid.SetSize( size );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetMomentum( const Float3 &worldG )
|
||||
{
|
||||
this->rigid.SetLinearMomentum( worldG );
|
||||
}
|
||||
//void SimpleRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
||||
//{
|
||||
// this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
||||
//}
|
||||
//
|
||||
//void SimpleRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
||||
//{
|
||||
// this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
||||
//}
|
||||
//
|
||||
//void SimpleRigidBody::SetMass_KeepVelocity( Float m )
|
||||
//{
|
||||
// this->rigid.SetMass_KeepVelocity( m );
|
||||
//}
|
||||
//
|
||||
//void SimpleRigidBody::SetMass_KeepMomentum( Float m )
|
||||
//{
|
||||
// this->rigid.SetMass_KeepMomentum( m );
|
||||
//}
|
||||
//
|
||||
//void SimpleRigidBody::SetCenter( const Float3 &worldPos )
|
||||
//{
|
||||
// this->rigid.SetCenter( worldPos );
|
||||
//}
|
||||
//
|
||||
//void SimpleRigidBody::SetRotation( const Float4x4 &rotation )
|
||||
//{
|
||||
// this->rigid.SetRotation( rotation );
|
||||
//}
|
||||
//
|
||||
//void SimpleRigidBody::SetOrientation( const Float4x4 &orientation )
|
||||
//{
|
||||
// this->rigid.SetOrientation( orientation );
|
||||
//}
|
||||
//
|
||||
//void SimpleRigidBody::SetSize( const Float3 &size )
|
||||
//{
|
||||
// this->rigid.SetSize( size );
|
||||
//}
|
||||
//
|
||||
//void SimpleRigidBody::SetMomentum( const Float3 &worldG )
|
||||
//{
|
||||
// this->rigid.SetLinearMomentum( worldG );
|
||||
//}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "..\PhysicsAPI.h"
|
||||
#include "RigidBody.h"
|
||||
#include "Octree.h"
|
||||
|
||||
namespace Oyster { namespace Physics
|
||||
{
|
||||
|
@ -18,41 +19,46 @@ namespace Oyster { namespace Physics
|
|||
State GetState() const;
|
||||
State & GetState( State &targetMem ) const;
|
||||
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 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, ::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::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 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
|
||||
::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
//::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
|
||||
//::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
//::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
//::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
|
||||
UpdateState Update( ::Oyster::Math::Float timeStepLength );
|
||||
void 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 SetGravity( bool ignore);
|
||||
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
|
||||
void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
||||
void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
||||
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
||||
void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
||||
void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
||||
void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
||||
void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
||||
void SetSize( const ::Oyster::Math::Float3 &size );
|
||||
void SetMomentum( const ::Oyster::Math::Float3 &worldG );
|
||||
//void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
||||
//void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
||||
//void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
||||
//void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
||||
//void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
||||
//void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
||||
//void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
||||
//void SetSize( const ::Oyster::Math::Float3 &size );
|
||||
//void SetMomentum( const ::Oyster::Math::Float3 &worldG );
|
||||
|
||||
private:
|
||||
::Oyster::Physics3D::RigidBody rigid;
|
||||
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||
::Oyster::Math::Float3 gravityNormal;
|
||||
EventAction_Collision collisionAction;
|
||||
bool ignoreGravity;
|
||||
Octree *scene;
|
||||
bool ignoreGravity, isForwarded;
|
||||
};
|
||||
} }
|
||||
|
||||
|
|
|
@ -10,18 +10,26 @@ using namespace ::Utility::Value;
|
|||
|
||||
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->collisionAction = Default::EventAction_Collision;
|
||||
this->ignoreGravity = false;
|
||||
this->ignoreGravity = this->isForwarded = false;
|
||||
this->scene = nullptr;
|
||||
this->body = Sphere( Float3::null, 0.5f );
|
||||
}
|
||||
|
||||
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
||||
{
|
||||
this->rigid = RigidBody( Box( desc.rotation, desc.centerPosition, Float3(2.0f * desc.radius) ),
|
||||
desc.mass,
|
||||
MomentOfInertia::CreateSphereMatrix( desc.mass, desc.radius ) );
|
||||
this->rigid = RigidBody();
|
||||
this->rigid.SetRotation( desc.rotation );
|
||||
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;
|
||||
|
||||
if( desc.subscription )
|
||||
|
@ -34,6 +42,7 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des
|
|||
}
|
||||
|
||||
this->ignoreGravity = desc.ignoreGravity;
|
||||
this->scene = nullptr;
|
||||
this->body = Sphere( desc.centerPosition, desc.radius );
|
||||
}
|
||||
|
||||
|
@ -46,24 +55,60 @@ UniquePointer<ICustomBody> SphericalRigidBody::Clone() 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
|
||||
{
|
||||
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 )
|
||||
{ /** @todo TODO: temporary solution! Need to know it's occtree */
|
||||
this->rigid.box.boundingOffset = state.GetReach();
|
||||
this->rigid.box.center = state.GetCenterPosition();
|
||||
this->rigid.box.rotation = state.GetRotation();
|
||||
{
|
||||
this->rigid.centerPos = state.GetCenterPosition();
|
||||
this->rigid.SetRotation( 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
|
||||
|
@ -71,23 +116,19 @@ bool SphericalRigidBody::IsAffectedByGravity() const
|
|||
return !this->ignoreGravity;
|
||||
}
|
||||
|
||||
bool SphericalRigidBody::Intersects( const ICustomBody &object, Float timeStepLength, Float &deltaWhen, Float3 &worldPointOfContact ) const
|
||||
{
|
||||
if( object.Intersects(this->body) )
|
||||
{ //! @todo TODO: better implementation needed
|
||||
deltaWhen = timeStepLength;
|
||||
worldPointOfContact = Average( this->body.center, object.GetCenter() );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SphericalRigidBody::Intersects( const ICollideable &shape ) const
|
||||
{
|
||||
return this->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
|
||||
|
@ -95,10 +136,16 @@ Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
|||
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
|
||||
return targetMem = (worldPos - this->rigid.box.center).GetNormalized();
|
||||
targetMem = worldPos - this->rigid.centerPos;
|
||||
Float magnitude = targetMem.GetMagnitude();
|
||||
if( magnitude != 0.0f )
|
||||
{ // sanity check
|
||||
targetMem.Normalize();
|
||||
}
|
||||
|
||||
return targetMem;
|
||||
}
|
||||
|
||||
Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||
|
@ -106,41 +153,54 @@ Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
|||
return targetMem = this->gravityNormal;
|
||||
}
|
||||
|
||||
Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
|
||||
{
|
||||
return targetMem = this->rigid.box.center;
|
||||
}
|
||||
//Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
|
||||
//{
|
||||
// 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
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
Float3 SphericalRigidBody::GetRigidLinearVelocity() const
|
||||
{
|
||||
return this->rigid.GetLinearVelocity();
|
||||
}
|
||||
//Float3 SphericalRigidBody::GetRigidLinearVelocity() const
|
||||
//{
|
||||
// return this->rigid.GetLinearVelocity();
|
||||
//}
|
||||
|
||||
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->body.center = this->rigid.GetCenter();
|
||||
this->body.center = this->rigid.centerPos;
|
||||
|
||||
// compare previous and new state and return result
|
||||
//return this->current == this->previous ? UpdateState_resting : 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 )
|
||||
{
|
||||
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->gravityNormal = Float3::null;
|
||||
|
@ -164,50 +229,50 @@ void SphericalRigidBody::SetGravityNormal( const Float3 &normalizedVector )
|
|||
this->gravityNormal = normalizedVector;
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
||||
{
|
||||
this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
||||
{
|
||||
this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetMass_KeepVelocity( Float m )
|
||||
{
|
||||
this->rigid.SetMass_KeepVelocity( m );
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetMass_KeepMomentum( Float m )
|
||||
{
|
||||
this->rigid.SetMass_KeepMomentum( m );
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetCenter( const Float3 &worldPos )
|
||||
{
|
||||
this->rigid.SetCenter( worldPos );
|
||||
this->body.center = worldPos;
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetRotation( const Float4x4 &rotation )
|
||||
{
|
||||
this->rigid.SetRotation( rotation );
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetOrientation( const Float4x4 &orientation )
|
||||
{
|
||||
this->rigid.SetOrientation( orientation );
|
||||
this->body.center = orientation.v[3].xyz;
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetSize( const Float3 &size )
|
||||
{
|
||||
this->rigid.SetSize( size );
|
||||
this->body.radius = 0.5f * Min( Min( size.x, size.y ), size.z ); // inline Min( FloatN )?
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetMomentum( const Float3 &worldG )
|
||||
{
|
||||
this->rigid.SetLinearMomentum( worldG );
|
||||
}
|
||||
//void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
||||
//{
|
||||
// this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
||||
//}
|
||||
//
|
||||
//void SphericalRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
||||
//{
|
||||
// this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
||||
//}
|
||||
//
|
||||
//void SphericalRigidBody::SetMass_KeepVelocity( Float m )
|
||||
//{
|
||||
// this->rigid.SetMass_KeepVelocity( m );
|
||||
//}
|
||||
//
|
||||
//void SphericalRigidBody::SetMass_KeepMomentum( Float m )
|
||||
//{
|
||||
// this->rigid.SetMass_KeepMomentum( m );
|
||||
//}
|
||||
//
|
||||
//void SphericalRigidBody::SetCenter( const Float3 &worldPos )
|
||||
//{
|
||||
// this->rigid.SetCenter( worldPos );
|
||||
// this->body.center = worldPos;
|
||||
//}
|
||||
//
|
||||
//void SphericalRigidBody::SetRotation( const Float4x4 &rotation )
|
||||
//{
|
||||
// this->rigid.SetRotation( rotation );
|
||||
//}
|
||||
//
|
||||
//void SphericalRigidBody::SetOrientation( const Float4x4 &orientation )
|
||||
//{
|
||||
// this->rigid.SetOrientation( orientation );
|
||||
// this->body.center = orientation.v[3].xyz;
|
||||
//}
|
||||
//
|
||||
//void SphericalRigidBody::SetSize( const Float3 &size )
|
||||
//{
|
||||
// this->rigid.SetSize( size );
|
||||
// this->body.radius = 0.5f * Min( Min( size.x, size.y ), size.z ); // inline Min( FloatN )?
|
||||
//}
|
||||
//
|
||||
//void SphericalRigidBody::SetMomentum( const Float3 &worldG )
|
||||
//{
|
||||
// this->rigid.SetLinearMomentum( worldG );
|
||||
//}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "..\PhysicsAPI.h"
|
||||
#include "RigidBody.h"
|
||||
#include "Sphere.h"
|
||||
#include "Octree.h"
|
||||
|
||||
namespace Oyster { namespace Physics
|
||||
{
|
||||
|
@ -19,41 +20,46 @@ namespace Oyster { namespace Physics
|
|||
State GetState() const;
|
||||
State & GetState( State &targetMem = State() ) const;
|
||||
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 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, ::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::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 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
|
||||
::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
//::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
|
||||
//::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
//::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
//::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const;
|
||||
|
||||
UpdateState Update( ::Oyster::Math::Float timeStepLength );
|
||||
void 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 SetGravity( bool ignore);
|
||||
void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector );
|
||||
void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
||||
void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
||||
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
||||
void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
||||
void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
||||
void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
||||
void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
||||
void SetSize( const ::Oyster::Math::Float3 &size );
|
||||
void SetMomentum( const ::Oyster::Math::Float3 &worldG );
|
||||
//void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
||||
//void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
||||
//void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
||||
//void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
||||
//void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
||||
//void SetRotation( const ::Oyster::Math::Float4x4 &rotation );
|
||||
//void SetOrientation( const ::Oyster::Math::Float4x4 &orientation );
|
||||
//void SetSize( const ::Oyster::Math::Float3 &size );
|
||||
//void SetMomentum( const ::Oyster::Math::Float3 &worldG );
|
||||
|
||||
private:
|
||||
::Oyster::Physics3D::RigidBody rigid;
|
||||
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||
::Oyster::Math::Float3 gravityNormal;
|
||||
EventAction_Collision collisionAction;
|
||||
bool ignoreGravity;
|
||||
bool ignoreGravity, isForwarded;
|
||||
Octree *scene;
|
||||
::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.
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -138,82 +124,73 @@ namespace Oyster
|
|||
********************************************************/
|
||||
virtual void DestroyObject( const ICustomBody* objRef ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Apply force on an object.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param worldPos: Relative to the world origo. (Not relative to object) [m]
|
||||
* @param worldF: Vector with the direction and magnitude of the force. [N]
|
||||
********************************************************/
|
||||
virtual void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ) = 0;
|
||||
///********************************************************
|
||||
// * Apply force on an object.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param worldPos: Relative to the world origo. (Not relative to object) [m]
|
||||
// * @param worldF: Vector with the direction and magnitude of the force. [N]
|
||||
// ********************************************************/
|
||||
//virtual void ApplyForceAt( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &worldF ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Apply force on an object.
|
||||
* @param objRefA: A pointer to the ICustomBody representing a physical object.
|
||||
* @param objRefB: A pointer to the ICustomBody representing a physical object.
|
||||
* @param deltaWhen: The elapsed simulation time since last update frame. [s]
|
||||
* @param worldPointOfContact: Point of Collision, relative to the world origo. (Not relative to the objects) [m]
|
||||
********************************************************/
|
||||
virtual void ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Sets the MomentOfInertia tensor matrix of an object without changing it's angular velocity.
|
||||
* Noticeable effect: The angular momentum will change. Changing the amount of kinetic energy.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace.
|
||||
********************************************************/
|
||||
virtual void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Sets the MomentOfInertia tensor matrix of an object without changing it's angular momentum.
|
||||
* Noticeable effect: The angular velocity will change. Can be used to create slow effects.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace.
|
||||
********************************************************/
|
||||
virtual void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Sets the mass of an object without changing it's linear velocity.
|
||||
* Noticeable effect: The linear momentum will change. Changing the amount of kinetic energy.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param m: [kg]
|
||||
********************************************************/
|
||||
virtual void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Sets the mass of an object without changing it's linear velocity.
|
||||
* Noticeable effect: The linear velocity will change. Can be used to create slow effects.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param m: [kg]
|
||||
********************************************************/
|
||||
virtual void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Instantly moves an object.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param worldPos: Relative to the world origo. (Not relative to object) [m]
|
||||
********************************************************/
|
||||
virtual void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Instantly redirects object.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param rotation: New rotation.
|
||||
********************************************************/
|
||||
virtual void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Instantly moves and redirects object.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param orientation: New orientation.
|
||||
********************************************************/
|
||||
virtual void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Resizes the boundingBox.
|
||||
* @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
* @param size: New size of this [m]
|
||||
********************************************************/
|
||||
virtual void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size ) = 0;
|
||||
///********************************************************
|
||||
// * Sets the MomentOfInertia tensor matrix of an object without changing it's angular velocity.
|
||||
// * Noticeable effect: The angular momentum will change. Changing the amount of kinetic energy.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace.
|
||||
// ********************************************************/
|
||||
//virtual void SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * Sets the MomentOfInertia tensor matrix of an object without changing it's angular momentum.
|
||||
// * Noticeable effect: The angular velocity will change. Can be used to create slow effects.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param localI: The tensor matrix relative to the axises of the object. @see MomentOfInertia namespace.
|
||||
// ********************************************************/
|
||||
//virtual void SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &localI ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * Sets the mass of an object without changing it's linear velocity.
|
||||
// * Noticeable effect: The linear momentum will change. Changing the amount of kinetic energy.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param m: [kg]
|
||||
// ********************************************************/
|
||||
//virtual void SetMass_KeepVelocity( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * Sets the mass of an object without changing it's linear velocity.
|
||||
// * Noticeable effect: The linear velocity will change. Can be used to create slow effects.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param m: [kg]
|
||||
// ********************************************************/
|
||||
//virtual void SetMass_KeepMomentum( const ICustomBody* objRef, ::Oyster::Math::Float m ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * Instantly moves an object.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param worldPos: Relative to the world origo. (Not relative to object) [m]
|
||||
// ********************************************************/
|
||||
//virtual void SetCenter( const ICustomBody* objRef, const ::Oyster::Math::Float3 &worldPos ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * Instantly redirects object.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param rotation: New rotation.
|
||||
// ********************************************************/
|
||||
//virtual void SetRotation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &rotation ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * Instantly moves and redirects object.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param orientation: New orientation.
|
||||
// ********************************************************/
|
||||
//virtual void SetOrientation( const ICustomBody* objRef, const ::Oyster::Math::Float4x4 &orientation ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * Resizes the boundingBox.
|
||||
// * @param objRef: A pointer to the ICustomBody representing a physical object.
|
||||
// * @param size: New size of this [m]
|
||||
// ********************************************************/
|
||||
//virtual void SetSize( const ICustomBody* objRef, const ::Oyster::Math::Float3 &size ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Creates a new dynamically allocated object that can be used as a component for more complex ICustomBodies.
|
||||
|
@ -245,11 +222,6 @@ namespace Oyster
|
|||
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 Struct::SimpleBodyDescription SimpleBodyDescription;
|
||||
typedef Struct::SphericalBodyDescription SphericalBodyDescription;
|
||||
|
@ -266,7 +238,7 @@ namespace Oyster
|
|||
/********************************************************
|
||||
* @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
|
||||
|
@ -281,7 +253,7 @@ namespace Oyster
|
|||
/********************************************************
|
||||
* @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
|
||||
|
@ -293,22 +265,28 @@ namespace Oyster
|
|||
********************************************************/
|
||||
virtual bool IsAffectedByGravity() const = 0;
|
||||
|
||||
/********************************************************
|
||||
* Performs a detailed Intersect test and returns if, when and where.
|
||||
* @param object: What this is intersect testing against.
|
||||
* @param timeStepLength: The value set by API::SetDeltaTime(...)
|
||||
* @param deltaWhen: Time in seconds since last update frame til timeOfContact. 0.0f <= deltaWhen <= timeStepLength
|
||||
* @param worldPointOfContact: Where at timeOfContact, this and object touches eachother.
|
||||
* @return true if this truly intersects with object.
|
||||
********************************************************/
|
||||
virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const = 0;
|
||||
|
||||
/********************************************************
|
||||
* param shape: Any defined sample shape.
|
||||
* @return true if this truly intersects with shape.
|
||||
********************************************************/
|
||||
virtual bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const = 0;
|
||||
|
||||
/********************************************************
|
||||
* 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.
|
||||
* @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.
|
||||
* @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.
|
||||
|
@ -331,30 +309,30 @@ namespace Oyster
|
|||
********************************************************/
|
||||
virtual ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
|
||||
|
||||
/********************************************************
|
||||
* The world position of this center of gravity.
|
||||
* @param targetMem: Provided memory that written into and then returned.
|
||||
* @return a position in worldSpace.
|
||||
********************************************************/
|
||||
virtual ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
|
||||
|
||||
/********************************************************
|
||||
* @param targetMem: Provided memory that written into and then returned.
|
||||
* @return a copy of this's rotation matrix.
|
||||
********************************************************/
|
||||
virtual ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||
|
||||
/********************************************************
|
||||
* @param targetMem: Provided memory that written into and then returned.
|
||||
* @return a copy of this's orientation matrix.
|
||||
********************************************************/
|
||||
virtual ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||
|
||||
/********************************************************
|
||||
* @param targetMem: Provided memory that written into and then returned.
|
||||
* @return a copy of this's view matrix.
|
||||
********************************************************/
|
||||
virtual ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||
///********************************************************
|
||||
// * The world position of this center of gravity.
|
||||
// * @param targetMem: Provided memory that written into and then returned.
|
||||
// * @return a position in worldSpace.
|
||||
// ********************************************************/
|
||||
//virtual ::Oyster::Math::Float3 & GetCenter( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * @param targetMem: Provided memory that written into and then returned.
|
||||
// * @return a copy of this's rotation matrix.
|
||||
// ********************************************************/
|
||||
//virtual ::Oyster::Math::Float4x4 & GetRotation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * @param targetMem: Provided memory that written into and then returned.
|
||||
// * @return a copy of this's orientation matrix.
|
||||
// ********************************************************/
|
||||
//virtual ::Oyster::Math::Float4x4 & GetOrientation( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * @param targetMem: Provided memory that written into and then returned.
|
||||
// * @return a copy of this's view matrix.
|
||||
// ********************************************************/
|
||||
//virtual ::Oyster::Math::Float4x4 & GetView( ::Oyster::Math::Float4x4 &targetMem = ::Oyster::Math::Float4x4() ) const = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
|
@ -362,6 +340,18 @@ namespace Oyster
|
|||
********************************************************/
|
||||
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
|
||||
* whenever a collision occurs.
|
||||
|
@ -380,63 +370,64 @@ namespace Oyster
|
|||
********************************************************/
|
||||
virtual void SetGravityNormal( const ::Oyster::Math::Float3 &normalizedVector ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
* Use API::SetMomentOfInertiaTensor_KeepVelocity(...) instead
|
||||
********************************************************/
|
||||
virtual void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ) = 0;
|
||||
///********************************************************
|
||||
// * To not be called if is in Engine
|
||||
// * Use API::SetMomentOfInertiaTensor_KeepVelocity(...) instead
|
||||
// ********************************************************/
|
||||
//virtual void SetMomentOfInertiaTensor_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * To not be called if is in Engine
|
||||
// * Use API::SetMomentOfInertiaTensor_KeepMomentum(...)
|
||||
// ********************************************************/
|
||||
//virtual void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * To not be called if is in Engine
|
||||
// * Use API::SetMass_KeepVelocity(...)
|
||||
// ********************************************************/
|
||||
//virtual void SetMass_KeepVelocity( ::Oyster::Math::Float m ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * To not be called if is in Engine
|
||||
// * Use API::SetMass_KeepMomentum(...)
|
||||
// ********************************************************/
|
||||
//virtual void SetMass_KeepMomentum( ::Oyster::Math::Float m ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * To not be called if is in Engine
|
||||
// * Use API::SetCenter(...)
|
||||
// ********************************************************/
|
||||
//virtual void SetCenter( const ::Oyster::Math::Float3 &worldPos ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * To not be called if is in Engine
|
||||
// * Use API::SetRotation(...)
|
||||
// ********************************************************/
|
||||
//virtual void SetRotation( const ::Oyster::Math::Float4x4 &rotation ) = 0;
|
||||
//
|
||||
///********************************************************
|
||||
// * To not be called if is in Engine
|
||||
// * Use API::SetOrientation(...)
|
||||
// ********************************************************/
|
||||
//virtual void SetOrientation( const ::Oyster::Math::Float4x4 &orientation ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
* Use API::SetMomentOfInertiaTensor_KeepMomentum(...)
|
||||
********************************************************/
|
||||
virtual void SetMomentOfInertiaTensor_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ) = 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::SetMass_KeepVelocity(...)
|
||||
********************************************************/
|
||||
virtual void SetMass_KeepVelocity( ::Oyster::Math::Float m ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
* Use API::SetMass_KeepMomentum(...)
|
||||
********************************************************/
|
||||
virtual void SetMass_KeepMomentum( ::Oyster::Math::Float m ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
* Use API::SetCenter(...)
|
||||
********************************************************/
|
||||
virtual void SetCenter( const ::Oyster::Math::Float3 &worldPos ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
* Use API::SetRotation(...)
|
||||
********************************************************/
|
||||
virtual void SetRotation( const ::Oyster::Math::Float4x4 &rotation ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
* Use API::SetOrientation(...)
|
||||
********************************************************/
|
||||
virtual void SetOrientation( const ::Oyster::Math::Float4x4 &orientation ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
* Use API::SetSize(...)
|
||||
********************************************************/
|
||||
virtual void SetSize( const ::Oyster::Math::Float3 &size ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* To not be called if is in Engine
|
||||
* Use API::?? @todo TODO:
|
||||
********************************************************/
|
||||
virtual void SetMomentum( const ::Oyster::Math::Float3 &worldG ) = 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 "PhysicsFormula.h"
|
||||
|
||||
#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()
|
||||
{
|
||||
this->rotation = ::Oyster::Math::Float4x4::identity;
|
||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
||||
this->size = ::Oyster::Math::Float3( 1.0f );
|
||||
this->centerPosition = ::Oyster::Math::Float4::null;
|
||||
this->size = ::Oyster::Math::Float4( 1.0f );
|
||||
this->mass = 12.0f;
|
||||
this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
|
||||
this->subscription = NULL;
|
||||
|
@ -21,33 +21,77 @@ namespace Oyster { namespace Physics
|
|||
inline SphericalBodyDescription::SphericalBodyDescription()
|
||||
{
|
||||
this->rotation = ::Oyster::Math::Float4x4::identity;
|
||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
||||
this->centerPosition = ::Oyster::Math::Float4::null;
|
||||
this->radius = 0.5f;
|
||||
this->mass = 10.0f;
|
||||
this->subscription = NULL;
|
||||
this->ignoreGravity = false;
|
||||
}
|
||||
|
||||
|
||||
inline CustomBodyState::CustomBodyState( const ::Oyster::Math::Float3 &reach, const ::Oyster::Math::Float3 ¢erPos, const ::Oyster::Math::Float3 &rotation )
|
||||
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 )
|
||||
{
|
||||
this->reach = ::Oyster::Math::Float4( reach, 0.0f );
|
||||
this->centerPos = ::Oyster::Math::Float4( centerPos, 1.0f );
|
||||
this->angularAxis = ::Oyster::Math::Float4( rotation, 0.0f );
|
||||
this->isSpatiallyAltered = this->isDisturbed = false;
|
||||
this->mass = mass;
|
||||
this->restitutionCoeff = restitutionCoeff;
|
||||
this->staticFrictionCoeff = staticFrictionCoeff;
|
||||
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 )
|
||||
{
|
||||
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->centerPos = state.centerPos;
|
||||
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->isDisturbed = state.isDisturbed;
|
||||
this->isForwarded = state.isForwarded;
|
||||
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
|
||||
{
|
||||
return this->reach;
|
||||
|
@ -73,25 +117,116 @@ namespace Oyster { namespace Physics
|
|||
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 );
|
||||
}
|
||||
|
||||
inline void CustomBodyState::SetReach( const ::Oyster::Math::Float3 &halfSize )
|
||||
inline void CustomBodyState::SetReach( const ::Oyster::Math::Float4 &halfSize )
|
||||
{
|
||||
this->reach.xyz = halfSize;
|
||||
this->reach = ::Utility::Value::Max( this->reach, ::Oyster::Math::Float4::null );
|
||||
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->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->isSpatiallyAltered = this->isDisturbed = true;
|
||||
|
@ -99,7 +234,78 @@ namespace Oyster { namespace Physics
|
|||
|
||||
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
|
||||
|
@ -111,6 +317,11 @@ namespace Oyster { namespace Physics
|
|||
{
|
||||
return this->isDisturbed;
|
||||
}
|
||||
|
||||
inline bool CustomBodyState::IsForwarded() const
|
||||
{
|
||||
return this->isForwarded;
|
||||
}
|
||||
}
|
||||
} }
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ namespace Oyster { namespace Physics
|
|||
struct SimpleBodyDescription
|
||||
{
|
||||
::Oyster::Math::Float4x4 rotation;
|
||||
::Oyster::Math::Float3 centerPosition;
|
||||
::Oyster::Math::Float3 size;
|
||||
::Oyster::Math::Float4 centerPosition;
|
||||
::Oyster::Math::Float4 size;
|
||||
::Oyster::Math::Float mass;
|
||||
::Oyster::Math::Float4x4 inertiaTensor;
|
||||
::Oyster::Physics::ICustomBody::EventAction_Collision subscription;
|
||||
|
@ -24,7 +24,7 @@ namespace Oyster { namespace Physics
|
|||
struct SphericalBodyDescription
|
||||
{
|
||||
::Oyster::Math::Float4x4 rotation;
|
||||
::Oyster::Math::Float3 centerPosition;
|
||||
::Oyster::Math::Float4 centerPosition;
|
||||
::Oyster::Math::Float radius;
|
||||
::Oyster::Math::Float mass;
|
||||
::Oyster::Physics::ICustomBody::EventAction_Collision subscription;
|
||||
|
@ -36,31 +36,77 @@ namespace Oyster { namespace Physics
|
|||
struct CustomBodyState
|
||||
{
|
||||
public:
|
||||
CustomBodyState( const ::Oyster::Math::Float3 &reach = ::Oyster::Math::Float3::null,
|
||||
const ::Oyster::Math::Float3 ¢erPos = ::Oyster::Math::Float3::null,
|
||||
const ::Oyster::Math::Float3 &rotation = ::Oyster::Math::Float3::null );
|
||||
CustomBodyState( ::Oyster::Math::Float mass = 1.0f,
|
||||
::Oyster::Math::Float restitutionCoeff = 1.0f,
|
||||
::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 );
|
||||
|
||||
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;
|
||||
::Oyster::Math::Float4 GetSize() const;
|
||||
const ::Oyster::Math::Float4 & GetCenterPosition() const;
|
||||
const ::Oyster::Math::Float4 & GetAngularAxis() 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 SetReach( const ::Oyster::Math::Float3 &halfSize );
|
||||
void SetCenterPosition( const ::Oyster::Math::Float3 ¢erPos );
|
||||
void SetRotation( const ::Oyster::Math::Float3 &angularAxis );
|
||||
void SetMass_KeepMomentum( ::Oyster::Math::Float m );
|
||||
void SetMass_KeepVelocity( ::Oyster::Math::Float m );
|
||||
void SetRestitutionCoeff( ::Oyster::Math::Float e );
|
||||
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 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 IsDisturbed() const;
|
||||
bool IsForwarded() const;
|
||||
|
||||
private:
|
||||
::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, kineticFrictionCoeff;
|
||||
::Oyster::Math::Float4x4 inertiaTensor;
|
||||
::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) );
|
||||
}
|
||||
|
||||
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>
|
||||
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 );
|
||||
}
|
||||
|
||||
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>
|
||||
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>
|
||||
::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &sumDeltaAngularAxis, const ::LinearAlgebra::Vector3<ScalarType> &sumTranslation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||
{ /** @todo TODO: not tested */
|
||||
ScalarType radian = sumDeltaAngularAxis.Dot( sumDeltaAngularAxis );
|
||||
::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( 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 OrientationMatrix( sumDeltaAngularAxis / radian, radian, sumTranslation, targetMem );
|
||||
return OrientationMatrix( angularAxis / radian, radian, translation, targetMem );
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -534,9 +657,17 @@ namespace LinearAlgebra3D
|
|||
inline ::LinearAlgebra::Vector3<ScalarType> VectorProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &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>
|
||||
inline ::LinearAlgebra::Vector3<ScalarType> NormalProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &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"
|
||||
|
|
|
@ -91,11 +91,61 @@ namespace Oyster { namespace Math3D
|
|||
return ::LinearAlgebra3D::AngularAxis( rotationMatrix );
|
||||
}
|
||||
|
||||
Float4 ExtractAngularAxis( const Float4x4 &orientationMatrix )
|
||||
{
|
||||
return ::LinearAlgebra3D::ExtractAngularAxis( orientationMatrix );
|
||||
}
|
||||
|
||||
Float4x4 & TranslationMatrix( const Float3 &position, Float4x4 &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 )
|
||||
{
|
||||
return ::LinearAlgebra3D::RotationMatrix_AxisX( radian, targetMem );
|
||||
|
@ -147,9 +197,14 @@ namespace Oyster { namespace Math3D
|
|||
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 )
|
||||
|
@ -207,8 +262,18 @@ namespace Oyster { namespace Math3D
|
|||
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 )
|
||||
{
|
||||
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 <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::Vector3<Float> Float3; /// 3D Linear Vector for Oyster
|
||||
typedef ::LinearAlgebra::Vector4<Float> Float4; /// 4D 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::Vector4<Float> Float4; //!< 4D Linear Vector for Oyster
|
||||
|
||||
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2; /// 2x2 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::Matrix2x2<Float> Float2x2; //!< 2x2 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::Quaternion<Float> Quaternion; //!< Quaternion for Oyster
|
||||
|
||||
typedef Float4x4 Matrix; // 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;
|
||||
|
||||
/// 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
|
||||
//! 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
|
||||
bool IsSupported();
|
||||
|
||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||
/// Returns false if there is no explicit solution.
|
||||
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||
//! Returns false if there is no explicit solution.
|
||||
bool SuperpositionMatrix( const Float2x2 &in, const Float2x2 &out, Float2x2 &targetMem );
|
||||
|
||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||
/// Returns false if there is no explicit solution.
|
||||
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||
//! Returns false if there is no explicit solution.
|
||||
bool SuperpositionMatrix( const Float3x3 &in, const Float3x3 &out, Float3x3 &targetMem );
|
||||
|
||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||
/// Returns false if there is no explicit solution.
|
||||
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||
//! Returns false if there is no explicit solution.
|
||||
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 )
|
||||
{ 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
|
||||
|
||||
/// 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.
|
||||
//! 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.
|
||||
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.
|
||||
/// Recommended too make sure that yAxis is normalized.
|
||||
//! 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.
|
||||
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() );
|
||||
|
||||
/// Sets and returns targetMem as a counterclockwise rotationMatrix
|
||||
//! Sets and returns targetMem as a counterclockwise rotationMatrix
|
||||
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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// Sets and returns targetMem as an orientation Matrix that is rotated around localCenterOfRotation and then translated with position.
|
||||
/// TODO: not tested
|
||||
//! Sets and returns targetMem as an orientation Matrix that is rotated around localCenterOfRotation and then translated with position.
|
||||
//! TODO: not tested
|
||||
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() );
|
||||
|
||||
/// 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() );
|
||||
} }
|
||||
|
||||
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
|
||||
|
||||
|
@ -153,35 +155,65 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
|||
//! Extracts the angularAxis from 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the normalizedAxis.
|
||||
/// Please make sure normalizedAxis is normalized.
|
||||
//! Sets and returns targetMem as an counterclockwise rotation matrix around the normalizedAxis.
|
||||
//! Please make sure normalizedAxis is normalized.
|
||||
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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/// 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() );
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -191,19 +223,26 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
|||
* @param sumTranslation: sum of all the translation vectors.
|
||||
* @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates.
|
||||
* @return targetMem
|
||||
* @todo TODO: not tested
|
||||
*******************************************************************/
|
||||
Float4x4 & OrientationMatrix( const Float3 &normalizedAxis, const Float & deltaRadian, const Float3 &sumTranslation, Float4x4 &targetMem = Float4x4() );
|
||||
|
||||
/*******************************************************************
|
||||
* 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 sumTranslation: sum of all the translation vectors.
|
||||
* @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
|
||||
* @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
|
||||
|
@ -228,14 +267,14 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
|||
//! @todo TODO: Add documentation and not tested
|
||||
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() );
|
||||
|
||||
// O0 = T0 * R0
|
||||
// O1 = T1 * T0 * R1 * R0
|
||||
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() );
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -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() );
|
||||
|
||||
/// 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 );
|
||||
|
||||
/// 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 );
|
||||
|
||||
/// 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() )
|
||||
{ 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 )
|
||||
{ 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() )
|
||||
{ return targetMem = transformer * transformee; }
|
||||
} }
|
||||
|
|
|
@ -22,8 +22,10 @@ namespace LinearAlgebra
|
|||
char byte[sizeof(ScalarType[2])];
|
||||
};
|
||||
|
||||
static const Quaternion<ScalarType> null;
|
||||
static const Quaternion<ScalarType> identity;
|
||||
|
||||
Quaternion( );
|
||||
Quaternion( const Quaternion &quaternion );
|
||||
Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real );
|
||||
|
||||
operator ScalarType* ( );
|
||||
|
@ -53,40 +55,54 @@ namespace LinearAlgebra
|
|||
// 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>
|
||||
Quaternion<ScalarType>::Quaternion( ) : imaginary(), real() {}
|
||||
|
||||
template<typename ScalarType>
|
||||
Quaternion<ScalarType>::Quaternion( const Quaternion &quaternion )
|
||||
{ this->imaginary = quaternion.imaginary; this->real = quaternion.real; }
|
||||
|
||||
template<typename ScalarType>
|
||||
Quaternion<ScalarType>::Quaternion( const Vector3<ScalarType> &_imaginary, const ScalarType &_real )
|
||||
{ this->imaginary = _imaginary; this->real = _real; }
|
||||
Quaternion<ScalarType>::Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real )
|
||||
{
|
||||
this->imaginary = imaginary;
|
||||
this->real = real;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType>::operator ScalarType* ( )
|
||||
{ return this->element; }
|
||||
{
|
||||
return this->element;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType>::operator const ScalarType* ( ) const
|
||||
{ return this->element; }
|
||||
{
|
||||
return this->element;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType>::operator char* ( )
|
||||
{ return this->byte; }
|
||||
{
|
||||
return this->byte;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType>::operator const char* ( ) const
|
||||
{ return this->byte; }
|
||||
{
|
||||
return this->byte;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline ScalarType & Quaternion<ScalarType>::operator [] ( int i )
|
||||
{ return this->element[i]; }
|
||||
{
|
||||
return this->element[i];
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline const ScalarType & Quaternion<ScalarType>::operator [] ( int i ) const
|
||||
{ return this->element[i]; }
|
||||
{
|
||||
return this->element[i];
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
Quaternion<ScalarType> & Quaternion<ScalarType>::operator = ( const Quaternion<ScalarType> &quaternion )
|
||||
|
@ -154,27 +170,39 @@ namespace LinearAlgebra
|
|||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const ScalarType &scalar ) const
|
||||
{ return Quaternion<ScalarType>(*this) *= scalar; }
|
||||
{
|
||||
return Quaternion<ScalarType>(*this) *= scalar;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator / ( const ScalarType &scalar ) const
|
||||
{ return Quaternion<ScalarType>(*this) /= scalar; }
|
||||
{
|
||||
return Quaternion<ScalarType>(*this) /= scalar;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator + ( const Quaternion<ScalarType> &quaternion ) const
|
||||
{ return Quaternion<ScalarType>(*this) += quaternion; }
|
||||
{
|
||||
return Quaternion<ScalarType>(*this) += quaternion;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( const Quaternion<ScalarType> &quaternion ) const
|
||||
{ return Quaternion<ScalarType>(*this) -= quaternion; }
|
||||
{
|
||||
return Quaternion<ScalarType>(*this) -= quaternion;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( ) const
|
||||
{ return Quaternion<ScalarType>(-this->imaginary, -this->real); }
|
||||
{
|
||||
return Quaternion<ScalarType>(-this->imaginary, -this->real);
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::GetConjugate( ) const
|
||||
{ return Quaternion<ScalarType>(-this->imaginary, this->real ); }
|
||||
{
|
||||
return Quaternion<ScalarType>(-this->imaginary, this->real );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -16,10 +16,17 @@ Box::Box( ) : 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->center = p;
|
||||
this->boundingOffset = Float3(s*0.5);
|
||||
this->boundingOffset = s * 0.5f;
|
||||
}
|
||||
|
||||
Box::~Box( ) {}
|
||||
|
@ -42,13 +49,32 @@ bool Box::Intersects( const ICollideable &target ) const
|
|||
switch( target.type )
|
||||
{
|
||||
case Type_universe: return true;
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
||||
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target );
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||
case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
|
||||
// case Type_triangle: return false; // TODO: :
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target );
|
||||
case Type_box: return Utility::Intersect( *this, *(Box*)&target );
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *this, (const BoxAxisAligned&)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: :
|
||||
default: return false;
|
||||
}
|
||||
|
@ -58,12 +84,12 @@ bool Box::Contains( const ICollideable &target ) const
|
|||
{
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
// case Type_sphere: return false; // TODO:
|
||||
// case Type_triangle: return false; // TODO:
|
||||
// case Type_box_axis_aligned: return false; // TODO:
|
||||
// case Type_box: return false; // TODO:
|
||||
// case Type_frustrum: return false; // TODO:
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
//case Type_sphere: return false; // TODO:
|
||||
//case Type_triangle: return false; // TODO:
|
||||
//case Type_box_axis_aligned: return false; // TODO:
|
||||
//case Type_box: return false; // TODO:
|
||||
//case Type_frustrum: return false; // TODO:
|
||||
default: return false;
|
||||
}
|
||||
}
|
|
@ -16,24 +16,26 @@ namespace Oyster { namespace Collision3D
|
|||
public:
|
||||
union
|
||||
{
|
||||
struct{ ::Oyster::Math::Float4x4 rotation; ::Oyster::Math::Float3 center, boundingOffset; };
|
||||
struct{ ::Oyster::Math::Float4x4 rotation; ::Oyster::Math::Float4 center, boundingOffset; };
|
||||
struct
|
||||
{
|
||||
::Oyster::Math::Float3 xAxis; ::Oyster::Math::Float paddingA;
|
||||
::Oyster::Math::Float3 yAxis; ::Oyster::Math::Float paddingB;
|
||||
::Oyster::Math::Float3 zAxis; ::Oyster::Math::Float paddingC;
|
||||
::Oyster::Math::Float4 xAxis;
|
||||
::Oyster::Math::Float4 yAxis;
|
||||
::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( 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( );
|
||||
|
||||
Box & operator = ( const Box &box );
|
||||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) 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 );
|
||||
}
|
||||
|
||||
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->maxVertex = _maxVertex;
|
||||
this->minVertex = Float4( minVertex, 1.0f );
|
||||
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)
|
||||
{
|
||||
this->minVertex = Float3( leftClip, bottomClip, nearClip );
|
||||
this->maxVertex = Float3( rightClip, topClip, farClip );
|
||||
this->minVertex = Float4( leftClip, bottomClip, nearClip, 1.0f );
|
||||
this->maxVertex = Float4( rightClip, topClip, farClip, 1.0f );
|
||||
}
|
||||
|
||||
BoxAxisAligned::~BoxAxisAligned( ) {}
|
||||
|
@ -45,28 +45,35 @@ bool BoxAxisAligned::Intersects( const ICollideable &target ) const
|
|||
switch( target.type )
|
||||
{
|
||||
case Type_universe: return true;
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
||||
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target );
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||
case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
|
||||
// case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target );
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *this, (const BoxAxisAligned&)target );
|
||||
// case Type_box: return false; // TODO:
|
||||
// case Type_frustrum: return false; // TODO:
|
||||
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
|
||||
{
|
||||
switch( target.type )
|
||||
{
|
||||
// case Type_point: return false; // TODO:
|
||||
// case Type_sphere: return false; // TODO:
|
||||
// case Type_triangle: return false; // TODO:
|
||||
// case Type_box_axis_aligned: return false; // TODO:
|
||||
// case Type_box: return false; // TODO:
|
||||
// case Type_frustrum: return false; // TODO:
|
||||
default: return false;
|
||||
}
|
||||
//switch( target.type )
|
||||
//{
|
||||
////case Type_point: return false; // TODO:
|
||||
////case Type_sphere: return false; // TODO:
|
||||
////case Type_triangle: return false; // TODO:
|
||||
////case Type_box_axis_aligned: return false; // TODO:
|
||||
////case Type_box: return false; // TODO:
|
||||
////case Type_frustrum: return false; // TODO:
|
||||
//default: return false;
|
||||
//}
|
||||
return false;
|
||||
}
|
|
@ -16,8 +16,8 @@ namespace Oyster { namespace Collision3D
|
|||
public:
|
||||
union
|
||||
{
|
||||
struct{ ::Oyster::Math::Float3 minVertex, maxVertex; };
|
||||
char byte[2*sizeof(::Oyster::Math::Float3)];
|
||||
struct{ ::Oyster::Math::Float4 minVertex, maxVertex; };
|
||||
char byte[2*sizeof(::Oyster::Math::Float4)];
|
||||
};
|
||||
|
||||
BoxAxisAligned( );
|
||||
|
@ -29,6 +29,7 @@ namespace Oyster { namespace Collision3D
|
|||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
};
|
||||
} }
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include "Frustrum.h"
|
||||
#include "OysterCollision3D.h"
|
||||
|
||||
using namespace Oyster::Math;
|
||||
using namespace Oyster::Collision3D;
|
||||
using namespace ::Oyster::Math;
|
||||
using namespace ::Oyster::Collision3D;
|
||||
|
||||
namespace PrivateStatic
|
||||
{
|
||||
|
@ -76,12 +76,12 @@ namespace PrivateStatic
|
|||
|
||||
Frustrum::Frustrum() : ICollideable(Type_frustrum)
|
||||
{
|
||||
this->leftPlane = Plane( Float3::standard_unit_x, -0.5f );
|
||||
this->rightPlane = Plane(-Float3::standard_unit_x, 0.5f ),
|
||||
this->bottomPlane = Plane( Float3::standard_unit_y, -0.5f );
|
||||
this->topPlane = Plane(-Float3::standard_unit_y, 0.5f );
|
||||
this->nearPlane = Plane( Float3::standard_unit_z, -0.5f );
|
||||
this->farPlane = Plane(-Float3::standard_unit_z, 0.5f );
|
||||
this->leftPlane = Plane( Float4::standard_unit_x, -0.5f );
|
||||
this->rightPlane = Plane(-Float4::standard_unit_x, 0.5f ),
|
||||
this->bottomPlane = Plane( Float4::standard_unit_y, -0.5f );
|
||||
this->topPlane = Plane(-Float4::standard_unit_y, 0.5f );
|
||||
this->nearPlane = Plane( Float4::standard_unit_z, -0.5f );
|
||||
this->farPlane = Plane(-Float4::standard_unit_z, 0.5f );
|
||||
}
|
||||
|
||||
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
|
||||
{ return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Frustrum(*this) ); }
|
||||
{
|
||||
return ::Utility::DynamicMemory::UniquePointer<ICollideable>( new Frustrum(*this) );
|
||||
}
|
||||
|
||||
bool Frustrum::Intersects( const ICollideable &target ) const
|
||||
{
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_universe: return true;
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
||||
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target );
|
||||
// case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *this, *(BoxAxisAligned*)&target );
|
||||
case Type_box: return Utility::Intersect( *this, *(Box*)&target );
|
||||
case Type_frustrum: return Utility::Intersect( *this, *(Frustrum*)&target );
|
||||
// case Type_line: return false; // TODO:
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||
case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
|
||||
//case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *this, (const BoxAxisAligned&)target );
|
||||
case Type_box: return Utility::Intersect( *this, (const Box&)target );
|
||||
case Type_frustrum: return Utility::Intersect( *this, (const Frustrum&)target );
|
||||
//case Type_line: return false; // TODO:
|
||||
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
|
||||
{
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
// case Type_ray: return false; // TODO:
|
||||
// case Type_sphere: return false; // TODO:
|
||||
// case Type_plane: return false; // TODO:
|
||||
// case Type_triangle: return false; // TODO:
|
||||
// case Type_box_axis_aligned: return false; // TODO:
|
||||
// case Type_box: return false; // TODO:
|
||||
// case Type_frustrum: return false; // TODO:
|
||||
// case Type_line: return false; // TODO:
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
//case Type_ray: return false; // TODO:
|
||||
//case Type_sphere: return false; // TODO:
|
||||
//case Type_plane: return false; // TODO:
|
||||
//case Type_triangle: return false; // TODO:
|
||||
//case Type_box_axis_aligned: return false; // TODO:
|
||||
//case Type_box: return false; // TODO:
|
||||
//case Type_frustrum: return false; // TODO:
|
||||
//case Type_line: return false; // TODO:
|
||||
default: return false;
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ namespace Oyster { namespace Collision3D
|
|||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef OYSTER_COLLISION_3D_ICOLLIDEABLE_H
|
||||
#define OYSTER_COLLISION_3D_ICOLLIDEABLE_H
|
||||
|
||||
#include "OysterMath.h"
|
||||
#include "Utilities.h"
|
||||
|
||||
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 ::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 Contains( const ICollideable &target ) const = 0;
|
||||
};
|
||||
|
|
|
@ -46,8 +46,29 @@ bool Line::Intersects( const ICollideable &target ) const
|
|||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return false;
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace Oyster { namespace Collision3D
|
|||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
};
|
||||
} }
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
}
|
||||
|
||||
// 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
|
||||
Float e = axis.Dot( deltaPos ),
|
||||
f = axis.Dot( rayDirection );
|
||||
|
@ -51,12 +51,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
return false;
|
||||
}
|
||||
|
||||
inline bool Contains( const Plane &container, const Float3 &pos )
|
||||
inline bool Contains( const Plane &container, const Float4 &pos )
|
||||
{ // by Dan Andersson
|
||||
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
|
||||
connectOffset = plane.normal.Dot(pos);
|
||||
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 )
|
||||
{ // 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
|
||||
boxExtend = h.x * Abs(plane.normal.x); // Box max extending towards plane
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
/*****************************************************************
|
||||
|
@ -103,37 +103,37 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
Float3 absWorldOffset = Abs(worldOffset); // |t|: [absWorldOffset]
|
||||
|
||||
// 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}|
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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}|
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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}|
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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
|
||||
return false;
|
||||
}
|
||||
|
@ -203,13 +203,187 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
|
||||
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 //////////////////////////////////////////////////////
|
||||
|
||||
void Compare( Float &connectDistance, Float &connectOffsetSquared, const Ray &ray, const Point &point )
|
||||
{ // by Dan Andersson
|
||||
Float3 dP = point.center - ray.origin;
|
||||
Float4 dP = point.center - ray.origin;
|
||||
|
||||
connectDistance = dP.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 )
|
||||
{ // by Dan Andersson
|
||||
Float3 dP = rayB.origin - rayA.origin;
|
||||
Float4 dP = rayB.origin - rayA.origin;
|
||||
connectDistanceA = rayA.direction.Dot( dP );
|
||||
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
|
||||
}
|
||||
|
||||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float connectOffsetSquared;
|
||||
|
@ -264,6 +444,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float connectOffsetSquared;
|
||||
|
@ -279,6 +465,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float3 dP = point.center - sphere.center;
|
||||
|
@ -287,9 +479,15 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{// by Dan Andersson
|
||||
Float3 dP = sphere.center - ray.origin;
|
||||
Float4 dP = sphere.center - ray.origin;
|
||||
Float s = dP.Dot( ray.direction ),
|
||||
dSquared = dP.Dot( dP ),
|
||||
rSquared = sphere.radius * sphere.radius;
|
||||
|
@ -307,9 +505,15 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Fredrick Johansson
|
||||
Float3 C = sphereA.center;
|
||||
Float4 C = sphereA.center;
|
||||
C -= sphereB.center;
|
||||
Float r = (sphereA.radius + sphereB.radius);
|
||||
|
||||
|
@ -321,6 +525,27 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float connectOffset;
|
||||
|
@ -328,6 +553,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float c = plane.normal.Dot(ray.direction);
|
||||
|
@ -348,6 +579,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float connectOffset;
|
||||
|
@ -355,6 +592,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
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
|
||||
}
|
||||
|
||||
bool Intersect( const Plane &planeA, const Plane &planeB, Float4 &worldPointOfContact )
|
||||
{
|
||||
//! @todo TODO: implement Stub
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Intersect( const BoxAxisAligned &box, const Point &point )
|
||||
{ // by Dan Andersson
|
||||
if( point.center.x < box.minVertex.x ) return false;
|
||||
|
@ -375,31 +624,66 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float tMin = ::std::numeric_limits<Float>::max(),
|
||||
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;
|
||||
if( Private::BoxVsRayPerSlabCheck( Float3::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( Float3::standard_unit_z, boundingOffset.z, 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( Float4::standard_unit_y, boundingOffset.y, 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;
|
||||
else connectDistance = tMax;
|
||||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float4 e = Max( Float4(box.minVertex - sphere.center, 0.0f), Float4::null );
|
||||
e += Max( Float4(sphere.center - box.maxVertex, 0.0f), Float4::null );
|
||||
Float4 e = Max( box.minVertex - sphere.center, Float4::null );
|
||||
e += Max( sphere.center - box.maxVertex, Float4::null );
|
||||
|
||||
if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
|
||||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float e, d;
|
||||
|
@ -409,6 +693,12 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
// { return false; /* TODO: */ }
|
||||
|
||||
|
@ -425,7 +715,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
|
||||
bool Intersect( const Box &box, const Point &point )
|
||||
{ // by Dan Andersson
|
||||
Float3 dPos = point.center - box.center;
|
||||
Float4 dPos = point.center - box.center;
|
||||
|
||||
Float coordinate = dPos.Dot( box.xAxis );
|
||||
if( coordinate > box.boundingOffset.x ) return false;
|
||||
|
@ -442,12 +732,22 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float tMin = ::std::numeric_limits<Float>::max(),
|
||||
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.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; }
|
||||
|
@ -457,18 +757,43 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
// 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 );
|
||||
e += Max( center - Float4(box.boundingOffset, 0.0f), Float4::null );
|
||||
Float4 e = Max( -box.boundingOffset - center, Float4::null );
|
||||
e += Max( center - box.boundingOffset, Float4::null );
|
||||
|
||||
if( e.Dot(e) > (sphere.radius * sphere.radius) ) return false;
|
||||
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 )
|
||||
{// by Dan Andersson
|
||||
Float e, d;
|
||||
|
@ -478,22 +803,53 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float3 alignedOffsetBoundaries = (boxB.maxVertex - boxB.minVertex) * 0.5f,
|
||||
offset = boxA.center - Average( boxB.minVertex, boxB.maxVertex );
|
||||
Float4 alignedOffsetBoundaries = (boxB.maxVertex - boxB.minVertex) * 0.5f,
|
||||
offset = boxA.center- Average( boxB.maxVertex, boxB.minVertex );
|
||||
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 )
|
||||
{ // by Dan Andersson
|
||||
Float4x4 orientationA = OrientationMatrix(boxA.rotation, boxA.center),
|
||||
orientationB = OrientationMatrix(boxB.rotation, boxB.center),
|
||||
invOrientationA = InverseOrientationMatrix( orientationA );
|
||||
Float4x4 rotationB = TransformMatrix( InverseRotationMatrix(boxA.rotation), boxB.rotation );
|
||||
Float4 posB = boxB.center - boxA.center;
|
||||
|
||||
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 )
|
||||
|
|
|
@ -25,18 +25,28 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
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, ::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, ::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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
|
||||
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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
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, ::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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
|
||||
// bool Intersect( const Triangle &triangle, const Point &point, ? );
|
||||
// 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 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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
// bool Intersect( const BoxAxisAligned &box, const Triangle &triangle );
|
||||
bool Intersect( const BoxAxisAligned &boxA, const BoxAxisAligned &boxB );
|
||||
|
||||
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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
// bool Intersect( const Box &box, const Triangle &triangle, ? );
|
||||
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, ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
|
||||
bool Intersect( const Frustrum &frustrum, const Point &point );
|
||||
bool Intersect( const Frustrum &frustrum, const Ray &ray, ::Oyster::Math::Float &connectDistance );
|
||||
|
|
|
@ -12,6 +12,60 @@ namespace Oyster { namespace Physics3D
|
|||
namespace Formula
|
||||
{ /// 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.
|
||||
* @todo TODO: improve doc
|
||||
|
@ -138,6 +192,15 @@ namespace Oyster { namespace Physics3D
|
|||
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.
|
||||
* @todo TODO: improve doc
|
||||
|
@ -183,6 +246,15 @@ namespace Oyster { namespace Physics3D
|
|||
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
|
||||
* @todo TODO: improve doc
|
||||
|
@ -192,10 +264,13 @@ namespace Oyster { namespace Physics3D
|
|||
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 ::Oyster::Math::Float3::null;
|
||||
return momentOfInertia * angularImpulseAcceleration;
|
||||
}
|
||||
|
||||
namespace MomentOfInertia
|
||||
|
|
|
@ -163,6 +163,7 @@
|
|||
<ClInclude Include="Point.h" />
|
||||
<ClInclude Include="Ray.h" />
|
||||
<ClInclude Include="RigidBody.h" />
|
||||
<ClInclude Include="RigidBody_Inline.h" />
|
||||
<ClInclude Include="Sphere.h" />
|
||||
<ClInclude Include="Spring.h" />
|
||||
<ClInclude Include="Universe.h" />
|
||||
|
|
|
@ -75,6 +75,9 @@
|
|||
<ClInclude Include="RigidBody.h">
|
||||
<Filter>Header Files\Physics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RigidBody_Inline.h">
|
||||
<Filter>Header Files\Physics</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Box.cpp">
|
||||
|
|
|
@ -34,7 +34,7 @@ Particle & Particle::operator = ( const Particle &particle )
|
|||
void Particle::Update_LeapFrog( Float deltaTime )
|
||||
{ // Euler leap frog update when Runga Kutta is not needed
|
||||
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->impulseForceSum = Float3::null;
|
||||
|
||||
|
@ -66,12 +66,12 @@ void Particle::ApplyLinearImpulseAcceleration( const Float3 &a )
|
|||
|
||||
Float3 & Particle::AccessCenter()
|
||||
{
|
||||
return this->sphere.center;
|
||||
return this->sphere.center.xyz;
|
||||
}
|
||||
|
||||
const Float3 & Particle::AccessCenter() const
|
||||
{
|
||||
return this->sphere.center;
|
||||
return this->sphere.center.xyz;
|
||||
}
|
||||
|
||||
Float & Particle::AccessRadius()
|
||||
|
@ -91,7 +91,7 @@ const Float & Particle::GetMass() const
|
|||
|
||||
const Float3 & Particle::GetCenter() const
|
||||
{
|
||||
return this->sphere.center;
|
||||
return this->sphere.center.xyz;
|
||||
}
|
||||
|
||||
const Float & Particle::GetRadius() const
|
||||
|
|
|
@ -10,11 +10,11 @@ using namespace ::Oyster::Math;
|
|||
|
||||
Plane::Plane( ) : ICollideable(Type_plane)
|
||||
{
|
||||
this->normal = Float3::standard_unit_z;
|
||||
this->normal = Float4::standard_unit_z;
|
||||
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->phasing = p;
|
||||
|
@ -30,34 +30,57 @@ Plane & Plane::operator = ( const Plane &plane )
|
|||
}
|
||||
|
||||
::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
|
||||
{
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_universe: return true;
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
||||
case Type_plane: return Utility::Intersect( *this, *(Plane*)&target );
|
||||
// case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this );
|
||||
case Type_box: return Utility::Intersect( *(Box*)&target, *this );
|
||||
case Type_frustrum: return false; // TODO:
|
||||
case Type_line: return false; // TODO:
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||
case Type_plane: return Utility::Intersect( *this, (const Plane&)target );
|
||||
//case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
|
||||
case Type_box: return Utility::Intersect( (const Box&)target, *this );
|
||||
//case Type_frustrum: return false; // TODO:
|
||||
//case Type_line: return false; // TODO:
|
||||
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
|
||||
{
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
case Type_ray: return Utility::Contains( *this, *(Ray*)&target );
|
||||
case Type_plane: return Utility::Contains( *this, *(Plane*)&target );
|
||||
// case Type_triangle: return false; // TODO:
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
case Type_ray: return Utility::Contains( *this, (const Ray&)target );
|
||||
case Type_plane: return Utility::Contains( *this, (const Plane&)target );
|
||||
//case Type_triangle: return false; // TODO:
|
||||
default: return false;
|
||||
}
|
||||
}
|
|
@ -16,19 +16,20 @@ namespace Oyster { namespace Collision3D
|
|||
public:
|
||||
union
|
||||
{
|
||||
struct{ ::Oyster::Math::Float3 normal; ::Oyster::Math::Float phasing; };
|
||||
::Oyster::Math::Float element[4];
|
||||
char byte[sizeof(::Oyster::Math::Float3) + sizeof(::Oyster::Math::Float)];
|
||||
struct{ ::Oyster::Math::Float4 normal; ::Oyster::Math::Float phasing; };
|
||||
::Oyster::Math::Float element[5];
|
||||
char byte[sizeof(::Oyster::Math::Float4) + sizeof(::Oyster::Math::Float)];
|
||||
};
|
||||
|
||||
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( );
|
||||
|
||||
Plane & operator = ( const Plane &plane );
|
||||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
};
|
||||
} }
|
||||
|
|
|
@ -10,10 +10,15 @@ using namespace ::Oyster::Math3D;
|
|||
|
||||
Point::Point( ) : ICollideable(Type_point)
|
||||
{
|
||||
this->center = Float3::null;
|
||||
this->center = Float4::standard_unit_w;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -36,23 +41,44 @@ bool Point::Intersects( const ICollideable &target ) const
|
|||
switch( target.type )
|
||||
{
|
||||
case Type_universe: return true;
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
case Type_ray: return Utility::Intersect( *(Ray*)&target, *this, ((Ray*)&target)->collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this );
|
||||
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this );
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
case Type_ray: return Utility::Intersect( (const Ray&)target, *this, ((const Ray&)target).collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this );
|
||||
case Type_plane: return Utility::Intersect( (const Plane&)target, *this );
|
||||
//case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this );
|
||||
case Type_box: return Utility::Intersect( *(Box*)&target, *this );
|
||||
case Type_frustrum: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
|
||||
case Type_box: return Utility::Intersect( (const Box&)target, *this );
|
||||
//case Type_frustrum: return false; // TODO:
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -16,18 +16,20 @@ namespace Oyster { namespace Collision3D
|
|||
public:
|
||||
union
|
||||
{
|
||||
struct{ ::Oyster::Math::Float3 center; };
|
||||
char byte[sizeof(::Oyster::Math::Float3)];
|
||||
struct{ ::Oyster::Math::Float4 center; };
|
||||
char byte[sizeof(::Oyster::Math::Float4)];
|
||||
};
|
||||
|
||||
Point( );
|
||||
Point( const ::Oyster::Math::Float3 &position );
|
||||
Point( const ::Oyster::Math::Float4 &position );
|
||||
virtual ~Point( );
|
||||
|
||||
Point & operator = ( const Point &point );
|
||||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
};
|
||||
} }
|
||||
|
|
|
@ -10,12 +10,19 @@ using namespace ::Oyster::Math3D;
|
|||
|
||||
Ray::Ray( ) : ICollideable(Type_ray)
|
||||
{
|
||||
this->origin = Float3::null;
|
||||
this->direction = Float3::standard_unit_z;
|
||||
this->origin = Float4::standard_unit_w;
|
||||
this->direction = Float4::standard_unit_z;
|
||||
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->direction = d;
|
||||
|
@ -43,24 +50,46 @@ bool Ray::Intersects( const ICollideable &target ) const
|
|||
case Type_universe:
|
||||
this->collisionDistance = 0.0f;
|
||||
return true;
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target, this->collisionDistance );
|
||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, this->collisionDistance, ((Ray*)&target)->collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *(Sphere*)&target, *this, this->collisionDistance );
|
||||
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this, this->collisionDistance );
|
||||
// case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this, this->collisionDistance );
|
||||
case Type_box: return Utility::Intersect( *(Box*)&target, *this, this->collisionDistance );
|
||||
case Type_frustrum: return false; // TODO:
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target, this->collisionDistance );
|
||||
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, this->collisionDistance, ((const Ray&)target).collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( (const Sphere&)target, *this, this->collisionDistance );
|
||||
case Type_plane: return Utility::Intersect( (const Plane&)target, *this, this->collisionDistance );
|
||||
//case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this, this->collisionDistance );
|
||||
case Type_box: return Utility::Intersect( (const Box&)target, *this, this->collisionDistance );
|
||||
//case Type_frustrum: return false; // TODO:
|
||||
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
|
||||
{
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target, this->collisionDistance );
|
||||
case Type_ray: return Utility::Contains( *this, *(Ray*)&target );
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target, this->collisionDistance );
|
||||
case Type_ray: return Utility::Contains( *this, (const Ray&)target );
|
||||
default: return false;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
#ifndef OYSTER_COLLISION_3D_RAY_H
|
||||
#define OYSTER_COLLISION_3D_RAY_H
|
||||
|
||||
#include "OysterMath.h"
|
||||
#include "ICollideable.h"
|
||||
|
||||
namespace Oyster { namespace Collision3D
|
||||
|
@ -22,21 +21,23 @@ namespace Oyster { namespace Collision3D
|
|||
{
|
||||
struct
|
||||
{
|
||||
::Oyster::Math::Float3 origin,
|
||||
::Oyster::Math::Float4 origin,
|
||||
direction; /// Assumed to be normalized
|
||||
};
|
||||
char byte[2*sizeof(::Oyster::Math::Float3)];
|
||||
char byte[2*sizeof(::Oyster::Math::Float4)];
|
||||
};
|
||||
mutable float collisionDistance;
|
||||
|
||||
Ray( );
|
||||
Ray( const ::Oyster::Math::Float3 &origin, const ::Oyster::Math::Float3 &normalizedDirection );
|
||||
Ray( const ::Oyster::Math::Float4 &origin, const ::Oyster::Math::Float4 &normalizedDirection );
|
||||
virtual ~Ray( );
|
||||
|
||||
Ray & operator = ( const Ray &ray );
|
||||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
};
|
||||
} }
|
||||
|
|
|
@ -8,413 +8,224 @@
|
|||
using namespace ::Oyster::Collision3D;
|
||||
using namespace ::Oyster::Physics3D;
|
||||
using namespace ::Oyster::Math3D;
|
||||
using namespace ::Utility::Value;
|
||||
|
||||
RigidBody::RigidBody( const Box &b, Float m, const Float4x4 &inertiaTensor )
|
||||
RigidBody::RigidBody( )
|
||||
{ // by Dan Andersson
|
||||
this->box = b;
|
||||
this->angularMomentum = Float3::null;
|
||||
this->linearMomentum = Float3::null;
|
||||
this->impulseTorqueSum = Float3::null;
|
||||
this->impulseForceSum = Float3::null;
|
||||
|
||||
if( m != 0.0f )
|
||||
{
|
||||
this->mass = m;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->mass = ::Utility::Value::numeric_limits<Float>::epsilon();
|
||||
}
|
||||
|
||||
if( inertiaTensor.GetDeterminant() != 0.0f )
|
||||
{
|
||||
this->momentOfInertiaTensor = inertiaTensor;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->centerPos = Float4::standard_unit_w;
|
||||
this->axis = Float4::null;
|
||||
this->boundingReach = Float4( 0.5f, 0.5f, 0.5f, 0.0f );
|
||||
this->momentum_Linear = Float4::null;
|
||||
this->momentum_Angular = Float4::null;
|
||||
this->impulse_Linear = Float4::null;
|
||||
this->impulse_Angular = Float4::null;
|
||||
this->restitutionCoeff = 1.0f;
|
||||
this->frictionCoeff_Static = 0.5f;
|
||||
this->frictionCoeff_Kinetic = 1.0f;
|
||||
this->mass = 10;
|
||||
this->momentOfInertiaTensor = Float4x4::identity;
|
||||
}
|
||||
this->rotation = Quaternion::identity;
|
||||
}
|
||||
|
||||
RigidBody & RigidBody::operator = ( const RigidBody &body )
|
||||
{ // by Dan Andersson
|
||||
this->box = body.box;
|
||||
this->angularMomentum = body.angularMomentum;
|
||||
this->linearMomentum = body.linearMomentum;
|
||||
this->impulseTorqueSum = body.impulseTorqueSum;
|
||||
this->impulseForceSum = body.impulseForceSum;
|
||||
this->centerPos = body.centerPos;
|
||||
this->axis = body.axis;
|
||||
this->boundingReach = body.boundingReach;
|
||||
this->momentum_Linear = body.momentum_Linear;
|
||||
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->momentOfInertiaTensor = body.momentOfInertiaTensor;
|
||||
this->rotation = body.rotation;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool RigidBody::operator == ( const RigidBody &body )
|
||||
{
|
||||
if( this->box.center != body.box.center )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->box.rotation != body.box.rotation )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->box.boundingOffset != body.box.boundingOffset )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->angularMomentum != body.angularMomentum )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->linearMomentum != body.linearMomentum )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->impulseTorqueSum != body.impulseTorqueSum )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->impulseForceSum != body.impulseForceSum )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RigidBody::operator != ( const RigidBody &body )
|
||||
{
|
||||
return !this->operator==( body );
|
||||
}
|
||||
|
||||
void RigidBody::Update_LeapFrog( Float deltaTime )
|
||||
void RigidBody::Update_LeapFrog( Float updateFrameLength )
|
||||
{ // 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
|
||||
// dG = F * dt
|
||||
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
|
||||
Float3 linearImpulse = this->impulseForceSum * deltaTime; // aka deltaLinearMomentum
|
||||
Float3 deltaPos = ( deltaTime / this->mass ) * ::Utility::Value::AverageWithDelta( this->linearMomentum, linearImpulse );
|
||||
this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
|
||||
|
||||
// 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
|
||||
Float3 angularImpulse = this->impulseTorqueSum * deltaTime; // aka deltaAngularMomentum
|
||||
Float3 rotationAxis = Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(),
|
||||
::Utility::Value::AverageWithDelta(this->angularMomentum, angularImpulse) );
|
||||
this->axis += Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, this->impulse_Angular) );
|
||||
this->rotation = Rotation( this->axis );
|
||||
|
||||
Float deltaRadian = rotationAxis.Dot( rotationAxis );
|
||||
if( deltaRadian != 0.0f )
|
||||
{ // branch depending if there is rotation
|
||||
deltaRadian = ::std::sqrt( deltaRadian );
|
||||
rotationAxis /= deltaRadian;
|
||||
|
||||
// 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;
|
||||
// update momentums and clear impulse_Linear and impulse_Angular
|
||||
this->momentum_Linear += this->impulse_Linear;
|
||||
this->impulse_Linear = Float4::null;
|
||||
this->momentum_Angular += this->impulse_Angular;
|
||||
this->impulse_Angular = Float4::null;
|
||||
}
|
||||
|
||||
void RigidBody::ApplyImpulseForce( const Float3 &worldF )
|
||||
{ // by Dan Andersson
|
||||
this->impulseForceSum += worldF;
|
||||
void RigidBody::Predict_LeapFrog( Float4 &outDeltaPos, Float4 &outDeltaAxis, const Float4 &actingLinearImpulse, const Float4 &actingAngularImpulse, Float deltaTime )
|
||||
{
|
||||
// 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
|
||||
Float3 worldOffset = worldPos - this->box.center;
|
||||
if( worldOffset != Float3::null )
|
||||
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||
if( worldOffset != Float4::null )
|
||||
{
|
||||
this->impulseForceSum += VectorProjection( worldF, worldOffset );
|
||||
this->impulseTorqueSum += Formula::ImpulseTorque( worldF, worldOffset );
|
||||
this->impulse_Linear += VectorProjection( worldJ, atWorldPos );
|
||||
this->impulse_Angular += Formula::ImpulseTorque( worldJ, atWorldPos );
|
||||
}
|
||||
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
|
||||
{ // by Dan Andersson
|
||||
return this->momentOfInertiaTensor;
|
||||
}
|
||||
|
||||
const Float & RigidBody::GetMass() const
|
||||
Float RigidBody::GetMass() const
|
||||
{ // by Dan Andersson
|
||||
return this->mass;
|
||||
}
|
||||
|
||||
const Float4x4 RigidBody::GetOrientation() const
|
||||
const Quaternion & RigidBody::GetRotation() const
|
||||
{ // 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
|
||||
{ // 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
|
||||
return this->box.boundingOffset;
|
||||
return Formula::LinearVelocity( this->mass, this->momentum_Linear );
|
||||
}
|
||||
|
||||
Float3 RigidBody::GetSize() const
|
||||
Float4 RigidBody::GetVelocity_Angular() const
|
||||
{ // 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
|
||||
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
|
||||
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
|
||||
{ // by Dan Andersson
|
||||
return this->angularMomentum;
|
||||
}
|
||||
|
||||
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 );
|
||||
Float4 w = Formula::AngularVelocity( (rotationMatrix * this->momentOfInertiaTensor).GetInverse(), this->momentum_Angular );
|
||||
this->momentOfInertiaTensor = localTensorI;
|
||||
this->momentum_Angular = Formula::AngularMomentum( rotationMatrix * localTensorI, w );
|
||||
}
|
||||
}
|
||||
|
||||
void RigidBody::SetMomentOfInertia_KeepMomentum( const Float4x4 &localI )
|
||||
void RigidBody::SetMomentOfInertia_KeepMomentum( const Float4x4 &localTensorI )
|
||||
{ // by Dan Andersson
|
||||
if( localI.GetDeterminant() != 0.0f ) // insanitycheck! momentOfInertiaTensor must be invertable
|
||||
{
|
||||
this->momentOfInertiaTensor = localI;
|
||||
if( localTensorI.GetDeterminant() != 0.0f )
|
||||
{ // insanity check! MomentOfInertiaTensor must be invertable
|
||||
this->momentOfInertiaTensor = localTensorI;
|
||||
}
|
||||
}
|
||||
|
||||
void RigidBody::SetMass_KeepVelocity( const Float &m )
|
||||
{ // by Dan Andersson
|
||||
if( m != 0.0f ) // insanitycheck! mass must be invertable
|
||||
{
|
||||
Float3 v = Formula::LinearVelocity( this->mass, this->linearMomentum );
|
||||
if( m != 0.0f )
|
||||
{ // insanity check! Mass must be invertable
|
||||
Float4 v = Formula::LinearVelocity( this->mass, this->momentum_Linear );
|
||||
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 )
|
||||
{ // 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;
|
||||
}
|
||||
}
|
||||
|
||||
void RigidBody::SetOrientation( const Float4x4 &o )
|
||||
{ // by Dan Andersson
|
||||
ExtractRotationMatrix( o, this->box.rotation );
|
||||
this->box.center = 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;
|
||||
this->axis = ExtractAngularAxis( o );
|
||||
this->rotation = Rotation( this->axis );
|
||||
this->centerPos = o.v[3].xyz;
|
||||
}
|
||||
|
||||
void RigidBody::SetRotation( const Float4x4 &r )
|
||||
{ // 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
this->impulseForceSum = worldF;
|
||||
}
|
||||
|
||||
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) );
|
||||
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||
this->impulse_Linear = VectorProjection( worldJ, worldOffset );
|
||||
this->impulse_Angular = Formula::ImpulseTorque( worldJ, worldOffset );
|
||||
}
|
|
@ -12,109 +12,76 @@
|
|||
namespace Oyster { namespace Physics3D
|
||||
{
|
||||
struct RigidBody
|
||||
{ /// A struct of a simple rigid body.
|
||||
{ //! A struct of a simple rigid body.
|
||||
public:
|
||||
::Oyster::Collision3D::Box box; /** Contains data representing physical presence. (worldValue) */
|
||||
::Oyster::Math::Float3 angularMomentum, /** The angular momentum H (Nm*s) around an parallell axis. (worldValue) */
|
||||
linearMomentum, /** The linear momentum G (kg*m/s). (worldValue) */
|
||||
impulseTorqueSum, /** The impulse torque T (Nm) that will be consumed each update. (worldValue) */
|
||||
impulseForceSum; /** The impulse force F (N) that will be consumed each update. (worldValue) */
|
||||
::Oyster::Math::Float4 centerPos, //!< Location of the body's center in the world.
|
||||
axis, //!< Euler rotationAxis of the body.
|
||||
boundingReach, //!<
|
||||
momentum_Linear, //!< The linear momentum G (kg*m/s).
|
||||
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(),
|
||||
::Oyster::Math::Float mass = 12.0f,
|
||||
const ::Oyster::Math::Float4x4 &inertiaTensor = ::Oyster::Math::Float4x4::identity );
|
||||
RigidBody();
|
||||
|
||||
RigidBody & operator = ( const RigidBody &body );
|
||||
|
||||
bool operator == ( const RigidBody &body );
|
||||
bool operator != ( const RigidBody &body );
|
||||
void Update_LeapFrog( ::Oyster::Math::Float updateFrameLength );
|
||||
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 ApplyImpulseForce( const ::Oyster::Math::Float3 &worldF );
|
||||
void ApplyImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos );
|
||||
void ApplyLinearImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
||||
void ApplyLinearImpulseAccelerationAt( const ::Oyster::Math::Float3 &worldA, const ::Oyster::Math::Float3 &worldPos );
|
||||
void ApplyImpulseTorque( const ::Oyster::Math::Float3 &worldT );
|
||||
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;
|
||||
void Move( const ::Oyster::Math::Float4 &deltaPos, const ::Oyster::Math::Float4 &deltaAxis );
|
||||
void ApplyImpulse( const ::Oyster::Math::Float4 &worldJ, const ::Oyster::Math::Float4 &atWorldPos );
|
||||
void ApplyImpulse_Linear( const ::Oyster::Math::Float4 &worldJ );
|
||||
void ApplyImpulse_Angular( const ::Oyster::Math::Float4 &worldJ );
|
||||
void ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength );
|
||||
void ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos );
|
||||
|
||||
// GET METHODS ////////////////////////////////
|
||||
|
||||
const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const;
|
||||
const ::Oyster::Math::Float & GetMass() const;
|
||||
|
||||
const ::Oyster::Math::Float4x4 GetOrientation() const;
|
||||
::Oyster::Math::Float GetMass() const;
|
||||
const ::Oyster::Math::Quaternion & GetRotation() const;
|
||||
::Oyster::Math::Float4x4 GetRotationMatrix() const;
|
||||
::Oyster::Math::Float4x4 GetOrientation() const;
|
||||
::Oyster::Math::Float4x4 GetView() const;
|
||||
const ::Oyster::Math::Float4x4 & GetToWorldMatrix() const;
|
||||
::Oyster::Math::Float4x4 GetToWorldMatrix() const;
|
||||
::Oyster::Math::Float4x4 GetToLocalMatrix() const;
|
||||
|
||||
const ::Oyster::Math::Float3 & GetBoundingReach() const;
|
||||
::Oyster::Math::Float3 GetSize() 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;
|
||||
::Oyster::Math::Float4 GetSize() const;
|
||||
::Oyster::Math::Float4 GetVelocity_Linear() const;
|
||||
::Oyster::Math::Float4 GetVelocity_Angular() const;
|
||||
::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float4 &atWorldPos ) const;
|
||||
|
||||
// SET METHODS ////////////////////////////////
|
||||
|
||||
void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
||||
void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
||||
void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localTensorI );
|
||||
void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &localTensorI );
|
||||
void SetMass_KeepVelocity( const ::Oyster::Math::Float &m );
|
||||
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
|
||||
|
||||
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 SetSize( const ::Oyster::Math::Float4 &widthHeight );
|
||||
|
||||
void SetImpulseTorque( const ::Oyster::Math::Float3 &worldT );
|
||||
void SetAngularMomentum( const ::Oyster::Math::Float3 &worldH );
|
||||
void SetAngularImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
||||
void SetAngularVelocity( const ::Oyster::Math::Float3 &worldW );
|
||||
void SetMomentum_Linear( const ::Oyster::Math::Float4 &worldG, const ::Oyster::Math::Float4 &atWorldPos );
|
||||
|
||||
void SetImpulseForce( const ::Oyster::Math::Float3 &worldF );
|
||||
void SetLinearMomentum( const ::Oyster::Math::Float3 &worldG );
|
||||
void SetLinearImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
||||
void SetLinearVelocity( const ::Oyster::Math::Float3 &worldV );
|
||||
void SetVelocity_Linear( const ::Oyster::Math::Float4 &worldV );
|
||||
void SetVelocity_Linear( const ::Oyster::Math::Float4 &worldV, const ::Oyster::Math::Float4 &atWorldPos );
|
||||
void SetVelocity_Angular( const ::Oyster::Math::Float4 &worldW );
|
||||
|
||||
void SetImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos );
|
||||
void SetLinearMomentumAt( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &worldPos );
|
||||
void SetImpulseAccelerationAt( const ::Oyster::Math::Float3 &worldA, const ::Oyster::Math::Float3 &worldPos );
|
||||
void SetLinearVelocityAt( const ::Oyster::Math::Float3 &worldV, const ::Oyster::Math::Float3 &worldPos );
|
||||
void SetImpulse_Linear( const ::Oyster::Math::Float4 &worldJ, const ::Oyster::Math::Float4 &atWorldPos );
|
||||
void SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength );
|
||||
void SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos );
|
||||
|
||||
private:
|
||||
::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::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::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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
this->center = Float3::null;
|
||||
this->center = Float4::standard_unit_w;
|
||||
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->radius = _radius;
|
||||
this->center = Float4( p, 1.0f );
|
||||
this->radius = r;
|
||||
}
|
||||
|
||||
Sphere::Sphere( const Float4 &p, const Float &r ) : ICollideable(Type_sphere)
|
||||
{
|
||||
this->center = p;
|
||||
this->radius = r;
|
||||
}
|
||||
|
||||
Sphere::~Sphere( ) {}
|
||||
|
@ -26,35 +32,58 @@ Sphere & Sphere::operator = ( const Sphere &sphere )
|
|||
}
|
||||
|
||||
::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
|
||||
{
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_universe: return true;
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
case Type_ray: return Utility::Intersect( *this, *(Ray*)&target, ((Ray*)&target)->collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, *(Sphere*)&target );
|
||||
case Type_plane: return Utility::Intersect( *(Plane*)&target, *this );
|
||||
// case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( *(BoxAxisAligned*)&target, *this );
|
||||
case Type_box: return Utility::Intersect( *(Box*)&target, *this );
|
||||
case Type_frustrum: return false; // TODO:
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
case Type_ray: return Utility::Intersect( *this, (const Ray&)target, ((const Ray&)target).collisionDistance );
|
||||
case Type_sphere: return Utility::Intersect( *this, (const Sphere&)target );
|
||||
case Type_plane: return Utility::Intersect( (const Plane&)target, *this );
|
||||
//case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return Utility::Intersect( (const BoxAxisAligned&)target, *this );
|
||||
case Type_box: return Utility::Intersect( (const Box&)target, *this );
|
||||
//case Type_frustrum: return false; // TODO:
|
||||
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
|
||||
{
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_point: return Utility::Intersect( *this, *(Point*)&target );
|
||||
case Type_sphere: return Utility::Contains( *this, *(Sphere*)&target );
|
||||
// case Type_triangle: return false; // TODO:
|
||||
case Type_box_axis_aligned: return false; // TODO:
|
||||
case Type_box: return false; // TODO:
|
||||
case Type_frustrum: return false; // TODO:
|
||||
case Type_point: return Utility::Intersect( *this, (const Point&)target );
|
||||
case Type_sphere: return Utility::Contains( *this, (const Sphere&)target );
|
||||
//case Type_triangle: return false; // TODO:
|
||||
//case Type_box_axis_aligned: return false; // TODO:
|
||||
//case Type_box: return false; // TODO:
|
||||
//case Type_frustrum: return false; // TODO:
|
||||
default: return false;
|
||||
}
|
||||
}
|
|
@ -16,18 +16,20 @@ namespace Oyster { namespace Collision3D
|
|||
public:
|
||||
union
|
||||
{
|
||||
struct{ ::Oyster::Math::Float3 center; ::Oyster::Math::Float radius; };
|
||||
char byte[sizeof(::Oyster::Math::Float3) + sizeof(::Oyster::Math::Float)];
|
||||
struct{ ::Oyster::Math::Float4 center; ::Oyster::Math::Float radius; };
|
||||
char byte[sizeof(::Oyster::Math::Float4) + sizeof(::Oyster::Math::Float)];
|
||||
};
|
||||
|
||||
Sphere( );
|
||||
Sphere( const ::Oyster::Math::Float3 ¢er, const ::Oyster::Math::Float &radius );
|
||||
Sphere( const ::Oyster::Math::Float4 ¢er, const ::Oyster::Math::Float &radius );
|
||||
virtual ~Sphere( );
|
||||
|
||||
Sphere & operator = ( const Sphere &sphere );
|
||||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
};
|
||||
} }
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "Universe.h"
|
||||
#include "OysterCollision3D.h"
|
||||
|
||||
using namespace ::Utility::Value;
|
||||
using namespace ::Oyster::Math;
|
||||
using namespace ::Oyster::Collision3D;
|
||||
using namespace ::Utility::DynamicMemory;
|
||||
|
||||
|
@ -8,20 +10,24 @@ Universe::Universe() : ICollideable(Type_universe) {}
|
|||
Universe::~Universe() {}
|
||||
|
||||
Universe & Universe::operator = ( const Universe &universe )
|
||||
{ return *this; }
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
UniquePointer<ICollideable> Universe::Clone( ) const
|
||||
{ return UniquePointer<ICollideable>( new Universe(*this) ); }
|
||||
{
|
||||
return UniquePointer<ICollideable>( new Universe(*this) );
|
||||
}
|
||||
|
||||
bool Universe::Intersects( const ICollideable &target ) const
|
||||
{ // universe touches everything
|
||||
switch( target.type )
|
||||
{
|
||||
case Type_ray:
|
||||
((Ray*)&target)->collisionDistance = 0.0f;
|
||||
((const Ray&)target).collisionDistance = 0.0f;
|
||||
break;
|
||||
case Type_line:
|
||||
((Line*)&target)->ray.collisionDistance = 0.0f;
|
||||
((const Line&)target).ray.collisionDistance = 0.0f;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
@ -29,6 +35,47 @@ bool Universe::Intersects( const ICollideable &target ) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Universe::Contains( const ICollideable &target ) const
|
||||
{ return true; } // universe contains everything
|
||||
bool Universe::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) const
|
||||
{ // 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
|
||||
|
||||
#include "ICollideable.h"
|
||||
#include "OysterMath.h"
|
||||
|
||||
namespace Oyster { namespace Collision3D
|
||||
{
|
||||
|
@ -20,6 +21,7 @@ namespace Oyster { namespace Collision3D
|
|||
|
||||
virtual ::Utility::DynamicMemory::UniquePointer<ICollideable> Clone( ) const;
|
||||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
};
|
||||
} }
|
||||
|
|
Loading…
Reference in New Issue