diff --git a/Code/Dokumentation/Other/Timestep_Impulse_Fix.odt b/Code/Dokumentation/Other/Timestep_Impulse_Fix.odt new file mode 100644 index 00000000..25ac526e Binary files /dev/null and b/Code/Dokumentation/Other/Timestep_Impulse_Fix.odt differ diff --git a/Code/Dokumentation/Other/Timestep_Impulse_Fix.pdf b/Code/Dokumentation/Other/Timestep_Impulse_Fix.pdf new file mode 100644 index 00000000..8ee3faea Binary files /dev/null and b/Code/Dokumentation/Other/Timestep_Impulse_Fix.pdf differ diff --git a/Code/Dokumentation/Other/angular momentum to angular velocity.odt b/Code/Dokumentation/Other/angular momentum to angular velocity.odt new file mode 100644 index 00000000..9cb22720 Binary files /dev/null and b/Code/Dokumentation/Other/angular momentum to angular velocity.odt differ diff --git a/Code/Dokumentation/Other/angular_momentum_to_angular_velocity.pdf b/Code/Dokumentation/Other/angular_momentum_to_angular_velocity.pdf new file mode 100644 index 00000000..820bf412 Binary files /dev/null and b/Code/Dokumentation/Other/angular_momentum_to_angular_velocity.pdf differ diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index 9fd8d219..bb497851 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -28,7 +28,7 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des 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->rigid.SetMomentOfInertia_KeepMomentum( MomentOfInertia::Sphere(desc.mass, desc.radius) ); this->deltaPos = Float4::null; this->deltaAxis = Float4::null; diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index 46de90cc..8918ab98 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -19,7 +19,7 @@ namespace Oyster this->restitutionCoeff = 1.0f; this->frictionCoeff_Dynamic = 0.5f; this->frictionCoeff_Static = 0.5f; - this->inertiaTensor = ::Oyster::Math::Float4x4::identity; + this->inertiaTensor = ::Oyster::Physics3D::MomentOfInertia(); this->subscription_onCollision = NULL; this->subscription_onCollisionResponse = NULL; this->subscription_onMovement = NULL; @@ -41,7 +41,7 @@ namespace Oyster 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, const ::Oyster::Math::Float4 &gravityNormal ) + inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float kineticFrictionCoeff, const ::Oyster::Physics3D::MomentOfInertia &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, const ::Oyster::Math::Float4 &gravityNormal ) { this->mass = mass; this->restitutionCoeff = restitutionCoeff; @@ -102,7 +102,7 @@ namespace Oyster return this->kineticFrictionCoeff; } - inline const ::Oyster::Math::Float4x4 & CustomBodyState::GetMomentOfInertia() const + inline const ::Oyster::Physics3D::MomentOfInertia & CustomBodyState::GetMomentOfInertia() const { return this->inertiaTensor; } @@ -219,20 +219,17 @@ namespace Oyster this->kineticFrictionCoeff = kineticU; } - inline void CustomBodyState::SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &tensor ) + inline void CustomBodyState::SetMomentOfInertia_KeepMomentum( const ::Oyster::Physics3D::MomentOfInertia &tensor ) { this->inertiaTensor = tensor; } - inline void CustomBodyState::SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &tensor ) + inline void CustomBodyState::SetMomentOfInertia_KeepVelocity( const ::Oyster::Physics3D::MomentOfInertia &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 ); - } + ::Oyster::Math::Quaternion rotation = ::Oyster::Math3D::Rotation(this->angularAxis); + ::Oyster::Math::Float4 w = this->inertiaTensor.CalculateAngularVelocity( rotation, this->angularMomentum ); + this->inertiaTensor = tensor; + this->angularMomentum = this->inertiaTensor.CalculateAngularMomentum( rotation, w ); } inline void CustomBodyState::SetSize( const ::Oyster::Math::Float4 &size ) diff --git a/Code/GamePhysics/PhysicsStructs.h b/Code/GamePhysics/PhysicsStructs.h index 1bc1736f..4eaaf46d 100644 --- a/Code/GamePhysics/PhysicsStructs.h +++ b/Code/GamePhysics/PhysicsStructs.h @@ -3,6 +3,7 @@ #include "OysterMath.h" #include "PhysicsAPI.h" +#include "Inertia.h" namespace Oyster { namespace Physics { @@ -17,7 +18,7 @@ namespace Oyster { namespace Physics ::Oyster::Math::Float restitutionCoeff; ::Oyster::Math::Float frictionCoeff_Static; ::Oyster::Math::Float frictionCoeff_Dynamic; - ::Oyster::Math::Float4x4 inertiaTensor; + ::Oyster::Physics3D::MomentOfInertia inertiaTensor; ::Oyster::Physics::ICustomBody::EventAction_Collision subscription_onCollision; ::Oyster::Physics::ICustomBody::EventAction_CollisionResponse subscription_onCollisionResponse; ::Oyster::Physics::ICustomBody::EventAction_Move subscription_onMovement; @@ -50,7 +51,7 @@ namespace Oyster { namespace Physics ::Oyster::Math::Float restitutionCoeff = 1.0f, ::Oyster::Math::Float staticFrictionCoeff = 1.0f, ::Oyster::Math::Float kineticFrictionCoeff = 1.0f, - const ::Oyster::Math::Float4x4 &inertiaTensor = ::Oyster::Math::Float4x4::identity, + const ::Oyster::Physics3D::MomentOfInertia &inertiaTensor = ::Oyster::Physics3D::MomentOfInertia(), const ::Oyster::Math::Float4 &reach = ::Oyster::Math::Float4::null, const ::Oyster::Math::Float4 ¢erPos = ::Oyster::Math::Float4::standard_unit_w, const ::Oyster::Math::Float4 &rotation = ::Oyster::Math::Float4::null, @@ -64,7 +65,7 @@ namespace Oyster { namespace Physics const ::Oyster::Math::Float GetRestitutionCoeff() const; const ::Oyster::Math::Float GetFrictionCoeff_Static() const; const ::Oyster::Math::Float GetFrictionCoeff_Kinetic() const; - const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const; + const ::Oyster::Physics3D::MomentOfInertia & GetMomentOfInertia() const; const ::Oyster::Math::Float4 & GetReach() const; ::Oyster::Math::Float4 GetSize() const; const ::Oyster::Math::Float4 & GetCenterPosition() const; @@ -87,8 +88,8 @@ namespace Oyster { namespace Physics void SetMass_KeepVelocity( ::Oyster::Math::Float m ); void SetRestitutionCoeff( ::Oyster::Math::Float e ); void SetFrictionCoeff( ::Oyster::Math::Float staticU, ::Oyster::Math::Float kineticU ); - void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &tensor ); - void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &tensor ); + void SetMomentOfInertia_KeepMomentum( const ::Oyster::Physics3D::MomentOfInertia &tensor ); + void SetMomentOfInertia_KeepVelocity( const ::Oyster::Physics3D::MomentOfInertia &tensor ); void SetSize( const ::Oyster::Math::Float4 &size ); void SetReach( const ::Oyster::Math::Float4 &halfSize ); void SetCenterPosition( const ::Oyster::Math::Float4 ¢erPos ); @@ -115,7 +116,7 @@ namespace Oyster { namespace Physics private: ::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, kineticFrictionCoeff; - ::Oyster::Math::Float4x4 inertiaTensor; + ::Oyster::Physics3D::MomentOfInertia inertiaTensor; ::Oyster::Math::Float4 reach, centerPos, angularAxis; ::Oyster::Math::Float4 linearMomentum, angularMomentum; ::Oyster::Math::Float4 linearImpulse, angularImpulse; diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index 947f1d0f..50bcd36b 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -35,7 +35,7 @@ namespace std // x2 template -::LinearAlgebra::Matrix2x2 operator * ( const ::LinearAlgebra::Matrix2x2 &left, const ::LinearAlgebra::Matrix2x2 &right ) +inline ::LinearAlgebra::Matrix2x2 operator * ( const ::LinearAlgebra::Matrix2x2 &left, const ::LinearAlgebra::Matrix2x2 &right ) { return ::LinearAlgebra::Matrix2x2( (left.m11 * right.m11) + (left.m12 * right.m21), (left.m11 * right.m12) + (left.m12 * right.m22), @@ -44,14 +44,14 @@ template } template -::LinearAlgebra::Vector2 operator * ( const ::LinearAlgebra::Matrix2x2 &matrix, const ::LinearAlgebra::Vector2 &vector ) +inline ::LinearAlgebra::Vector2 operator * ( const ::LinearAlgebra::Matrix2x2 &matrix, const ::LinearAlgebra::Vector2 &vector ) { return ::LinearAlgebra::Vector2( (matrix.m11 * vector.x) + (matrix.m12 * vector.y), (matrix.m21 * vector.x) + (matrix.m22 * vector.y) ); } template -::LinearAlgebra::Vector2 operator * ( const ::LinearAlgebra::Vector2 &vector, const ::LinearAlgebra::Matrix2x2 &left ) +inline ::LinearAlgebra::Vector2 operator * ( const ::LinearAlgebra::Vector2 &vector, const ::LinearAlgebra::Matrix2x2 &left ) { return ::LinearAlgebra::Vector2( (vector.x * matrix.m11) + (vector.y * matrix.m21), (vector.x * matrix.m12) + (vector.y * matrix.m22) ); @@ -60,7 +60,7 @@ template // x3 template -::LinearAlgebra::Matrix3x3 operator * ( const ::LinearAlgebra::Matrix3x3 &left, const ::LinearAlgebra::Matrix3x3 &right ) +inline ::LinearAlgebra::Matrix3x3 operator * ( const ::LinearAlgebra::Matrix3x3 &left, const ::LinearAlgebra::Matrix3x3 &right ) { return ::LinearAlgebra::Matrix3x3( (left.m11 * right.m11) + (left.m12 * right.m21) + (left.m13 * right.m31), (left.m11 * right.m12) + (left.m12 * right.m22) + (left.m13 * right.m32), (left.m11 * right.m13) + (left.m12 * right.m23) + (left.m13 * right.m33), (left.m21 * right.m11) + (left.m22 * right.m21) + (left.m23 * right.m31), (left.m21 * right.m12) + (left.m22 * right.m22) + (left.m23 * right.m32), (left.m21 * right.m13) + (left.m22 * right.m23) + (left.m23 * right.m33), @@ -68,7 +68,7 @@ template } template -::LinearAlgebra::Vector3 operator * ( const ::LinearAlgebra::Matrix3x3 &matrix, const ::LinearAlgebra::Vector3 &vector ) +inline ::LinearAlgebra::Vector3 operator * ( const ::LinearAlgebra::Matrix3x3 &matrix, const ::LinearAlgebra::Vector3 &vector ) { return ::LinearAlgebra::Vector3( (matrix.m11 * vector.x) + (matrix.m12 * vector.y) + (matrix.m13 * vector.z), (matrix.m21 * vector.x) + (matrix.m22 * vector.y) + (matrix.m23 * vector.z), @@ -76,7 +76,7 @@ template } template -::LinearAlgebra::Vector3 operator * ( const ::LinearAlgebra::Vector3 &vector, const ::LinearAlgebra::Matrix3x3 &left ) +inline ::LinearAlgebra::Vector3 operator * ( const ::LinearAlgebra::Vector3 &vector, const ::LinearAlgebra::Matrix3x3 &left ) { return ::LinearAlgebra::Vector3( (vector.x * matrix.m11) + (vector.y * matrix.m21) + (vector.z * matrix.m31), (vector.x * matrix.m12) + (vector.y * matrix.m22) + (vector.z * matrix.m32), @@ -86,7 +86,7 @@ template // x4 template -::LinearAlgebra::Matrix4x4 operator * ( const ::LinearAlgebra::Matrix4x4 &left, const ::LinearAlgebra::Matrix4x4 &right ) +inline ::LinearAlgebra::Matrix4x4 operator * ( const ::LinearAlgebra::Matrix4x4 &left, const ::LinearAlgebra::Matrix4x4 &right ) { return ::LinearAlgebra::Matrix4x4( (left.m11 * right.m11) + (left.m12 * right.m21) + (left.m13 * right.m31) + (left.m14 * right.m41), (left.m11 * right.m12) + (left.m12 * right.m22) + (left.m13 * right.m32) + (left.m14 * right.m42), (left.m11 * right.m13) + (left.m12 * right.m23) + (left.m13 * right.m33) + (left.m14 * right.m43), (left.m11 * right.m14) + (left.m12 * right.m24) + (left.m13 * right.m34) + (left.m14 * right.m44), (left.m21 * right.m11) + (left.m22 * right.m21) + (left.m23 * right.m31) + (left.m24 * right.m41), (left.m21 * right.m12) + (left.m22 * right.m22) + (left.m23 * right.m32) + (left.m24 * right.m42), (left.m21 * right.m13) + (left.m22 * right.m23) + (left.m23 * right.m33) + (left.m24 * right.m43), (left.m21 * right.m14) + (left.m22 * right.m24) + (left.m23 * right.m34) + (left.m24 * right.m44), @@ -95,7 +95,7 @@ template } template -::LinearAlgebra::Vector4 operator * ( const ::LinearAlgebra::Matrix4x4 &matrix, const ::LinearAlgebra::Vector4 &vector ) +inline ::LinearAlgebra::Vector4 operator * ( const ::LinearAlgebra::Matrix4x4 &matrix, const ::LinearAlgebra::Vector4 &vector ) { return ::LinearAlgebra::Vector4( (matrix.m11 * vector.x) + (matrix.m12 * vector.y) + (matrix.m13 * vector.z) + (matrix.m14 * vector.w), (matrix.m21 * vector.x) + (matrix.m22 * vector.y) + (matrix.m23 * vector.z) + (matrix.m24 * vector.w), @@ -104,7 +104,7 @@ template } template -::LinearAlgebra::Vector4 operator * ( const ::LinearAlgebra::Vector4 &vector, const ::LinearAlgebra::Matrix4x4 &matrix ) +inline ::LinearAlgebra::Vector4 operator * ( const ::LinearAlgebra::Vector4 &vector, const ::LinearAlgebra::Matrix4x4 &matrix ) { return ::LinearAlgebra::Vector4( (vector.x * matrix.m11) + (vector.y * matrix.m21) + (vector.z * matrix.m31) + (vector.w * matrix.m41), (vector.x * matrix.m12) + (vector.y * matrix.m22) + (vector.z * matrix.m32) + (vector.w * matrix.m42), diff --git a/Code/OysterMath/Matrix.h b/Code/OysterMath/Matrix.h index c7b6b9e0..5d129431 100644 --- a/Code/OysterMath/Matrix.h +++ b/Code/OysterMath/Matrix.h @@ -163,12 +163,18 @@ namespace LinearAlgebra Vector4 GetRowVector( unsigned int rowID ) const; const Vector4 & GetColumnVector( unsigned int colID ) const; }; +} +template LinearAlgebra::Matrix2x2 operator * ( const ScalarType &left, const LinearAlgebra::Matrix2x2 &right ); +template LinearAlgebra::Matrix3x3 operator * ( const ScalarType &left, const LinearAlgebra::Matrix3x3 &right ); +template LinearAlgebra::Matrix4x4 operator * ( const ScalarType &left, const LinearAlgebra::Matrix4x4 &right ); /////////////////////////////////////////////////////////////////////////////////// // Body /////////////////////////////////////////////////////////////////////////////////// +namespace LinearAlgebra +{ // Matrix2x2 /////////////////////////////////////// template @@ -753,4 +759,22 @@ namespace LinearAlgebra { return this->v[colID]; } } +template +inline LinearAlgebra::Matrix2x2 operator * ( const ScalarType &left, const LinearAlgebra::Matrix2x2 &right ) +{ + return right * left; +} + +template +inline LinearAlgebra::Matrix3x3 operator * ( const ScalarType &left, const LinearAlgebra::Matrix3x3 &right ) +{ + return right * left; +} + +template +inline LinearAlgebra::Matrix4x4 operator * ( const ScalarType &left, const LinearAlgebra::Matrix4x4 &right ) +{ + return right * left; +} + #endif \ No newline at end of file diff --git a/Code/OysterMath/OysterMath.h b/Code/OysterMath/OysterMath.h index 62438e47..5970face 100644 --- a/Code/OysterMath/OysterMath.h +++ b/Code/OysterMath/OysterMath.h @@ -66,55 +66,29 @@ namespace Oyster { namespace Math //! Oyster's native math library inline ::Oyster::Math::Float2 & operator *= ( ::Oyster::Math::Float2 &left, const ::Oyster::Math::Float2 &right ) { - left.x *= right.x; - left.y *= right.y; - return left; + return left.PiecewiseMultiplicationAdd( right ); } inline ::Oyster::Math::Float2 operator * ( const ::Oyster::Math::Float2 &left, const ::Oyster::Math::Float2 &right ) -{ return ::Oyster::Math::Float2(left) *= right; } - -inline ::Oyster::Math::Float2 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float2 &right ) -{ return ::Oyster::Math::Float2(right) *= left; } +{ + return left.PiecewiseMultiplication( right ); +} inline ::Oyster::Math::Float3 & operator *= ( ::Oyster::Math::Float3 &left, const ::Oyster::Math::Float3 &right ) { - left.x *= right.x; - left.y *= right.y; - left.z *= right.z; - return left; + return left.PiecewiseMultiplicationAdd( right ); } inline ::Oyster::Math::Float3 operator * ( const ::Oyster::Math::Float3 &left, const ::Oyster::Math::Float3 &right ) -{ return ::Oyster::Math::Float3(left) *= right; } - -inline ::Oyster::Math::Float3 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float3 &right ) -{ return ::Oyster::Math::Float3(right) *= left; } +{ + return left.PiecewiseMultiplication( right ); +} inline ::Oyster::Math::Float4 & operator *= ( ::Oyster::Math::Float4 &left, const ::Oyster::Math::Float4 &right ) { - left.x *= right.x; - left.y *= right.y; - left.z *= right.z; - left.w *= right.w; - return left; + return left.PiecewiseMultiplicationAdd( right ); } -inline ::Oyster::Math::Float4 operator * ( const ::Oyster::Math::Float4 &left, const ::Oyster::Math::Float4 &right ) -{ return ::Oyster::Math::Float4(left) *= right; } - -inline ::Oyster::Math::Float4 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float4 &right ) -{ return ::Oyster::Math::Float4(right) *= left; } - -inline ::Oyster::Math::Float2x2 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float2x2 &right ) -{ return ::Oyster::Math::Float2x2(right) *= left; } - -inline ::Oyster::Math::Float3x3 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float3x3 &right ) -{ return ::Oyster::Math::Float3x3(right) *= left; } - -inline ::Oyster::Math::Float4x4 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float4x4 &right ) -{ return ::Oyster::Math::Float4x4(right) *= left; } - namespace Oyster { namespace Math2D //! Oyster's native math library specialized for 2D { using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace diff --git a/Code/OysterMath/Vector.h b/Code/OysterMath/Vector.h index 901ea5e4..ea36cfc9 100644 --- a/Code/OysterMath/Vector.h +++ b/Code/OysterMath/Vector.h @@ -57,6 +57,12 @@ namespace LinearAlgebra ScalarType GetMagnitude( ) const; ScalarType Dot( const Vector2 &vector ) const; + //! @return (a.x * b.x, a.y * b.y) + Vector2 PiecewiseMultiplication( const Vector2 &vector ) const; + + //! @return a = (a.x * b.x, a.y * b.y) + Vector2 & PiecewiseMultiplicationAdd( const Vector2 &vector ); + Vector2 & Normalize( ); Vector2 GetNormalized( ) const; }; @@ -112,6 +118,12 @@ namespace LinearAlgebra ScalarType Dot( const Vector3 &vector ) const; Vector3 Cross( const Vector3 &vector ) const; + //! @return (a.x * b.x, a.y * b.y, a.z * b.z) + Vector3 PiecewiseMultiplication( const Vector3 &vector ) const; + + //! @return a = (a.x * b.x, a.y * b.y, a.z * b.z) + Vector3 & PiecewiseMultiplicationAdd( const Vector3 &vector ); + Vector3 & Normalize( ); Vector3 GetNormalized( ) const; }; @@ -169,14 +181,27 @@ namespace LinearAlgebra ScalarType GetMagnitude( ) const; ScalarType Dot( const Vector4 &vector ) const; + //! @return (a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w) + Vector4 PiecewiseMultiplication( const Vector4 &vector ) const; + + //! @return a = (a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w) + Vector4 & PiecewiseMultiplicationAdd( const Vector4 &vector ); + Vector4 & Normalize( ); Vector4 GetNormalized( ) const; }; +} + +template ::LinearAlgebra::Vector2 operator * ( const ScalarType &left, const ::LinearAlgebra::Vector2 &right ); +template ::LinearAlgebra::Vector3 operator * ( const ScalarType &left, const ::LinearAlgebra::Vector3 &right ); +template ::LinearAlgebra::Vector4 operator * ( const ScalarType &left, const ::LinearAlgebra::Vector4 &right ); /////////////////////////////////////////////////////////////////////////////////// // Body /////////////////////////////////////////////////////////////////////////////////// +namespace LinearAlgebra +{ // Vector2 /////////////////////////////////////// template const Vector2 Vector2::null = Vector2( 0, 0 ); @@ -184,22 +209,22 @@ namespace LinearAlgebra template const Vector2 Vector2::standard_unit_y = Vector2( 0, 1 ); template - Vector2::Vector2( ) : x(), y() {} + inline Vector2::Vector2( ) : x(), y() {} template - Vector2::Vector2( const Vector2 &vector ) + inline Vector2::Vector2( const Vector2 &vector ) { this->x = vector.x; this->y = vector.y; } template - Vector2::Vector2( const ScalarType &_element ) + inline Vector2::Vector2( const ScalarType &_element ) { this->x = this->y = _element; } template - Vector2::Vector2( const ScalarType _element[2] ) + inline Vector2::Vector2( const ScalarType _element[2] ) { this->x = _element[0]; this->y = _element[1]; } template - Vector2::Vector2( const ScalarType &_x, const ScalarType &_y ) + inline Vector2::Vector2( const ScalarType &_x, const ScalarType &_y ) { this->x = _x; this->y = _y; } template @@ -227,7 +252,7 @@ namespace LinearAlgebra { return this->element[i]; } template - Vector2 & Vector2::operator = ( const Vector2 &vector ) + inline Vector2 & Vector2::operator = ( const Vector2 &vector ) { this->element[0] = vector.element[0]; this->element[1] = vector.element[1]; @@ -235,7 +260,7 @@ namespace LinearAlgebra } template - Vector2 & Vector2::operator = ( const ScalarType _element[2] ) + inline Vector2 & Vector2::operator = ( const ScalarType _element[2] ) { this->element[0] = _element[0]; this->element[1] = _element[1]; @@ -243,7 +268,7 @@ namespace LinearAlgebra } template - Vector2 & Vector2::operator *= ( const ScalarType &scalar ) + inline Vector2 & Vector2::operator *= ( const ScalarType &scalar ) { this->element[0] *= scalar; this->element[1] *= scalar; @@ -251,7 +276,7 @@ namespace LinearAlgebra } template - Vector2 & Vector2::operator /= ( const ScalarType &scalar ) + inline Vector2 & Vector2::operator /= ( const ScalarType &scalar ) { this->element[0] /= scalar; this->element[1] /= scalar; @@ -259,7 +284,7 @@ namespace LinearAlgebra } template - Vector2 & Vector2::operator += ( const Vector2 &vector ) + inline Vector2 & Vector2::operator += ( const Vector2 &vector ) { this->element[0] += vector.element[0]; this->element[1] += vector.element[1]; @@ -267,7 +292,7 @@ namespace LinearAlgebra } template - Vector2 & Vector2::operator -= ( const Vector2 &vector ) + inline Vector2 & Vector2::operator -= ( const Vector2 &vector ) { this->element[0] -= vector.element[0]; this->element[1] -= vector.element[1]; @@ -295,7 +320,7 @@ namespace LinearAlgebra { return Vector2(-this->x, -this->y); } template - bool Vector2::operator == ( const Vector2 &vector ) const + inline bool Vector2::operator == ( const Vector2 &vector ) const { if( this->x != vector.x ) return false; if( this->y != vector.y ) return false; @@ -303,7 +328,7 @@ namespace LinearAlgebra } template - bool Vector2::operator != ( const Vector2 &vector ) const + inline bool Vector2::operator != ( const Vector2 &vector ) const { if( this->x != vector.x ) return true; if( this->y != vector.y ) return true; @@ -319,7 +344,7 @@ namespace LinearAlgebra { return (ScalarType) ::sqrt( this->Dot(*this) ); } template - ScalarType Vector2::Dot( const Vector2 &vector ) const + inline ScalarType Vector2::Dot( const Vector2 &vector ) const { ScalarType value = 0; value += this->element[0] * vector.element[0]; @@ -327,6 +352,20 @@ namespace LinearAlgebra return value; } + template + inline Vector2 Vector2::PiecewiseMultiplication( const Vector2 &vector ) const + { + return Vector2( this->x * vector.x, this->y * vector.y ); + } + + template + inline Vector2 & Vector2::PiecewiseMultiplicationAdd( const Vector2 &vector ) + { + this->x *= vector.x; + this->y *= vector.y; + return *this; + } + template inline Vector2 & Vector2::Normalize( ) { return (*this) /= this->GetLength(); } @@ -343,26 +382,26 @@ namespace LinearAlgebra template const Vector3 Vector3::standard_unit_z = Vector3( 0, 0, 1 ); template - Vector3::Vector3( ) : x(), y(), z() {} + inline Vector3::Vector3( ) : x(), y(), z() {} template - Vector3::Vector3( const Vector3 &vector ) + inline Vector3::Vector3( const Vector3 &vector ) { this->x = vector.x; this->y = vector.y; this->z = vector.z; } template - Vector3::Vector3( const Vector2 &vector, const ScalarType &_z ) + inline Vector3::Vector3( const Vector2 &vector, const ScalarType &_z ) { this->x = vector.x; this->y = vector.y; this->z = _z; } template - Vector3::Vector3( const ScalarType &_element ) + inline Vector3::Vector3( const ScalarType &_element ) { this->x = this->y = this->z = _element; } template - Vector3::Vector3( const ScalarType _element[3] ) + inline Vector3::Vector3( const ScalarType _element[3] ) { this->x = _element[0]; this->y = _element[1]; this->z = _element[2]; } template - Vector3::Vector3( const ScalarType &_x, const ScalarType &_y, const ScalarType &_z ) + inline Vector3::Vector3( const ScalarType &_x, const ScalarType &_y, const ScalarType &_z ) { this->x = _x; this->y = _y; this->z = _z; } template @@ -382,7 +421,7 @@ namespace LinearAlgebra { return this->element[i]; } template - Vector3 & Vector3::operator = ( const Vector3 &vector ) + inline Vector3 & Vector3::operator = ( const Vector3 &vector ) { this->element[0] = vector.element[0]; this->element[1] = vector.element[1]; @@ -391,7 +430,7 @@ namespace LinearAlgebra } template - Vector3 & Vector3::operator = ( const ScalarType element[3] ) + inline Vector3 & Vector3::operator = ( const ScalarType element[3] ) { this->element[0] = element[0]; this->element[1] = element[1]; @@ -400,7 +439,7 @@ namespace LinearAlgebra } template - Vector3 & Vector3::operator *= ( const ScalarType &scalar ) + inline Vector3 & Vector3::operator *= ( const ScalarType &scalar ) { this->element[0] *= scalar; this->element[1] *= scalar; @@ -409,7 +448,7 @@ namespace LinearAlgebra } template - Vector3 & Vector3::operator /= ( const ScalarType &scalar ) + inline Vector3 & Vector3::operator /= ( const ScalarType &scalar ) { this->element[0] /= scalar; this->element[1] /= scalar; @@ -418,7 +457,7 @@ namespace LinearAlgebra } template - Vector3 & Vector3::operator += ( const Vector3 &vector ) + inline Vector3 & Vector3::operator += ( const Vector3 &vector ) { this->element[0] += vector.element[0]; this->element[1] += vector.element[1]; @@ -427,7 +466,7 @@ namespace LinearAlgebra } template - Vector3 & Vector3::operator -= ( const Vector3 &vector ) + inline Vector3 & Vector3::operator -= ( const Vector3 &vector ) { this->element[0] -= vector.element[0]; this->element[1] -= vector.element[1]; @@ -456,7 +495,7 @@ namespace LinearAlgebra { return Vector3(-this->x, -this->y, -this->z); } template - bool Vector3::operator == ( const Vector3 &vector ) const + inline bool Vector3::operator == ( const Vector3 &vector ) const { if( this->x != vector.x ) return false; if( this->y != vector.y ) return false; @@ -465,7 +504,7 @@ namespace LinearAlgebra } template - bool Vector3::operator != ( const Vector3 &vector ) const + inline bool Vector3::operator != ( const Vector3 &vector ) const { if( this->x != vector.x ) return true; if( this->y != vector.y ) return true; @@ -482,7 +521,7 @@ namespace LinearAlgebra { return (ScalarType) ::sqrt( this->Dot(*this) ); } template - ScalarType Vector3::Dot( const Vector3 &vector ) const + inline ScalarType Vector3::Dot( const Vector3 &vector ) const { ScalarType value = 0; value += this->element[0] * vector.element[0]; @@ -492,13 +531,28 @@ namespace LinearAlgebra } template - Vector3 Vector3::Cross( const Vector3 &vector ) const + inline Vector3 Vector3::Cross( const Vector3 &vector ) const { return Vector3( (this->y*vector.z) - (this->z*vector.y), (this->z*vector.x) - (this->x*vector.z), (this->x*vector.y) - (this->y*vector.x) ); } + template + inline Vector3 Vector3::PiecewiseMultiplication( const Vector3 &vector ) const + { + return Vector3( this->x * vector.x, this->y * vector.y, this->z * vector.z ); + } + + template + inline Vector3 & Vector3::PiecewiseMultiplicationAdd( const Vector3 &vector ) + { + this->x *= vector.x; + this->y *= vector.y; + this->z *= vector.z; + return *this; + } + template inline Vector3 & Vector3::Normalize( ) { return (*this) /= this->GetLength(); } @@ -516,30 +570,30 @@ namespace LinearAlgebra template const Vector4 Vector4::standard_unit_w = Vector4( 0, 0, 0, 1 ); template - Vector4::Vector4( ) : x(), y(), z(), w() {} + inline Vector4::Vector4( ) : x(), y(), z(), w() {} template - Vector4::Vector4( const Vector4 &vector ) + inline Vector4::Vector4( const Vector4 &vector ) { this->x = vector.x; this->y = vector.y; this->z = vector.z; this->w = vector.w; } template - Vector4::Vector4( const Vector3 &vector, const ScalarType &_w ) + inline Vector4::Vector4( const Vector3 &vector, const ScalarType &_w ) { this->x = vector.x; this->y = vector.y; this->z = vector.z; this->w = _w; } template - Vector4::Vector4( const Vector2 &vector, const ScalarType &_z, const ScalarType &_w ) + inline Vector4::Vector4( const Vector2 &vector, const ScalarType &_z, const ScalarType &_w ) { this->x = vector.x; this->y = vector.y; this->z = _z; this->w = _w; } template - Vector4::Vector4( const ScalarType &_element ) + inline Vector4::Vector4( const ScalarType &_element ) { this->x = this->y = this->z = this->w = _element; } template - Vector4::Vector4( const ScalarType _element[4] ) + inline Vector4::Vector4( const ScalarType _element[4] ) { this->x = _element[0]; this->y = _element[1]; this->z = _element[2]; this->w = _element[3]; } template - Vector4::Vector4( const ScalarType &_x, const ScalarType &_y, const ScalarType &_z, const ScalarType &_w ) + inline Vector4::Vector4( const ScalarType &_x, const ScalarType &_y, const ScalarType &_z, const ScalarType &_w ) { this->x = _x; this->y = _y; this->z = _z; this->w = _w; } template @@ -559,7 +613,7 @@ namespace LinearAlgebra { return this->element[i]; } template - Vector4 & Vector4::operator = ( const Vector4 &vector ) + inline Vector4 & Vector4::operator = ( const Vector4 &vector ) { this->element[0] = vector.element[0]; this->element[1] = vector.element[1]; @@ -569,7 +623,7 @@ namespace LinearAlgebra } template - Vector4 & Vector4::operator = ( const ScalarType element[4] ) + inline Vector4 & Vector4::operator = ( const ScalarType element[4] ) { this->element[0] = element[0]; this->element[1] = element[1]; @@ -579,7 +633,7 @@ namespace LinearAlgebra } template - Vector4 & Vector4::operator *= ( const ScalarType &scalar ) + inline Vector4 & Vector4::operator *= ( const ScalarType &scalar ) { this->element[0] *= scalar; this->element[1] *= scalar; @@ -589,7 +643,7 @@ namespace LinearAlgebra } template - Vector4 & Vector4::operator /= ( const ScalarType &scalar ) + inline Vector4 & Vector4::operator /= ( const ScalarType &scalar ) { this->element[0] /= scalar; this->element[1] /= scalar; @@ -599,7 +653,7 @@ namespace LinearAlgebra } template - Vector4 & Vector4::operator += ( const Vector4 &vector ) + inline Vector4 & Vector4::operator += ( const Vector4 &vector ) { this->element[0] += vector.element[0]; this->element[1] += vector.element[1]; @@ -609,7 +663,7 @@ namespace LinearAlgebra } template - Vector4 & Vector4::operator -= ( const Vector4 &vector ) + inline Vector4 & Vector4::operator -= ( const Vector4 &vector ) { this->element[0] -= vector.element[0]; this->element[1] -= vector.element[1]; @@ -639,7 +693,7 @@ namespace LinearAlgebra { return Vector4(-this->x, -this->y, -this->z, -this->w); } template - bool Vector4::operator == ( const Vector4 &vector ) const + inline bool Vector4::operator == ( const Vector4 &vector ) const { if( this->x != vector.x ) return false; if( this->y != vector.y ) return false; @@ -649,7 +703,7 @@ namespace LinearAlgebra } template - bool Vector4::operator != ( const Vector4 &vector ) const + inline bool Vector4::operator != ( const Vector4 &vector ) const { if( this->x != vector.x ) return true; if( this->y != vector.y ) return true; @@ -667,7 +721,7 @@ namespace LinearAlgebra { return (ScalarType) ::sqrt( this->Dot(*this) ); } template - ScalarType Vector4::Dot( const Vector4 &vector ) const + inline ScalarType Vector4::Dot( const Vector4 &vector ) const { ScalarType value = 0; value += this->element[0] * vector.element[0]; @@ -677,6 +731,22 @@ namespace LinearAlgebra return value; } + template + inline Vector4 Vector4::PiecewiseMultiplication( const Vector4 &vector ) const + { + return Vector4( this->x * vector.x, this->y * vector.y, this->z * vector.z, this->w * vector.w ); + } + + template + inline Vector4 & Vector4::PiecewiseMultiplicationAdd( const Vector4 &vector ) + { + this->x *= vector.x; + this->y *= vector.y; + this->z *= vector.z; + this->w *= vector.w; + return *this; + } + template inline Vector4 & Vector4::Normalize( ) { return (*this) /= this->GetLength(); } @@ -686,4 +756,22 @@ namespace LinearAlgebra { return Vector4(*this).Normalize(); } } +template +inline ::LinearAlgebra::Vector2 operator * ( const ScalarType &left, const ::LinearAlgebra::Vector2 &right ) +{ + return right * left; +} + +template +inline ::LinearAlgebra::Vector3 operator * ( const ScalarType &left, const ::LinearAlgebra::Vector3 &right ) +{ + return right * left; +} + +template +inline ::LinearAlgebra::Vector4 operator * ( const ScalarType &left, const ::LinearAlgebra::Vector4 &right ) +{ + return right * left; +} + #endif \ No newline at end of file diff --git a/Code/OysterPhysics3D/Inertia.cpp b/Code/OysterPhysics3D/Inertia.cpp new file mode 100644 index 00000000..69df0e01 --- /dev/null +++ b/Code/OysterPhysics3D/Inertia.cpp @@ -0,0 +1,51 @@ +/******************************************************************** + * Created by Dan Andersson 2014 + ********************************************************************/ + +#include "Inertia.h" + +using namespace ::Oyster::Math3D; +using namespace ::Oyster::Physics3D; + +MomentOfInertia::MomentOfInertia() +{ + this->rotation = Quaternion::identity; + this->magnitude = Float3( 1.0f ); +} + +MomentOfInertia::MomentOfInertia( const Quaternion &r, const Float3 &m ) +{ + this->rotation = r; + this->magnitude = m; +} + +MomentOfInertia & MomentOfInertia::operator = ( const MomentOfInertia &i ) +{ + this->rotation = i.rotation; + this->magnitude = i.magnitude; + return *this; +} + +Float4 MomentOfInertia::CalculateAngularVelocity( const Quaternion &externR, const Float4 &h ) const +{ + return this->CalculateAngularVelocity( externR, h, Float4() ); +} + +Float4 & MomentOfInertia::CalculateAngularVelocity( const Quaternion &externR, const Float4 &h, Float4 &targetMem ) const +{ // w = (R * I_R) * I_M^-1 * (R * I_R)^-1 * h + Float4x4 rotation = RotationMatrix( externR ) * RotationMatrix( this->rotation ); + Float4 w = rotation.GetInverse() * h; + return targetMem = rotation * w.PiecewiseMultiplicationAdd( Float4(1.0f / this->magnitude.x, 1.0f / this->magnitude.y, 1.0f / this->magnitude.z, 0.0f) ); +} + +Float4 MomentOfInertia::CalculateAngularMomentum( const Quaternion &externR, const Float4 &w ) const +{ + return this->CalculateAngularMomentum( externR, w, Float4() ); +} + +Float4 & MomentOfInertia::CalculateAngularMomentum( const Quaternion &externR, const Float4 &w, Float4 &targetMem ) const +{ // h = (R * I_R) * I_M * (R * I_R)^-1 * w + Float4x4 rotation = RotationMatrix( externR ) * RotationMatrix( this->rotation ); + Float4 h = rotation.GetInverse() * w; + return targetMem = rotation * h.PiecewiseMultiplicationAdd( Float4(this->magnitude.x, this->magnitude.y, this->magnitude.z, 0.0f) ); +} \ No newline at end of file diff --git a/Code/OysterPhysics3D/Inertia.h b/Code/OysterPhysics3D/Inertia.h new file mode 100644 index 00000000..c7ffc49f --- /dev/null +++ b/Code/OysterPhysics3D/Inertia.h @@ -0,0 +1,119 @@ +/******************************************************************** + * Created by Dan Andersson & Robin Engman 2014 + ********************************************************************/ + +#ifndef OYSTER_PHYSICS_3D_INERTIA_H +#define OYSTER_PHYSICS_3D_INERTIA_H + +#include "OysterMath.h" + +namespace Oyster { namespace Physics3D +{ + struct MomentOfInertia + { + ::Oyster::Math::Quaternion rotation; + ::Oyster::Math::Float3 magnitude; + + MomentOfInertia(); + MomentOfInertia( const ::Oyster::Math::Quaternion &r, const ::Oyster::Math::Float3 &m ); + + MomentOfInertia & operator = ( const MomentOfInertia &i ); + + ::Oyster::Math::Float4 CalculateAngularVelocity( const ::Oyster::Math::Quaternion &externR, const ::Oyster::Math::Float4 &angularMomentum ) const; + ::Oyster::Math::Float4 & CalculateAngularVelocity( const ::Oyster::Math::Quaternion &externR, const ::Oyster::Math::Float4 &angularMomentum, ::Oyster::Math::Float4 &targetMem ) const; + + ::Oyster::Math::Float4 CalculateAngularMomentum( const ::Oyster::Math::Quaternion &externR, const ::Oyster::Math::Float4 &angularVelocity ) const; + ::Oyster::Math::Float4 & CalculateAngularMomentum( const ::Oyster::Math::Quaternion &externR, const ::Oyster::Math::Float4 &angularVelocity, ::Oyster::Math::Float4 &targetMem ) const; + + static ::Oyster::Math::Float CalculateSphere( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ); + static ::Oyster::Math::Float CalculateHollowSphere( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ); + static ::Oyster::Math::Float CalculateCuboidX( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float depth ); + static ::Oyster::Math::Float CalculateCuboidY( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth ); + static ::Oyster::Math::Float CalculateCuboidZ( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float width, const ::Oyster::Math::Float height ); + static ::Oyster::Math::Float CalculateRodCenter( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length ); + static ::Oyster::Math::Float CalculateCylinderXY( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius ); + static ::Oyster::Math::Float CalculateCylinderZ( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ); + + static MomentOfInertia Sphere( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ); + static MomentOfInertia HollowSphere( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ); + static MomentOfInertia Cuboid( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth ); + static MomentOfInertia RodCenter( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length ); + static MomentOfInertia Cylinder( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius ); + }; + + inline ::Oyster::Math::Float MomentOfInertia::CalculateSphere( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ) + { + return (2.0f / 5.0f) * mass * radius * radius; + } + + inline ::Oyster::Math::Float MomentOfInertia::CalculateHollowSphere( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ) + { + return (2.0f / 3.0f) * mass * radius * radius; + } + + inline ::Oyster::Math::Float MomentOfInertia::CalculateCuboidX( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float depth ) + { + return (1.0f / 12.0f) * mass * (height * height + depth * depth); + } + + inline ::Oyster::Math::Float MomentOfInertia::CalculateCuboidY( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth ) + { + return (1.0f / 12.0f) * mass * (width * width + depth * depth); + } + + inline ::Oyster::Math::Float MomentOfInertia::CalculateCuboidZ( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float width, const ::Oyster::Math::Float height ) + { + return (1.0f / 12.0f) * mass * (height * height + width * width); + } + + inline ::Oyster::Math::Float MomentOfInertia::CalculateRodCenter( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length ) + { + return (1.0f / 12.0f) * mass * length * length; + } + + inline ::Oyster::Math::Float MomentOfInertia::CalculateCylinderXY( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius ) + { + return (1.0f / 12.0f) * mass * (3.0f * radius * radius + height * height); + } + + inline ::Oyster::Math::Float MomentOfInertia::CalculateCylinderZ( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ) + { + return 0.5f * mass * radius * radius; + } + + inline MomentOfInertia MomentOfInertia::Sphere( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ) + { + return MomentOfInertia( ::Oyster::Math::Quaternion::identity, + ::Oyster::Math::Float3(MomentOfInertia::CalculateSphere(mass, radius)) ); + } + + inline MomentOfInertia MomentOfInertia::HollowSphere( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ) + { + return MomentOfInertia( ::Oyster::Math::Quaternion::identity, + ::Oyster::Math::Float3(MomentOfInertia::CalculateHollowSphere(mass, radius)) ); + } + + inline MomentOfInertia MomentOfInertia::Cuboid( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth ) + { + return MomentOfInertia( ::Oyster::Math::Quaternion::identity, + ::Oyster::Math::Float3(MomentOfInertia::CalculateCuboidX(mass, height, depth), + MomentOfInertia::CalculateCuboidY(mass, width, depth), + MomentOfInertia::CalculateCuboidZ(mass, height, width)) ); + } + + inline MomentOfInertia MomentOfInertia::RodCenter( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length ) + { + return MomentOfInertia( ::Oyster::Math::Quaternion::identity, + ::Oyster::Math::Float3(MomentOfInertia::CalculateRodCenter(mass , length)) ); + } + + inline MomentOfInertia MomentOfInertia::Cylinder( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius ) + { + ::Oyster::Math::Float cylinderXY = MomentOfInertia::CalculateCylinderXY( mass , height, radius ); + return MomentOfInertia( ::Oyster::Math::Quaternion::identity, + ::Oyster::Math::Float3(cylinderXY, cylinderXY, + MomentOfInertia::CalculateCylinderZ(mass, radius)) ); + } +} } + +#endif \ No newline at end of file diff --git a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj index 186ea535..dffeca4f 100644 --- a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj +++ b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj @@ -155,6 +155,7 @@ + @@ -174,6 +175,7 @@ + diff --git a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters index 02919d28..da336ce5 100644 --- a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters +++ b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters @@ -78,6 +78,9 @@ Header Files\Physics + + Header Files\Physics + @@ -125,5 +128,8 @@ Source Files\Physics + + Source Files\Physics + \ No newline at end of file diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index 80c800a6..d4da0d00 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -23,7 +23,7 @@ RigidBody::RigidBody( ) this->frictionCoeff_Static = 0.5f; this->frictionCoeff_Kinetic = 1.0f; this->mass = 10; - this->momentOfInertiaTensor = Float4x4::identity; + this->momentOfInertiaTensor = MomentOfInertia(); this->rotation = Quaternion::identity; } @@ -51,17 +51,18 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength ) // updating the linear // ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear ); - + // updating the angular - Float4x4 rotationMatrix; ::Oyster::Math3D::RotationMatrix( this->rotation, rotationMatrix ); + //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 + //Float4x4 wMomentOfInertiaTensor = TransformMatrix( rotationMatrix, this->momentOfInertiaTensor ); // RI // dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H //! HACK: @todo Rotation temporary disabled //this->axis += Radian( Formula::AngularVelocity(wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, this->impulse_Angular)) ); - //this->rotation = Rotation( this->axis ); + this->axis += this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, AverageWithDelta(this->momentum_Angular, this->impulse_Angular) ); + this->rotation = Rotation( this->axis ); // update momentums and clear impulse_Linear and impulse_Angular this->momentum_Linear += this->impulse_Linear; @@ -78,11 +79,12 @@ void RigidBody::Predict_LeapFrog( Float4 &outDeltaPos, Float4 &outDeltaAxis, con outDeltaPos = ( deltaTime / this->mass ) * AverageWithDelta( this->momentum_Linear, actingLinearImpulse ); // updating the angular - Float4x4 rotationMatrix; ::Oyster::Math3D::RotationMatrix( this->rotation, rotationMatrix ); - Float4x4 wMomentOfInertiaTensor = TransformMatrix( rotationMatrix, this->momentOfInertiaTensor ); // RI + //Float4x4 rotationMatrix; ::Oyster::Math3D::RotationMatrix( this->rotation, rotationMatrix ); + //Float4x4 wMomentOfInertiaTensor = TransformMatrix( rotationMatrix, this->momentOfInertiaTensor ); // RI // dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H - outDeltaAxis = Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, actingAngularImpulse) ); + //outDeltaAxis = Formula::AngularVelocity( wMomentOfInertiaTensor.GetInverse(), AverageWithDelta(this->momentum_Angular, actingAngularImpulse) ); + outDeltaAxis = this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, AverageWithDelta(this->momentum_Angular, this->impulse_Angular) ); } void RigidBody::Move( const Float4 &deltaPos, const Float4 &deltaAxis ) @@ -106,7 +108,7 @@ void RigidBody::ApplyImpulse( const Float4 &worldJ, const Float4 &atWorldPos ) } } -const Float4x4 & RigidBody::GetMomentOfInertia() const +const MomentOfInertia & RigidBody::GetMomentOfInertia() const { // by Dan Andersson return this->momentOfInertiaTensor; } @@ -143,7 +145,7 @@ Float4 RigidBody::GetVelocity_Linear() const Float4 RigidBody::GetVelocity_Angular() const { // by Dan Andersson - return Formula::AngularVelocity( this->momentOfInertiaTensor.GetInverse(), this->momentum_Angular ); + return this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, this->momentum_Angular ); } Float4 RigidBody::GetLinearMomentum( const Float4 &atWorldPos ) const @@ -151,24 +153,16 @@ Float4 RigidBody::GetLinearMomentum( const Float4 &atWorldPos ) const return this->momentum_Linear + Formula::TangentialLinearMomentum( this->momentum_Angular, atWorldPos - this->centerPos ); } -void RigidBody::SetMomentOfInertia_KeepVelocity( const Float4x4 &localTensorI ) +void RigidBody::SetMomentOfInertia_KeepVelocity( const MomentOfInertia &localTensorI ) { // by Dan Andersson - 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 ); - } + Float4 w = this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, this->momentum_Angular ); + this->momentOfInertiaTensor = localTensorI; + this->momentum_Angular = this->momentOfInertiaTensor.CalculateAngularVelocity( this->rotation, w ); } -void RigidBody::SetMomentOfInertia_KeepMomentum( const Float4x4 &localTensorI ) +void RigidBody::SetMomentOfInertia_KeepMomentum( const MomentOfInertia &localTensorI ) { // by Dan Andersson - if( localTensorI.GetDeterminant() != 0.0f ) - { // insanity check! MomentOfInertiaTensor must be invertable - this->momentOfInertiaTensor = localTensorI; - } + this->momentOfInertiaTensor = localTensorI; } void RigidBody::SetMass_KeepVelocity( const Float &m ) @@ -217,13 +211,13 @@ void RigidBody::SetVelocity_Linear( const Float4 &worldV ) void RigidBody::SetVelocity_Linear( const Float4 &worldV, const Float4 &atWorldPos ) { // by Dan Andersson 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) ); + this->momentum_Linear = Formula::LinearMomentum( this->mass, VectorProjection(worldV, worldOffset) ); + this->momentum_Angular = this->momentOfInertiaTensor.CalculateAngularMomentum( this->rotation, Formula::AngularVelocity(worldV, worldOffset) ); } void RigidBody::SetVelocity_Angular( const Float4 &worldW ) { // by Dan Andersson - this->momentum_Angular = Formula::AngularMomentum( this->momentOfInertiaTensor, worldW ); + this->momentum_Angular = this->momentOfInertiaTensor.CalculateAngularMomentum( this->rotation, worldW ); } void RigidBody::SetImpulse_Linear( const Float4 &worldJ, const Float4 &atWorldPos ) diff --git a/Code/OysterPhysics3D/RigidBody.h b/Code/OysterPhysics3D/RigidBody.h index 51c5d2d8..ad619180 100644 --- a/Code/OysterPhysics3D/RigidBody.h +++ b/Code/OysterPhysics3D/RigidBody.h @@ -8,6 +8,7 @@ #include "OysterMath.h" #include "OysterCollision3D.h" #include "OysterPhysics3D.h" +#include "Inertia.h" namespace Oyster { namespace Physics3D { @@ -42,23 +43,23 @@ namespace Oyster { namespace Physics3D // GET METHODS //////////////////////////////// - const ::Oyster::Math::Float4x4 & GetMomentOfInertia() const; - ::Oyster::Math::Float GetMass() const; - const ::Oyster::Math::Quaternion & GetRotation() const; - ::Oyster::Math::Float4x4 GetRotationMatrix() const; - ::Oyster::Math::Float4x4 GetOrientation() const; - ::Oyster::Math::Float4x4 GetView() const; - ::Oyster::Math::Float4x4 GetToWorldMatrix() const; - ::Oyster::Math::Float4x4 GetToLocalMatrix() const; - ::Oyster::Math::Float4 GetSize() const; - ::Oyster::Math::Float4 GetVelocity_Linear() const; - ::Oyster::Math::Float4 GetVelocity_Angular() const; - ::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float4 &atWorldPos ) const; + const ::Oyster::Physics3D::MomentOfInertia & GetMomentOfInertia() const; + ::Oyster::Math::Float GetMass() const; + const ::Oyster::Math::Quaternion & GetRotation() const; + ::Oyster::Math::Float4x4 GetRotationMatrix() const; + ::Oyster::Math::Float4x4 GetOrientation() const; + ::Oyster::Math::Float4x4 GetView() const; + ::Oyster::Math::Float4x4 GetToWorldMatrix() const; + ::Oyster::Math::Float4x4 GetToLocalMatrix() const; + ::Oyster::Math::Float4 GetSize() const; + ::Oyster::Math::Float4 GetVelocity_Linear() const; + ::Oyster::Math::Float4 GetVelocity_Angular() const; + ::Oyster::Math::Float4 GetLinearMomentum( const ::Oyster::Math::Float4 &atWorldPos ) const; // SET METHODS //////////////////////////////// - void SetMomentOfInertia_KeepVelocity( const ::Oyster::Math::Float4x4 &localTensorI ); - void SetMomentOfInertia_KeepMomentum( const ::Oyster::Math::Float4x4 &localTensorI ); + void SetMomentOfInertia_KeepVelocity( const ::Oyster::Physics3D::MomentOfInertia &localTensorI ); + void SetMomentOfInertia_KeepMomentum( const ::Oyster::Physics3D::MomentOfInertia &localTensorI ); void SetMass_KeepVelocity( const ::Oyster::Math::Float &m ); void SetMass_KeepMomentum( const ::Oyster::Math::Float &m ); @@ -78,7 +79,8 @@ namespace Oyster { namespace Physics3D private: ::Oyster::Math::Float mass; //!< m (kg) - ::Oyster::Math::Float4x4 momentOfInertiaTensor; //!< I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue) + //::Oyster::Math::Float4x4 momentOfInertiaTensor; //!< I (Nm*s) Tensor matrix ( only need to be 3x3 matrix, but is 4x4 for future hardware acceleration ) (localValue) + ::Oyster::Physics3D::MomentOfInertia momentOfInertiaTensor; ::Oyster::Math::Quaternion rotation; //!< RotationAxis of the body. }; } }