RigidBody improved and Gimbal lock proofed
This commit is contained in:
parent
ff52977dcf
commit
bbc489eac9
|
@ -43,7 +43,8 @@ namespace Private
|
||||||
|
|
||||||
SimpleRigidBody::SimpleRigidBody()
|
SimpleRigidBody::SimpleRigidBody()
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody( Box(Float4x4::identity, Float3::null, Float3(1.0f)), 16.0f, Float4x4::identity );
|
this->rigid = RigidBody();
|
||||||
|
this->rigid.SetMass_KeepMomentum( 16.0f );
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
this->collisionAction = Default::EventAction_Collision;
|
this->collisionAction = Default::EventAction_Collision;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = false;
|
||||||
|
@ -52,9 +53,13 @@ SimpleRigidBody::SimpleRigidBody()
|
||||||
|
|
||||||
SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody( Box( desc.rotation, desc.centerPosition.xyz, desc.size.xyz ),
|
this->rigid = RigidBody();
|
||||||
desc.mass,
|
this->rigid.SetRotation( desc.rotation );
|
||||||
desc.inertiaTensor );
|
this->rigid.centerPos = desc.centerPosition;
|
||||||
|
this->rigid.SetSize( desc.size );
|
||||||
|
this->rigid.SetMass_KeepMomentum( desc.mass );
|
||||||
|
this->rigid.SetMomentOfInertia_KeepMomentum( desc.inertiaTensor );
|
||||||
|
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
|
|
||||||
if( desc.subscription )
|
if( desc.subscription )
|
||||||
|
@ -81,29 +86,29 @@ SimpleRigidBody::State SimpleRigidBody::GetState() const
|
||||||
{
|
{
|
||||||
return State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
return State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
||||||
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
||||||
this->rigid.GetMomentOfInertia(), this->rigid.box.boundingOffset,
|
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
|
||||||
this->rigid.box.center, AngularAxis(this->rigid.box.rotation),
|
this->rigid.centerPos, this->rigid.axis,
|
||||||
Float4(this->rigid.linearMomentum, 0.0f), Float4(this->rigid.angularMomentum, 0.0f) );
|
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targetMem ) const
|
SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
return targetMem = State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
||||||
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
||||||
this->rigid.GetMomentOfInertia(), this->rigid.box.boundingOffset,
|
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
|
||||||
this->rigid.box.center, AngularAxis(this->rigid.box.rotation),
|
this->rigid.centerPos, this->rigid.axis,
|
||||||
Float4(this->rigid.linearMomentum, 0.0f), Float4(this->rigid.angularMomentum, 0.0f) );
|
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
|
void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
|
||||||
{
|
{
|
||||||
this->rigid.box.boundingOffset = state.GetReach();
|
this->rigid.centerPos = state.GetCenterPosition();
|
||||||
this->rigid.box.center = state.GetCenterPosition();
|
this->rigid.SetRotation( state.GetRotation() );
|
||||||
this->rigid.box.rotation = state.GetRotation();
|
this->rigid.boundingReach = state.GetReach();
|
||||||
this->rigid.angularMomentum = state.GetAngularMomentum().xyz;
|
this->rigid.momentum_Linear = state.GetLinearMomentum();
|
||||||
this->rigid.linearMomentum = state.GetLinearMomentum().xyz;
|
this->rigid.momentum_Angular = state.GetAngularMomentum();
|
||||||
this->rigid.impulseTorqueSum += state.GetAngularImpulse().xyz;
|
this->rigid.impulse_Linear += state.GetLinearImpulse();
|
||||||
this->rigid.impulseForceSum += state.GetLinearImpulse().xyz;
|
this->rigid.impulse_Angular += state.GetAngularImpulse();
|
||||||
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
|
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
|
||||||
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
|
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
|
||||||
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
|
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
|
||||||
|
@ -135,27 +140,27 @@ bool SimpleRigidBody::IsAffectedByGravity() const
|
||||||
|
|
||||||
bool SimpleRigidBody::Intersects( const ICollideable &shape ) const
|
bool SimpleRigidBody::Intersects( const ICollideable &shape ) const
|
||||||
{
|
{
|
||||||
return this->rigid.box.Intersects( shape );
|
return Box( this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize() ).Intersects( shape );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SimpleRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
|
bool SimpleRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
|
||||||
{
|
{
|
||||||
return this->rigid.box.Intersects( shape, worldPointOfContact );
|
return Box( this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize() ).Intersects( shape, worldPointOfContact );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
|
bool SimpleRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
|
||||||
{
|
{
|
||||||
return object.Intersects( this->rigid.box, worldPointOfContact );
|
return object.Intersects( Box(this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize()), worldPointOfContact );
|
||||||
}
|
}
|
||||||
|
|
||||||
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = Sphere( this->rigid.box.center, this->rigid.box.boundingOffset.GetMagnitude() );
|
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.GetMagnitude() );
|
||||||
}
|
}
|
||||||
|
|
||||||
Float4 & SimpleRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
|
Float4 & SimpleRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
|
||||||
{
|
{
|
||||||
Float4 offset = worldPos - this->rigid.box.center;
|
Float4 offset = worldPos - this->rigid.centerPos;
|
||||||
Float distance = offset.Dot( offset );
|
Float distance = offset.Dot( offset );
|
||||||
Float3 normal = Float3::null;
|
Float3 normal = Float3::null;
|
||||||
|
|
||||||
|
@ -163,39 +168,40 @@ Float4 & SimpleRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem
|
||||||
{ // sanity check
|
{ // sanity check
|
||||||
Ray axis( Float4::standard_unit_w, offset / (Float)::std::sqrt(distance) );
|
Ray axis( Float4::standard_unit_w, offset / (Float)::std::sqrt(distance) );
|
||||||
Float minDistance = numeric_limits<Float>::max();
|
Float minDistance = numeric_limits<Float>::max();
|
||||||
|
Float4x4 rotationMatrix = this->rigid.GetRotationMatrix();
|
||||||
|
|
||||||
if( Private::Intersects(axis, Plane(this->rigid.box.xAxis, -this->rigid.box.boundingOffset.x), axis.collisionDistance) )
|
if( Private::Intersects(axis, Plane(rotationMatrix.v[0], -this->rigid.boundingReach.x), axis.collisionDistance) )
|
||||||
{ // check along x-axis
|
{ // check along x-axis
|
||||||
if( axis.collisionDistance < 0.0f )
|
if( axis.collisionDistance < 0.0f )
|
||||||
normal = -this->rigid.box.xAxis.xyz;
|
normal = -rotationMatrix.v[0].xyz;
|
||||||
else
|
else
|
||||||
normal = this->rigid.box.xAxis.xyz;
|
normal = rotationMatrix.v[0].xyz;
|
||||||
|
|
||||||
minDistance = Abs( axis.collisionDistance );
|
minDistance = Abs( axis.collisionDistance );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Private::Intersects(axis, Plane(this->rigid.box.yAxis, -this->rigid.box.boundingOffset.y), axis.collisionDistance) )
|
if( Private::Intersects(axis, Plane(rotationMatrix.v[1], -this->rigid.boundingReach.y), axis.collisionDistance) )
|
||||||
{ // check along y-axis
|
{ // check along y-axis
|
||||||
distance = Abs( axis.collisionDistance ); // recycling memory
|
distance = Abs( axis.collisionDistance ); // recycling memory
|
||||||
if( minDistance > distance )
|
if( minDistance > distance )
|
||||||
{
|
{
|
||||||
if( axis.collisionDistance < 0.0f )
|
if( axis.collisionDistance < 0.0f )
|
||||||
normal = -this->rigid.box.yAxis.xyz;
|
normal = -rotationMatrix.v[1].xyz;
|
||||||
else
|
else
|
||||||
normal = this->rigid.box.yAxis.xyz;
|
normal = rotationMatrix.v[1].xyz;
|
||||||
|
|
||||||
minDistance = distance;
|
minDistance = distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Private::Intersects(axis, Plane(this->rigid.box.zAxis, -this->rigid.box.boundingOffset.z), axis.collisionDistance) )
|
if( Private::Intersects(axis, Plane(rotationMatrix.v[2], -this->rigid.boundingReach.z), axis.collisionDistance) )
|
||||||
{ // check along z-axis
|
{ // check along z-axis
|
||||||
if( minDistance > Abs( axis.collisionDistance ) )
|
if( minDistance > Abs( axis.collisionDistance ) )
|
||||||
{
|
{
|
||||||
if( axis.collisionDistance < 0.0f )
|
if( axis.collisionDistance < 0.0f )
|
||||||
normal = -this->rigid.box.zAxis.xyz;
|
normal = -rotationMatrix.v[2].xyz;
|
||||||
else
|
else
|
||||||
normal = this->rigid.box.zAxis.xyz;
|
normal = rotationMatrix.v[2].xyz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +217,7 @@ Float3 & SimpleRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||||
|
|
||||||
//Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const
|
//Float3 & SimpleRigidBody::GetCenter( Float3 &targetMem ) const
|
||||||
//{
|
//{
|
||||||
// return targetMem = this->rigid.box.center;
|
// return targetMem = this->rigid.centerPos;
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//Float4x4 & SimpleRigidBody::GetRotation( Float4x4 &targetMem ) const
|
//Float4x4 & SimpleRigidBody::GetRotation( Float4x4 &targetMem ) const
|
||||||
|
|
|
@ -10,7 +10,8 @@ using namespace ::Utility::Value;
|
||||||
|
|
||||||
SphericalRigidBody::SphericalRigidBody()
|
SphericalRigidBody::SphericalRigidBody()
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody( Box(Float4x4::identity, Float3::null, Float3(1.0f)), 10.0f, Float4x4::identity );
|
this->rigid = RigidBody();
|
||||||
|
this->rigid.SetMass_KeepMomentum( 10.0f );
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
this->collisionAction = Default::EventAction_Collision;
|
this->collisionAction = Default::EventAction_Collision;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = false;
|
||||||
|
@ -20,9 +21,13 @@ SphericalRigidBody::SphericalRigidBody()
|
||||||
|
|
||||||
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody( Box( desc.rotation, desc.centerPosition.xyz, Float3(2.0f * desc.radius) ),
|
this->rigid = RigidBody();
|
||||||
desc.mass,
|
this->rigid.SetRotation( desc.rotation );
|
||||||
Formula::MomentOfInertia::CreateSphereMatrix( desc.mass, desc.radius ) );
|
this->rigid.centerPos = desc.centerPosition;
|
||||||
|
this->rigid.boundingReach = Float4( desc.radius, desc.radius, desc.radius, 0.0f );
|
||||||
|
this->rigid.SetMass_KeepMomentum( desc.mass );
|
||||||
|
this->rigid.SetMomentOfInertia_KeepMomentum( Formula::MomentOfInertia::CreateSphereMatrix( desc.mass, desc.radius ) );
|
||||||
|
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
|
|
||||||
if( desc.subscription )
|
if( desc.subscription )
|
||||||
|
@ -50,29 +55,29 @@ SphericalRigidBody::State SphericalRigidBody::GetState() const
|
||||||
{
|
{
|
||||||
return State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
return State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
||||||
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
||||||
this->rigid.GetMomentOfInertia(), this->rigid.box.boundingOffset,
|
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
|
||||||
this->rigid.box.center, AngularAxis(this->rigid.box.rotation),
|
this->rigid.centerPos, this->rigid.axis,
|
||||||
Float4(this->rigid.linearMomentum, 0.0f), Float4(this->rigid.angularMomentum, 0.0f) );
|
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
SphericalRigidBody::State & SphericalRigidBody::GetState( SphericalRigidBody::State &targetMem ) const
|
SphericalRigidBody::State & SphericalRigidBody::GetState( SphericalRigidBody::State &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
return targetMem = State( this->rigid.GetMass(), this->rigid.restitutionCoeff,
|
||||||
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
this->rigid.frictionCoeff_Static, this->rigid.frictionCoeff_Kinetic,
|
||||||
this->rigid.GetMomentOfInertia(), this->rigid.box.boundingOffset,
|
this->rigid.GetMomentOfInertia(), this->rigid.boundingReach,
|
||||||
this->rigid.box.center, AngularAxis(this->rigid.box.rotation),
|
this->rigid.centerPos, this->rigid.axis,
|
||||||
Float4(this->rigid.linearMomentum, 0.0f), Float4(this->rigid.angularMomentum, 0.0f) );
|
this->rigid.momentum_Linear, this->rigid.momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
|
void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
|
||||||
{
|
{
|
||||||
this->rigid.box.boundingOffset = state.GetReach();
|
this->rigid.centerPos = state.GetCenterPosition();
|
||||||
this->rigid.box.center = state.GetCenterPosition();
|
this->rigid.SetRotation( state.GetRotation() );
|
||||||
this->rigid.box.rotation = state.GetRotation();
|
this->rigid.boundingReach = state.GetReach();
|
||||||
this->rigid.angularMomentum = state.GetAngularMomentum().xyz;
|
this->rigid.momentum_Linear = state.GetLinearMomentum();
|
||||||
this->rigid.linearMomentum = state.GetLinearMomentum().xyz;
|
this->rigid.momentum_Angular = state.GetAngularMomentum();
|
||||||
this->rigid.impulseTorqueSum += state.GetAngularImpulse().xyz;
|
this->rigid.impulse_Linear += state.GetLinearImpulse();
|
||||||
this->rigid.impulseForceSum += state.GetLinearImpulse().xyz;
|
this->rigid.impulse_Angular += state.GetAngularImpulse();
|
||||||
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
|
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
|
||||||
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
|
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
|
||||||
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
|
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
|
||||||
|
@ -104,17 +109,17 @@ bool SphericalRigidBody::IsAffectedByGravity() const
|
||||||
|
|
||||||
bool SphericalRigidBody::Intersects( const ICollideable &shape ) const
|
bool SphericalRigidBody::Intersects( const ICollideable &shape ) const
|
||||||
{
|
{
|
||||||
return Sphere( this->rigid.box.center, this->rigid.box.boundingOffset.x ).Intersects( shape );
|
return Sphere( this->rigid.centerPos, this->rigid.boundingReach.x ).Intersects( shape );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SphericalRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
|
bool SphericalRigidBody::Intersects( const ICollideable &shape, Float4 &worldPointOfContact ) const
|
||||||
{
|
{
|
||||||
return Sphere( this->rigid.box.center, this->rigid.box.boundingOffset.x ).Intersects( shape, worldPointOfContact );
|
return Sphere( this->rigid.centerPos, this->rigid.boundingReach.x ).Intersects( shape, worldPointOfContact );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SphericalRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
|
bool SphericalRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointOfContact ) const
|
||||||
{
|
{
|
||||||
return object.Intersects( Sphere(this->rigid.box.center, this->rigid.box.boundingOffset.x), worldPointOfContact );
|
return object.Intersects( Sphere(this->rigid.centerPos, this->rigid.boundingReach.x), worldPointOfContact );
|
||||||
}
|
}
|
||||||
|
|
||||||
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
|
@ -124,7 +129,7 @@ Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
|
|
||||||
Float4 & SphericalRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
|
Float4 & SphericalRigidBody::GetNormalAt( const Float4 &worldPos, Float4 &targetMem ) const
|
||||||
{
|
{
|
||||||
targetMem = worldPos - this->rigid.box.center;
|
targetMem = worldPos - this->rigid.centerPos;
|
||||||
Float magnitude = targetMem.GetMagnitude();
|
Float magnitude = targetMem.GetMagnitude();
|
||||||
if( magnitude != 0.0f )
|
if( magnitude != 0.0f )
|
||||||
{ // sanity check
|
{ // sanity check
|
||||||
|
@ -141,7 +146,7 @@ Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||||
|
|
||||||
//Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
|
//Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
|
||||||
//{
|
//{
|
||||||
// return targetMem = this->rigid.box.center;
|
// return targetMem = this->rigid.centerPos;
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//Float4x4 & SphericalRigidBody::GetRotation( Float4x4 &targetMem ) const
|
//Float4x4 & SphericalRigidBody::GetRotation( Float4x4 &targetMem ) const
|
||||||
|
@ -167,7 +172,7 @@ Float3 SphericalRigidBody::GetRigidLinearVelocity() const
|
||||||
UpdateState SphericalRigidBody::Update( Float timeStepLength )
|
UpdateState SphericalRigidBody::Update( Float timeStepLength )
|
||||||
{
|
{
|
||||||
this->rigid.Update_LeapFrog( timeStepLength );
|
this->rigid.Update_LeapFrog( timeStepLength );
|
||||||
this->body.center = this->rigid.GetCenter();
|
this->body.center = this->rigid.centerPos;
|
||||||
|
|
||||||
// compare previous and new state and return result
|
// compare previous and new state and return result
|
||||||
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
||||||
|
|
|
@ -281,6 +281,106 @@ namespace LinearAlgebra3D
|
||||||
0, 0, 0, 1 );
|
0, 0, 0, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Quaternion<ScalarType> Rotation( const ScalarType &radian, const ::LinearAlgebra::Vector3<ScalarType> &normalizedAxis )
|
||||||
|
{
|
||||||
|
ScalarType r = radian * 0.5f,
|
||||||
|
s = std::sin( r ),
|
||||||
|
c = std::cos( r );
|
||||||
|
|
||||||
|
return ::LinearAlgebra::Quaternion<ScalarType>( normalizedAxis * s, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Quaternion<ScalarType> Rotation( const ScalarType &radian, const ::LinearAlgebra::Vector4<ScalarType> &normalizedAxis )
|
||||||
|
{
|
||||||
|
ScalarType r = radian * 0.5f,
|
||||||
|
s = std::sin( r ),
|
||||||
|
c = std::cos( r );
|
||||||
|
|
||||||
|
return ::LinearAlgebra::Quaternion<ScalarType>( (normalizedAxis * s).xyz, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Quaternion<ScalarType> Rotation( const ::LinearAlgebra::Vector3<ScalarType> &angularAxis )
|
||||||
|
{
|
||||||
|
ScalarType radius = angularAxis.Dot( angularAxis );
|
||||||
|
if( radius != 0 )
|
||||||
|
{
|
||||||
|
radius = (ScalarType)::std::sqrt( radius );
|
||||||
|
return Rotation( radius, angularAxis / radius );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra::Quaternion<ScalarType>::identity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Quaternion<ScalarType> Rotation( const ::LinearAlgebra::Vector4<ScalarType> &angularAxis )
|
||||||
|
{
|
||||||
|
ScalarType radius = angularAxis.Dot( angularAxis );
|
||||||
|
if( radius != 0 )
|
||||||
|
{
|
||||||
|
radius = (ScalarType)::std::sqrt( radius );
|
||||||
|
return Rotation( radius, angularAxis / radius );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra::Quaternion<ScalarType>::identity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & RotationMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, ::LinearAlgebra::Matrix4x4<ScalarType> targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
::LinearAlgebra::Quaternion<ScalarType> conjugate = rotationQuaternion.GetConjugate();
|
||||||
|
|
||||||
|
targetMem.v[0] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(1,0,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[1] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,1,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[2] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,0,1)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[3] = ::LinearAlgebra::Vector4<ScalarType>::standard_unit_w;
|
||||||
|
return targetMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, const ::LinearAlgebra::Vector3<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
::LinearAlgebra::Quaternion<ScalarType> conjugate = rotationQuaternion.GetConjugate();
|
||||||
|
|
||||||
|
targetMem.v[0] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(1,0,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[1] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,1,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[2] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,0,1)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[3] = ::LinearAlgebra::Vector4<ScalarType>( translation, 1 );
|
||||||
|
return targetMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, const ::LinearAlgebra::Vector4<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
::LinearAlgebra::Quaternion<ScalarType> conjugate = rotationQuaternion.GetConjugate();
|
||||||
|
|
||||||
|
targetMem.v[0] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(1,0,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[1] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,1,0)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[2] = ::LinearAlgebra::Vector4<ScalarType>( (rotationQuaternion*::LinearAlgebra::Vector3<ScalarType>(0,0,1)*conjugate).imaginary, 0 );
|
||||||
|
targetMem.v[3] = translation;
|
||||||
|
return targetMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & ViewMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, const ::LinearAlgebra::Vector3<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
OrientationMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
return InverseOrientationMatrix( targetMem, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Matrix4x4<ScalarType> & ViewMatrix( const ::LinearAlgebra::Quaternion<ScalarType> &rotationQuaternion, const ::LinearAlgebra::Vector4<ScalarType> &translation, ::LinearAlgebra::Matrix4x4<ScalarType> targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
|
||||||
|
{
|
||||||
|
OrientationMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
return InverseOrientationMatrix( targetMem, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline ::LinearAlgebra::Matrix3x3<ScalarType> & RotationMatrix_AxisX( const ScalarType &radian, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
|
inline ::LinearAlgebra::Matrix3x3<ScalarType> & RotationMatrix_AxisX( const ScalarType &radian, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
|
||||||
{
|
{
|
||||||
|
@ -557,9 +657,17 @@ namespace LinearAlgebra3D
|
||||||
inline ::LinearAlgebra::Vector3<ScalarType> VectorProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &axis )
|
inline ::LinearAlgebra::Vector3<ScalarType> VectorProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &axis )
|
||||||
{ return axis * ( vector.Dot(axis) / axis.Dot(axis) ); }
|
{ return axis * ( vector.Dot(axis) / axis.Dot(axis) ); }
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Vector4<ScalarType> VectorProjection( const ::LinearAlgebra::Vector4<ScalarType> &vector, const ::LinearAlgebra::Vector4<ScalarType> &axis )
|
||||||
|
{ return axis * ( vector.Dot(axis) / axis.Dot(axis) ); }
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline ::LinearAlgebra::Vector3<ScalarType> NormalProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &normalizedAxis )
|
inline ::LinearAlgebra::Vector3<ScalarType> NormalProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &normalizedAxis )
|
||||||
{ return normalizedAxis * ( vector.Dot(normalizedAxis) ); }
|
{ return normalizedAxis * ( vector.Dot(normalizedAxis) ); }
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Vector4<ScalarType> NormalProjection( const ::LinearAlgebra::Vector4<ScalarType> &vector, const ::LinearAlgebra::Vector4<ScalarType> &normalizedAxis )
|
||||||
|
{ return normalizedAxis * ( vector.Dot(normalizedAxis) ); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
|
|
|
@ -101,6 +101,51 @@ namespace Oyster { namespace Math3D
|
||||||
return ::LinearAlgebra3D::TranslationMatrix( position, targetMem );
|
return ::LinearAlgebra3D::TranslationMatrix( position, targetMem );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quaternion Rotation( Float radian, const Float3 &normalizedAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::Rotation( radian, normalizedAxis );
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Rotation( Float radian, const Float4 &normalizedAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::Rotation( radian, normalizedAxis );
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Rotation( const Float3 &angularAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::Rotation( angularAxis );
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Rotation( const Float4 &angularAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::Rotation( angularAxis );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & RotationMatrix( const Quaternion &rotationQuaternion, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::RotationMatrix( rotationQuaternion, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & OrientationMatrix( const Quaternion &rotationQuaternion, const Float3 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::OrientationMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & OrientationMatrix( const Quaternion &rotationQuaternion, const Float4 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::OrientationMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & ViewMatrix( const Quaternion &rotationQuaternion, const Float3 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::ViewMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 & ViewMatrix( const Quaternion &rotationQuaternion, const Float4 &translation, Float4x4 &targetMem )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::ViewMatrix( rotationQuaternion, translation, targetMem );
|
||||||
|
}
|
||||||
|
|
||||||
Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem )
|
Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem )
|
||||||
{
|
{
|
||||||
return ::LinearAlgebra3D::RotationMatrix_AxisX( radian, targetMem );
|
return ::LinearAlgebra3D::RotationMatrix_AxisX( radian, targetMem );
|
||||||
|
@ -217,8 +262,18 @@ namespace Oyster { namespace Math3D
|
||||||
return ::LinearAlgebra3D::VectorProjection( vector, axis );
|
return ::LinearAlgebra3D::VectorProjection( vector, axis );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Float4 VectorProjection( const Float4 &vector, const Float4 &axis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::VectorProjection( vector, axis );
|
||||||
|
}
|
||||||
|
|
||||||
Float3 NormalProjection( const Float3 &vector, const Float3 &normalizedAxis )
|
Float3 NormalProjection( const Float3 &vector, const Float3 &normalizedAxis )
|
||||||
{
|
{
|
||||||
return ::LinearAlgebra3D::NormalProjection( vector, normalizedAxis );
|
return ::LinearAlgebra3D::NormalProjection( vector, normalizedAxis );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Float4 NormalProjection( const Float4 &vector, const Float4 &normalizedAxis )
|
||||||
|
{
|
||||||
|
return ::LinearAlgebra3D::NormalProjection( vector, normalizedAxis );
|
||||||
|
}
|
||||||
} }
|
} }
|
|
@ -9,17 +9,19 @@
|
||||||
#include "LinearMath.h"
|
#include "LinearMath.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace Oyster { namespace Math /// Oyster's native math library
|
namespace Oyster { namespace Math //! Oyster's native math library
|
||||||
{
|
{
|
||||||
typedef float Float; /// Oyster's native scalar is float
|
typedef float Float; //!< Oyster's native scalar is float
|
||||||
|
|
||||||
typedef ::LinearAlgebra::Vector2<Float> Float2; /// 2D Linear Vector for Oyster
|
typedef ::LinearAlgebra::Vector2<Float> Float2; //!< 2D Linear Vector for Oyster
|
||||||
typedef ::LinearAlgebra::Vector3<Float> Float3; /// 3D Linear Vector for Oyster
|
typedef ::LinearAlgebra::Vector3<Float> Float3; //!< 3D Linear Vector for Oyster
|
||||||
typedef ::LinearAlgebra::Vector4<Float> Float4; /// 4D Linear Vector for Oyster
|
typedef ::LinearAlgebra::Vector4<Float> Float4; //!< 4D Linear Vector for Oyster
|
||||||
|
|
||||||
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2; /// 2x2 Linear Matrix for Oyster
|
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2; //!< 2x2 Linear Matrix for Oyster
|
||||||
typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3; /// 3x3 Linear Matrix for Oyster
|
typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3; //!< 3x3 Linear Matrix for Oyster
|
||||||
typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4; /// 4x4 Linear Matrix for Oyster
|
typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4; //!< 4x4 Linear Matrix for Oyster
|
||||||
|
|
||||||
|
typedef ::LinearAlgebra::Quaternion<Float> Quaternion; //!< Quaternion for Oyster
|
||||||
|
|
||||||
typedef Float4x4 Matrix; // by popular demand
|
typedef Float4x4 Matrix; // by popular demand
|
||||||
typedef Float2 Vector2; // by popular demand
|
typedef Float2 Vector2; // by popular demand
|
||||||
|
@ -28,20 +30,20 @@ namespace Oyster { namespace Math /// Oyster's native math library
|
||||||
|
|
||||||
const Float pi = 3.1415926535897932384626433832795f;
|
const Float pi = 3.1415926535897932384626433832795f;
|
||||||
|
|
||||||
/// Function Highly recommended to check at start, just in case current version is using a feature that might be available.
|
//! Function Highly recommended to check at start, just in case current version is using a feature that might be available.
|
||||||
/// @todo TODO: create a template UniquePointer to use here
|
//! @todo TODO: create a template UniquePointer to use here
|
||||||
bool IsSupported();
|
bool IsSupported();
|
||||||
|
|
||||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||||
/// Returns false if there is no explicit solution.
|
//! Returns false if there is no explicit solution.
|
||||||
bool SuperpositionMatrix( const Float2x2 &in, const Float2x2 &out, Float2x2 &targetMem );
|
bool SuperpositionMatrix( const Float2x2 &in, const Float2x2 &out, Float2x2 &targetMem );
|
||||||
|
|
||||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||||
/// Returns false if there is no explicit solution.
|
//! Returns false if there is no explicit solution.
|
||||||
bool SuperpositionMatrix( const Float3x3 &in, const Float3x3 &out, Float3x3 &targetMem );
|
bool SuperpositionMatrix( const Float3x3 &in, const Float3x3 &out, Float3x3 &targetMem );
|
||||||
|
|
||||||
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
//! Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||||
/// Returns false if there is no explicit solution.
|
//! Returns false if there is no explicit solution.
|
||||||
bool SuperpositionMatrix( const Float4x4 &in, const Float4x4 &out, Float4x4 &targetMem );
|
bool SuperpositionMatrix( const Float4x4 &in, const Float4x4 &out, Float4x4 &targetMem );
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
@ -96,54 +98,54 @@ inline ::Oyster::Math::Float3x3 operator * ( const ::Oyster::Math::Float &left,
|
||||||
inline ::Oyster::Math::Float4x4 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float4x4 &right )
|
inline ::Oyster::Math::Float4x4 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float4x4 &right )
|
||||||
{ return ::Oyster::Math::Float4x4(right) *= left; }
|
{ return ::Oyster::Math::Float4x4(right) *= left; }
|
||||||
|
|
||||||
namespace Oyster { namespace Math2D /// Oyster's native math library specialized for 2D
|
namespace Oyster { namespace Math2D //! Oyster's native math library specialized for 2D
|
||||||
{
|
{
|
||||||
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
|
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
|
||||||
|
|
||||||
/// If there is an Y-axis on a 2D plane, then there is an explicit X-axis on and that is what is returned.
|
//! If there is an Y-axis on a 2D plane, then there is an explicit X-axis on and that is what is returned.
|
||||||
/// Recommended too make sure that yAxis is normalized.
|
//! Recommended too make sure that yAxis is normalized.
|
||||||
Float2 X_AxisTo( const Float2 &yAxis );
|
Float2 X_AxisTo( const Float2 &yAxis );
|
||||||
|
|
||||||
/// If there is an X-axis on a 2D plane, then there is an explicit Y-axis and that is what is returned.
|
//! If there is an X-axis on a 2D plane, then there is an explicit Y-axis and that is what is returned.
|
||||||
/// Recommended too make sure that yAxis is normalized.
|
//! Recommended too make sure that yAxis is normalized.
|
||||||
Float2 Y_AxisTo( const Float2 &xAxis );
|
Float2 Y_AxisTo( const Float2 &xAxis );
|
||||||
|
|
||||||
/// Sets and returns targetMem to a translationMatrix with position as translation.
|
//! Sets and returns targetMem to a translationMatrix with position as translation.
|
||||||
Float3x3 & TranslationMatrix( const Float2 &position, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & TranslationMatrix( const Float2 &position, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as a counterclockwise rotationMatrix
|
//! Sets and returns targetMem as a counterclockwise rotationMatrix
|
||||||
Float3x3 & RotationMatrix( const Float &radian, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & RotationMatrix( const Float &radian, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
//! If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
||||||
Float2x2 & InverseRotationMatrix( const Float2x2 &rotation, Float2x2 &targetMem = Float2x2() );
|
Float2x2 & InverseRotationMatrix( const Float2x2 &rotation, Float2x2 &targetMem = Float2x2() );
|
||||||
|
|
||||||
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
//! If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
||||||
Float3x3 & InverseRotationMatrix( const Float3x3 &rotation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & InverseRotationMatrix( const Float3x3 &rotation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
//! Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
||||||
Float3x3 & OrientationMatrix( const Float2x2 &rotation, const Float2 &translation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float2x2 &rotation, const Float2 &translation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
//! Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
||||||
Float3x3 & OrientationMatrix( const Float3x3 &rotation, const Float2 &translation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float3x3 &rotation, const Float2 &translation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix with position as translation and radian rotation
|
//! Sets and returns targetMem as an orientation Matrix with position as translation and radian rotation
|
||||||
Float3x3 & OrientationMatrix( const Float2 &position, const Float &radian, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float2 &position, const Float &radian, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix with position as translation and local y-axis directed at lookAt
|
//! Sets and returns targetMem as an orientation Matrix with position as translation and local y-axis directed at lookAt
|
||||||
Float3x3 & OrientationMatrix( const Float2 &position, const Float2 &lookAt, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float2 &position, const Float2 &lookAt, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix that is rotated around localCenterOfRotation and then translated with position.
|
//! Sets and returns targetMem as an orientation Matrix that is rotated around localCenterOfRotation and then translated with position.
|
||||||
/// TODO: not tested
|
//! TODO: not tested
|
||||||
Float3x3 & OrientationMatrix( const Float2 &position, Float radian, const Float2 &localCenterOfRotation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & OrientationMatrix( const Float2 &position, Float radian, const Float2 &localCenterOfRotation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
|
//! If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
|
||||||
Float3x3 & InverseOrientationMatrix( const Float3x3 &orientationMatrix, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & InverseOrientationMatrix( const Float3x3 &orientationMatrix, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// Returns targetmem after writing the rotation data from orientation, into it.
|
//! Returns targetmem after writing the rotation data from orientation, into it.
|
||||||
Float3x3 & ExtractRotationMatrix( const Float3x3 &orientation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & ExtractRotationMatrix( const Float3x3 &orientation, Float3x3 &targetMem = Float3x3() );
|
||||||
} }
|
} }
|
||||||
|
|
||||||
namespace Oyster { namespace Math3D /// Oyster's native math library specialized for 3D
|
namespace Oyster { namespace Math3D //! Oyster's native math library specialized for 3D
|
||||||
{
|
{
|
||||||
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
|
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
|
||||||
|
|
||||||
|
@ -156,35 +158,62 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
//! Extracts the angularAxis from orientationMatrix
|
//! Extracts the angularAxis from orientationMatrix
|
||||||
Float4 ExtractAngularAxis( const Float4x4 &orientationMatrix );
|
Float4 ExtractAngularAxis( const Float4x4 &orientationMatrix );
|
||||||
|
|
||||||
/// Sets and returns targetMem to a translationMatrix with position as translation.
|
//! Sets and returns targetMem to a translationMatrix with position as translation.
|
||||||
Float4x4 & TranslationMatrix( const Float3 &position, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & TranslationMatrix( const Float3 &position, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global X-axis
|
/** @todo TODO: add doc */
|
||||||
|
Quaternion Rotation( Float radian, const Float3 &normalizedAxis );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Quaternion Rotation( Float radian, const Float3 &normalizedAxis );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Quaternion Rotation( const Float3 &angularAxis );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Quaternion Rotation( const Float4 &angularAxis );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & RotationMatrix( const Quaternion &rotationQuaternion, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & OrientationMatrix( const Quaternion &rotationQuaternion, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & OrientationMatrix( const Quaternion &rotationQuaternion, const Float4 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & ViewMatrix( const Quaternion &rotationQuaternion, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
/** @todo TODO: add doc */
|
||||||
|
Float4x4 & ViewMatrix( const Quaternion &rotationQuaternion, const Float4 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the global X-axis
|
||||||
Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global Y-axis
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the global Y-axis
|
||||||
Float4x4 & RotationMatrix_AxisY( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix_AxisY( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global Z-axis
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the global Z-axis
|
||||||
Float4x4 & RotationMatrix_AxisZ( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix_AxisZ( const Float &radian, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the angularAxis.
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the angularAxis.
|
||||||
Float4x4 & RotationMatrix( const Float3 &angularAxis, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix( const Float3 &angularAxis, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an counterclockwise rotation matrix around the normalizedAxis.
|
//! Sets and returns targetMem as an counterclockwise rotation matrix around the normalizedAxis.
|
||||||
/// Please make sure normalizedAxis is normalized.
|
//! Please make sure normalizedAxis is normalized.
|
||||||
Float4x4 & RotationMatrix( const Float &radian, const Float3 &normalizedAxis, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & RotationMatrix( const Float &radian, const Float3 &normalizedAxis, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
//! If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
||||||
Float3x3 & InverseRotationMatrix( const Float3x3 &rotation, Float3x3 &targetMem = Float3x3() );
|
Float3x3 & InverseRotationMatrix( const Float3x3 &rotation, Float3x3 &targetMem = Float3x3() );
|
||||||
|
|
||||||
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
//! If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
|
||||||
Float4x4 & InverseRotationMatrix( const Float4x4 &rotation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & InverseRotationMatrix( const Float4x4 &rotation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
//! Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
||||||
Float4x4 & OrientationMatrix( const Float3x3 &rotation, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & OrientationMatrix( const Float3x3 &rotation, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
//! Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
|
||||||
Float4x4 & OrientationMatrix( const Float4x4 &rotation, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & OrientationMatrix( const Float4x4 &rotation, const Float3 &translation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
@ -238,14 +267,14 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
//! @todo TODO: Add documentation and not tested
|
//! @todo TODO: Add documentation and not tested
|
||||||
Float4x4 & ViewMatrix_LookAtPos( const Float3 &worldLookAt, const Float3 &normalizedUpVector, const Float3 &worldPos, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & ViewMatrix_LookAtPos( const Float3 &worldLookAt, const Float3 &normalizedUpVector, const Float3 &worldPos, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
|
//! If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
|
||||||
Float4x4 & InverseOrientationMatrix( const Float4x4 &orientationMatrix, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & InverseOrientationMatrix( const Float4x4 &orientationMatrix, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
// O0 = T0 * R0
|
// O0 = T0 * R0
|
||||||
// O1 = T1 * T0 * R1 * R0
|
// O1 = T1 * T0 * R1 * R0
|
||||||
Float4x4 & UpdateOrientationMatrix( const Float3 &deltaPosition, const Float4x4 &deltaRotationMatrix, Float4x4 &orientationMatrix );
|
Float4x4 & UpdateOrientationMatrix( const Float3 &deltaPosition, const Float4x4 &deltaRotationMatrix, Float4x4 &orientationMatrix );
|
||||||
|
|
||||||
/// Returns targetmem after writing the rotation data from orientation, into it.
|
//! Returns targetmem after writing the rotation data from orientation, into it.
|
||||||
Float4x4 & ExtractRotationMatrix( const Float4x4 &orientation, Float4x4 &targetMem = Float4x4() );
|
Float4x4 & ExtractRotationMatrix( const Float4x4 &orientation, Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
@ -272,13 +301,19 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
Float4x4 & ProjectionMatrix_Perspective( const Float &verticalFoV, const Float &aspectRatio, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max(), Float4x4 &targetMem = Float4x4() );
|
Float4x4 & ProjectionMatrix_Perspective( const Float &verticalFoV, const Float &aspectRatio, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max(), Float4x4 &targetMem = Float4x4() );
|
||||||
|
|
||||||
/// returns the component vector of vector that is parallell with axis
|
//! returns the component vector of vector that is parallell with axis
|
||||||
Float3 VectorProjection( const Float3 &vector, const Float3 &axis );
|
Float3 VectorProjection( const Float3 &vector, const Float3 &axis );
|
||||||
|
|
||||||
/// returns the component vector of vector that is parallell with axis. Faster than VectorProjection.
|
//! returns the component vector of vector that is parallell with axis
|
||||||
|
Float4 VectorProjection( const Float4 &vector, const Float4 &axis );
|
||||||
|
|
||||||
|
//! returns the component vector of vector that is parallell with axis. Faster than VectorProjection.
|
||||||
Float3 NormalProjection( const Float3 &vector, const Float3 &normalizedAxis );
|
Float3 NormalProjection( const Float3 &vector, const Float3 &normalizedAxis );
|
||||||
|
|
||||||
/// Helper inline function that sets and then returns targetMem = projection * view
|
//! returns the component vector of vector that is parallell with axis. Faster than VectorProjection.
|
||||||
|
Float4 NormalProjection( const Float4 &vector, const Float4 &normalizedAxis );
|
||||||
|
|
||||||
|
//! Helper inline function that sets and then returns targetMem = projection * view
|
||||||
inline Float4x4 & ViewProjectionMatrix( const Float4x4 &view, const Float4x4 &projection, Float4x4 &targetMem = Float4x4() )
|
inline Float4x4 & ViewProjectionMatrix( const Float4x4 &view, const Float4x4 &projection, Float4x4 &targetMem = Float4x4() )
|
||||||
{ return targetMem = projection * view; }
|
{ return targetMem = projection * view; }
|
||||||
|
|
||||||
|
@ -290,7 +325,7 @@ namespace Oyster { namespace Math3D /// Oyster's native math library specialized
|
||||||
inline Float4x4 TransformMatrix( const Float4x4 &transformer, const Float4x4 &transformee )
|
inline Float4x4 TransformMatrix( const Float4x4 &transformer, const Float4x4 &transformee )
|
||||||
{ return transformer * transformee; }
|
{ return transformer * transformee; }
|
||||||
|
|
||||||
/// Helper inline function that sets and then returns targetMem = transformer * transformee
|
//! Helper inline function that sets and then returns targetMem = transformer * transformee
|
||||||
inline Float4 & TransformVector( const Float4x4 &transformer, const Float4 &transformee, Float4 &targetMem = Float4() )
|
inline Float4 & TransformVector( const Float4x4 &transformer, const Float4 &transformee, Float4 &targetMem = Float4() )
|
||||||
{ return targetMem = transformer * transformee; }
|
{ return targetMem = transformer * transformee; }
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -22,8 +22,10 @@ namespace LinearAlgebra
|
||||||
char byte[sizeof(ScalarType[2])];
|
char byte[sizeof(ScalarType[2])];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const Quaternion<ScalarType> null;
|
||||||
|
static const Quaternion<ScalarType> identity;
|
||||||
|
|
||||||
Quaternion( );
|
Quaternion( );
|
||||||
Quaternion( const Quaternion &quaternion );
|
|
||||||
Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real );
|
Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real );
|
||||||
|
|
||||||
operator ScalarType* ( );
|
operator ScalarType* ( );
|
||||||
|
@ -53,40 +55,54 @@ namespace LinearAlgebra
|
||||||
// Body
|
// Body
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<typename ScalarType> const Quaternion<ScalarType> Quaternion<ScalarType>::null = Quaternion<ScalarType>( Vector3<ScalarType>((ScalarType)0), (ScalarType)0 );
|
||||||
|
template<typename ScalarType> const Quaternion<ScalarType> Quaternion<ScalarType>::identity = Quaternion<ScalarType>( Vector3<ScalarType>((ScalarType)0), (ScalarType)1 );
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
Quaternion<ScalarType>::Quaternion( ) : imaginary(), real() {}
|
Quaternion<ScalarType>::Quaternion( ) : imaginary(), real() {}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
Quaternion<ScalarType>::Quaternion( const Quaternion &quaternion )
|
Quaternion<ScalarType>::Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real )
|
||||||
{ this->imaginary = quaternion.imaginary; this->real = quaternion.real; }
|
{
|
||||||
|
this->imaginary = imaginary;
|
||||||
template<typename ScalarType>
|
this->real = real;
|
||||||
Quaternion<ScalarType>::Quaternion( const Vector3<ScalarType> &_imaginary, const ScalarType &_real )
|
}
|
||||||
{ this->imaginary = _imaginary; this->real = _real; }
|
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType>::operator ScalarType* ( )
|
inline Quaternion<ScalarType>::operator ScalarType* ( )
|
||||||
{ return this->element; }
|
{
|
||||||
|
return this->element;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType>::operator const ScalarType* ( ) const
|
inline Quaternion<ScalarType>::operator const ScalarType* ( ) const
|
||||||
{ return this->element; }
|
{
|
||||||
|
return this->element;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType>::operator char* ( )
|
inline Quaternion<ScalarType>::operator char* ( )
|
||||||
{ return this->byte; }
|
{
|
||||||
|
return this->byte;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType>::operator const char* ( ) const
|
inline Quaternion<ScalarType>::operator const char* ( ) const
|
||||||
{ return this->byte; }
|
{
|
||||||
|
return this->byte;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline ScalarType & Quaternion<ScalarType>::operator [] ( int i )
|
inline ScalarType & Quaternion<ScalarType>::operator [] ( int i )
|
||||||
{ return this->element[i]; }
|
{
|
||||||
|
return this->element[i];
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline const ScalarType & Quaternion<ScalarType>::operator [] ( int i ) const
|
inline const ScalarType & Quaternion<ScalarType>::operator [] ( int i ) const
|
||||||
{ return this->element[i]; }
|
{
|
||||||
|
return this->element[i];
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
Quaternion<ScalarType> & Quaternion<ScalarType>::operator = ( const Quaternion<ScalarType> &quaternion )
|
Quaternion<ScalarType> & Quaternion<ScalarType>::operator = ( const Quaternion<ScalarType> &quaternion )
|
||||||
|
@ -154,27 +170,39 @@ namespace LinearAlgebra
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const ScalarType &scalar ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const ScalarType &scalar ) const
|
||||||
{ return Quaternion<ScalarType>(*this) *= scalar; }
|
{
|
||||||
|
return Quaternion<ScalarType>(*this) *= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator / ( const ScalarType &scalar ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator / ( const ScalarType &scalar ) const
|
||||||
{ return Quaternion<ScalarType>(*this) /= scalar; }
|
{
|
||||||
|
return Quaternion<ScalarType>(*this) /= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator + ( const Quaternion<ScalarType> &quaternion ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator + ( const Quaternion<ScalarType> &quaternion ) const
|
||||||
{ return Quaternion<ScalarType>(*this) += quaternion; }
|
{
|
||||||
|
return Quaternion<ScalarType>(*this) += quaternion;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( const Quaternion<ScalarType> &quaternion ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( const Quaternion<ScalarType> &quaternion ) const
|
||||||
{ return Quaternion<ScalarType>(*this) -= quaternion; }
|
{
|
||||||
|
return Quaternion<ScalarType>(*this) -= quaternion;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( ) const
|
||||||
{ return Quaternion<ScalarType>(-this->imaginary, -this->real); }
|
{
|
||||||
|
return Quaternion<ScalarType>(-this->imaginary, -this->real);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
inline Quaternion<ScalarType> Quaternion<ScalarType>::GetConjugate( ) const
|
inline Quaternion<ScalarType> Quaternion<ScalarType>::GetConjugate( ) const
|
||||||
{ return Quaternion<ScalarType>(-this->imaginary, this->real ); }
|
{
|
||||||
|
return Quaternion<ScalarType>(-this->imaginary, this->real );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -22,6 +22,13 @@ Box::Box( const Float4x4 &r, const Float3 &p, const Float3 &s ) : ICollideable(T
|
||||||
this->boundingOffset = Float4( s * 0.5f , 0.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 = s * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
Box::~Box( ) {}
|
Box::~Box( ) {}
|
||||||
|
|
||||||
Box & Box::operator = ( const Box &box )
|
Box & Box::operator = ( const Box &box )
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace Oyster { namespace Collision3D
|
||||||
|
|
||||||
Box( );
|
Box( );
|
||||||
Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &size );
|
Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &size );
|
||||||
|
Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float4 &worldPos, const ::Oyster::Math::Float4 &size );
|
||||||
virtual ~Box( );
|
virtual ~Box( );
|
||||||
|
|
||||||
Box & operator = ( const Box &box );
|
Box & operator = ( const Box &box );
|
||||||
|
|
|
@ -192,6 +192,15 @@ namespace Oyster { namespace Physics3D
|
||||||
return worldOffset.Cross( linearVelocity );
|
return worldOffset.Cross( linearVelocity );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* Returns the world angular velocity of a mass in rotation.
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 AngularVelocity( const ::Oyster::Math::Float4 &linearVelocity, const ::Oyster::Math::Float4 &worldOffset )
|
||||||
|
{
|
||||||
|
return ::Oyster::Math::Float4( worldOffset.xyz.Cross( linearVelocity.xyz ), 0.0f );
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* Returns the world tangential velocity at worldPos, of a mass in rotation.
|
* Returns the world tangential velocity at worldPos, of a mass in rotation.
|
||||||
* @todo TODO: improve doc
|
* @todo TODO: improve doc
|
||||||
|
@ -237,6 +246,15 @@ namespace Oyster { namespace Physics3D
|
||||||
return worldOffset.Cross( impulseForce );
|
return worldOffset.Cross( impulseForce );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
*
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 ImpulseTorque( const ::Oyster::Math::Float4 & impulseForce, const ::Oyster::Math::Float4 &worldOffset )
|
||||||
|
{
|
||||||
|
return ::Oyster::Math::Float4( worldOffset.xyz.Cross(impulseForce.xyz), 0.0f );
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* T = I*a
|
* T = I*a
|
||||||
* @todo TODO: improve doc
|
* @todo TODO: improve doc
|
||||||
|
@ -246,6 +264,15 @@ namespace Oyster { namespace Physics3D
|
||||||
return ( momentOfInertia * ::Oyster::Math::Float4(angularImpulseAcceleration, 0.0f) ).xyz;
|
return ( momentOfInertia * ::Oyster::Math::Float4(angularImpulseAcceleration, 0.0f) ).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* T = I*a
|
||||||
|
* @todo TODO: improve doc
|
||||||
|
******************************************************************/
|
||||||
|
inline ::Oyster::Math::Float4 ImpulseTorque( const ::Oyster::Math::Float4x4 & momentOfInertia, const ::Oyster::Math::Float4 &angularImpulseAcceleration )
|
||||||
|
{
|
||||||
|
return momentOfInertia * angularImpulseAcceleration;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MomentOfInertia
|
namespace MomentOfInertia
|
||||||
{ /// Library of Formulas to calculate moment of inerta for simple shapes
|
{ /// Library of Formulas to calculate moment of inerta for simple shapes
|
||||||
/** @todo TODO: add MomentOfInertia tensor formulas */
|
/** @todo TODO: add MomentOfInertia tensor formulas */
|
||||||
|
|
|
@ -159,6 +159,7 @@
|
||||||
<ClInclude Include="Point.h" />
|
<ClInclude Include="Point.h" />
|
||||||
<ClInclude Include="Ray.h" />
|
<ClInclude Include="Ray.h" />
|
||||||
<ClInclude Include="RigidBody.h" />
|
<ClInclude Include="RigidBody.h" />
|
||||||
|
<ClInclude Include="RigidBody_Inline.h" />
|
||||||
<ClInclude Include="Sphere.h" />
|
<ClInclude Include="Sphere.h" />
|
||||||
<ClInclude Include="Spring.h" />
|
<ClInclude Include="Spring.h" />
|
||||||
<ClInclude Include="Universe.h" />
|
<ClInclude Include="Universe.h" />
|
||||||
|
|
|
@ -75,6 +75,9 @@
|
||||||
<ClInclude Include="RigidBody.h">
|
<ClInclude Include="RigidBody.h">
|
||||||
<Filter>Header Files\Physics</Filter>
|
<Filter>Header Files\Physics</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="RigidBody_Inline.h">
|
||||||
|
<Filter>Header Files\Physics</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Box.cpp">
|
<ClCompile Include="Box.cpp">
|
||||||
|
|
|
@ -9,418 +9,201 @@ using namespace ::Oyster::Collision3D;
|
||||||
using namespace ::Oyster::Physics3D;
|
using namespace ::Oyster::Physics3D;
|
||||||
using namespace ::Oyster::Math3D;
|
using namespace ::Oyster::Math3D;
|
||||||
|
|
||||||
RigidBody::RigidBody( const Box &b, Float m, const Float4x4 &inertiaTensor )
|
RigidBody::RigidBody( )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->box = b;
|
this->centerPos = Float4::standard_unit_w;
|
||||||
this->angularMomentum = Float3::null;
|
this->axis = Float4::null;
|
||||||
this->linearMomentum = Float3::null;
|
this->boundingReach = Float4( 0.5f, 0.5f, 0.5f, 0.0f );
|
||||||
this->impulseTorqueSum = Float3::null;
|
this->momentum_Linear = Float4::null;
|
||||||
this->impulseForceSum = Float3::null;
|
this->momentum_Angular = Float4::null;
|
||||||
|
this->impulse_Linear = Float4::null;
|
||||||
|
this->impulse_Angular = Float4::null;
|
||||||
this->restitutionCoeff = 1.0f;
|
this->restitutionCoeff = 1.0f;
|
||||||
this->frictionCoeff_Static = 1.0f;
|
this->frictionCoeff_Static = 0.5f;
|
||||||
this->frictionCoeff_Kinetic = 1.0f;
|
this->frictionCoeff_Kinetic = 1.0f;
|
||||||
|
this->mass = 10;
|
||||||
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->momentOfInertiaTensor = Float4x4::identity;
|
this->momentOfInertiaTensor = Float4x4::identity;
|
||||||
}
|
this->rotation = Quaternion::identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
RigidBody & RigidBody::operator = ( const RigidBody &body )
|
RigidBody & RigidBody::operator = ( const RigidBody &body )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->box = body.box;
|
this->centerPos = body.centerPos;
|
||||||
this->angularMomentum = body.angularMomentum;
|
this->axis = body.axis;
|
||||||
this->linearMomentum = body.linearMomentum;
|
this->boundingReach = body.boundingReach;
|
||||||
this->impulseTorqueSum = body.impulseTorqueSum;
|
this->momentum_Linear = body.momentum_Linear;
|
||||||
this->impulseForceSum = body.impulseForceSum;
|
this->momentum_Angular = body.momentum_Angular;
|
||||||
|
this->impulse_Linear = body.impulse_Linear;
|
||||||
|
this->impulse_Angular = body.impulse_Angular;
|
||||||
this->restitutionCoeff = body.restitutionCoeff;
|
this->restitutionCoeff = body.restitutionCoeff;
|
||||||
this->frictionCoeff_Static = body.frictionCoeff_Static;
|
this->frictionCoeff_Static = body.frictionCoeff_Static;
|
||||||
this->frictionCoeff_Kinetic = body.frictionCoeff_Kinetic;
|
this->frictionCoeff_Kinetic = body.frictionCoeff_Kinetic;
|
||||||
this->mass = body.mass;
|
this->mass = body.mass;
|
||||||
this->momentOfInertiaTensor = body.momentOfInertiaTensor;
|
this->momentOfInertiaTensor = body.momentOfInertiaTensor;
|
||||||
|
this->rotation = body.rotation;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RigidBody::operator == ( const RigidBody &body )
|
void RigidBody::Update_LeapFrog( Float updateFrameLength )
|
||||||
{
|
|
||||||
if( this->box.center != body.box.center )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this->box.rotation != body.box.rotation )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this->box.boundingOffset != body.box.boundingOffset )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this->angularMomentum != body.angularMomentum )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this->linearMomentum != body.linearMomentum )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this->impulseTorqueSum != body.impulseTorqueSum )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this->impulseForceSum != body.impulseForceSum )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RigidBody::operator != ( const RigidBody &body )
|
|
||||||
{
|
|
||||||
return !this->operator==( body );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::Update_LeapFrog( Float deltaTime )
|
|
||||||
{ // by Dan Andersson: Euler leap frog update when Runga Kutta is not needed
|
{ // by Dan Andersson: Euler leap frog update when Runga Kutta is not needed
|
||||||
|
|
||||||
// Important! The member data is all world data except the Inertia tensor. Thus a new InertiaTensor needs to be created to be compatible with the rest of the world data.
|
|
||||||
Float4x4 wMomentOfInertiaTensor = TransformMatrix( this->box.rotation, this->momentOfInertiaTensor ); // RI
|
|
||||||
|
|
||||||
// updating the linear
|
// updating the linear
|
||||||
// dG = F * dt
|
|
||||||
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
|
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
|
||||||
Float3 linearImpulse = this->impulseForceSum; // HACK: * deltaTime; // aka deltaLinearMomentum
|
this->centerPos += ( updateFrameLength / this->mass ) * ::Utility::Value::AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
|
||||||
Float3 deltaPos = ( deltaTime / this->mass ) * ::Utility::Value::AverageWithDelta( this->linearMomentum, linearImpulse );
|
|
||||||
|
|
||||||
// updating the angular
|
// updating the angular
|
||||||
// dH = T * dt
|
Float4x4 rotationMatrix; ::Oyster::Math3D::RotationMatrix( this->rotation, rotationMatrix );
|
||||||
|
// Important! The member data is all world data except the Inertia tensor. Thus a new InertiaTensor needs to be created to be compatible with the rest of the world data.
|
||||||
|
Float4x4 wMomentOfInertiaTensor = TransformMatrix( rotationMatrix, this->momentOfInertiaTensor ); // RI
|
||||||
|
|
||||||
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
|
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
|
||||||
Float3 angularImpulse = this->impulseTorqueSum; // HACK: * deltaTime; // aka deltaAngularMomentum
|
this->axis += Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), ::Utility::Value::AverageWithDelta(this->momentum_Angular, this->impulse_Angular) );
|
||||||
Float3 rotationAxis = Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(),
|
this->rotation = Rotation( this->axis );
|
||||||
::Utility::Value::AverageWithDelta(this->angularMomentum, angularImpulse) );
|
|
||||||
|
|
||||||
Float deltaRadian = rotationAxis.Dot( rotationAxis );
|
// update momentums and clear impulse_Linear and impulse_Angular
|
||||||
if( deltaRadian != 0.0f )
|
this->momentum_Linear += this->impulse_Linear;
|
||||||
{ // branch depending if there is rotation
|
this->impulse_Linear = Float4::null;
|
||||||
deltaRadian = ::std::sqrt( deltaRadian );
|
this->momentum_Angular += this->impulse_Angular;
|
||||||
rotationAxis /= deltaRadian;
|
this->impulse_Angular = Float4::null;
|
||||||
|
|
||||||
// using rotationAxis, deltaRadian and deltaPos to create a matrix to update the box
|
|
||||||
this->box.center.xyz += deltaPos;
|
|
||||||
TransformMatrix( RotationMatrix(deltaRadian, rotationAxis), this->box.rotation, this->box.rotation );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // no rotation, only use deltaPos to translate the RigidBody
|
|
||||||
this->box.center.xyz += deltaPos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update momentums and clear impulseForceSum and impulseTorqueSum
|
void RigidBody::ApplyImpulse( const Float4 &worldJ, const Float4 &atWorldPos )
|
||||||
this->linearMomentum += linearImpulse;
|
|
||||||
this->impulseForceSum = Float3::null;
|
|
||||||
this->angularMomentum += angularImpulse;
|
|
||||||
this->impulseTorqueSum = Float3::null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::ApplyImpulseForce( const Float3 &worldF )
|
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->impulseForceSum += worldF;
|
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||||
}
|
if( worldOffset != Float4::null )
|
||||||
|
|
||||||
void RigidBody::ApplyImpulseForceAt( const Float3 &worldF, const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center.xyz;
|
|
||||||
if( worldOffset != Float3::null )
|
|
||||||
{
|
{
|
||||||
this->impulseForceSum += VectorProjection( worldF, worldOffset );
|
this->impulse_Linear += VectorProjection( worldJ, atWorldPos );
|
||||||
this->impulseTorqueSum += Formula::ImpulseTorque( worldF, worldOffset );
|
this->impulse_Angular += Formula::ImpulseTorque( worldJ, atWorldPos );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->impulseForceSum += worldF;
|
this->impulse_Linear += worldJ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::ApplyLinearImpulseAcceleration( const Float3 &worldA )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->impulseForceSum += Formula::ImpulseForce( this->mass, worldA );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::ApplyLinearImpulseAccelerationAt( const Float3 &worldA, const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center.xyz;
|
|
||||||
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.xyz;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Float3 & RigidBody::AccessBoundingReach() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->box.boundingOffset.xyz;
|
|
||||||
}
|
|
||||||
|
|
||||||
Float3 & RigidBody::AccessCenter()
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->box.center.xyz;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Float3 & RigidBody::AccessCenter() const
|
|
||||||
{ // by Dan Andersson
|
|
||||||
return this->box.center.xyz;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Float4x4 & RigidBody::GetMomentOfInertia() const
|
const Float4x4 & RigidBody::GetMomentOfInertia() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->momentOfInertiaTensor;
|
return this->momentOfInertiaTensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float & RigidBody::GetMass() const
|
Float RigidBody::GetMass() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->mass;
|
return this->mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float4x4 RigidBody::GetOrientation() const
|
const Quaternion & RigidBody::GetRotation() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return OrientationMatrix( this->box.rotation, this->box.center.xyz );
|
return this->rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 RigidBody::GetRotationMatrix() const
|
||||||
|
{ // by Dan Andersson
|
||||||
|
return RotationMatrix( this->rotation );
|
||||||
|
}
|
||||||
|
|
||||||
|
Float4x4 RigidBody::GetOrientation() const
|
||||||
|
{ // by Dan Andersson
|
||||||
|
return ::Oyster::Math3D::OrientationMatrix( this->rotation, this->centerPos );
|
||||||
}
|
}
|
||||||
|
|
||||||
Float4x4 RigidBody::GetView() const
|
Float4x4 RigidBody::GetView() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return InverseOrientationMatrix( this->GetOrientation() );
|
return ViewMatrix( this->rotation, this->centerPos );
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float3 & RigidBody::GetBoundingReach() const
|
Float4 RigidBody::GetVelocity_Linear() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->box.boundingOffset.xyz;
|
return Formula::LinearVelocity( this->mass, this->momentum_Linear );
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 RigidBody::GetSize() const
|
Float4 RigidBody::GetVelocity_Angular() const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return 2.0f * this->box.boundingOffset.xyz;
|
return Formula::AngularVelocity( this->momentOfInertiaTensor.GetInverse(), this->momentum_Angular );
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float3 & RigidBody::GetCenter() const
|
Float4 RigidBody::GetLinearMomentum( const Float4 &atWorldPos ) const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->box.center.xyz;
|
return this->momentum_Linear + Formula::TangentialLinearMomentum( this->momentum_Angular, atWorldPos - this->centerPos );
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float3 & RigidBody::GetImpulsTorque() const
|
void RigidBody::SetMomentOfInertia_KeepVelocity( const Float4x4 &localTensorI )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->impulseTorqueSum;
|
if( localTensorI.GetDeterminant() != 0.0f )
|
||||||
|
{ // insanity check! MomentOfInertiaTensor must be invertable
|
||||||
|
Float4x4 rotationMatrix; RotationMatrix( this->rotation, rotationMatrix );
|
||||||
|
|
||||||
|
Float4 w = Formula::AngularVelocity( (rotationMatrix * this->momentOfInertiaTensor).GetInverse(), this->momentum_Angular );
|
||||||
|
this->momentOfInertiaTensor = localTensorI;
|
||||||
|
this->momentum_Angular = Formula::AngularMomentum( rotationMatrix * localTensorI, w );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Float3 & RigidBody::GetAngularMomentum() const
|
void RigidBody::SetMomentOfInertia_KeepMomentum( const Float4x4 &localTensorI )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->angularMomentum;
|
if( localTensorI.GetDeterminant() != 0.0f )
|
||||||
}
|
{ // insanity check! MomentOfInertiaTensor must be invertable
|
||||||
|
this->momentOfInertiaTensor = localTensorI;
|
||||||
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.xyz;
|
|
||||||
Float3 momentum = Formula::TangentialLinearMomentum( this->angularMomentum, worldOffset );
|
|
||||||
momentum += this->linearMomentum;
|
|
||||||
|
|
||||||
normalMomentum = NormalProjection( momentum, surfaceNormal );
|
|
||||||
tangentialMomentum = momentum - normalMomentum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localI )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
if( localI.GetDeterminant() != 0.0f ) // insanitycheck! momentOfInertiaTensor must be invertable
|
|
||||||
{
|
|
||||||
Float3 w = Formula::AngularVelocity( (this->box.rotation * this->momentOfInertiaTensor).GetInverse(),
|
|
||||||
this->angularMomentum );
|
|
||||||
this->momentOfInertiaTensor = localI;
|
|
||||||
this->angularMomentum = Formula::AngularMomentum( this->box.rotation*localI, w );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetMomentOfInertia_KeepMomentum( const Float4x4 &localI )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
if( localI.GetDeterminant() != 0.0f ) // insanitycheck! momentOfInertiaTensor must be invertable
|
|
||||||
{
|
|
||||||
this->momentOfInertiaTensor = localI;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetMass_KeepVelocity( const Float &m )
|
void RigidBody::SetMass_KeepVelocity( const Float &m )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
if( m != 0.0f ) // insanitycheck! mass must be invertable
|
if( m != 0.0f )
|
||||||
{
|
{ // insanity check! Mass must be invertable
|
||||||
Float3 v = Formula::LinearVelocity( this->mass, this->linearMomentum );
|
Float4 v = Formula::LinearVelocity( this->mass, this->momentum_Linear );
|
||||||
this->mass = m;
|
this->mass = m;
|
||||||
this->linearMomentum = Formula::LinearMomentum( this->mass, v );
|
this->momentum_Linear = Formula::LinearMomentum( this->mass, v );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetMass_KeepMomentum( const Float &m )
|
void RigidBody::SetMass_KeepMomentum( const Float &m )
|
||||||
{ // by Dan Anderson
|
{ // by Dan Anderson
|
||||||
if( m != 0.0f ) // insanitycheck! mass must be invertable
|
if( m != 0.0f )
|
||||||
{
|
{ // insanity check! Mass must be invertable
|
||||||
this->mass = m;
|
this->mass = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetOrientation( const Float4x4 &o )
|
void RigidBody::SetOrientation( const Float4x4 &o )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
ExtractRotationMatrix( o, this->box.rotation );
|
this->axis = ExtractAngularAxis( o );
|
||||||
this->box.center = o.v[3].xyz;
|
this->rotation = Rotation( this->axis );
|
||||||
}
|
this->centerPos = o.v[3].xyz;
|
||||||
|
|
||||||
void RigidBody::SetSize( const Float3 &widthHeight )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->box.boundingOffset = 0.5f * widthHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetCenter( const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->box.center = worldPos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetRotation( const Float4x4 &r )
|
void RigidBody::SetRotation( const Float4x4 &r )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->box.rotation = r;
|
this->axis = ExtractAngularAxis( r );
|
||||||
|
this->rotation = Rotation( this->axis );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetImpulseTorque( const Float3 &worldT )
|
void RigidBody::SetMomentum_Linear( const Float4 &worldG, const Float4 &atWorldPos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->impulseTorqueSum = worldT;
|
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||||
|
this->momentum_Linear = VectorProjection( worldG, worldOffset );
|
||||||
|
this->momentum_Angular = Formula::AngularMomentum( worldG, worldOffset );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetAngularMomentum( const Float3 &worldH )
|
void RigidBody::SetVelocity_Linear( const Float4 &worldV )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->angularMomentum = worldH;
|
this->momentum_Linear = Formula::LinearMomentum( this->mass, worldV );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetAngularImpulseAcceleration( const Float3 &worldA )
|
void RigidBody::SetVelocity_Linear( const Float4 &worldV, const Float4 &atWorldPos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->impulseTorqueSum = Formula::ImpulseTorque( this->momentOfInertiaTensor, worldA );
|
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||||
|
this->momentum_Linear = Formula::LinearMomentum( this->mass, VectorProjection(worldV, worldOffset) );
|
||||||
|
this->momentum_Angular = Formula::AngularMomentum( RotationMatrix(this->rotation) * this->momentOfInertiaTensor, Formula::AngularVelocity(worldV, worldOffset) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetAngularVelocity( const Float3 &worldW )
|
void RigidBody::SetVelocity_Angular( const Float4 &worldW )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->angularMomentum = Formula::AngularMomentum( this->momentOfInertiaTensor, worldW );
|
this->momentum_Angular = Formula::AngularMomentum( this->momentOfInertiaTensor, worldW );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetImpulseForce( const Float3 &worldF )
|
void RigidBody::SetImpulse_Linear( const Float4 &worldJ, const Float4 &atWorldPos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
this->impulseForceSum = worldF;
|
Float4 worldOffset = atWorldPos - this->centerPos;
|
||||||
}
|
this->impulse_Linear = VectorProjection( worldJ, worldOffset );
|
||||||
|
this->impulse_Angular = Formula::ImpulseTorque( worldJ, worldOffset );
|
||||||
void RigidBody::SetLinearMomentum( const Float3 &worldG )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->linearMomentum = worldG;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetLinearImpulseAcceleration( const Float3 &worldA )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->impulseForceSum = Formula::ImpulseForce( this->mass, worldA );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetLinearVelocity( const Float3 &worldV )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
this->linearMomentum = Formula::LinearMomentum( this->mass, worldV );
|
|
||||||
}
|
|
||||||
|
|
||||||
void RigidBody::SetImpulseForceAt( const Float3 &worldForce, const Float3 &worldPos )
|
|
||||||
{ // by Dan Andersson
|
|
||||||
Float3 worldOffset = worldPos - this->box.center.xyz;
|
|
||||||
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.xyz;
|
|
||||||
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.xyz;
|
|
||||||
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.xyz;
|
|
||||||
this->linearMomentum = Formula::LinearMomentum( this->mass, VectorProjection(worldV, worldOffset) );
|
|
||||||
this->angularMomentum = Formula::AngularMomentum( this->box.rotation * this->momentOfInertiaTensor,
|
|
||||||
Formula::AngularVelocity(worldV, worldOffset) );
|
|
||||||
}
|
}
|
|
@ -12,110 +12,74 @@
|
||||||
namespace Oyster { namespace Physics3D
|
namespace Oyster { namespace Physics3D
|
||||||
{
|
{
|
||||||
struct RigidBody
|
struct RigidBody
|
||||||
{ /// A struct of a simple rigid body.
|
{ //! A struct of a simple rigid body.
|
||||||
public:
|
public:
|
||||||
::Oyster::Collision3D::Box box; /** Contains data representing physical presence. (worldValue) */
|
::Oyster::Math::Float4 centerPos, //!< Location of the body's center in the world.
|
||||||
::Oyster::Math::Float3 angularMomentum, /** The angular momentum H (Nm*s) around an parallell axis. (worldValue) */
|
axis, //!< Euler rotationAxis of the body.
|
||||||
linearMomentum, /** The linear momentum G (kg*m/s). (worldValue) */
|
boundingReach, //!<
|
||||||
impulseTorqueSum, /** The impulse torque T (Nm) that will be consumed each update. (worldValue) */
|
momentum_Linear, //!< The linear momentum G (kg*m/s).
|
||||||
impulseForceSum; /** The impulse force F (N) that will be consumed each update. (worldValue) */
|
momentum_Angular, //!< The angular momentum H (Nm*s) around an parallell axis.
|
||||||
::Oyster::Math::Float restitutionCoeff, frictionCoeff_Static, frictionCoeff_Kinetic;
|
impulse_Linear, //!< The linear impulse sum Jl (kg*m/s) that will be consumed each update.
|
||||||
|
impulse_Angular; //!< The angular impulse sum Ja (kg*m^2/s) that will be consumed each update.
|
||||||
|
::Oyster::Math::Float restitutionCoeff, //!<
|
||||||
|
frictionCoeff_Static, //!<
|
||||||
|
frictionCoeff_Kinetic; //!<
|
||||||
|
|
||||||
RigidBody( const ::Oyster::Collision3D::Box &box = ::Oyster::Collision3D::Box(),
|
RigidBody();
|
||||||
::Oyster::Math::Float mass = 12.0f,
|
|
||||||
const ::Oyster::Math::Float4x4 &inertiaTensor = ::Oyster::Math::Float4x4::identity );
|
|
||||||
|
|
||||||
RigidBody & operator = ( const RigidBody &body );
|
RigidBody & operator = ( const RigidBody &body );
|
||||||
|
|
||||||
bool operator == ( const RigidBody &body );
|
void Update_LeapFrog( ::Oyster::Math::Float updateFrameLength );
|
||||||
bool operator != ( const RigidBody &body );
|
|
||||||
|
|
||||||
void Update_LeapFrog( ::Oyster::Math::Float deltaTime );
|
void ApplyImpulse( const ::Oyster::Math::Float4 &worldJ, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void ApplyImpulseForce( const ::Oyster::Math::Float3 &worldF );
|
void ApplyImpulse_Linear( const ::Oyster::Math::Float4 &worldJ );
|
||||||
void ApplyImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos );
|
void ApplyImpulse_Angular( const ::Oyster::Math::Float4 &worldJ );
|
||||||
void ApplyLinearImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
void ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength );
|
||||||
void ApplyLinearImpulseAccelerationAt( const ::Oyster::Math::Float3 &worldA, const ::Oyster::Math::Float3 &worldPos );
|
void ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
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;
|
|
||||||
|
|
||||||
// GET METHODS ////////////////////////////////
|
// GET METHODS ////////////////////////////////
|
||||||
|
|
||||||
const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const;
|
const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const;
|
||||||
const ::Oyster::Math::Float & GetMass() const;
|
::Oyster::Math::Float GetMass() const;
|
||||||
|
const ::Oyster::Math::Quaternion & GetRotation() const;
|
||||||
const ::Oyster::Math::Float4x4 GetOrientation() const;
|
::Oyster::Math::Float4x4 GetRotationMatrix() const;
|
||||||
|
::Oyster::Math::Float4x4 GetOrientation() const;
|
||||||
::Oyster::Math::Float4x4 GetView() const;
|
::Oyster::Math::Float4x4 GetView() const;
|
||||||
const ::Oyster::Math::Float4x4 & GetToWorldMatrix() const;
|
::Oyster::Math::Float4x4 GetToWorldMatrix() const;
|
||||||
::Oyster::Math::Float4x4 GetToLocalMatrix() const;
|
::Oyster::Math::Float4x4 GetToLocalMatrix() const;
|
||||||
|
::Oyster::Math::Float4 GetSize() const;
|
||||||
const ::Oyster::Math::Float3 & GetBoundingReach() const;
|
::Oyster::Math::Float4 GetVelocity_Linear() const;
|
||||||
::Oyster::Math::Float3 GetSize() const;
|
::Oyster::Math::Float4 GetVelocity_Angular() const;
|
||||||
|
::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float4 &atWorldPos ) const;
|
||||||
const ::Oyster::Math::Float3 & GetCenter() const;
|
|
||||||
|
|
||||||
const ::Oyster::Math::Float3 & GetImpulsTorque() const;
|
|
||||||
const ::Oyster::Math::Float3 & GetAngularMomentum() const;
|
|
||||||
::Oyster::Math::Float3 GetAngularImpulseAcceleration() const;
|
|
||||||
::Oyster::Math::Float3 GetAngularVelocity() const;
|
|
||||||
|
|
||||||
const ::Oyster::Math::Float3 & GetImpulseForce() const;
|
|
||||||
const ::Oyster::Math::Float3 & GetLinearMomentum() const;
|
|
||||||
::Oyster::Math::Float3 GetLinearImpulseAcceleration() const;
|
|
||||||
::Oyster::Math::Float3 GetLinearVelocity() const;
|
|
||||||
|
|
||||||
void GetMomentumAt( const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &surfaceNormal, ::Oyster::Math::Float3 &normalMomentum, ::Oyster::Math::Float3 &tangentialMomentum ) const;
|
|
||||||
|
|
||||||
// SET METHODS ////////////////////////////////
|
// SET METHODS ////////////////////////////////
|
||||||
|
|
||||||
void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localI );
|
void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localTensorI );
|
||||||
void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &localI );
|
void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &localTensorI );
|
||||||
void SetMass_KeepVelocity( const ::Oyster::Math::Float &m );
|
void SetMass_KeepVelocity( const ::Oyster::Math::Float &m );
|
||||||
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
|
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
|
||||||
|
|
||||||
void SetOrientation( const ::Oyster::Math::Float4x4 &o );
|
void SetOrientation( const ::Oyster::Math::Float4x4 &o );
|
||||||
void SetSize( const ::Oyster::Math::Float3 &widthHeight );
|
|
||||||
void SetCenter( const ::Oyster::Math::Float3 &worldPos );
|
|
||||||
void SetRotation( const ::Oyster::Math::Float4x4 &r );
|
void SetRotation( const ::Oyster::Math::Float4x4 &r );
|
||||||
|
void SetSize( const ::Oyster::Math::Float4 &widthHeight );
|
||||||
|
|
||||||
void SetImpulseTorque( const ::Oyster::Math::Float3 &worldT );
|
void SetMomentum_Linear( const ::Oyster::Math::Float4 &worldG, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void SetAngularMomentum( const ::Oyster::Math::Float3 &worldH );
|
|
||||||
void SetAngularImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
|
||||||
void SetAngularVelocity( const ::Oyster::Math::Float3 &worldW );
|
|
||||||
|
|
||||||
void SetImpulseForce( const ::Oyster::Math::Float3 &worldF );
|
void SetVelocity_Linear( const ::Oyster::Math::Float4 &worldV );
|
||||||
void SetLinearMomentum( const ::Oyster::Math::Float3 &worldG );
|
void SetVelocity_Linear( const ::Oyster::Math::Float4 &worldV, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void SetLinearImpulseAcceleration( const ::Oyster::Math::Float3 &worldA );
|
void SetVelocity_Angular( const ::Oyster::Math::Float4 &worldW );
|
||||||
void SetLinearVelocity( const ::Oyster::Math::Float3 &worldV );
|
|
||||||
|
|
||||||
void SetImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos );
|
void SetImpulse_Linear( const ::Oyster::Math::Float4 &worldJ, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void SetLinearMomentumAt( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &worldPos );
|
void SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength );
|
||||||
void SetImpulseAccelerationAt( const ::Oyster::Math::Float3 &worldA, const ::Oyster::Math::Float3 &worldPos );
|
void SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos );
|
||||||
void SetLinearVelocityAt( const ::Oyster::Math::Float3 &worldV, const ::Oyster::Math::Float3 &worldPos );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Oyster::Math::Float mass; /** m (kg) */
|
::Oyster::Math::Float mass; //!< m (kg)
|
||||||
::Oyster::Math::Float4x4 momentOfInertiaTensor; /** I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue) */
|
::Oyster::Math::Float4x4 momentOfInertiaTensor; //!< I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue)
|
||||||
|
::Oyster::Math::Quaternion rotation; //!< RotationAxis of the body.
|
||||||
};
|
};
|
||||||
|
|
||||||
// INLINE IMPLEMENTATIONS ///////////////////////////////////////
|
|
||||||
|
|
||||||
inline const ::Oyster::Math::Float4x4 & RigidBody::GetToWorldMatrix() const
|
|
||||||
{
|
|
||||||
return this->GetOrientation();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ::Oyster::Math::Float4x4 RigidBody::GetToLocalMatrix() const
|
|
||||||
{
|
|
||||||
return this->GetView();
|
|
||||||
}
|
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
#include "RigidBody_Inline.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// INLINE IMPLEMENTATIONS
|
||||||
|
// Created by Dan Andersson 2013
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef OYSTER_PHYSICS_3D_RIGIDBODY_INLINE_H
|
||||||
|
#define OYSTER_PHYSICS_3D_RIGIDBODY_INLINE_H
|
||||||
|
|
||||||
|
#include "RigidBody.h"
|
||||||
|
|
||||||
|
namespace Oyster { namespace Physics3D
|
||||||
|
{
|
||||||
|
inline void RigidBody::ApplyImpulse_Linear( const ::Oyster::Math::Float4 &worldJ )
|
||||||
|
{
|
||||||
|
this->impulse_Linear += worldJ;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::ApplyImpulse_Angular( const ::Oyster::Math::Float4 &worldJ )
|
||||||
|
{
|
||||||
|
this->impulse_Angular += worldJ;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength )
|
||||||
|
{
|
||||||
|
this->impulse_Linear += worldF * updateFrameLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::ApplyForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos )
|
||||||
|
{
|
||||||
|
this->ApplyImpulse( worldF * updateFrameLength, atWorldPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 RigidBody::GetToWorldMatrix() const
|
||||||
|
{
|
||||||
|
return this->GetOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4x4 RigidBody::GetToLocalMatrix() const
|
||||||
|
{
|
||||||
|
return this->GetView();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::Oyster::Math::Float4 RigidBody::GetSize() const
|
||||||
|
{
|
||||||
|
return 2.0f * this->boundingReach;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::SetSize( const ::Oyster::Math::Float4 &widthHeight )
|
||||||
|
{
|
||||||
|
this->boundingReach = ::Utility::Value::Abs( 0.5f * widthHeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength )
|
||||||
|
{
|
||||||
|
this->impulse_Linear = worldF * updateFrameLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RigidBody::SetForce( const ::Oyster::Math::Float4 &worldF, ::Oyster::Math::Float updateFrameLength, const ::Oyster::Math::Float4 &atWorldPos )
|
||||||
|
{
|
||||||
|
this->SetImpulse_Linear( worldF * updateFrameLength, atWorldPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
} }
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue