Merge remote-tracking branch 'origin/Physics' into GameLogic

This commit is contained in:
lindaandersson 2014-01-16 09:30:30 +01:00
commit a070e4d459
10 changed files with 531 additions and 301 deletions

View File

@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

View File

@ -38,6 +38,27 @@ namespace
Float protoG_Magnitude = protoG.Dot( normal ),
deuterG_Magnitude = deuterG.Dot( normal );
// if they are not relatively moving towards eachother, there is no collision
Float deltaPos = normal.Dot( deuterState.GetCenterPosition() - protoState.GetCenterPosition() );
if( deltaPos < 0.0f )
{
if( protoG_Magnitude >= deuterG_Magnitude )
{
break;
}
}
else if( deltaPos > 0.0f )
{
if( protoG_Magnitude <= deuterG_Magnitude )
{
break;
}
}
else
{
break;
}
// bounce
Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(),
deuterState.GetMass(), deuterG_Magnitude,
@ -65,14 +86,14 @@ namespace
//sumJ += ( 1 / deuterState.GetMass() )*frictionImpulse;
// FRICTION END
Float4 forwardedDeltaPos, forwardedDeltaAxis;
{ // @todo TODO: is this right?
Float4 bounceAngularImpulse = ::Oyster::Math::Float4( (worldPointOfContact - protoState.GetCenterPosition()).xyz.Cross(bounce.xyz), 0.0f ),
bounceLinearImpulse = bounce - bounceAngularImpulse;
proto->Predict( forwardedDeltaPos, forwardedDeltaAxis, bounceLinearImpulse, bounceAngularImpulse, API_instance.GetFrameTimeLength() );
}
// Float4 forwardedDeltaPos, forwardedDeltaAxis;
// { // @todo TODO: is this right?
// Float4 bounceAngularImpulse = ::Oyster::Math::Float4( (worldPointOfContact - protoState.GetCenterPosition()).xyz.Cross(bounce.xyz), 0.0f ),
// bounceLinearImpulse = bounce - bounceAngularImpulse;
// proto->Predict( forwardedDeltaPos, forwardedDeltaAxis, bounceLinearImpulse, bounceAngularImpulse, API_instance.GetFrameTimeLength() );
// }
protoState.ApplyForwarding( forwardedDeltaPos, forwardedDeltaAxis );
// protoState.ApplyForwarding( forwardedDeltaPos, forwardedDeltaAxis );
protoState.ApplyImpulse( bounce, worldPointOfContact, normal );
proto->SetState( protoState );
}

View File

