///////////////////////////////////////////////////////////////////// // Created by Dan Andersson 2013 ///////////////////////////////////////////////////////////////////// #ifndef OYSTER_PHYSICS_3D_RIGIDBODY_H #define OYSTER_PHYSICS_3D_RIGIDBODY_H #include "OysterMath.h" #include "OysterCollision3D.h" #include "OysterPhysics3D.h" namespace Oyster { namespace Physics3D { struct RigidBody { /// A struct of a simple rigid body. public: ::Oyster::Collision3D::Box box; /** Contains data representing physical presence. (worldValue) */ ::Oyster::Math::Float3 angularMomentum, /** The angular momentum H (Nm*s) around an parallell axis. (worldValue) */ linearMomentum, /** The linear momentum G (kg*m/s). (worldValue) */ impulseTorqueSum, /** The impulse torque T (Nm) that will be consumed each update. (worldValue) */ impulseForceSum; /** The impulse force F (N) that will be consumed each update. (worldValue) */ ::Oyster::Math::Float restitutionCoeff, frictionCoeff; RigidBody( const ::Oyster::Collision3D::Box &box = ::Oyster::Collision3D::Box(), ::Oyster::Math::Float mass = 12.0f, const ::Oyster::Math::Float4x4 &inertiaTensor = ::Oyster::Math::Float4x4::identity ); RigidBody & operator = ( const RigidBody &body ); bool operator == ( const RigidBody &body ); bool operator != ( const RigidBody &body ); void Update_LeapFrog( ::Oyster::Math::Float deltaTime ); void ApplyImpulseForce( const ::Oyster::Math::Float3 &worldF ); void ApplyImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos ); void ApplyLinearImpulseAcceleration( const ::Oyster::Math::Float3 &worldA ); void ApplyLinearImpulseAccelerationAt( const ::Oyster::Math::Float3 &worldA, const ::Oyster::Math::Float3 &worldPos ); void ApplyImpulseTorque( const ::Oyster::Math::Float3 &worldT ); void ApplyAngularImpulseAcceleration( const ::Oyster::Math::Float3 &worldA ); // ACCESS METHODS ///////////////////////////// ::Oyster::Math::Float3 & AccessBoundingReach(); const ::Oyster::Math::Float3 & AccessBoundingReach() const; ::Oyster::Math::Float3 & AccessCenter(); const ::Oyster::Math::Float3 & AccessCenter() const; // GET METHODS //////////////////////////////// const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const; const ::Oyster::Math::Float & GetMass() const; const ::Oyster::Math::Float4x4 GetOrientation() const; ::Oyster::Math::Float4x4 GetView() const; const ::Oyster::Math::Float4x4 & GetToWorldMatrix() const; ::Oyster::Math::Float4x4 GetToLocalMatrix() const; const ::Oyster::Math::Float3 & GetBoundingReach() const; ::Oyster::Math::Float3 GetSize() const; const ::Oyster::Math::Float3 & GetCenter() const; const ::Oyster::Math::Float3 & GetImpulsTorque() const; const ::Oyster::Math::Float3 & GetAngularMomentum() const; ::Oyster::Math::Float3 GetAngularImpulseAcceleration() const; ::Oyster::Math::Float3 GetAngularVelocity() const; const ::Oyster::Math::Float3 & GetImpulseForce() const; const ::Oyster::Math::Float3 & GetLinearMomentum() const; ::Oyster::Math::Float3 GetLinearImpulseAcceleration() const; ::Oyster::Math::Float3 GetLinearVelocity() const; void GetMomentumAt( const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &surfaceNormal, ::Oyster::Math::Float3 &normalMomentum, ::Oyster::Math::Float3 &tangentialMomentum ) const; // SET METHODS //////////////////////////////// void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localI ); void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &localI ); void SetMass_KeepVelocity( const ::Oyster::Math::Float &m ); void SetMass_KeepMomentum( const ::Oyster::Math::Float &m ); void SetOrientation( const ::Oyster::Math::Float4x4 &o ); void SetSize( const ::Oyster::Math::Float3 &widthHeight ); void SetCenter( const ::Oyster::Math::Float3 &worldPos ); void SetRotation( const ::Oyster::Math::Float4x4 &r ); void SetImpulseTorque( const ::Oyster::Math::Float3 &worldT ); void SetAngularMomentum( const ::Oyster::Math::Float3 &worldH ); void SetAngularImpulseAcceleration( const ::Oyster::Math::Float3 &worldA ); void SetAngularVelocity( const ::Oyster::Math::Float3 &worldW ); void SetImpulseForce( const ::Oyster::Math::Float3 &worldF ); void SetLinearMomentum( const ::Oyster::Math::Float3 &worldG ); void SetLinearImpulseAcceleration( const ::Oyster::Math::Float3 &worldA ); void SetLinearVelocity( const ::Oyster::Math::Float3 &worldV ); void SetImpulseForceAt( const ::Oyster::Math::Float3 &worldF, const ::Oyster::Math::Float3 &worldPos ); void SetLinearMomentumAt( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &worldPos ); void SetImpulseAccelerationAt( const ::Oyster::Math::Float3 &worldA, const ::Oyster::Math::Float3 &worldPos ); void SetLinearVelocityAt( const ::Oyster::Math::Float3 &worldV, const ::Oyster::Math::Float3 &worldPos ); private: ::Oyster::Math::Float mass; /** m (kg) */ ::Oyster::Math::Float4x4 momentOfInertiaTensor; /** I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue) */ }; // INLINE IMPLEMENTATIONS /////////////////////////////////////// inline const ::Oyster::Math::Float4x4 & RigidBody::GetToWorldMatrix() const { return this->GetOrientation(); } inline ::Oyster::Math::Float4x4 RigidBody::GetToLocalMatrix() const { return this->GetView(); } } } #endif