diff --git a/Code/GamePhysics/GamePhysics.vcxproj.user b/Code/GamePhysics/GamePhysics.vcxproj.user index 9a0b0ae0..4b847ee6 100644 --- a/Code/GamePhysics/GamePhysics.vcxproj.user +++ b/Code/GamePhysics/GamePhysics.vcxproj.user @@ -1,6 +1,22 @@  - true + false + + + $(OutDir) + WindowsLocalDebugger + + + $(OutDir) + WindowsLocalDebugger + + + $(OutDir) + WindowsLocalDebugger + + + $(OutDir) + WindowsLocalDebugger \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index f917407b..b3abf32c 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -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 ); } diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 09855984..49fa292f 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -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() ) { diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index 95901763..2d96412c 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -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() ) { diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index e7704460..c74c6537 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -2,327 +2,443 @@ #define PHYSICS_STRUCTS_IMPL_H #include "PhysicsStructs.h" +#include "OysterPhysics3D.h" -namespace Oyster { namespace Physics -{ - namespace Struct +namespace Oyster +{ + namespace Physics { - inline SimpleBodyDescription::SimpleBodyDescription() + namespace Struct { - this->rotation = ::Oyster::Math::Float4x4::identity; - this->centerPosition = ::Oyster::Math::Float4::null; - this->size = ::Oyster::Math::Float4( 1.0f ); - this->mass = 12.0f; - this->inertiaTensor = ::Oyster::Math::Float4x4::identity; - this->subscription = NULL; - this->ignoreGravity = false; - } + inline SimpleBodyDescription::SimpleBodyDescription() + { + this->rotation = ::Oyster::Math::Float4x4::identity; + 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; + this->subscription = NULL; + this->ignoreGravity = false; + } - inline SphericalBodyDescription::SphericalBodyDescription() - { - this->rotation = ::Oyster::Math::Float4x4::identity; - this->centerPosition = ::Oyster::Math::Float4::null; - this->radius = 0.5f; - this->mass = 10.0f; - this->subscription = NULL; - this->ignoreGravity = false; - } + inline SphericalBodyDescription::SphericalBodyDescription() + { + this->rotation = ::Oyster::Math::Float4x4::identity; + this->centerPosition = ::Oyster::Math::Float4::standard_unit_w; + this->radius = 0.5f; + this->mass = 10.0f; + this->subscription = NULL; + this->ignoreGravity = false; + } - inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float kineticFrictionCoeff, const ::Oyster::Math::Float4x4 &inertiaTensor, const ::Oyster::Math::Float4 &reach, const ::Oyster::Math::Float4 ¢erPos, const ::Oyster::Math::Float4 &rotation, const ::Oyster::Math::Float4 &linearMomentum, const ::Oyster::Math::Float4 &angularMomentum ) - { - this->mass = mass; - this->restitutionCoeff = restitutionCoeff; - this->staticFrictionCoeff = staticFrictionCoeff; - this->kineticFrictionCoeff = kineticFrictionCoeff; - this->inertiaTensor = inertiaTensor; - this->reach = reach; - this->centerPos = centerPos; - this->angularAxis = rotation; - this->linearMomentum = linearMomentum; - this->angularMomentum = angularMomentum; - this->linearImpulse = this->angularImpulse = ::Oyster::Math::Float4::null; - this->deltaPos = this->deltaAxis = ::Oyster::Math::Float4::null; - this->isSpatiallyAltered = this->isDisturbed = this->isForwarded = false; - } + inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float kineticFrictionCoeff, const ::Oyster::Math::Float4x4 &inertiaTensor, const ::Oyster::Math::Float4 &reach, const ::Oyster::Math::Float4 ¢erPos, const ::Oyster::Math::Float4 &rotation, const ::Oyster::Math::Float4 &linearMomentum, const ::Oyster::Math::Float4 &angularMomentum ) + { + this->mass = mass; + this->restitutionCoeff = restitutionCoeff; + this->staticFrictionCoeff = staticFrictionCoeff; + this->kineticFrictionCoeff = kineticFrictionCoeff; + this->inertiaTensor = inertiaTensor; + this->reach = reach; + this->centerPos = centerPos; + this->angularAxis = rotation; + this->linearMomentum = linearMomentum; + this->angularMomentum = angularMomentum; + this->linearImpulse = this->angularImpulse = ::Oyster::Math::Float4::null; + this->deltaPos = this->deltaAxis = ::Oyster::Math::Float4::null; + this->isSpatiallyAltered = this->isDisturbed = this->isForwarded = false; + } - inline CustomBodyState & CustomBodyState::operator = ( const CustomBodyState &state ) - { - this->mass = state.mass; - this->restitutionCoeff = state.restitutionCoeff; - this->staticFrictionCoeff = state.staticFrictionCoeff; - this->kineticFrictionCoeff = state.kineticFrictionCoeff; - this->inertiaTensor = state.inertiaTensor; - this->reach = state.reach; - this->centerPos = state.centerPos; - this->angularAxis = state.angularAxis; - this->linearMomentum = state.linearMomentum; - this->angularMomentum = state.angularMomentum; - this->linearImpulse = state.linearImpulse; - this->angularImpulse = state.angularImpulse; - this->deltaPos = state.deltaPos; - this->deltaAxis = state.deltaAxis; - this->isSpatiallyAltered = state.isSpatiallyAltered; - this->isDisturbed = state.isDisturbed; - this->isForwarded = state.isForwarded; - return *this; - } + inline CustomBodyState & CustomBodyState::operator = ( const CustomBodyState &state ) + { + this->mass = state.mass; + this->restitutionCoeff = state.restitutionCoeff; + this->staticFrictionCoeff = state.staticFrictionCoeff; + this->kineticFrictionCoeff = state.kineticFrictionCoeff; + this->inertiaTensor = state.inertiaTensor; + this->reach = state.reach; + this->centerPos = state.centerPos; + this->angularAxis = state.angularAxis; + this->linearMomentum = state.linearMomentum; + this->angularMomentum = state.angularMomentum; + this->linearImpulse = state.linearImpulse; + this->angularImpulse = state.angularImpulse; + this->deltaPos = state.deltaPos; + this->deltaAxis = state.deltaAxis; + this->isSpatiallyAltered = state.isSpatiallyAltered; + this->isDisturbed = state.isDisturbed; + this->isForwarded = state.isForwarded; + return *this; + } - inline const ::Oyster::Math::Float CustomBodyState::GetMass() const - { - return this->mass; - } + inline const ::Oyster::Math::Float CustomBodyState::GetMass() const + { + return this->mass; + } - inline const ::Oyster::Math::Float CustomBodyState::GetRestitutionCoeff() const - { - return this->restitutionCoeff; - } + inline const ::Oyster::Math::Float CustomBodyState::GetRestitutionCoeff() const + { + return this->restitutionCoeff; + } - inline const ::Oyster::Math::Float CustomBodyState::GetFrictionCoeff_Static() const - { - return this->staticFrictionCoeff; - } + inline const ::Oyster::Math::Float CustomBodyState::GetFrictionCoeff_Static() const + { + return this->staticFrictionCoeff; + } - inline const ::Oyster::Math::Float CustomBodyState::GetFrictionCoeff_Kinetic() const - { - return this->kineticFrictionCoeff; - } + inline const ::Oyster::Math::Float CustomBodyState::GetFrictionCoeff_Kinetic() const + { + return this->kineticFrictionCoeff; + } - inline const ::Oyster::Math::Float4x4 & CustomBodyState::GetMomentOfInertia() const - { - return this->inertiaTensor; - } + inline const ::Oyster::Math::Float4x4 & CustomBodyState::GetMomentOfInertia() const + { + return this->inertiaTensor; + } - inline const ::Oyster::Math::Float4 & CustomBodyState::GetReach() const - { - return this->reach; - } + inline const ::Oyster::Math::Float4 & CustomBodyState::GetReach() const + { + return this->reach; + } - inline ::Oyster::Math::Float4 CustomBodyState::GetSize() const - { - return 2.0f * this->GetReach(); - } + inline ::Oyster::Math::Float4 CustomBodyState::GetSize() const + { + return 2.0f * this->GetReach(); + } - inline const ::Oyster::Math::Float4 & CustomBodyState::GetCenterPosition() const - { - return this->centerPos; - } + inline const ::Oyster::Math::Float4 & CustomBodyState::GetCenterPosition() const + { + return this->centerPos; + } - inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularAxis() const - { - return this->angularAxis; - } + inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularAxis() const + { + return this->angularAxis; + } - inline ::Oyster::Math::Float4x4 CustomBodyState::GetRotation() const - { - return ::Oyster::Math3D::RotationMatrix( this->GetAngularAxis().xyz ); - } + inline ::Oyster::Math::Float4x4 CustomBodyState::GetRotation() const + { + return ::Oyster::Math3D::RotationMatrix( this->GetAngularAxis().xyz ); + } - inline ::Oyster::Math::Float4x4 CustomBodyState::GetOrientation() const - { - return ::Oyster::Math3D::OrientationMatrix( this->angularAxis.xyz, this->centerPos.xyz ); - } + inline ::Oyster::Math::Float4x4 CustomBodyState::GetOrientation() const + { + return ::Oyster::Math3D::OrientationMatrix( this->angularAxis.xyz, this->centerPos.xyz ); + } - inline ::Oyster::Math::Float4x4 CustomBodyState::GetView() const - { - return ::Oyster::Math3D::ViewMatrix( this->angularAxis.xyz, this->centerPos.xyz ); - } + inline ::Oyster::Math::Float4x4 CustomBodyState::GetOrientation( const ::Oyster::Math::Float4 &offset ) const + { + return ::Oyster::Math3D::OrientationMatrix( this->angularAxis.xyz, (this->centerPos + offset).xyz ); + } - inline const ::Oyster::Math::Float4 & CustomBodyState::GetLinearMomentum() const - { - return this->linearMomentum; - } + inline ::Oyster::Math::Float4x4 CustomBodyState::GetView() const + { + return ::Oyster::Math3D::ViewMatrix( this->angularAxis.xyz, this->centerPos.xyz ); + } - inline ::Oyster::Math::Float4 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float4 &at ) const - { - //return this->linearMomentum + ::Oyster::Physics3D::Formula::TangentialLinearMomentum( this->angularMomentum, at - this->centerPos ); // C3083 error? - return this->linearMomentum + ::Oyster::Math::Float4( this->angularMomentum.xyz.Cross((at - this->centerPos).xyz), 0.0f ); - } + inline ::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::GetAngularMomentum() const - { - return this->angularMomentum; - } + inline const ::Oyster::Math::Float4 & CustomBodyState::GetLinearMomentum() const + { + return this->linearMomentum; + } - inline const ::Oyster::Math::Float4 & CustomBodyState::GetLinearImpulse() const - { - return this->linearImpulse; - } + inline ::Oyster::Math::Float4 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float4 &at ) const + { + return this->linearMomentum + ::Oyster::Physics3D::Formula::TangentialLinearMomentum( this->angularMomentum, at - this->centerPos ); + } - inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularImpulse() const - { - return this->angularImpulse; - } + inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularMomentum() const + { + return this->angularMomentum; + } - inline const ::Oyster::Math::Float4 & CustomBodyState::GetForward_DeltaPos() const - { - return this->deltaPos; - } + inline const ::Oyster::Math::Float4 & CustomBodyState::GetLinearImpulse() const + { + return this->linearImpulse; + } - inline const ::Oyster::Math::Float4 & CustomBodyState::GetForward_DeltaAxis() const - { - return this->deltaAxis; - } + inline const ::Oyster::Math::Float4 & CustomBodyState::GetAngularImpulse() const + { + return this->angularImpulse; + } - inline void CustomBodyState::SetMass_KeepMomentum( ::Oyster::Math::Float m ) - { - this->mass = m; - } + inline const ::Oyster::Math::Float4 & CustomBodyState::GetForward_DeltaPos() const + { + return this->deltaPos; + } - inline void CustomBodyState::SetMass_KeepVelocity( ::Oyster::Math::Float m ) - { - if( m != 0.0f ) - { // sanity block! - // Formula::LinearMomentum( m, Formula::LinearVelocity(this->mass, this->linearMomentum) ) - // is the same as (this->linearMomentum / this->mass) * m = (m / this->mass) * this->linearMomentum - this->linearMomentum *= (m / this->mass); + inline const ::Oyster::Math::Float4 & CustomBodyState::GetForward_DeltaAxis() const + { + return this->deltaAxis; + } + + inline void CustomBodyState::SetMass_KeepMomentum( ::Oyster::Math::Float m ) + { this->mass = m; } - } - inline void CustomBodyState::SetRestitutionCoeff( ::Oyster::Math::Float e ) - { - this->restitutionCoeff = e; - } + inline void CustomBodyState::SetMass_KeepVelocity( ::Oyster::Math::Float m ) + { + if( m != 0.0f ) + { // sanity block! + // Formula::LinearMomentum( m, Formula::LinearVelocity(this->mass, this->linearMomentum) ) + // is the same as (this->linearMomentum / this->mass) * m = (m / this->mass) * this->linearMomentum + this->linearMomentum *= (m / this->mass); + this->mass = m; + } + } - inline void CustomBodyState::SetFrictionCoeff( ::Oyster::Math::Float staticU, ::Oyster::Math::Float kineticU ) - { - this->staticFrictionCoeff = staticU; - this->kineticFrictionCoeff = kineticU; - } + inline void CustomBodyState::SetRestitutionCoeff( ::Oyster::Math::Float e ) + { + this->restitutionCoeff = e; + } - inline void CustomBodyState::SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &tensor ) - { - this->inertiaTensor = tensor; - } + inline void CustomBodyState::SetFrictionCoeff( ::Oyster::Math::Float staticU, ::Oyster::Math::Float kineticU ) + { + this->staticFrictionCoeff = staticU; + this->kineticFrictionCoeff = kineticU; + } - inline void CustomBodyState::SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &tensor ) - { - if( tensor.GetDeterminant() != 0.0f ) - { // sanity block! - ::Oyster::Math::Float4x4 rotation = ::Oyster::Math3D::RotationMatrix(this->angularAxis.xyz); - //::Oyster::Math::Float4 w = ::Oyster::Physics3D::Formula::AngularVelocity( (rotation * this->inertiaTensor).GetInverse(), this->angularMomentum ); // C3083 error? - ::Oyster::Math::Float4 w = (rotation * this->inertiaTensor).GetInverse() * this->angularMomentum; + inline void CustomBodyState::SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &tensor ) + { this->inertiaTensor = tensor; - //this->angularMomentum = ::Oyster::Physics3D::Formula::AngularMomentum( rotation * tensor, w ); // C3083 error? - this->angularMomentum = rotation * tensor * w; + } + + inline void CustomBodyState::SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &tensor ) + { + if( tensor.GetDeterminant() != 0.0f ) + { // sanity block! + ::Oyster::Math::Float4x4 rotation = ::Oyster::Math3D::RotationMatrix(this->angularAxis.xyz); + ::Oyster::Math::Float4 w = ::Oyster::Physics3D::Formula::AngularVelocity( (rotation * this->inertiaTensor).GetInverse(), this->angularMomentum ); + this->inertiaTensor = tensor; + this->angularMomentum = ::Oyster::Physics3D::Formula::AngularMomentum( rotation * tensor, w ); + } + } + + inline void CustomBodyState::SetSize( const ::Oyster::Math::Float4 &size ) + { + this->SetReach( 0.5f * size ); + } + + inline void CustomBodyState::SetReach( const ::Oyster::Math::Float4 &halfSize ) + { + this->reach.xyz = halfSize; + this->reach = ::Utility::Value::Max( this->reach, ::Oyster::Math::Float4::null ); + this->isSpatiallyAltered = this->isDisturbed = true; + } + + inline void CustomBodyState::SetCenterPosition( const ::Oyster::Math::Float4 ¢erPos ) + { + this->centerPos.xyz = centerPos; + this->isSpatiallyAltered = this->isDisturbed = true; + } + + inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float4 &angularAxis ) + { + this->angularAxis.xyz = angularAxis; + this->isSpatiallyAltered = this->isDisturbed = true; + } + + inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float4x4 &rotation ) + { + this->SetRotation( ::Oyster::Math3D::AngularAxis(rotation) ); + } + + inline void CustomBodyState::SetOrientation( const ::Oyster::Math::Float4x4 &orientation ) + { + this->SetRotation( ::Oyster::Math3D::ExtractAngularAxis(orientation) ); + this->SetCenterPosition( orientation.v[3] ); + } + + inline void CustomBodyState::SetLinearMomentum( const ::Oyster::Math::Float4 &g ) + { + this->linearMomentum.xyz = g; + this->isDisturbed = true; + } + + inline void CustomBodyState::SetAngularMomentum( const ::Oyster::Math::Float4 &h ) + { + this->angularMomentum.xyz = h; + this->isDisturbed = true; + } + + inline void CustomBodyState::SetLinearImpulse( const ::Oyster::Math::Float4 &j ) + { + this->linearImpulse.xyz = j; + this->isDisturbed = true; + } + + inline void CustomBodyState::SetAngularImpulse( const ::Oyster::Math::Float4 &j ) + { + this->angularImpulse.xyz = j; + this->isDisturbed = true; + } + + inline void CustomBodyState::AddRotation( const ::Oyster::Math::Float4 &angularAxis ) + { + this->angularAxis += angularAxis; + this->isSpatiallyAltered = this->isDisturbed = true; + } + + inline void CustomBodyState::AddTranslation( const ::Oyster::Math::Float4 &deltaPos ) + { + this->centerPos += deltaPos; + this->isSpatiallyAltered = this->isDisturbed = true; + } + + inline void CustomBodyState::ApplyLinearImpulse( const ::Oyster::Math::Float4 &j ) + { + this->linearImpulse += j; + this->isDisturbed = true; + } + + inline void CustomBodyState::ApplyAngularImpulse( const ::Oyster::Math::Float4 &j ) + { + this->angularImpulse += j; + this->isDisturbed = true; + } + + inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float4 &j, const ::Oyster::Math::Float4 &at, const ::Oyster::Math::Float4 &normal ) + { + ::Oyster::Math::Float4 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; + } + + inline void CustomBodyState::ApplyForwarding( const ::Oyster::Math::Float4 &deltaPos, const ::Oyster::Math::Float4 &deltaAxis ) + { + this->deltaPos += deltaPos; + this->deltaAxis += deltaAxis; + this->isDisturbed = this->isForwarded = true; + } + + inline bool CustomBodyState::IsSpatiallyAltered() const + { + return this->isSpatiallyAltered; + } + + inline bool CustomBodyState::IsDisturbed() const + { + return this->isDisturbed; + } + + inline bool CustomBodyState::IsForwarded() const + { + 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; } } - - inline void CustomBodyState::SetSize( const ::Oyster::Math::Float4 &size ) - { - this->SetReach( 0.5f * size ); - } - - inline void CustomBodyState::SetReach( const ::Oyster::Math::Float4 &halfSize ) - { - this->reach.xyz = halfSize; - this->reach = ::Utility::Value::Max( this->reach, ::Oyster::Math::Float4::null ); - this->isSpatiallyAltered = this->isDisturbed = true; - } - - inline void CustomBodyState::SetCenterPosition( const ::Oyster::Math::Float4 ¢erPos ) - { - this->centerPos.xyz = centerPos; - this->isSpatiallyAltered = this->isDisturbed = true; - } - - inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float4 &angularAxis ) - { - this->angularAxis.xyz = angularAxis; - this->isSpatiallyAltered = this->isDisturbed = true; - } - - inline void CustomBodyState::SetRotation( const ::Oyster::Math::Float4x4 &rotation ) - { - this->SetRotation( ::Oyster::Math3D::AngularAxis(rotation) ); - } - - inline void CustomBodyState::SetOrientation( const ::Oyster::Math::Float4x4 &orientation ) - { - this->SetRotation( ::Oyster::Math3D::ExtractAngularAxis(orientation) ); - this->SetCenterPosition( orientation.v[3] ); - } - - inline void CustomBodyState::SetLinearMomentum( const ::Oyster::Math::Float4 &g ) - { - this->linearMomentum.xyz = g; - this->isDisturbed = true; - } - - inline void CustomBodyState::SetAngularMomentum( const ::Oyster::Math::Float4 &h ) - { - this->angularMomentum.xyz = h; - this->isDisturbed = true; - } - - inline void CustomBodyState::SetLinearImpulse( const ::Oyster::Math::Float4 &j ) - { - this->linearImpulse.xyz = j; - this->isDisturbed = true; - } - - inline void CustomBodyState::SetAngularImpulse( const ::Oyster::Math::Float4 &j ) - { - this->angularImpulse.xyz = j; - this->isDisturbed = true; - } - - inline void CustomBodyState::AddRotation( const ::Oyster::Math::Float4 &angularAxis ) - { - this->angularAxis += angularAxis; - this->isSpatiallyAltered = this->isDisturbed = true; - } - - inline void CustomBodyState::AddTranslation( const ::Oyster::Math::Float4 &deltaPos ) - { - this->centerPos += deltaPos; - this->isSpatiallyAltered = this->isDisturbed = true; - } - - inline void CustomBodyState::ApplyLinearImpulse( const ::Oyster::Math::Float4 &j ) - { - this->linearImpulse += j; - this->isDisturbed = true; - } - - inline void CustomBodyState::ApplyAngularImpulse( const ::Oyster::Math::Float4 &j ) - { - this->angularImpulse += j; - this->isDisturbed = true; - } - - inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float4 &j, const ::Oyster::Math::Float4 &at, const ::Oyster::Math::Float4 &normal ) - { - //::Oyster::Math::Float4 tangentialImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, at - this->centerPos ); // C3083 error? - ::Oyster::Math::Float4 tangentialImpulse = ::Oyster::Math::Float4( (at - this->centerPos).xyz.Cross(j.xyz), 0.0f ); - this->linearImpulse += j - tangentialImpulse; - this->angularImpulse += tangentialImpulse; - - this->isDisturbed = true; - } - - inline void CustomBodyState::ApplyForwarding( const ::Oyster::Math::Float4 &deltaPos, const ::Oyster::Math::Float4 &deltaAxis ) - { - this->deltaPos += deltaPos; - this->deltaAxis += deltaAxis; - this->isDisturbed = this->isForwarded = true; - } - - inline bool CustomBodyState::IsSpatiallyAltered() const - { - return this->isSpatiallyAltered; - } - - inline bool CustomBodyState::IsDisturbed() const - { - return this->isDisturbed; - } - - inline bool CustomBodyState::IsForwarded() const - { - return this->isForwarded; - } - } -} } + } +} #endif \ No newline at end of file diff --git a/Code/GamePhysics/PhysicsStructs.h b/Code/GamePhysics/PhysicsStructs.h index 3c17ae6d..bf6c0618 100644 --- a/Code/GamePhysics/PhysicsStructs.h +++ b/Code/GamePhysics/PhysicsStructs.h @@ -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 \ No newline at end of file diff --git a/Code/OysterGraphics/ClassDiagram.cd b/Code/OysterGraphics/ClassDiagram.cd new file mode 100644 index 00000000..7b894197 --- /dev/null +++ b/Code/OysterGraphics/ClassDiagram.cd @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Code/OysterPhysics3D/OysterPhysics3D.h b/Code/OysterPhysics3D/OysterPhysics3D.h index f70d228f..970d739e 100644 --- a/Code/OysterPhysics3D/OysterPhysics3D.h +++ b/Code/OysterPhysics3D/OysterPhysics3D.h @@ -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 ); } /****************************************************************** diff --git a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.user b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.user index 9a0b0ae0..3f030911 100644 --- a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.user +++ b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.user @@ -1,6 +1,6 @@  - true + false \ No newline at end of file diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index 3ae48511..6fef6311 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -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