00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define STATEVECTOR RigidBody::StateVector
00024
00025 inline
00026 STATEVECTOR::StateVector() {
00027 }
00028
00029 inline
00030 STATEVECTOR::StateVector(const Vector3 &x, const Quaternion &q,
00031 const Vector3 &P, const Vector3 &L) {
00032
00033
00034 m_x = x;
00035 m_q = q;
00036 m_P = P;
00037 m_L = L;
00038 }
00039
00040 inline
00041 STATEVECTOR STATEVECTOR::operator+(const STATEVECTOR &s) const {
00042 return STATEVECTOR(m_x+s.m_x, m_q+s.m_q, m_P+s.m_P, m_L+s.m_L);
00043 }
00044
00045 inline
00046 STATEVECTOR STATEVECTOR::operator*(Real r) const {
00047 return STATEVECTOR(m_x*r, m_q*r, m_P*r, m_L*r);
00048 }
00049
00050 inline
00051 RigidBody::StateVectorDE::StateVectorDE(const RigidBody *parent) {
00052 assert(parent);
00053
00054 m_parent = parent;
00055 }
00056
00057 inline
00058 Real RigidBody::GetMass() const {
00059
00060
00061 return m_mass;
00062 }
00063
00064 inline
00065 const Matrix3 &RigidBody::GetInertiaTensor() const {
00066
00067
00068 return m_inertia;
00069 }
00070
00071 inline
00072 Matrix3 RigidBody::GetWorldInertiaTensor() const {
00073
00074
00075 assert(feq(m_state.m_q.Norm(), 1));
00076
00077 Matrix3 R = Matrix3::Rotation(m_state.m_q);
00078
00079 assert(feq(R.Determinant(), 1));
00080
00081 return R * m_inertia * R.Transpose();
00082 }
00083
00084 inline
00085 void RigidBody::Freeze() {
00086 m_state.m_P = 0;
00087 m_state.m_L = 0;
00088 m_total_force = 0;
00089 m_total_torque = 0;
00090
00091 m_is_frozen = true;
00092 }
00093
00094 inline
00095 void RigidBody::Unfreeze() {
00096 m_is_frozen = false;
00097 }
00098
00099 inline
00100 bool RigidBody::IsFrozen() const {
00101 return m_is_frozen;
00102 }
00103
00104 inline
00105 void RigidBody::SetPosition(const Vector3 &x) {
00106 m_state.m_x = x;
00107 }
00108
00109 inline
00110 const Vector3 &RigidBody::GetPosition() const {
00111 return m_state.m_x;
00112 }
00113
00114 inline
00115 void RigidBody::SetOrientation(const Quaternion &q) {
00116 m_state.m_q = q;
00117 }
00118
00119 inline
00120 const Quaternion &RigidBody::GetOrientation() const {
00121 return m_state.m_q;
00122 }
00123
00124 inline
00125 void RigidBody::SetLinearVelocity(const Vector3 &v) {
00126 assert(!m_is_frozen);
00127
00128 if(!m_is_frozen)
00129 m_state.m_P = m_mass * v;
00130 }
00131
00132 inline
00133 Vector3 RigidBody::GetLinearVelocity() const {
00134 return m_is_frozen ? 0 : 1.0 / m_mass * m_state.m_P;
00135 }
00136
00137 inline
00138 void RigidBody::SetAngularVelocity(const Vector3 &omega) {
00139 assert(!m_is_frozen);
00140
00141 if(!m_is_frozen)
00142 m_state.m_L = GetWorldInertiaTensor() * omega;
00143 }
00144
00145 inline
00146 Vector3 RigidBody::GetAngularVelocity() const {
00147 return m_is_frozen ? 0 : GetWorldInertiaTensor().Inverse() * m_state.m_L;
00148 }
00149
00150 inline
00151 Real RigidBody::GetKineticEnergy() const {
00152 if(m_is_frozen)
00153 return 0;
00154
00155 Real linear_term = 0.5 * (GetMass() * GetLinearVelocity() * GetLinearVelocity());
00156 Real angular_term = 0.5 * (GetWorldInertiaTensor() * GetAngularVelocity() * GetAngularVelocity());
00157
00158 return linear_term + angular_term;
00159 }
00160
00161 inline
00162 Vector3 RigidBody::TransformVectorToWorld(const Vector3 &v) const {
00163 assert(feq(m_state.m_q.Norm(), 1));
00164
00165 return (m_state.m_q * Quaternion(0, v) * m_state.m_q.Conjugate()).m_v;
00166 }
00167
00168 inline
00169 Vector3 RigidBody::TransformVectorToBody(const Vector3 &v) const {
00170 assert(feq(m_state.m_q.Norm(), 1));
00171
00172 return (m_state.m_q.Conjugate() * Quaternion(0, v) * m_state.m_q).m_v;
00173 }
00174
00175 inline
00176 Vector3 RigidBody::TransformPointToWorld(const Vector3 &p) const {
00177 return TransformVectorToWorld(p) + GetPosition();
00178 }
00179
00180 inline
00181 Vector3 RigidBody::TransformPointToBody(const Vector3 &p) const {
00182 return TransformVectorToBody(p - GetPosition());
00183 }
00184
00185 inline
00186 Vector3 RigidBody::GetPointVelocity(const Vector3 &p) const {
00187 return GetLinearVelocity() + (GetAngularVelocity() ^ TransformVectorToWorld(p));
00188 }
00189
00190 inline
00191 void RigidBody::ApplyForce(const Vector3 &f) {
00192 if(!m_is_frozen)
00193 m_total_force += f;
00194 }
00195
00196 inline
00197 void RigidBody::ApplyForce(const Vector3 &f, const Vector3 &p) {
00198 if(!m_is_frozen) {
00199 m_total_force += f;
00200 m_total_torque += TransformVectorToWorld(p) ^ f;
00201 }
00202 }
00203
00204 inline
00205 void RigidBody::ApplyTorque(const Vector3 &t) {
00206 if(!m_is_frozen) {
00207 m_total_torque += t;
00208 }
00209 }
00210
00211 inline
00212 void RigidBody::ZeroForce() {
00213 m_total_force = 0;
00214 }
00215
00216 inline
00217 void RigidBody::ZeroTorque() {
00218 m_total_torque = 0;
00219 }
00220
00221 inline
00222 Vector3 RigidBody::GetTotalForce() const {
00223 return m_total_force;
00224 }
00225
00226 inline
00227 Vector3 RigidBody::GetTotalTorque() const {
00228 return m_total_torque;
00229 }
00230
00231 inline
00232 void RigidBody::ApplyLinearImpulse(const Vector3 &j) {
00233 if(!m_is_frozen)
00234 m_state.m_P += j;
00235 }
00236
00237 inline
00238 void RigidBody::ApplyAngularImpulse(const Vector3 &j) {
00239 if(!m_is_frozen)
00240 m_state.m_L += j;
00241 }
00242
00243 inline
00244 void RigidBody::SetState(const STATEVECTOR &s) {
00245 if(!m_is_frozen)
00246 m_state = s;
00247 }
00248
00249 inline
00250 STATEVECTOR RigidBody::GetState() const {
00251 return m_state;
00252 }
00253
00254 #undef STATEVECTOR