TAPs 0.7.7.3
TAPsRigidBodyDynamics.cpp
Go to the documentation of this file.
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----+----
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines