123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- #pragma once
- #include <Mathematics/Matrix3x3.h>
- #include <Mathematics/Rotation.h>
- #include <functional>
- namespace WwiseGTE
- {
- template <typename Real>
- class RigidBody
- {
- public:
-
-
-
- virtual ~RigidBody() = default;
- RigidBody()
- :
- mMass(std::numeric_limits<Real>::max()),
- mInvMass((Real)0),
- mInertia(Matrix3x3<Real>::Identity()),
- mInvInertia(Matrix3x3<Real>::Zero()),
- mPosition(Vector3<Real>::Zero()),
- mQuatOrient(Quaternion<Real>::Identity()),
- mLinearMomentum(Vector3<Real>::Zero()),
- mAngularMomentum(Vector3<Real>::Zero()),
- mRotOrient(Matrix3x3<Real>::Identity()),
- mLinearVelocity(Vector3<Real>::Zero()),
- mAngularVelocity(Vector3<Real>::Zero())
- {
-
- }
-
- void SetMass(float mass)
- {
- if ((Real)0 < mass && mass < std::numeric_limits<Real>::max())
- {
- mMass = mass;
- mInvMass = (Real)1 / mass;
- }
- else
- {
-
- mMass = std::numeric_limits<Real>::max();
- mInvMass = (Real)0;
- mInertia = Matrix3x3<Real>::Identity();
- mInvInertia = Matrix3x3<Real>::Zero();
- mQuatOrient = Quaternion<Real>::Identity();
- mLinearMomentum = Vector3<Real>::Zero();
- mAngularMomentum = Vector3<Real>::Zero();
- mRotOrient = Matrix3x3<Real>::Identity();
- mLinearVelocity = Vector3<Real>::Zero();
- mAngularVelocity = Vector3<Real>::Zero();
- }
- }
- void SetBodyInertia(Matrix3x3<Real> const& inertia)
- {
- mInertia = inertia;
- mInvInertia = Inverse(mInertia);
- }
- inline void SetPosition(Vector3<Real> const& position)
- {
- mPosition = position;
- }
- void SetQOrientation(Quaternion<Real> const& quatOrient)
- {
- mQuatOrient = quatOrient;
- mRotOrient = Rotation<3, Real>(mQuatOrient);
- }
- void SetLinearMomentum(Vector3<Real> const& linearMomentum)
- {
- mLinearMomentum = linearMomentum;
- mLinearVelocity = mInvMass * mLinearMomentum;
- }
- void SetAngularMomentum(Vector3<Real> const& angularMomentum)
- {
- mAngularMomentum = angularMomentum;
-
- mAngularVelocity = mAngularMomentum * mRotOrient;
-
- mAngularVelocity = mInvInertia * mAngularVelocity;
-
- mAngularVelocity = mRotOrient * mAngularVelocity;
- }
- void SetROrientation(Matrix3x3<Real> const& rotOrient)
- {
- mRotOrient = rotOrient;
- mQuatOrient = Rotation<3, Real>(mRotOrient);
- }
- void SetLinearVelocity(Vector3<Real> const& linearVelocity)
- {
- mLinearVelocity = linearVelocity;
- mLinearMomentum = mMass * mLinearVelocity;
- }
- void SetAngularVelocity(Vector3<Real> const& angularVelocity)
- {
- mAngularVelocity = angularVelocity;
-
- mAngularMomentum = mAngularVelocity * mRotOrient;
-
- mAngularMomentum = mInertia * mAngularMomentum;
-
- mAngularMomentum = mRotOrient * mAngularMomentum;
- }
-
- inline Real GetMass() const
- {
- return mMass;
- }
- inline Real GetInverseMass() const
- {
- return mInvMass;
- }
- inline Matrix3x3<Real> const& GetBodyInertia() const
- {
- return mInertia;
- }
- inline Matrix3x3<Real> const& GetBodyInverseInertia() const
- {
- return mInvInertia;
- }
- Matrix3x3<Real> GetWorldInertia() const
- {
- return MultiplyABT(mRotOrient * mInertia, mRotOrient);
- }
- Matrix3x3<Real> GetWorldInverseInertia() const
- {
-
- return MultiplyABT(mRotOrient * mInvInertia, mRotOrient);
- }
- inline Vector3<Real> const& GetPosition() const
- {
- return mPosition;
- }
- Quaternion<Real> const& GetQOrientation() const
- {
- return mQuatOrient;
- }
- inline Vector3<Real> const& GetLinearMomentum() const
- {
- return mLinearMomentum;
- }
- inline Vector3<Real> const& GetAngularMomentum() const
- {
- return mAngularMomentum;
- }
- inline Matrix3x3<Real> const& GetROrientation() const
- {
- return mRotOrient;
- }
- inline Vector3<Real> const& GetLinearVelocity() const
- {
- return mLinearVelocity;
- }
- inline Vector3<Real> const& GetAngularVelocity() const
- {
- return mAngularVelocity;
- }
-
- typedef std::function
- <
- Vector3<Real>
- (
- Real,
- Real,
- Vector3<Real> const&,
- Quaternion<Real> const&,
- Vector3<Real> const&,
- Vector3<Real> const&,
- Matrix3x3<Real> const&,
- Vector3<Real> const&,
- Vector3<Real> const&
- )
- >
- Function;
-
- Function mForce;
- Function mTorque;
-
- void Update(Real t, Real dt)
- {
-
-
-
- Real halfDT = (Real)0.5 * dt;
- Real sixthDT = dt / (Real)6;
- Real TpHalfDT = t + halfDT;
- Real TpDT = t + dt;
- Vector3<Real> newPosition, newLinearMomentum, newAngularMomentum;
- Vector3<Real> newLinearVelocity, newAngularVelocity;
- Quaternion<Real> newQuatOrient;
- Matrix3x3<Real> newRotOrient;
-
- Vector3<Real> A1DXDT = mLinearVelocity;
- Quaternion<Real> W = Quaternion<Real>(mAngularVelocity[0],
- mAngularVelocity[1], mAngularVelocity[2], (Real)0);
- Quaternion<Real> A1DQDT = (Real)0.5 * W * mQuatOrient;
- Vector3<Real> A1DPDT = mForce(t, mMass, mPosition, mQuatOrient,
- mLinearMomentum, mAngularMomentum, mRotOrient, mLinearVelocity,
- mAngularVelocity);
- Vector3<Real> A1DLDT = mTorque(t, mMass, mPosition, mQuatOrient,
- mLinearMomentum, mAngularMomentum, mRotOrient, mLinearVelocity,
- mAngularVelocity);
- newPosition = mPosition + halfDT * A1DXDT;
- newQuatOrient = mQuatOrient + halfDT * A1DQDT;
- newLinearMomentum = mLinearMomentum + halfDT * A1DPDT;
- newAngularMomentum = mAngularMomentum + halfDT * A1DLDT;
- newRotOrient = Rotation<3, Real>(newQuatOrient);
- newLinearVelocity = mInvMass * newLinearMomentum;
- newAngularVelocity = newAngularMomentum * newRotOrient;
- newAngularVelocity = mInvInertia * newAngularVelocity;
- newAngularVelocity = newRotOrient * newAngularVelocity;
-
- Vector3<Real> A2DXDT = newLinearVelocity;
- W = Quaternion<Real>(newAngularVelocity[0], newAngularVelocity[1],
- newAngularVelocity[2], (Real)0);
- Quaternion<Real> A2DQDT = (Real)0.5 * W * newQuatOrient;
- Vector3<Real> A2DPDT = mForce(TpHalfDT, mMass, newPosition,
- newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
- newLinearVelocity, newAngularVelocity);
- Vector3<Real> A2DLDT = mTorque(TpHalfDT, mMass, newPosition,
- newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
- newLinearVelocity, newAngularVelocity);
- newPosition = mPosition + halfDT * A2DXDT;
- newQuatOrient = mQuatOrient + halfDT * A2DQDT;
- newLinearMomentum = mLinearMomentum + halfDT * A2DPDT;
- newAngularMomentum = mAngularMomentum + halfDT * A2DLDT;
- newRotOrient = Rotation<3, Real>(newQuatOrient);
- newLinearVelocity = mInvMass * newLinearMomentum;
- newAngularVelocity = newAngularMomentum * newRotOrient;
- newAngularVelocity = mInvInertia * newAngularVelocity;
- newAngularVelocity = newRotOrient * newAngularVelocity;
-
- Vector3<Real> A3DXDT = newLinearVelocity;
- W = Quaternion<Real>(newAngularVelocity[0], newAngularVelocity[1],
- newAngularVelocity[2], (Real)0);
- Quaternion<Real> A3DQDT = (Real)0.5 * W * newQuatOrient;
- Vector3<Real> A3DPDT = mForce(TpHalfDT, mMass, newPosition,
- newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
- newLinearVelocity, newAngularVelocity);
- Vector3<Real> A3DLDT = mTorque(TpHalfDT, mMass, newPosition,
- newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
- newLinearVelocity, newAngularVelocity);
- newPosition = mPosition + dt * A3DXDT;
- newQuatOrient = mQuatOrient + dt * A3DQDT;
- newLinearMomentum = mLinearMomentum + dt * A3DPDT;
- newAngularMomentum = mAngularMomentum + dt * A3DLDT;
- newRotOrient = Rotation<3, Real>(newQuatOrient);
- newLinearVelocity = mInvMass * newLinearMomentum;
- newAngularVelocity = newAngularMomentum * newRotOrient;
- newAngularVelocity = mInvInertia * newAngularVelocity;
- newAngularVelocity = newRotOrient * newAngularVelocity;
-
- Vector3<Real> A4DXDT = newLinearVelocity;
- W = Quaternion<Real>(newAngularVelocity[0], newAngularVelocity[1],
- newAngularVelocity[2], (Real)0);
- Quaternion<Real> A4DQDT = (Real)0.5 * W * newQuatOrient;
- Vector3<Real> A4DPDT = mForce(TpDT, mMass, newPosition,
- newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
- newLinearVelocity, newAngularVelocity);
- Vector3<Real> A4DLDT = mTorque(TpDT, mMass, newPosition, newQuatOrient,
- newLinearMomentum, newAngularMomentum, newRotOrient,
- newLinearVelocity, newAngularVelocity);
- mPosition += sixthDT * (A1DXDT + (Real)2 * (A2DXDT + A3DXDT) + A4DXDT);
- mQuatOrient += sixthDT * (A1DQDT + (Real)2 * (A2DQDT + A3DQDT) + A4DQDT);
- mLinearMomentum += sixthDT * (A1DPDT + (Real)2 * (A2DPDT + A3DPDT) + A4DPDT);
- mAngularMomentum += sixthDT * (A1DLDT + (Real)2 * (A2DLDT + A3DLDT) + A4DLDT);
- mRotOrient = Rotation<3, Real>(mQuatOrient);
- mLinearVelocity = mInvMass * mLinearMomentum;
- mAngularVelocity = mAngularMomentum * mRotOrient;
- mAngularVelocity = mInvInertia * mAngularVelocity;
- mAngularVelocity = mRotOrient * mAngularVelocity;
- }
- protected:
-
- Real mMass, mInvMass;
- Matrix3x3<Real> mInertia, mInvInertia;
-
- Vector3<Real> mPosition;
- Quaternion<Real> mQuatOrient;
- Vector3<Real> mLinearMomentum;
- Vector3<Real> mAngularMomentum;
-
- Matrix3x3<Real> mRotOrient;
- Vector3<Real> mLinearVelocity;
- Vector3<Real> mAngularVelocity;
- };
- }
|