@ -113,6 +113,8 @@ void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
this->rigid.SetMass_KeepMomentum( state.GetMass() );
this->rigid.SetMomentOfInertia_KeepMomentum( state.GetMomentOfInertia() );
if( state.IsForwarded() )
{

View File

@ -83,6 +83,8 @@ void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
this->rigid.restitutionCoeff = state.GetRestitutionCoeff();
this->rigid.frictionCoeff_Static = state.GetFrictionCoeff_Static();
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
this->rigid.SetMass_KeepMomentum( state.GetMass() );
this->rigid.SetMomentOfInertia_KeepMomentum( state.GetMomentOfInertia() );
if( state.IsForwarded() )
{

View File

@ -2,15 +2,18 @@
#define PHYSICS_STRUCTS_IMPL_H
#include "PhysicsStructs.h"
#include "OysterPhysics3D.h"
namespace Oyster { namespace Physics
namespace Oyster
{
namespace Physics
{
namespace Struct
{
inline SimpleBodyDescription::SimpleBodyDescription()
{
this->rotation = ::Oyster::Math::Float4x4::identity;
this->centerPosition = ::Oyster::Math::Float4::null;
this->centerPosition = ::Oyster::Math::Float4::standard_unit_w;
this->size = ::Oyster::Math::Float4( 1.0f );
this->mass = 12.0f;
this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
@ -21,7 +24,7 @@ namespace Oyster { namespace Physics
inline SphericalBodyDescription::SphericalBodyDescription()
{
this->rotation = ::Oyster::Math::Float4x4::identity;
this->centerPosition = ::Oyster::Math::Float4::null;
this->centerPosition = ::Oyster::Math::Float4::standard_unit_w;
this->radius = 0.5f;
this->mass = 10.0f;
this->subscription = NULL;
@ -122,11 +125,21 @@ namespace Oyster { namespace Physics
return ::Oyster::Math3D::OrientationMatrix( this->angularAxis.xyz, this->centerPos.xyz );
}
inline ::Oyster::Math::Float4x4 CustomBodyState::GetOrientation( const ::Oyster::Math::Float4 &offset ) const
{
return ::Oyster::Math3D::OrientationMatrix( this->angularAxis.xyz, (this->centerPos + offset).xyz );
}
inline ::Oyster::Math::Float4x4 CustomBodyState::GetView() const
{
return ::Oyster::Math3D::ViewMatrix( this->angularAxis.xyz, this->centerPos.xyz );
}
inline ::Oyster::Math::Float4x4 CustomBodyState::GetView( const ::Oyster::Math::Float4 &offset ) const
{
return ::Oyster::Math3D::ViewMatrix( this->angularAxis.xyz, (this->centerPos + offset).xyz );
}
inline const ::Oyster::Math::Float4 & CustomBodyState::GetLinearMomentum() const
{
return this->linearMomentum;
@ -134,8 +147,7 @@ namespace Oyster { namespace Physics
inline ::Oyster::Math::Float4 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float4 &at ) const
{
//return this->linearMomentum + ::Oyster::Physics3D::Formula::TangentialLinearMomentum( this->angularMomentum, at - this->centerPos ); // C3083 error?
return this->linearMomentum + ::Oyster::Math::Float4( this->angularMomentum.xyz.Cross((at - this->centerPos).xyz), 0.0f );
return this->linearMomentum + ::Oyster::Physics3D::Formula::TangentialLinearMomentum( this->angularMomentum, at - this->centerPos );
}
inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularMomentum() const
@ -200,11 +212,9 @@ namespace Oyster { namespace Physics
if( tensor.GetDeterminant() != 0.0f )
{ // sanity block!
::Oyster::Math::Float4x4 rotation = ::Oyster::Math3D::RotationMatrix(this->angularAxis.xyz);
//::Oyster::Math::Float4 w = ::Oyster::Physics3D::Formula::AngularVelocity( (rotation * this->inertiaTensor).GetInverse(), this->angularMomentum ); // C3083 error?
::Oyster::Math::Float4 w = (rotation * this->inertiaTensor).GetInverse() * this->angularMomentum;
::Oyster::Math::Float4 w = ::Oyster::Physics3D::Formula::AngularVelocity( (rotation * this->inertiaTensor).GetInverse(), this->angularMomentum );
this->inertiaTensor = tensor;
//this->angularMomentum = ::Oyster::Physics3D::Formula::AngularMomentum( rotation * tensor, w ); // C3083 error?
this->angularMomentum = rotation * tensor * w;
this->angularMomentum = ::Oyster::Physics3D::Formula::AngularMomentum( rotation * tensor, w );
}
}
@ -293,10 +303,10 @@ namespace Oyster { namespace Physics
inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float4 &j, const ::Oyster::Math::Float4 &at, const ::Oyster::Math::Float4 &normal )
{
//::Oyster::Math::Float4 tangentialImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, at - this->centerPos ); // C3083 error?
::Oyster::Math::Float4 tangentialImpulse = ::Oyster::Math::Float4( (at - this->centerPos).xyz.Cross(j.xyz), 0.0f );
this->linearImpulse += j - tangentialImpulse;
this->angularImpulse += tangentialImpulse;
::Oyster::Math::Float4 offset = at - this->centerPos;
::Oyster::Math::Float4 deltaAngularImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, offset );
this->linearImpulse += j - ::Oyster::Physics3D::Formula::TangentialLinearMomentum( deltaAngularImpulse, offset );
this->angularImpulse += deltaAngularImpulse;
this->isDisturbed = true;
}
@ -322,7 +332,113 @@ namespace Oyster { namespace Physics
{
return this->isForwarded;
}
inline GravityWell::GravityWell( )
{
this->position = ::Oyster::Math::Float3::null;
this->mass = 0.0f;
}
inline GravityWell::GravityWell( const GravityWell &gravityWell )
{
this->position = gravityWell.position;
this->mass = gravityWell.mass;
}
inline GravityWell & GravityWell::operator = ( const GravityWell &gravityWell )
{
this->position = gravityWell.position;
this->mass = gravityWell.mass;
return *this;
}
inline GravityDirected::GravityDirected( )
{
this->impulse = ::Oyster::Math::Float3::null;
}
inline GravityDirected::GravityDirected( const GravityDirected &gravityDirected )
{
this->impulse = gravityDirected.impulse;
}
inline GravityDirected & GravityDirected::operator = ( const GravityDirected &gravityDirected )
{
this->impulse = gravityDirected.impulse;
return *this;
}
inline GravityDirectedField::GravityDirectedField( )
{
this->normalizedDirection = ::Oyster::Math::Float3::null;
this->mass = 0.0f;
this->magnitude = 0.0f;
}
inline GravityDirectedField::GravityDirectedField( const GravityDirectedField &gravityDirectedField )
{
this->normalizedDirection = gravityDirectedField.normalizedDirection;
this->mass = gravityDirectedField.mass;
this->magnitude = gravityDirectedField.magnitude;
}
inline GravityDirectedField & GravityDirectedField::operator = ( const GravityDirectedField &gravityDirectedField )
{
this->normalizedDirection = gravityDirectedField.normalizedDirection;
this->mass = gravityDirectedField.mass;
this->magnitude = gravityDirectedField.magnitude;
return *this;
}
inline Gravity::Gravity()
{
this->gravityType = GravityType_Undefined;
}
inline Gravity::Gravity( const Gravity &gravity )
{
this->gravityType = gravity.gravityType;
switch( gravity.gravityType )
{
case GravityType_Well:
this->well = gravity.well;
break;
case GravityType_Directed:
this->directed = gravity.directed;
break;
case GravityType_DirectedField:
this->directedField = gravity.directedField;
break;
default: break;
}
}
inline Gravity & Gravity::operator = ( const Gravity &gravity )
{
this->gravityType = gravity.gravityType;
switch( gravity.gravityType )
{
case GravityType_Well:
this->well = gravity.well;
break;
case GravityType_Directed:
this->directed = gravity.directed;
break;
case GravityType_DirectedField:
this->directedField = gravity.directedField;
break;
default: break;
}
return *this;
}
}
}
}
} }
#endif

View File

@ -60,7 +60,9 @@ namespace Oyster { namespace Physics
const ::Oyster::Math::Float4 & GetAngularAxis() const;
::Oyster::Math::Float4x4 GetRotation() const;
::Oyster::Math::Float4x4 GetOrientation() const;
::Oyster::Math::Float4x4 GetOrientation( const ::Oyster::Math::Float4 &offset ) const;
::Oyster::Math::Float4x4 GetView() const;
::Oyster::Math::Float4x4 GetView( const ::Oyster::Math::Float4 &offset ) const;
const ::Oyster::Math::Float4 & GetLinearMomentum() const;
::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float4 &at ) const;
const ::Oyster::Math::Float4 & GetAngularMomentum() const;
@ -108,9 +110,78 @@ namespace Oyster { namespace Physics
bool isSpatiallyAltered, isDisturbed, isForwarded;
};
/**
###############################################################################
Can't define structs inside structs in a union therefor they are declared here.
###############################################################################
*/
struct GravityWell
{
::Oyster::Math::Float3 position;
::Oyster::Math::Float mass;
GravityWell( );
GravityWell( const GravityWell &gravityWell );
GravityWell& operator=( const GravityWell &gravityWell );
};
struct GravityDirected
{
::Oyster::Math::Float3 impulse;
GravityDirected( );
GravityDirected( const GravityDirected &gravityDirected );
GravityDirected & operator = ( const GravityDirected &gravityDirected );
};
struct GravityDirectedField
{
::Oyster::Math::Float3 normalizedDirection;
::Oyster::Math::Float mass;
::Oyster::Math::Float magnitude;
GravityDirectedField( );
GravityDirectedField( const GravityDirectedField &gravityDirectedField );
GravityDirectedField & operator=( const GravityDirectedField &gravityDirectedField );
};
struct Gravity
{
enum GravityType
{
GravityType_Undefined = -1,
GravityType_Well = 0,
GravityType_Directed = 1,
GravityType_DirectedField = 2,
} gravityType;
union
{
struct
{
GravityWell well;
};
struct
{
GravityDirected directed;
};
struct
{
GravityDirectedField directedField;
};
};
Gravity( );
Gravity( const Gravity &gravity );
Gravity & operator = ( const Gravity &gravity );
};
}
} }
#include "PhysicsStructs-Impl.h"
#endif

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram />

View File

@ -63,7 +63,7 @@ namespace Oyster { namespace Physics3D
******************************************************************/
inline ::Oyster::Math::Float4 TangentialLinearMomentum( const ::Oyster::Math::Float4 &angularMomentum, const ::Oyster::Math::Float4 &worldOffset )
{
return ::Oyster::Math::Float4( angularMomentum.xyz.Cross(worldOffset.xyz), 0.0f );
return ::Oyster::Math::Float4( angularMomentum.xyz.Cross(worldOffset.xyz), 0.0f ) /= worldOffset.Dot( worldOffset );
}
/******************************************************************
@ -126,7 +126,7 @@ namespace Oyster { namespace Physics3D
******************************************************************/
inline ::Oyster::Math::Float3 TangentialLinearMomentum( const ::Oyster::Math::Float3 &angularMomentum, const ::Oyster::Math::Float3 &worldOffset )
{
return angularMomentum.Cross( worldOffset );
return angularMomentum.Cross( worldOffset ) /= worldOffset.Dot( worldOffset );
}
/******************************************************************
@ -135,7 +135,7 @@ namespace Oyster { namespace Physics3D
******************************************************************/
inline ::Oyster::Math::Float3 TangentialLinearMomentum( const ::Oyster::Math::Float4x4 &momentOfInertia, const ::Oyster::Math::Float3 &angularVelocity, const ::Oyster::Math::Float3 &worldOffset )
{
return TangentialLinearMomentum( AngularMomentum(momentOfInertia, angularVelocity), worldOffset );
return TangentialLinearMomentum( AngularMomentum(momentOfInertia, angularVelocity), worldOffset ) /= worldOffset.Dot( worldOffset );
}
/******************************************************************
@ -144,7 +144,7 @@ namespace Oyster { namespace Physics3D
******************************************************************/
inline ::Oyster::Math::Float3 TangentialImpulseForce( const ::Oyster::Math::Float3 &impulseTorque, const ::Oyster::Math::Float3 &worldOffset )
{
return impulseTorque.Cross( worldOffset );
return impulseTorque.Cross( worldOffset ) /= worldOffset.Dot( worldOffset );
}
/******************************************************************
@ -207,7 +207,7 @@ namespace Oyster { namespace Physics3D
******************************************************************/
inline ::Oyster::Math::Float3 TangentialLinearVelocity( const ::Oyster::Math::Float3 &angularVelocity, const ::Oyster::Math::Float3 &worldOffset )
{
return angularVelocity.Cross( worldOffset );
return angularVelocity.Cross( worldOffset ) /= worldOffset.Dot( worldOffset );
}
/******************************************************************

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
</Project>

View File

@ -58,7 +58,7 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength )
Float4x4 wMomentOfInertiaTensor = TransformMatrix( rotationMatrix, this->momentOfInertiaTensor ); // RI
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
this->axis += Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, this->impulse_Angular) );
this->axis += Radian( Formula::AngularVelocity(wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, this->impulse_Angular)) );
this->rotation = Rotation( this->axis );
// update momentums and clear impulse_Linear and impulse_Angular