![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsRigidBodyDynamics.cpp 00003 ******************************************************************************/ 00007 /****************************************************************************** 00008 SUKITTI PUNAK (03/25/2010) 00009 UPDATE (12/03/2010) 00010 ******************************************************************************/ 00011 #include "TAPsRigidBodyDynamics.hpp" 00012 // Using Inclusion Model (i.e. definitions are included in declarations) 00013 // (this name.cpp is included in name.hpp) 00014 // Each friend is defined directly inside its declaration. 00015 00016 BEGIN_NAMESPACE_TAPs 00017 //============================================================================= 00018 // Constructors 00019 //----------------------------------------------------------------------------- 00020 template <typename T> 00021 RigidBodyDynamics<T>::RigidBodyDynamics () : m_bPositionLocked( false ) 00022 {} 00023 //----------------------------------------------------------------------------- 00024 template <typename T> 00025 RigidBodyDynamics<T>::RigidBodyDynamics ( Vector3<T> const & Origin, Quaternion<T> const & Orientation ) 00026 : RigidBodyBase<T>( Origin, Orientation ) 00027 , m_bPositionLocked( false ) 00028 {} 00029 //----------------------------------------------------------------------------- 00030 //template <typename T> 00031 //RigidBodyDynamics<T>::RigidBodyDynamics ( RigidBodyDynamics<T> const &orig ) 00032 // : 00033 //{} 00034 //----------------------------------------------------------------------------- 00035 template <typename T> 00036 RigidBodyDynamics<T>::~RigidBodyDynamics () 00037 {} 00038 //----------------------------------------------------------------------------- 00039 template <typename T> 00040 std::string RigidBodyDynamics<T>::StrInfo () const 00041 { 00042 std::ostringstream ss; 00043 ss << "RigidBodyDynamics<" << typeid(T).name() << ">"; 00044 ss << " is " << RigidBodyBase<T>::StrInfo(); 00045 //ss << " with physical properties " << m_PhysicalProperties; 00046 return ss.str(); 00047 } 00048 //----------------------------------------------------------------------------- 00049 template <typename T> 00050 bool RigidBodyDynamics<T>::CreateInteractionPointGroupBasedOnBVHTree ( 00051 int level 00052 ) 00053 { 00054 if ( level < 0 ) return false; 00055 //----------------------------------------------------- 00056 m_IPGroup.GetTheSetOfInteractionPoints().clear(); // clear the interaction point group 00057 //----------------------------------------------------- 00058 // Currently only HalfEdgeModel supports BVH tree 00059 OpenGL::HalfEdgeModel<T> * pHFModel = dynamic_cast< OpenGL::HalfEdgeModel<T> * >( m_pModel ); 00060 if ( !pHFModel ) return false; 00061 //----------------------------------------------------- 00062 // if BVH tree is note created yet, 00063 // then create it and delete it later 00064 bool bDelBVH = false; 00065 if ( pHFModel->GetBVHTree() == NULL ) { 00066 pHFModel->BuildBVHTree( TAPs::Enum::BVH_TREE_BINARY_SPHERE ); 00067 bDelBVH = true; 00068 } 00069 //----------------------------------------------------- 00070 bool result = false; 00071 if ( pHFModel->GetBVHTree() != NULL ) { 00072 // Use a recursive function 00073 BVHNode<T> ** L = new BVHNode<T>*[1]; 00074 L[0] = pHFModel->GetBVHTree()->Root(); 00075 result = CreateInteractionPointGroupBasedOnBVHTree_Recursive( L, 1, 0, level ); 00076 delete [] L; 00077 } 00078 //----------------------------------------------------- 00079 // Delete the BVH tree if the BVH tree was not created before this function call 00080 if ( bDelBVH ) { 00081 pHFModel->ClearBVHTree(); 00082 } 00083 //----------------------------------------------------- 00084 return result; 00085 } 00086 //----------------------------------------------------------------------------- 00087 template <typename T> 00088 std::vector< Vector3<T> > RigidBodyDynamics<T>::GetAllInteractionPointPositionsInWorldSpace () const 00089 { 00090 OpenGL::HalfEdgeModel<T> const * m_pHalfEdgeModel = dynamic_cast< OpenGL::HalfEdgeModel<T> const * >( GetPtrToModel() ); 00091 if ( !m_pHalfEdgeModel ) { 00092 std::vector< Vector3<T> > nothing; 00093 return nothing; 00094 }; 00095 00096 Matrix4x4<T> Trx( 1, 0, 0, GetOriginPoint()[0], 0, 1, 0, GetOriginPoint()[1], 0, 0, 1, GetOriginPoint()[2], 0, 0, 0, 1 ); 00097 Trx *= GetOrientation().GetRotationMatrix4x4(); 00098 Trx *= m_pHalfEdgeModel->GetTransform().RefToMatrixTransform(); 00099 00100 std::vector< Vector3<T> > positions; 00101 for ( unsigned int i = 0; i < RefToInteractionPointGroup().GetNumOfInteractionPoints(); ++i ) { 00102 positions.push_back( Trx * RefToInteractionPointGroup().GetInteractionPointAtIndex(i).GetPosition() ); 00103 } 00104 00105 return positions; 00106 } 00107 //----------------------------------------------------------------------------- 00108 template <typename T> 00109 bool RigidBodyDynamics<T>::CreateInteractionPointGroupBasedOnBVHTree_Recursive ( 00110 BVHNode<T> ** node, 00111 int numOfNodes, 00112 int currentLevel, 00113 int finalLevel 00114 ) 00115 { 00116 bool result = false; 00117 if ( currentLevel == finalLevel ) { 00118 for ( int i = 0; i < numOfNodes; ++i ) { 00119 m_IPGroup.AddInteractionPoint( node[i]->GetCenter() ); 00120 } 00121 return true; 00122 } 00123 else { 00124 int size = numOfNodes * 2; 00125 BVHNode<T> ** L = new BVHNode<T>*[ size ]; 00126 for ( int i = 0, j = 0; i < numOfNodes; ++i, j+=2 ) { 00127 L[j ] = node[i]->Child(0); 00128 L[j+1] = node[i]->Child(1); 00129 } 00130 bool result = CreateInteractionPointGroupBasedOnBVHTree_Recursive( L, size, ++currentLevel, finalLevel ); 00131 delete [] L; 00132 } 00133 return result; 00134 } 00135 //----------------------------------------------------------------------------- 00136 template <typename T> 00137 bool RigidBodyDynamics<T>::CalAndSetVolumeAndCentroid_BasedOnTetrahedra () 00138 { 00139 if ( !GetPtrToModel() ) return false; 00140 00141 TAPs::CGAlgo<T>::Physics::CalVolumeAndCentroid_BasedOnTetrahedron( GetPtrToModel(), mPhyProp_tVolume, mPhyProp_vCenterOfMass ); 00142 m_OrientationCenter = mPhyProp_vCenterOfMass; 00143 m_OriginPt = mPhyProp_vCenterOfMass; 00144 00145 return true; 00146 } 00147 //----------------------------------------------------------------------------- 00148 template <typename T> 00149 bool RigidBodyDynamics<T>::CalAndSetVolumeAndCentroid_BasedOnInteractionPointGroup () 00150 { 00151 if ( !GetPtrToModel() ) return false; 00152 00153 m_IPGroup.CalVolumeAndCentroid( mPhyProp_tVolume, mPhyProp_vCenterOfMass ); 00154 m_OrientationCenter = mPhyProp_vCenterOfMass; 00155 m_OriginPt = mPhyProp_vCenterOfMass; 00156 00157 return true; 00158 } 00159 //----------------------------------------------------------------------------- 00160 template <typename T> 00161 void RigidBodyDynamics<T>::ClearAllForcesAndTorques () 00162 { 00163 ClearForceAndTorque(); 00164 RefToInteractionPointGroup().RefToCDPointForces().clear(); 00165 } 00166 //----------------------------------------------------------------------------- 00167 //============================================================================= 00168 00169 00170 00171 00172 //============================================================================= 00173 // Override the member functions from PhysicsSupport 00174 //----------------------------------------------------------------------------- 00175 template <typename T> 00176 Vector3<T> const & RigidBodyDynamics<T>::GetCenterOfMass () const 00177 { 00178 return mPhyProp_vCenterOfMass; 00179 } 00180 //----------------------------------------------------------------------------- 00181 template <typename T> 00182 void RigidBodyDynamics<T>::SetCenterOfMass ( Vector3<T> const & COM ) 00183 { 00184 mPhyProp_vCenterOfMass = COM; 00185 } 00186 //----------------------------------------------------------------------------- 00187 template <typename T> 00188 void RigidBodyDynamics<T>::SetCenterOfMass ( T x, T y, T z ) 00189 { 00190 mPhyProp_vCenterOfMass.SetXYZ( x, y, z ); 00191 } 00192 //----------------------------------------------------------------------------- 00193 template <typename T> 00194 void RigidBodyDynamics<T>::AdjustCenterOfMass ( Vector3<T> const & COM ) 00195 { 00196 m_OriginPt -= mPhyProp_vCenterOfMass; 00197 m_OrientationCenter -= mPhyProp_vCenterOfMass; 00198 mPhyProp_vCenterOfMass = COM; 00199 m_OrientationCenter += mPhyProp_vCenterOfMass; 00200 m_OriginPt += mPhyProp_vCenterOfMass; 00201 } 00202 //----------------------------------------------------------------------------- 00203 template <typename T> 00204 void RigidBodyDynamics<T>::AdjustCenterOfMass ( T x, T y, T z ) 00205 { 00206 m_OriginPt -= mPhyProp_vCenterOfMass; 00207 m_OrientationCenter -= mPhyProp_vCenterOfMass; 00208 mPhyProp_vCenterOfMass.SetXYZ( x, y, z ); 00209 m_OrientationCenter += mPhyProp_vCenterOfMass; 00210 m_OriginPt += mPhyProp_vCenterOfMass; 00211 } 00212 //----------------------------------------------------------------------------- 00213 // Override the member functions from PhysicsSupport 00214 //============================================================================= 00215 00216 00217 00218 00219 //============================================================================= 00220 // Override the member functions from AdvanceSimulationInterface 00221 //----------------------------------------------------------------------------- 00222 template <typename T> 00223 void RigidBodyDynamics<T>::AdvanceSimulation ( T timeStep ) 00224 { 00225 StepSimulation( timeStep ); 00226 } 00227 //----------------------------------------------------------------------------- 00228 template <typename T> 00229 void RigidBodyDynamics<T>::AdvanceSimulation ( T tCurrent, T tNext ) 00230 { 00231 StepSimulation( tNext - tCurrent ); 00232 } 00233 //----------------------------------------------------------------------------- 00234 template <typename T> 00235 void RigidBodyDynamics<T>::AdvanceSimulation ( Simulation::SimClock<T> & simClock ) 00236 { 00237 if ( simClock.Current >= simClock.End ) return; 00238 StepSimulation( simClock.Step ); 00239 } 00240 //----------------------------------------------------------------------------- 00241 template <typename T> 00242 void RigidBodyDynamics<T>::StepSimulation ( T dt ) 00243 { 00244 if ( IsPositionLocked() ) return; 00245 00246 // Calculate all of the forces and moments on the object 00247 // ... 00248 00249 // 00250 // Translation (Explicit Euler Integration) 00251 // 00252 // Calculate the linear acceleration (in world space) -- Acc = F/mass 00253 mPhyProp_vLinearAcceleration = mPhyProp_vTotalForce / mPhyProp_tMass; 00254 00255 #ifdef TAPs_ADD_RESTING_LEVEL_Y 00256 if ( m_OriginPt[1] > mPhyProp_tRestingLevel ) { 00257 mPhyProp_vLinearAcceleration[1] -= GetPhyPropGravitationalConstant(); 00258 } 00259 #else //TAPs_ADD_RESTING_LEVEL_Y 00260 mPhyProp_vLinearAcceleration[1] -= GetPhyPropGravitationalConstant(); 00261 #endif//TAPs_ADD_RESTING_LEVEL_Y 00262 // Calculate the linear velocity (in wolrd space) -- Vel = Acc * dt 00263 mPhyProp_vLinearVelocity -= mPhyProp_vLinearVelocity.ComponentWiseMult( mPhyProp_vDampingLinearVelocity ); 00264 mPhyProp_vLinearVelocity += mPhyProp_vLinearAcceleration * dt; 00265 // Calculate the position of the object (in world space) 00266 m_OriginPt += mPhyProp_vLinearVelocity * dt; 00267 00268 // 00269 // Rotation (Explicit Euler Integration) 00270 // 00271 // Calculate the angular acceleration (in body space) 00272 //m_vAngularAcceleration = m_vTotalTorque - ( m_vAngularVelocity ^ ( m_mMomentOfInertia * m_vAngularVelocity )); 00273 // Calculate the angular velocity (in body space) 00274 mPhyProp_vAngularVelocity -= mPhyProp_vAngularVelocity.ComponentWiseMult( mPhyProp_vDampingAngularVelocity ); 00275 mPhyProp_vAngularVelocity += mPhyProp_mInvMomentOfInertiaTensor * mPhyProp_vTotalTorque - 00276 ( mPhyProp_vAngularVelocity ^ ( mPhyProp_mMomentOfInertiaTensor * mPhyProp_vAngularVelocity ) ); 00277 // Calculate the new orientation represented by quaternion 00278 // (in body space) -- (1/2 * quaternion * quaternion(0,angular_velocity))*dt 00279 // If angular_velocity is expressed in world space, 00280 // then the equation is (1/2 * quaternion(0,angular_velocity) * quaternion)*dt 00281 m_Orientation += m_Orientation * mPhyProp_vAngularVelocity * (T(0.5)*dt); 00282 m_Orientation.Normalized(); 00283 } 00284 //----------------------------------------------------------------------------- 00285 // Override the member functions from AdvanceSimulationInterface 00286 //============================================================================= 00287 00288 00289 00290 00291 //============================================================================= 00292 // Override the member functions from RigidBodyBase 00293 //----------------------------------------------------------------------------- 00294 //----------------------------------------------------------------------------- 00295 template <typename T> 00296 void RigidBodyDynamics<T>::SetBVOfType ( Enum::CD type ) 00297 { 00298 RigidBodyBase::SetBVOfType( type ); 00299 if ( !m_pBV ) return; 00300 m_pBV->SetPhysicsSupport( this ); 00301 } 00302 //----------------------------------------------------------------------------- 00303 // Override the member functions from RigidBodyBase 00304 //============================================================================= 00305 00306 00307 00308 00309 //============================================================================= 00310 // OpenGL 00311 #if defined(__gl_h_) || defined(__GL_H__) 00312 //----------------------------------------------------------------------------- 00313 template <typename T> 00314 void RigidBodyDynamics<T>::Draw () const 00315 { 00316 //std::cout << "m_pModel: " << m_pModel << "\n"; 00317 if ( m_pModel ) { 00318 00319 glPushMatrix(); 00320 00321 /* 00322 // In body space transformation sequence 00323 // 1) Translate to the center of mass in world space ( origin pt (in world space) + center of rotation (in body space) ) 00324 // 2) Then rotate by the orientation 00325 // 3) Then translate back by the center of rotation in body space 00326 Matrix4x4<T> Trx( 00327 CGMath<T>::MatrixTranslation( GetOriginPoint() + GetOrientationCenter() ) * 00328 GetOrientation().GetRotationMatrix4x4() * 00329 CGMath<T>::MatrixTranslation( -GetOrientationCenter() ) 00330 ); 00331 //*/ 00332 00333 Matrix4x4<T> Trx( CalMatrixTransform() ); 00334 GLfloat m[16] = { 00335 static_cast<GLfloat>(Trx[ 0]), static_cast<GLfloat>(Trx[ 4]), static_cast<GLfloat>(Trx[ 8]), static_cast<GLfloat>(Trx[ 12]), 00336 static_cast<GLfloat>(Trx[ 1]), static_cast<GLfloat>(Trx[ 5]), static_cast<GLfloat>(Trx[ 9]), static_cast<GLfloat>(Trx[ 13]), 00337 static_cast<GLfloat>(Trx[ 2]), static_cast<GLfloat>(Trx[ 6]), static_cast<GLfloat>(Trx[10]), static_cast<GLfloat>(Trx[ 14]), 00338 static_cast<GLfloat>(Trx[ 3]), static_cast<GLfloat>(Trx[ 7]), static_cast<GLfloat>(Trx[11]), static_cast<GLfloat>(Trx[ 15]) 00339 }; 00340 glMultMatrixf( m ); 00341 00342 m_pModel->Draw(); 00343 00344 /* 00345 // Draw BVH Tree 00346 if ( m_pModel->GetBVHTree() ) { 00347 m_pModel->GetBVHTree()->Draw(); 00348 //m_pModel->GetBVHTree()->DrawByOpenGLOnlyEndLevel(); 00349 } 00350 //*/ 00351 00352 glPopMatrix(); 00353 } 00354 else { 00355 glPushMatrix(); 00356 glPushAttrib( GL_ALL_ATTRIB_BITS ); 00357 glPointSize( 5 ); 00358 glTranslatef( m_OriginPt[0], m_OriginPt[1], m_OriginPt[2] ); 00359 glBegin( GL_POINTS ); 00360 glVertex3f( 0, 0, 0 ); 00361 glEnd(); 00362 glPopAttrib(); 00363 glPopMatrix(); 00364 } 00365 } 00366 //----------------------------------------------------------------------------- 00367 template <typename T> 00368 void RigidBodyDynamics<T>::DrawCenterOfMass () const 00369 { 00370 Matrix4x4<T> Trx( CalMatrixTransform() ); 00371 Vector3<T> COM( Trx * GetCenterOfMass() ); 00372 glPushMatrix(); 00373 glPushAttrib( GL_ALL_ATTRIB_BITS ); 00374 glDisable( GL_DEPTH_TEST ); 00375 glDisable( GL_LIGHTING ); 00376 glColor3f( 0.25, 0.25, 0.25 ); 00377 glPointSize( 5 ); 00378 glBegin( GL_POINTS ); 00379 glVertex3f( COM[0], COM[1], COM[2] ); 00380 glEnd(); 00381 glPopAttrib(); 00382 glPopMatrix(); 00383 } 00384 //----------------------------------------------------------------------------- 00385 template <typename T> 00386 void RigidBodyDynamics<T>::DrawInteractionPointGroup () const 00387 { 00388 glPushMatrix(); 00389 glPushAttrib( GL_ALL_ATTRIB_BITS ); 00390 glDisable( GL_DEPTH_TEST ); 00391 Matrix4x4<T> Trx = CalMatrixTransform(); 00392 GLfloat m[16] = { 00393 static_cast<GLfloat>(Trx[ 0]), static_cast<GLfloat>(Trx[ 4]), static_cast<GLfloat>(Trx[ 8]), static_cast<GLfloat>(Trx[ 12]), 00394 static_cast<GLfloat>(Trx[ 1]), static_cast<GLfloat>(Trx[ 5]), static_cast<GLfloat>(Trx[ 9]), static_cast<GLfloat>(Trx[ 13]), 00395 static_cast<GLfloat>(Trx[ 2]), static_cast<GLfloat>(Trx[ 6]), static_cast<GLfloat>(Trx[10]), static_cast<GLfloat>(Trx[ 14]), 00396 static_cast<GLfloat>(Trx[ 3]), static_cast<GLfloat>(Trx[ 7]), static_cast<GLfloat>(Trx[11]), static_cast<GLfloat>(Trx[ 15]) 00397 }; 00398 glMultMatrixf( m ); 00399 m_IPGroup.Draw(); 00400 00401 //OpenGL::HalfEdgeModel<T> * pHFModel = dynamic_cast< OpenGL::HalfEdgeModel<T> * >( m_pModel ); 00402 //pHFModel->GetBVHTree()->Draw(); 00403 00404 glPopAttrib(); 00405 glPopMatrix(); 00406 } 00407 //----------------------------------------------------------------------------- 00408 template <typename T> 00409 void RigidBodyDynamics<T>::DrawForDebugging () const 00410 { 00411 Draw(); 00412 DrawInteractionPointGroup(); 00413 DrawCenterOfMass(); 00414 DrawOrigin(); 00415 DrawOrientation(); 00416 00417 DrawBV(); 00418 } 00419 //----------------------------------------------------------------------------- 00420 #endif // OpenGL 00421 //============================================================================= 00422 00423 00424 //============================================================================= 00425 END_NAMESPACE_TAPs 00426 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00427 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----