![]() |
TAPs 0.7.7.3
|
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