TAPs 0.7.7.3
TAPsVolPresTriModel.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsVolPresTriModel.cpp
00003 
00004 A Triangulated Model that is deformable with volume preservation.
00005 
00006 SUKITTI PUNAK   (11/02/2004)
00007 UPDATE          (11/11/2004)
00008 ********************************************************************************
00009 +====================+
00010 | DESCRIPTION / NOTE |
00011 +====================+
00012 
00013 The model is a triangulated mesh of V (number of vertices) masses, which each 
00014 mass linked to its neighbors by massless springs of natural length greater than 
00015 zeroes.
00016 
00017 Since the model is triangulated mesh, the linkage between neighbors comprised 
00018 of two kinds of linking springs:
00019   -- Structural springs linking vertices of a face f along its edges
00020      (i.e. metric deformation)
00021      e.g.    2-----1      2
00022               \   /      /|
00023                \ /      / |
00024                 0      0--1
00025   -- Flexion springs linking diagonally between two faces
00026      (i.e. bending deformation)
00027      e.g.     2-----1    this example shows the link of vertex 2 and 3
00028                \ + / \
00029                 \ / + \
00030                  0-----3
00031   (-- No Shear springs (i.e. shearing deformation))
00032 
00033                     (2)-----------(2)-----------(2)
00034                     / \           /|\           / \
00035                    /   \         / | \         /   \
00036                   /     \       /  |  \       /     \
00037                  /       \     /   |   \     /       \
00038                 /         \   /    |    \   /         \
00039                /           \ /     |     \ /           \
00040              (2)-----------(1)-----|-----(1)-----------(2)
00041              / \  .        / \     |     / \        .  / \
00042             /   \   .     /   \    |    /   \     .   /   \
00043            /     \    .  /     \   |   /     \  .    /     \
00044           /       \     / .     \  |  /     . \     /       \
00045          /         \   /    .    \ | /    .    \   /         \
00046         /           \ /        .  \|/  .        \ /           \
00047       (2)-----------(1)-----------(0)-----------(1)----------(2)
00048         \           / \        .  /|\  .        / \           /
00049          \         /   \    .    / | \   .     /   \         /
00050           \       /     \ .     /  |  \    .  /     \       /
00051            \     /     . \     /   |   \     / .     \     /
00052             \   /   .     \   /    |    \   /    .    \   /
00053              \ / .         \ /     |     \ /        .  \ /
00054              (2)-----------(1)-----|-----(1)-----------(2)
00055                \           / \     |     / \           /
00056                 \         /   \    |    /   \         /
00057                  \       /     \   |   /     \       /
00058                   \     /       \  |  /       \     /
00059                    \   /         \ | /         \   /
00060                     \ /           \|/           \ /
00061                     (2)------------(2)----------(2)
00062   
00063   Data Structure:
00064   ===============
00065   Need edge list
00066   Each edge incidents to two faces, find cross list
00067 
00068 
00069 
00070     In case of Quadrateral Mesh
00071   (0,0)---------(0,1)---------(0,2)
00072     |  \       /  |  \       /  |
00073     |    \   /    |    \   /    |
00074     |      +      |      +      |
00075     |    /   \    |    /   \    |
00076     |  /       \  |  /       \  |
00077   (1,0)---------(1,1)---------(1,2)
00078     |  \       /  |  \       /  |
00079     |    \   /    |    \   /    |
00080     |      +      |      +      |
00081     |    /   \    |    /   \    |
00082     |  /       \  |  /       \  |
00083   (2,0)---------(2,1)---------(2,2)
00084 
00085 ******************************************************************************/
00086 #include "TAPsVolPresTriModel.hpp"
00087 // Using Inclusion Model (i.e. definitions are included in declarations)
00088 //                       (this name.cpp is included in name.hpp)
00089 // Each friend is defined directly inside its declaration.
00090 
00091 BEGIN_NAMESPACE_TAPs__OpenGL
00092 //=============================================================================
00093 //-----------------------------------------------------------------------------
00094 // default constructor
00095 template <typename T>
00096 VolPresTriModel<T>::VolPresTriModel ()
00097     : XTrigonalModel<T>(), m_tVolume(), m_vtCentroid(),
00098       m_iNoEdges( 0 ), m_prEdge( NULL ),
00099       // Spring
00100       m_pprParticleVertex( NULL ),
00101       m_pprSpringVertex( NULL )
00102 {
00103     #ifdef  TAPs_ENABLE_DEBUG
00104     std::cout << "VolPresTriModel<" << typeid(T).name() << "> Constructor\n";
00105     #endif//TAPs_ENABLE_DEBUG
00106 }
00107 //-----------------------------------------------------------------------------
00108 // destructor
00109 template <typename T>
00110 VolPresTriModel<T>::~VolPresTriModel ()
00111 {
00112     delete [] m_prEdge;
00113     m_prEdge = NULL;
00114 
00115     #ifdef  TAPs_ENABLE_DEBUG
00116     std::cout << "VolPresTriModel<" << typeid(T).name() << "> Destructor\n";
00117     #endif//TAPs_ENABLE_DEBUG
00118 
00119     // Delete All ParticleVertex
00120     for ( int i = 0; i < m_iNoVertices; ++i ) {
00121         delete m_pprParticleVertex[i];
00122     }
00123     delete [] m_pprParticleVertex;
00124     // Delete All SpringVertex
00125     for ( int i = 0; i < m_iNoEdges; ++i ) {
00126         delete m_pprSpringVertex[i];
00127     }
00128     delete [] m_pprSpringVertex;
00129 }
00130 //-----------------------------------------------------------------------------
00131 // Initialize
00132 template <typename T>
00133 void VolPresTriModel<T>::Initialize ()
00134 {
00135     // Model Initialization
00136     DetermineAndSortRings();
00137     CalAndSetNormals();
00138     // DetermineAndSortRings();
00139     ApplyMaterial();
00140     DetermineEdgeList();
00141 }
00142 //-----------------------------------------------------------------------------
00143 // Find Edge List
00144 template <typename T>
00145 void VolPresTriModel<T>::DetermineEdgeList ()
00146 {
00147     std::vector<int> *edgeRecord;
00148     edgeRecord = new std::vector<int>[ m_iNoVertices ];
00149     int iOrig, iDest;   // original vertex# and destination vertex# of edge
00150     int iV;     // temp vertex number
00151     int numberOfEdges = 0;
00152 
00153     // Get edges in a temp data
00154     for ( int f = 0; f < m_iNoFaces; ++f ) {
00155         iV = m_prFace[f].GetVertexNo( 0 );
00156         for ( int v = 1; v < m_prFace[f].GetNoVertices(); ++v ) {
00157             iOrig = iV;
00158             iDest = m_prFace[f].GetVertexNo( v );
00159             
00160             // Make the original vertex always smaller than the destination vertex
00161             if ( iOrig > iDest ) {
00162                 int tmp = iOrig;
00163                 iOrig = iDest;
00164                 iDest = tmp;
00165             }
00166             iV = iDest;     // keep the current vertex
00167 
00168             // Record the edge
00169             bool notStored = true;
00170             for ( int e = 0; e < static_cast<int>( edgeRecord[iOrig].size() ); ++e ) {
00171                 if ( edgeRecord[iOrig][e] == iDest ) {
00172                     notStored = false;
00173                     break;
00174                 }
00175             }
00176             if ( notStored ) {
00177                 edgeRecord[iOrig].push_back( iDest );
00178                 ++numberOfEdges;
00179                 //std::cout << "Edge: from " << iOrig << " to " << iDest << std::endl;
00180             }
00181         }
00182     }
00183 
00184     // Set edges
00185     int edgeNo = 0;
00186     m_iNoEdges = numberOfEdges;
00187     m_prEdge = new Edge[numberOfEdges];
00188     for ( int v = 0; v < m_iNoVertices; ++v ) {
00189         for ( int e = 0; e < static_cast<int>( edgeRecord[v].size() ); ++e ) {
00190             m_prEdge[edgeNo++].SetOrigAndDest( v, edgeRecord[v][e] );
00191             //std::cout << "Edge: from " << v << " to " << edgeRecord[v][e] << std::endl;
00192         }
00193     }
00194 
00195     CreateParticleVerticesFromVertices();
00196     CreateSpringVerticesFromEdges();
00197     CalVolume2();
00198 
00199     /*
00200     for ( int i = 0; i < m_iNoEdges; ++i ) {
00201         std::cout << "Spring#" << i << ":" << *m_pprSpring[i] << "\n";
00202     }
00203     */
00204 }
00205 //-----------------------------------------------------------------------------
00206 // Create Particles From Vertices
00207 template <typename T>
00208 void VolPresTriModel<T>::CreateParticleVerticesFromVertices ()
00209 {
00210     m_pprParticleVertex = new ParticleVertex<T>*[m_iNoVertices];
00211     for ( int i = 0; i < m_iNoVertices; ++i ) {
00212         m_pprParticleVertex[i] = new ParticleVertex<T> ( 
00213             2.0,                // Mass
00214             m_prXVertex[i],     // Vertex (including Position and Normal Vectors)
00215             Vector3<T>(),       // Velocity
00216             Vector3<T>(),       // Acceleration
00217             Vector3<T>()        // Force
00218         );
00219     }
00220 }
00221 //-----------------------------------------------------------------------------
00222 // Create Springs From Edges
00223 template <typename T>
00224 void VolPresTriModel<T>::CreateSpringVerticesFromEdges ()
00225 {
00226     m_pprSpringVertex = new SpringVertex<T>*[m_iNoEdges];
00227     for ( int i = 0; i < m_iNoEdges; ++i ) {
00228         m_pprSpringVertex[i] = new SpringVertex<T> ( 
00229             *m_pprParticleVertex[m_prEdge[i].GetOriginal()],    // Vertex#1
00230             *m_pprParticleVertex[m_prEdge[i].GetDestination()], // Vertex#2
00231             10.0,   // K (spring constant)
00232             0.25    // D (damping constant)
00233         );
00234     }
00235 }
00236 //-----------------------------------------------------------------------------
00237 // Calculate Volume
00238 template <typename T>
00239 T VolPresTriModel<T>::CalVolume ()
00240 {
00241     Vector3<T> va, vb, vc;
00242     Vector3<T> vd;
00243     Vector3<T> vmom;
00244     T tv;
00245     T tVolume = 0.0;
00246     for ( int i = 0; i < m_iNoFaces; ++i ) {
00247         va.SetXYZ ( 
00248             m_prXVertex[m_prFace[i].GetVertexNo(0)][0],
00249             m_prXVertex[m_prFace[i].GetVertexNo(0)][1],
00250             m_prXVertex[m_prFace[i].GetVertexNo(0)][2]
00251         );
00252         vb.SetXYZ ( 
00253             m_prXVertex[m_prFace[i].GetVertexNo(1)][0],
00254             m_prXVertex[m_prFace[i].GetVertexNo(1)][1],
00255             m_prXVertex[m_prFace[i].GetVertexNo(1)][2]
00256         );
00257         vc.SetXYZ ( 
00258             m_prXVertex[m_prFace[i].GetVertexNo(2)][0],
00259             m_prXVertex[m_prFace[i].GetVertexNo(2)][1],
00260             m_prXVertex[m_prFace[i].GetVertexNo(2)][2]
00261         );
00262 
00263         tVolume += tv = ( va * ( vb ^ vc ) ) / 6.0;
00264         vd = ( va + vb + vc ) / 4.0;
00265         vmom += vd * tv;
00266     }
00267     //m_tVolume = tVolume;
00268     m_vtCentroid = vmom / tVolume;
00269     return tVolume;
00270 }
00271 //-----------------------------------------------------------------------------
00272 // Calculate Volume Too
00273 template <typename T>
00274 T VolPresTriModel<T>::CalVolume2 ()
00275 {
00276     T wgt[4] = { 0, 0, 0, 0 };
00277     T v[3][3];
00278     T dv[3][3];
00279 
00281     dv[0][0] = dv[0][1] = dv[0][2] = 0;
00282     dv[1][0] = dv[1][1] = dv[1][2] = 0;
00283     dv[2][0] = dv[2][1] = dv[2][2] = 0;
00284     //*/
00285 
00286     for ( int i = 0; i < m_iNoFaces; ++i ) {
00287         v[0][0] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ][0];
00288         v[0][1] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ][1];
00289         v[0][2] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ][2];
00290         v[1][0] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ][0];
00291         v[1][1] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ][1];
00292         v[1][2] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ][2];
00293         v[2][0] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ][0];
00294         v[2][1] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ][1];
00295         v[2][2] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ][2];
00296 
00297         d3mom0 ( v, dv, wgt );  // call subroutine
00298     }
00299 
00300     m_tVolume = wgt[0];
00301     return m_tVolume;
00302 }
00303 //-----------------------------------------------------------------------------
00304 // Preserve Volume
00305 template <typename T>
00306 void VolPresTriModel<T>::PreserveVolume ( T wgt[4] )
00307 {
00308     wgt[0] = wgt[1] = wgt[2] = wgt[3] = 0;
00309     T v[3][3];
00310     T dv[3][3];
00311 
00312     /*
00313     dv[0][0] = dv[0][1] = dv[0][2] = 0;
00314     dv[1][0] = dv[1][1] = dv[1][2] = 0;
00315     dv[2][0] = dv[2][1] = dv[2][2] = 0;
00316     */
00317 
00318     for ( int i = 0; i < m_iNoFaces; ++i ) {
00319         v[0][0] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ][0];
00320         v[0][1] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ][1];
00321         v[0][2] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ][2];
00322         v[1][0] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ][0];
00323         v[1][1] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ][1];
00324         v[1][2] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ][2];
00325         v[2][0] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ][0];
00326         v[2][1] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ][1];
00327         v[2][2] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ][2];
00328 
00330         dv[0][0] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ].GetNormal().GetX();
00331         dv[0][1] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ].GetNormal().GetY();
00332         dv[0][2] = m_prXVertex[ m_prFace[i].GetVertexNo(0) ].GetNormal().GetZ();
00333         dv[1][0] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ].GetNormal().GetX();
00334         dv[1][1] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ].GetNormal().GetY();
00335         dv[1][2] = m_prXVertex[ m_prFace[i].GetVertexNo(1) ].GetNormal().GetZ();
00336         dv[2][0] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ].GetNormal().GetX();
00337         dv[2][1] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ].GetNormal().GetY();
00338         dv[2][2] = m_prXVertex[ m_prFace[i].GetVertexNo(2) ].GetNormal().GetZ();
00339         //*/
00340         
00341         d3mom0 ( v, dv, wgt );  // call subroutine
00342     }
00343 
00344     T diffVolume = wgt[0] - m_tVolume;
00345     if ( diffVolume != 0 ) {
00346     //if ( fabs( diffVolume ) > Math<T>::ROUND_ERROR ) {
00347         T sigma = SP_Maths::rootOfCubicPolynomial( wgt[3], wgt[2], wgt[1], diffVolume, 1 );
00348 
00349         #ifdef  TAPs_ENABLE_DEBUG
00350         std::cout << "\nsigma: " << sigma << "\n";
00351         #endif//TAPs_ENABLE_DEBUG
00352 
00353         for ( int i = 0; i < m_iNoVertices; ++i ) {
00354             m_prXVertex[i].SetPosition( m_prXVertex[i].GetPosition() + sigma * m_prXVertex[i].GetNormal() );
00355             //m_prXVertex[i].SetPosition( m_prXVertex[i].GetPosition() * sigma );
00356         }
00357     }
00358     
00359     // Recalculate Normals
00360     CalAndSetFaceNormalsNotNormalized();
00361     CalAndSetVertexNormals();
00362     NormalizeFaceNormals();
00363 
00364     // For Checking
00365     CalVolume2();
00366 }
00367 //-----------------------------------------------------------------------------
00368 /* IN : coefficients  v  of degree  1  patch
00369  *   and coefficients dv  of the pertubation
00370  * OUT: weights   wgt  of moment 0: 
00371  *     vol = wgt[0]+wgt[1]*s+wgt[2]*s^2+wgt[3]*s^3 
00372  * generated by Jorg Peters and Maple */
00373 //#define PTS 3 
00374 //#define XYZ 3
00375 //double d3mom0 (double v[PTS][XYZ], double
00376 //               dv[PTS][XYZ], double wgt[4] )
00377 template <typename T>
00378 inline void VolPresTriModel<T>::d3mom0 ( T v[][3], T dv[][3], T wgt[4] )
00379 //void VolPresTriModel<T>::d3mom0 ()
00380 {
00381     T t[184];
00382     //-------------------------------------------------------------------------
00383     t[1]  = v[1][2];
00384     t[2]  = v[2][0];
00385     t[3]  = t[1]*t[2];
00386     t[4]  = v[1][1];
00387     t[6]  = v[0][2];
00388     t[7]  = t[6]*t[2];
00389     t[9]  = v[1][0];
00390     t[10] = t[6]*t[9];
00391     t[11] = v[2][1];
00392     t[13] = v[0][1];
00393     t[15] = v[0][0];
00394     t[16] = t[6]*t[15];
00395     t[20] = t[1]*t[9];
00396     t[23] = t[1]*t[15];
00397     t[27] = v[2][2];
00398     t[28] = t[27]*t[2];
00399     t[30] = t[27]*t[9];
00400     t[33] = t[27]*t[15];
00401     t[37] = -t[3]*t[4]-t[7]*t[4]+t[10]*t[11]-t[10]*t[13]-t[16]*t[11]+t[7]*t[13]+t[16]*t[4]+t[20]*t[11]-t[20]*t[13]-
00402         t[23]*t[11]+t[3]*t[13]+t[23]*t[4]-t[28]*t[4]+t[30]*t[11]-t[30]*t[13]-t[33]*t[11]+t[28]*t[13]+t[33]*t[4];
00403     wgt[0] += t[37]/6.0;
00404     //-------------------------------------------------------------------------
00405     t[38] = dv[1][0];
00406     t[40] = dv[2][0];
00407     t[43] = dv[1][1];
00408     t[45] = dv[2][1];
00409     t[47] = dv[0][1];
00410     t[51] = dv[0][0];
00411     t[56] = t[38]*t[11]-t[40]*t[4]+t[40]*t[13]+t[15]*t[43]+t[9]*t[45]-t[9]*t[47]-t[38]*t[13]-t[15]*t[45]-t[51]*
00412         t[11]+t[2]*t[47]-t[2]*t[43]+t[51]*t[4];
00413     t[58] = dv[0][2];
00414     t[65] = -t[2]*t[4]+t[9]*t[11]-t[9]*t[13]-t[15]*t[11]+t[2]*t[13]+t[15]*t[4];
00415     t[68] = dv[1][2];
00416     t[71] = dv[2][2];
00417     wgt[1] += t[6]*t[56]/6.0 + t[58]*t[65]/6.0 + t[1]*t[56]/6.0 + t[68]*t[65]/6.0 + t[27]*t[56]/6.0 + 
00418         t[71]*t[65]/6.0;
00419     //-------------------------------------------------------------------------
00420     t[74] = t[71]*t[15];
00421     t[76] = t[68]*t[15];
00422     t[78] = t[58]*t[40];
00423     t[81] = t[71]*t[9];
00424     t[83] = t[68]*t[38];
00425     t[87] = t[71]*t[2];
00426     t[89] = t[58]*t[15];
00427     t[91] = t[68]*t[2];
00428     t[93] = t[58]*t[2];
00429     t[96] = t[74]*t[43]-t[76]*t[45]+t[78]*t[13]+t[76]*t[43]-t[81]*t[47]-t[83]*t[13]-t[78]*t[4]+t[83]*t[11]+t[87]*
00430         t[47]-t[89]*t[45]-t[91]*t[43]+t[93]*t[47]+t[81]*t[45];
00431     t[98] = t[58]*t[38];
00432     t[100] = t[71]*t[51];
00433     t[102] = t[6]*t[38];
00434     t[104] = t[27]*t[51];
00435     t[106] = t[27]*t[38];
00436     t[108] = t[27]*t[40];
00437     t[111] = t[6]*t[51];
00438     t[113] = t[1]*t[38];
00439     t[115] = t[71]*t[40];
00440     t[121] = t[98]*t[11]-t[100]*t[11]-t[102]*t[47]-t[104]*t[45]+t[106]*t[45]-t[108]*t[43]+t[108]*t[47]+t[111]
00441         *t[43]-t[113]*t[47]-t[115]*t[4]+t[91]*t[47]-t[87]*t[43]+t[89]*t[43]+t[113]*t[45];
00442     t[124] = t[68]*t[40];
00443     t[126] = t[68]*t[51];
00444     t[130] = t[1]*t[51];
00445     t[133] = t[6]*t[40];
00446     t[136] = t[71]*t[38];
00447     t[142] = -t[124]*t[4]+t[126]*t[4]+t[100]*t[4]-t[74]*t[45]-t[130]*t[45]+t[102]*t[45]+t[133]*t[47]-t[93]*
00448         t[43]-t[136]*t[13]+t[130]*t[43]-t[98]*t[13]-t[111]*t[45]-t[133]*t[43];
00449     t[144] = t[58]*t[9];
00450     t[147] = t[58]*t[51];
00451     t[150] = t[1]*t[40];
00452     t[154] = t[68]*t[9];
00453     t[162] = t[144]*t[45]-t[144]*t[47]-t[147]*t[11]+t[147]*t[4]+t[150]*t[47]-t[150]*t[43]+t[124]*t[13]+t[154]
00454         *t[45]-t[154]*t[47]-t[126]*t[11]+t[104]*t[43]-t[106]*t[47]+t[136]*t[11]+t[115]*t[13];
00455     wgt[2] += t[162]/6.0 + t[142]/6.0 + t[121]/6.0 + t[96]/6.0;
00456     //-------------------------------------------------------------------------
00457     t[183] = t[78]*t[47]+t[147]*t[43]+t[98]*t[45]-t[98]*t[47]-t[147]*t[45]-t[78]*t[43]+t[124]*t[47]+t[126]*
00458         t[43]+t[83]*t[45]-t[83]*t[47]-t[126]*t[45]-t[124]*t[43]+t[115]*t[47]+t[100]*t[43]+t[136]*t[45]-t[136]*t[47]-t[100]*
00459     t[45]-t[115]*t[43];
00460     wgt[3] += t[183]/6.0;
00461     //-------------------------------------------------------------------------
00462 }
00463 //-----------------------------------------------------------------------------
00464 //-----------------------------------------------------------------------------
00465 // StepSimulation
00466 template <typename T>
00467 void VolPresTriModel<T>::StepSimulation( T dt ) {
00468     T divider = 10.0;
00469     
00470     //CalForces( Vector3<T>( (rand()%1000)/divider, (rand()%10)/divider, (rand()%10)/divider ) );
00471     CalForces( Vector3<T>() );
00472     
00473     //CalForces();
00474     // Euler's Method for Integration for ODE Solver
00475     for ( int n = 0; n < m_iNoVertices; ++n ) {
00476         m_pprParticleVertex[n]->SetAcceleration( m_pprParticleVertex[n]->GetForce() / m_pprParticleVertex[n]->GetMass() );
00477         m_pprParticleVertex[n]->SetVelocity( m_pprParticleVertex[n]->GetVelocity() 
00478                                             + ( m_pprParticleVertex[n]->GetAcceleration() * dt ) );
00479         m_pprParticleVertex[n]->SetPosition( m_pprParticleVertex[n]->GetPosition() 
00480                                             + ( m_pprParticleVertex[n]->GetVelocity() * dt ) );
00481     }
00482 }
00483 //-----------------------------------------------------------------------------
00484 // Calculate All Forces Acting on Particles
00485 template <typename T>
00486 void VolPresTriModel<T>::CalForces( Vector3<T> vWind, T g )
00487 {
00488     //CalParticleNormals( 0 );  // calculate particle normals use for finding force due to wind
00489     static int simCounter = 0;
00490 
00491     T zero = 0, y = 0;
00492     for ( int n = 0; n < m_iNoVertices; ++n ) {
00493         if ( m_pprParticleVertex[n]->GetFixStatus() ) {     // If the particle is fixed, skip it!
00494             m_pprParticleVertex[n]->SetForce( 0, 0, 0 );
00495             continue;
00496         }
00497         // Clear and Calculate Force due to Acceleration of Gravity --------
00498         //     Fij = mass * g; where g is a vector
00499         y = m_pprParticleVertex[n]->GetMass() * (-g);
00500 
00501         /*
00502         m_pprParticleVertex[n]->SetForce( 0, y, 0 );
00503         */
00505         if ( simCounter++ < 10 && ( n == 0 || n == 4 ) ) {
00506             m_pprParticleVertex[n]->SetPosition( m_pprParticleVertex[n]->GetPosition() * 0.9999999999 );
00507         }
00508         //*/
00509 
00510         // Add Force due to Viscous Damping --------------------------------
00511         //     Fij = -Kvd * Vij
00512         m_pprParticleVertex[n]->SetForce( m_pprParticleVertex[n]->GetForce() 
00513                 + 0.1/*m_tKvd (viscous damping)*/ * m_pprParticleVertex[n]->GetVelocity() );
00514 
00515         // Add Force due to viscous fluid moving (wind) --------------------
00516         //     Fij = Kvfm * [Nij * (vWind - Vij)] * Nij
00517         //         where Nij is the unit normal on the surface at particle Pij
00518         m_pprParticleVertex[n]->SetForce( m_pprParticleVertex[n]->GetForce()
00519                 + 0.1/*m_tKvfm (viscous fluid moving damping)*/ 
00520                     * ( m_pprParticleVertex[n]->GetNormal() * ( vWind - m_pprParticleVertex[n]->GetVelocity() ) )
00521                     * m_pprParticleVertex[n]->GetNormal() );
00522 
00523         // Dump
00524         //cout << "Mass: " << m_pcParticle[m][n]->m_tMass << "    Force: " << m_pcParticle[m][n]->m_vtForce << "\n";
00525     }
00526     
00527     AddSpringForces();  // calculate and add spring forces to particle forces
00528 }
00529 //-----------------------------------------------------------------------------
00530 // Calculate and Add the Force of a Spring
00531 template <typename T>
00532 inline void VolPresTriModel<T>::AddSpringForces()
00533 {
00534     for ( int i = 0; i < m_iNoEdges; ++i ) {
00535 
00537         //------------------------------------------------------------
00538         // Local Variables
00539         // spring current length vector
00540         Vector3<T> cL = ( m_pprSpringVertex[i]->GetParticleVertexOne().GetPosition()
00541                         - m_pprSpringVertex[i]->GetParticleVertexTwo().GetPosition() );
00542         // spring current length scalar
00543         T scl = cL.Length();
00544         // velocity difference of the two particles linked by the spring
00545         Vector3<T> V = ( m_pprSpringVertex[i]->GetParticleVertexOne().GetVelocity()
00546                        - m_pprSpringVertex[i]->GetParticleVertexTwo().GetVelocity() );
00547 
00548         // F1 = -{Ks(l - r) + Kd[(V1-V2)*L]/l}*L/l
00549         // F2 = -F1
00550         //   where Ks = spring stiffness, Kd = spring damping,
00551         //     V1 and V2 are velocity of particles linked by the spring
00552         //     r = spring rest length
00553         //     L = vector of difference of positions of particle#1 and #2
00554         //     l = magnitude of L
00555         Vector3<T> f  = -( 
00556                   ( m_pprSpringVertex[i]->GetConstantK() * ( scl - m_pprSpringVertex[i]->GetRestLengthL() ) ) 
00557                 + ( m_pprSpringVertex[i]->GetDampingD() * ((V*cL) / scl) ) ) 
00558                 * (cL / scl);
00560         //*/
00561 
00562         //std::cout << "Spring Force: " << f << std::endl;
00563         /*
00564         if ( !m_pprSpringVertex[i]->GetParticleVertexOne().GetFixStatus() )
00565             m_pprSpringVertex[i]->GetParticleVertexOne().SetForce( f );
00566         if ( !m_pprSpringVertex[i]->GetParticleVertexTwo().GetFixStatus() )
00567             m_pprSpringVertex[i]->GetParticleVertexTwo().SetForce( -f );
00568         */
00570         if ( !m_pprSpringVertex[i]->GetParticleVertexOne().GetFixStatus() )
00571             m_pprSpringVertex[i]->GetParticleVertexOne().SetForce( 
00572                       m_pprSpringVertex[i]->GetParticleVertexOne().GetForce()
00573                     + m_pprSpringVertex[i]->GetForce() 
00574                     + f
00575             );
00576         if ( !m_pprSpringVertex[i]->GetParticleVertexTwo().GetFixStatus() )
00577             m_pprSpringVertex[i]->GetParticleVertexTwo().SetForce( 
00578                       m_pprSpringVertex[i]->GetParticleVertexTwo().GetForce()
00579                     - m_pprSpringVertex[i]->GetForce() 
00580                     - f 
00581             );
00582         //*/
00583     }
00584 }
00585 //-----------------------------------------------------------------------------
00586 //=============================================================================
00587 END_NAMESPACE_TAPs__OpenGL
00588 //-----------------------------------------------------------------------------
00589 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00590 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines