![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsCloth.hpp 00003 00004 Cloth class is a class for a cloth modeled by a network of springs. 00005 00006 SUKITTI PUNAK (09/16/2004) 00007 UPDATE (05/30/2008) 00008 ******************************************************************************* 00009 +====================+ 00010 | DESCRIPTION / NOTE | 00011 +====================+ 00012 00013 Adapted from "Provot, X. "Deformation Constraints in a Mass-Spring Model to 00014 Describe Rigid Cloth Behavior," Proc. Graphics Interface, 1995, pp. 147-154." 00015 00016 The model is a mesh of m-by-n virtual masses, which each mass linked to 00017 its neighbors by massless springs of natural length greater than zeroes. 00018 The linkage between neighbors comprised of three kinds of linking springs: 00019 -- Structural springs linking masses [m,n] and [m+1,n], and 00020 masses [m,n] and [m,n+1] 00021 -- Shear springs linking masses [m,n] and [m+1,n+1], and 00022 masses [m+1,n] and [m,n+1] 00023 -- Flexion springs linking masses [m,n] and [m+2,n], and 00024 masses [m,n] and [m,n+2] 00025 00026 (0,0)---------(0,1)---------(0,2) 00027 | \ / | \ / | 00028 | \ / | \ / | 00029 | + | + | 00030 | / \ | / \ | 00031 | / \ | / \ | 00032 (1,0)---------(1,1)---------(1,2) 00033 | \ / | \ / | 00034 | \ / | \ / | 00035 | + | + | 00036 | / \ | / \ | 00037 | / \ | / \ | 00038 (2,0)---------(2,1)---------(2,2) 00039 00040 ******************************************************************************/ 00041 #ifndef TAPs_CLOTH_HPP 00042 #define TAPs_CLOTH_HPP 00043 00044 #include "../Physics/TAPsPhysics.hpp" // for gravitational constant 00045 #include "../Physics/TAPsSpring.hpp" // SPT_Spring.h all ready include SPT_Particle.h 00046 #include "../OpenGL/TAPsOpenGLSupport.hpp" 00047 00048 BEGIN_NAMESPACE_TAPs 00049 //============================================================================= 00050 template <typename T> 00051 class Cloth : public /*virtual*/ OpenGL::OpenGLSupport { 00052 //============================================================================= 00053 //------------------------------------------------------------------------- 00054 // put it through ostream 00055 friend std::ostream &operator<<( std::ostream &output, const Cloth<T> &Obj ) 00056 { 00057 output << "Cloth ==> " 00058 << "\n number of rows: " << Obj.m_iNoRows 00059 << "\n number of columns: " << Obj.m_iNoCols 00060 << "\n viscous damping: " << Obj.m_tKvd 00061 << "\n wind damping: " << Obj.m_tKvfm 00062 << "\n stiffness of structural, shear, and flexion springs: " 00063 << Obj.m_tKs[0] << ", " << Obj.m_tKs[1] << ", and " << Obj.m_tKs[2] 00064 << "\n damping constant for structural, shear, and flexion springs: " 00065 << Obj.m_tKd[0] << ", " << Obj.m_tKd[1] << ", and " << Obj.m_tKd[2] 00066 << "\n length constrain for structural, shear, and flextion springs: " 00067 << Obj.m_tLengthConstrain[0] << ", " 00068 << Obj.m_tLengthConstrain[1] << ", and " 00069 << Obj.m_tLengthConstrain[2] 00070 << "\n"; 00071 00072 return output; 00073 } 00074 00075 //------------------------------------------------------------------------------------------------- 00076 private: 00077 // Data Members ============================================================================ 00078 int m_iNoRows; // number of rows in y-direction (y values) (normally called weft) 00079 int m_iNoCols; // number of columns in x-direction (x values) (normally called warp) 00080 T m_tKvd; // viscous damping of cloth 00081 T m_tKvfm; // viscous fluid moving damping of cloth 00082 T m_tKs[3]; // stiffness spring constant for structural, shear, and flexion springs 00083 T m_tKd[3]; // damping constant for structural, shear, and flexion springs 00084 T m_tLengthConstrain[3]; // Length Constrain for structural, shear, and flexion springs 00085 00086 // Mass Points 00087 Particle<T> ***m_pcParticle; 00088 // Linking Springs 00089 Spring<T> ***m_pcSpringStructuralRow; // (structural, stretching, or tensile) springs linking masses [m,n] and [m,n+1] 00090 Spring<T> ***m_pcSpringStructuralCol; // (structural, stretching, or tensile) springs linking masses [m,n] and [m+1,n] 00091 Spring<T> ***m_pcSpringShearTLtoBR; // (shear) springs linking masses [m,n] and [m+1,n+1] 00092 Spring<T> ***m_pcSpringShearBLtoTR; // (shear) springs linking masses [m+1,n] and [m,n+1] 00093 Spring<T> ***m_pcSpringFlexionRow; // (flexion or bending) springs linking masses [m,n] and [m,n+2] 00094 Spring<T> ***m_pcSpringFlexionCol; // (flexion or bending) springs linking masses [m,n] and [m+2,n] 00095 00096 // object counters 00097 int m, n; // m = row number; n = col number 00098 //------------------------------------------------------------------------------------------------- 00099 private: 00100 // Helper Functions ======================================================================== 00101 void CreateParticles( Vector3<T> const &topLeftPos, Vector3<T> const &bottomRightPos, T mass ); 00102 void DeleteParticles(); 00103 void CreateSprings(); 00104 void DeleteSprings(); 00105 void AddSpringForces(); // calculate and add spring forces to particle forces 00106 // This fn calls AddSpringForce(.) fn. 00107 inline void AddSpringForce( Spring<T> * const sp ); // calculate and add the force of a spring 00108 00109 // Limit Lengths of Springs 00110 void LimitSpringLengths(); // limit the lengths of all springs 00111 // This fn calls LimitSpringLength(.) fn. 00112 inline void LimitSpringLength( Spring<T> * const sp, T lengthLimit ); 00113 00114 //void BindingTexture 00115 //------------------------------------------------------------------------------------------------- 00116 public: 00117 // Member Functions ======================================================================== 00118 // Constructor ------------------------------------------------------------- 00119 Cloth( int rows, // number of rows (on world-y-axis) 00120 int cols, // number of rows (on world-x-axis) 00121 T Kvd, // viscous damping constant 00122 T Kvfm, // viscous fluid moving constant 00123 T Ks, // spring stiffness constant 00124 T Kd, // spring damping constant 00125 T lengthConstrain, // spring rest length 00126 const Vector3<T> &topLeftPos, // start position (should be top left cornor) 00127 const Vector3<T> &bottomRightPos, // end position (should be bottom right cornor) 00128 T mass, // the whole mass 00129 BitmapImage * = NULL ); // Image Pointer 00130 // Constructor ------------------------------------------------------------- 00131 Cloth( int rows, // number of rows (on world-y-axis) 00132 int cols, // number of rows (on world-x-axis) 00133 T Kvd, // viscous damping constant 00134 T Kvfm, // viscous fluid moving constant 00135 T Ks0, // structural spring stiffness constant 00136 T Ks1, // shear spring stiffness constant 00137 T Ks2, // flexion spring stiffness constant 00138 T Kd0, // structural spring damping constant 00139 T Kd1, // shear spring damping constant 00140 T Kd2, // flexion spring damping constant 00141 T lengthConstrain0, // structural spring rest length 00142 T lengthConstrain1, // shear spring rest length 00143 T lengthConstrain2, // flexion spring rest length 00144 const Vector3<T> &topLeftPos, // start position (should be top left cornor) 00145 const Vector3<T> &bottomRightPos, // end position (should be bottom right cornor) 00146 T mass, // the whole mass 00147 BitmapImage * = NULL ); // Image Pointer 00148 //------------------------------------------------------------------------- 00149 ~Cloth(); // destructor 00150 //------------------------------------------------------------------------- 00151 // CalParticleNormals( int i ) should runs faster than CalParticleNormals(), 00152 // since it calculates the normals more direct. 00153 void CalParticleNormals(); // calculate particle normals 00154 void CalParticleNormals( int i ); // calculate particle normals, int i is dummy 00155 void AddNormal( Vector3<T> & Dest, 00156 Vector3<T> const & A, Vector3<T> const & B, Vector3<T> const & C ); 00157 00158 00159 // Calculate Forces -------------------------------------------------------- 00160 /* 00161 void ClearForce(); // clear force of particles to zeros 00162 void ForceDueToGravity( T g = SP_Physics::g ); // calculate (weight) force due to (acceleration of) gravity 00163 void ForceDueToViscousDamping(); // calculate (a loss) force due to viscous damping 00164 void ForceDueToViscousFluidMoving(); // calculate (wind) force due to viscous fluid moving 00165 */ 00166 // Calculate All Forces Acting on Particles 00167 void CalForces( Vector3<T> vWind = Vector3<T>(0,0,0), T g = Physics_SI::K::g ); 00168 00169 // Display Routine(s) ------------------------------------------------------ 00170 void DisplayGL( OpenGL::Enum::DrawMode DM = OpenGL::Enum::POLYGON ); // display cloth 00171 void DisplayGL_ParticleNormals(); // display particle normals 00172 protected: 00173 //------------------------------------------------------------------------- 00174 // Override a pure Virtual fn inherited from OpenGLSupport class 00175 // Helper Fn 00176 // void DrawGL() 00177 virtual void DrawGL ( GLenum ) {}; 00178 //------------------------------------------------------------------------- 00179 public: 00180 // Get/Set Functions 00181 bool GetParticleFixStatus( int r, int c ) const { return m_pcParticle[r][c]->m_bFixed; } 00182 void SetParticleFixStatus( int r, int c, bool b ) { m_pcParticle[r][c]->m_bFixed = b; } 00183 00184 // TEST 00185 void StepSimulation( T dt ) { 00186 T divider = 10.0; 00187 CalForces( Vector3<T>( (rand()%1000)/divider, (rand()%10)/divider, (rand()%10)/divider ) ); 00188 //CalForces(); 00189 // Euler's Method for Integration for ODE Solver 00190 for ( m = 0; m < m_iNoRows; m++ ) { 00191 for ( n = 0; n < m_iNoCols; n++ ) { 00192 m_pcParticle[m][n]->m_vtAccel = m_pcParticle[m][n]->m_vtForce / m_pcParticle[m][n]->m_tMass; 00193 m_pcParticle[m][n]->m_vtVeloc += m_pcParticle[m][n]->m_vtAccel * dt; 00194 m_pcParticle[m][n]->m_vtPosit += m_pcParticle[m][n]->m_vtVeloc * dt; 00195 } 00196 } 00197 LimitSpringLengths(); 00198 } 00199 }; 00200 //CLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLASSCLA 00201 00202 00203 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE 00204 // 00205 // Cloth H E L P E R F U N C T I O N M E M B E R D E F I N I T I O N S 00206 // 00207 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE 00208 //------------------------------------------------------------------------------------------------- 00209 // Create Particles 00210 template <typename T> 00211 void Cloth<T>::CreateParticles( const Vector3<T> &topLeftPos, const Vector3<T> &bottomRightPos, T mass ) 00212 { 00213 // Local Variable 00214 Vector3<T> currentPosVector = topLeftPos; 00215 Vector3<T> diagonalVector = bottomRightPos - topLeftPos; 00216 T ptMass = mass / ( m_iNoCols * m_iNoRows ); 00217 T colIncStep = diagonalVector[0] / (m_iNoCols-1); 00218 T rowIncStep = diagonalVector[1] / (m_iNoRows-1); 00219 //T zIncStep = diagonalVector[2] / ((m_iNoCols + m_iNoRows)/2.0); 00220 T zIncStep = diagonalVector[2] / (m_iNoRows-1); 00221 00222 // Create Particle Pointers 00223 m_pcParticle = new Particle<T>**[m_iNoRows]; 00224 for ( m = 0; m < m_iNoRows; m++ ) { 00225 m_pcParticle[m] = new Particle<T>*[m_iNoCols]; 00226 } 00227 00228 // Create Particles 00229 Vector3<T> zeroVector(0,0,0); 00230 for ( m = 0; m < m_iNoRows; m++ ) { // row loops 00231 for ( n = 0; n < m_iNoCols; n++ ) { // column loops 00232 m_pcParticle[m][n] = new Particle<T>( ptMass, // mass 00233 currentPosVector, // position 00234 zeroVector, // velocity 00235 zeroVector, // acceleration 00236 zeroVector ); // force 00237 currentPosVector[0] = currentPosVector[0] + colIncStep; // increment x position 00238 } 00239 currentPosVector[0] = topLeftPos[0]; // reset x position 00240 currentPosVector[1] = currentPosVector[1] + rowIncStep; // increment y position 00241 currentPosVector[2] = currentPosVector[2] + zIncStep; // increment z position 00242 } 00243 00244 #ifdef TAPs_DEBUG_MODE 00245 // Dump Particle Positions on Screen 00246 for ( m = 0; m < m_iNoRows; m++ ) { // row loops 00247 for ( n = 0; n < m_iNoCols; n++ ) { // column loops 00248 std::cout << "[" << m << "," << n << "] " << m_pcParticle[m][n]->m_vtPosit << " "; 00249 } 00250 std::cout << "\n"; 00251 } 00252 #endif//TAPs_DEBUG_MODE 00253 } 00254 //------------------------------------------------------------------------------------------------- 00255 // Delete Particles 00256 template <typename T> 00257 void Cloth<T>::DeleteParticles() 00258 { 00259 // Delete Particles 00260 for ( m = 0; m < m_iNoRows; m++ ) { 00261 for ( n = 0; n < m_iNoCols; n++ ) { 00262 delete m_pcParticle[m][n]; 00263 } 00264 delete [] m_pcParticle[m]; 00265 } 00266 delete [] m_pcParticle; 00267 } 00268 //------------------------------------------------------------------------------------------------- 00269 // Create Springs 00270 template <typename T> 00271 void Cloth<T>::CreateSprings() 00272 { 00273 // ========== CREATE SPRING POINTERS ======================================= 00274 // Create Structural Spring Pointers --------------------------------------- 00275 m_pcSpringStructuralRow = new Spring<T>**[m_iNoRows]; // Row [m,n] and [m,n+1] 00276 for ( m = 0; m < m_iNoRows; m++ ) { 00277 m_pcSpringStructuralRow[m] = new Spring<T>*[m_iNoCols-1]; 00278 } 00279 m_pcSpringStructuralCol = new Spring<T>**[m_iNoCols]; // Col [m,n] and [m+1,n] 00280 for ( n = 0; n < m_iNoCols; n++ ) { 00281 m_pcSpringStructuralCol[n] = new Spring<T>*[m_iNoRows-1]; 00282 } 00283 // Create Shear Spring Pointers -------------------------------------------- 00284 m_pcSpringShearTLtoBR = new Spring<T>**[m_iNoRows-1]; // [m,n] and [m+1,n+1] 00285 m_pcSpringShearBLtoTR = new Spring<T>**[m_iNoRows-1]; // [m+1,n] and [m,n+1] 00286 for ( m = 0; m < m_iNoRows-1; m++ ) { 00287 m_pcSpringShearTLtoBR[m] = new Spring<T>*[m_iNoCols-1]; 00288 m_pcSpringShearBLtoTR[m] = new Spring<T>*[m_iNoCols-1]; 00289 } 00290 // Create Flexion Spring Pointers ------------------------------------------ 00291 m_pcSpringFlexionRow = new Spring<T>**[m_iNoRows]; // Row [m,n] and [m,n+2] 00292 for ( m = 0; m < m_iNoRows; m++ ) { 00293 m_pcSpringFlexionRow[m] = new Spring<T>*[m_iNoCols-2]; 00294 } 00295 m_pcSpringFlexionCol = new Spring<T>**[m_iNoCols]; // Col [m,n] and [m+2,n] 00296 for ( n = 0; n < m_iNoCols; n++ ) { 00297 m_pcSpringFlexionCol[n] = new Spring<T>*[m_iNoRows-2]; 00298 } 00299 00300 // ========== CREATE SPRING ================================================ 00301 // Create Structural Springs ----------------------------------------------- 00302 // Row [m,n] and [m,n+1] 00303 int id = 0; // 0 for structural spring 00304 00305 #ifdef TAPs_DEBUG_MODE 00306 // Dump 00307 std::cout << "Spring Length of Row [m,n] and [m,n+1]\n"; 00308 #endif//TAPs_DEBUG_MODE 00309 00310 for ( m = 0; m < m_iNoRows; m++ ) { 00311 for ( n = 0; n < m_iNoCols-1; n++ ) { 00312 m_pcSpringStructuralRow[m][n] = new Spring<T>( 00313 *m_pcParticle[m][n], *m_pcParticle[m][n+1], // linked points 00314 m_tKs[id], m_tKd[id], // stiffness and damping const 00315 ( m_pcParticle[m][n]->m_vtPosit 00316 - m_pcParticle[m][n+1]->m_vtPosit).Length() // spring length 00317 ); 00318 00319 #ifdef TAPs_DEBUG_MODE 00320 // Dump (cont.) 00321 std::cout << " " << m_pcSpringStructuralRow[m][n]->GetRestLengthL(); 00322 #endif//TAPs_DEBUG_MODE 00323 } 00324 00325 #ifdef TAPs_DEBUG_MODE 00326 // Dump (cont.) 00327 std::cout << "\n"; 00328 #endif//TAPs_DEBUG_MODE 00329 } 00330 // Col [m,n] and [m+1,n] 00331 00332 #ifdef TAPs_DEBUG_MODE 00333 // Dump 00334 std::cout << "Spring Length of Col [m,n] and [m+1,n]\n"; 00335 #endif//TAPs_DEBUG_MODE 00336 00337 for ( n = 0; n < m_iNoCols; n++ ) { 00338 for ( m = 0; m < m_iNoRows-1; m++ ) { 00339 m_pcSpringStructuralCol[n][m] = new Spring<T>( 00340 *m_pcParticle[m][n], *m_pcParticle[m+1][n], // linked points 00341 m_tKs[id], m_tKd[id], // stiffness and damping const 00342 ( m_pcParticle[m][n]->m_vtPosit 00343 - m_pcParticle[m+1][n]->m_vtPosit).Length() // spring length 00344 ); 00345 00346 #ifdef TAPs_DEBUG_MODE 00347 // Dump (cont.) 00348 std::cout << " " << m_pcSpringStructuralCol[n][m]->GetRestLengthL(); 00349 #endif//TAPs_DEBUG_MODE 00350 } 00351 00352 #ifdef TAPs_DEBUG_MODE 00353 // Dump (cont.) 00354 std::cout << "\n"; 00355 #endif//TAPs_DEBUG_MODE 00356 } 00357 // Create Shear Springs ---------------------------------------------------- 00358 id = 1; // 1 for shear spring 00359 00360 #ifdef TAPs_DEBUG_MODE 00361 // Dump 00362 std::cout << "Spring Length of [m,n] and [m+1,n+1] and "; 00363 std::cout << "Spring Length of [m+1,n] and [m,n+1]\n"; 00364 #endif//TAPs_DEBUG_MODE 00365 00366 int mm, nn; 00367 for ( m = 0, mm = 1; m < m_iNoRows-1; m++, mm++ ) { 00368 for ( n = 0, nn = 1; n < m_iNoCols-1; n++, nn++ ) { 00369 m_pcSpringShearTLtoBR[m][n] = new Spring<T>( 00370 *m_pcParticle[m][n], *m_pcParticle[mm][nn], // linked points 00371 m_tKs[id], m_tKd[id], // stiffness and damping const 00372 ( m_pcParticle[m][n]->m_vtPosit 00373 - m_pcParticle[mm][nn]->m_vtPosit).Length() // spring length 00374 ); 00375 m_pcSpringShearBLtoTR[m][n] = new Spring<T>( 00376 *m_pcParticle[mm][n], *m_pcParticle[m][nn], // linked points 00377 m_tKs[id], m_tKd[id], // stiffness and damping const 00378 ( m_pcParticle[mm][n]->m_vtPosit 00379 - m_pcParticle[m][nn]->m_vtPosit).Length() // spring length 00380 ); 00381 00382 #ifdef TAPs_DEBUG_MODE 00383 // Dump (cont.) 00384 std::cout << " (" << m_pcSpringShearTLtoBR[m][n]->GetRestLengthL(); 00385 // Dump (cont.) 00386 std::cout << ", " << m_pcSpringShearBLtoTR[m][n]->GetRestLengthL() << ") "; 00387 #endif//TAPs_DEBUG_MODE 00388 } 00389 00390 #ifdef TAPs_DEBUG_MODE 00391 // Dump (cont.) 00392 std::cout << "\n"; 00393 #endif//TAPs_DEBUG_MODE 00394 } 00395 // Create Flexion Springs -------------------------------------------------- 00396 id = 2; // 2 for flexion spring 00397 // Row [m,n] and [m,n+2] 00398 00399 #ifdef TAPs_DEBUG_MODE 00400 // Dump 00401 std::cout << "Spring Length of Row [m,n] and [m,n+2]\n"; 00402 #endif//TAPs_DEBUG_MODE 00403 00404 for ( m = 0; m < m_iNoRows; m++ ) { 00405 for ( n = 0; n < m_iNoCols-2; n++ ) { 00406 m_pcSpringFlexionRow[m][n] = new Spring<T>( 00407 *m_pcParticle[m][n], *m_pcParticle[m][n+2], // linked points 00408 m_tKs[id], m_tKd[id], // stiffness and damping const 00409 ( m_pcParticle[m][n]->m_vtPosit 00410 - m_pcParticle[m][n+2]->m_vtPosit).Length() // spring length 00411 ); 00412 00413 #ifdef TAPs_DEBUG_MODE 00414 // Dump (cont.) 00415 std::cout << " " << m_pcSpringFlexionRow[m][n]->GetRestLengthL(); 00416 #endif//TAPs_DEBUG_MODE 00417 } 00418 00419 #ifdef TAPs_DEBUG_MODE 00420 // Dump (cont.) 00421 std::cout << "\n"; 00422 #endif//TAPs_DEBUG_MODE 00423 } 00424 // Col [m,n] and [m+2,n] 00425 00426 #ifdef TAPs_DEBUG_MODE 00427 // Dump 00428 std::cout << "Spring Length of Col [m,n] and [m+2,n]\n"; 00429 #endif//TAPs_DEBUG_MODE 00430 00431 for ( n = 0; n < m_iNoCols; n++ ) { 00432 for ( m = 0; m < m_iNoRows-2; m++ ) { 00433 m_pcSpringFlexionCol[n][m] = new Spring<T>( 00434 *m_pcParticle[m][n], *m_pcParticle[m+2][n], // linked points 00435 m_tKs[id], m_tKd[id], // stiffness and damping const 00436 ( m_pcParticle[m][n]->m_vtPosit 00437 - m_pcParticle[m+2][n]->m_vtPosit).Length() // spring length 00438 ); 00439 00440 #ifdef TAPs_DEBUG_MODE 00441 // Dump (cont.) 00442 std::cout << " " << m_pcSpringFlexionCol[n][m]->GetRestLengthL(); 00443 #endif//TAPs_DEBUG_MODE 00444 } 00445 00446 #ifdef TAPs_DEBUG_MODE 00447 // Dump (cont.) 00448 std::cout << "\n"; 00449 #endif//TAPs_DEBUG_MODE 00450 } 00451 } 00452 //------------------------------------------------------------------------------------------------- 00453 // Delete Springs 00454 template <typename T> 00455 void Cloth<T>::DeleteSprings() 00456 { 00457 // Delete Structural Springs ----------------------------------------------- 00458 // Row [m,n] and [m,n+1] 00459 for ( m = 0; m < m_iNoRows; m++ ) { 00460 for ( n = 0; n < m_iNoCols-1; n++ ) { 00461 delete m_pcSpringStructuralRow[m][n]; 00462 } 00463 delete [] m_pcSpringStructuralRow[m]; 00464 } 00465 delete [] m_pcSpringStructuralRow; 00466 // Col [m,n] and [m+1,n] 00467 for ( n = 0; n < m_iNoCols; n++ ) { 00468 for ( m = 0; m < m_iNoRows-1; m++ ) { 00469 delete m_pcSpringStructuralCol[n][m]; 00470 } 00471 delete [] m_pcSpringStructuralCol[n]; 00472 } 00473 delete [] m_pcSpringStructuralCol; 00474 // Delete Shear Springs ---------------------------------------------------- 00475 // [m,n] and [m+1,n+1] 00476 // [m+1,n] and [m,n+1] 00477 for ( m = 0; m < m_iNoRows-1; m++ ) { 00478 for ( n = 0; n < m_iNoCols-1; n++ ) { 00479 delete m_pcSpringShearTLtoBR[m][n]; 00480 delete m_pcSpringShearBLtoTR[m][n]; 00481 } 00482 delete [] m_pcSpringShearTLtoBR[m]; 00483 delete [] m_pcSpringShearBLtoTR[m]; 00484 } 00485 delete [] m_pcSpringShearTLtoBR; 00486 delete [] m_pcSpringShearBLtoTR; 00487 // Delete Flexion Springs -------------------------------------------------- 00488 // Row [m,n] and [m,n+2] 00489 for ( m = 0; m < m_iNoRows; m++ ) { 00490 for ( n = 0; n < m_iNoCols-2; n++ ) { 00491 delete m_pcSpringFlexionRow[m][n]; 00492 } 00493 delete [] m_pcSpringFlexionRow[m]; 00494 } 00495 delete [] m_pcSpringFlexionRow; 00496 // Col [m,n] and [m+2,n] 00497 for ( n = 0; n < m_iNoCols; n++ ) { 00498 for ( m = 0; m < m_iNoRows-2; m++ ) { 00499 delete m_pcSpringFlexionCol[n][m]; 00500 } 00501 delete [] m_pcSpringFlexionCol[n]; 00502 } 00503 delete [] m_pcSpringFlexionCol; 00504 } 00505 //------------------------------------------------------------------------------------------------- 00506 // Calculate and Add Spring Forces to Particle Forces 00507 template <typename T> 00508 void Cloth<T>::AddSpringForces() 00509 { 00510 //========================================================================== 00511 // CALCULATE STRUCTURAL SPRING FORCE 00512 // Process on Row Structural Spring 00513 for ( m = 0; m < m_iNoRows; m++ ) { 00514 for ( n = 0; n < m_iNoCols-1; n++ ) { 00515 AddSpringForce( m_pcSpringStructuralRow[m][n] ); 00516 } 00517 } 00518 // Process on Column Structural Spring 00519 for ( n = 0; n < m_iNoCols; n++ ) { 00520 for ( m = 0; m < m_iNoRows-1; m++ ) { 00521 AddSpringForce( m_pcSpringStructuralCol[n][m] ); 00522 } 00523 } 00524 //========================================================================== 00525 // CALCULATE SHEAR SPRING FORCE 00526 for ( m = 0; m < m_iNoRows-1; m++ ) { 00527 for ( n = 0; n < m_iNoCols-1; n++ ) { 00528 AddSpringForce( m_pcSpringShearTLtoBR[m][n] ); 00529 AddSpringForce( m_pcSpringShearBLtoTR[m][n] ); 00530 } 00531 } 00532 //========================================================================== 00533 // CALCULATE FLEXION SPRING FORCE 00534 // Process on Row Flexion Spring 00535 for ( m = 0; m < m_iNoRows; m++ ) { 00536 for ( n = 0; n < m_iNoCols-2; n++ ) { 00537 AddSpringForce( m_pcSpringFlexionRow[m][n] ); 00538 } 00539 } 00540 // Process on Column Flexion Spring 00541 for ( n = 0; n < m_iNoCols; n++ ) { 00542 for ( m = 0; m < m_iNoRows-2; m++ ) { 00543 AddSpringForce( m_pcSpringFlexionCol[n][m] ); 00544 } 00545 } 00546 } 00547 //------------------------------------------------------------------------------------------------- 00548 // Calculate and Add the Force of a Spring 00549 template <typename T> 00550 inline void Cloth<T>::AddSpringForce( Spring<T> * const sp ) 00551 { 00552 /* 00553 // Local Variables --------------------------------------------------------- 00554 // spring current length vector 00555 Vector3<T> cL = ( sp->m_rcP1.m_vtPosit - sp->m_rcP2.m_vtPosit ); 00556 // spring current length scalar 00557 T scl = cL.Length(); 00558 // velocity difference of the two particles linked by the spring 00559 Vector3<T> V = ( sp->m_rcP1.m_vtVeloc - sp->m_rcP2.m_vtVeloc ); 00560 00561 // F1 = -{Ks(l - r) + Kd[(V1-V2)*L]/l}*L/l 00562 // F2 = -F1 00563 // where Ks = spring stiffness, Kd = spring damping, 00564 // V1 and V2 are velocity of particles linked by the spring 00565 // r = spring rest length 00566 // L = vector of difference of positions of particle#1 and #2 00567 // l = magnitude of L 00568 Vector3<T> f = -( (sp->m_tK * (scl - sp->m_tL)) + (sp->m_tD * ((V*cL) / scl)) ) * (cL / scl); 00569 // Update the particle forces 00570 */ 00571 if ( !sp->m_rcP1.m_bFixed ) sp->m_rcP1.m_vtForce += sp->GetForce(); 00572 if ( !sp->m_rcP2.m_bFixed ) sp->m_rcP2.m_vtForce -= sp->GetForce(); 00573 } 00574 //------------------------------------------------------------------------------------------------- 00575 // Limit the Length of All Springs 00576 template <typename T> 00577 void Cloth<T>::LimitSpringLengths() 00578 { 00579 int d = 0; 00580 //========================================================================== 00581 // CALCULATE STRUCTURAL SPRING FORCE 00582 // Process on Row Structural Spring 00583 for ( m = 0; m < m_iNoRows; m++ ) { 00584 for ( n = 0; n < m_iNoCols-1; n++ ) { 00585 LimitSpringLength( m_pcSpringStructuralRow[m][n], m_tLengthConstrain[d] ); 00586 } 00587 } 00588 // Process on Column Structural Spring 00589 for ( n = 0; n < m_iNoCols; n++ ) { 00590 for ( m = 0; m < m_iNoRows-1; m++ ) { 00591 LimitSpringLength( m_pcSpringStructuralCol[n][m], m_tLengthConstrain[d] ); 00592 } 00593 } 00594 //========================================================================== 00595 // CALCULATE SHEAR SPRING FORCE 00596 d = 1; 00597 for ( m = 0; m < m_iNoRows-1; m++ ) { 00598 for ( n = 0; n < m_iNoCols-1; n++ ) { 00599 LimitSpringLength( m_pcSpringShearTLtoBR[m][n], m_tLengthConstrain[d] ); 00600 LimitSpringLength( m_pcSpringShearBLtoTR[m][n], m_tLengthConstrain[d] ); 00601 } 00602 } 00603 //========================================================================== 00604 // CALCULATE FLEXION SPRING FORCE 00605 // Process on Row Flexion Spring 00606 d = 2; 00607 for ( m = 0; m < m_iNoRows; m++ ) { 00608 for ( n = 0; n < m_iNoCols-2; n++ ) { 00609 LimitSpringLength( m_pcSpringFlexionRow[m][n], m_tLengthConstrain[d] ); 00610 } 00611 } 00612 // Process on Column Flexion Spring 00613 for ( n = 0; n < m_iNoCols; n++ ) { 00614 for ( m = 0; m < m_iNoRows-2; m++ ) { 00615 LimitSpringLength( m_pcSpringFlexionCol[n][m], m_tLengthConstrain[d] ); 00616 } 00617 } 00618 } 00619 //------------------------------------------------------------------------------------------------- 00620 // Limit the Length of All Springs 00621 template <typename T> 00622 inline void Cloth<T>::LimitSpringLength( Spring<T> * const sp, T lengthLimit ) 00623 { 00624 Vector3<T> vLength = sp->m_rcP2.m_vtPosit - sp->m_rcP1.m_vtPosit; 00625 T currentLength = vLength.Length(); 00626 T restLength = sp->GetRestLengthL(); 00627 T difference = currentLength - restLength; 00628 // Spring is straighten too high 00629 if ( difference > lengthLimit ) { 00630 // both particles are not fixed. 00631 if ( !sp->m_rcP2.m_bFixed && !sp->m_rcP1.m_bFixed ) { 00632 //cout << difference << " = " << currentLength << " - " << restLength << "\n"; 00633 vLength *= difference / 20.0; 00634 //vLength *= lengthLimit / 2.0; 00635 sp->m_rcP1.m_vtPosit += vLength; 00636 sp->m_rcP2.m_vtPosit -= vLength; 00637 return; 00638 } 00639 // particle#1 is fixed, while particle#2 is not fixed. 00640 else if ( sp->m_rcP2.m_bFixed && !sp->m_rcP1.m_bFixed ) { 00641 vLength *= difference; 00642 sp->m_rcP1.m_vtPosit += vLength; 00643 return; 00644 } 00645 // particle#1 is not fixed, while particle#2 is fixed. 00646 else if ( !sp->m_rcP2.m_bFixed && sp->m_rcP1.m_bFixed ) { 00647 vLength *= difference; 00648 sp->m_rcP2.m_vtPosit -= vLength; 00649 return; 00650 } 00651 } 00652 // Spring is compressed too high 00653 else if ( difference > -lengthLimit ) { 00654 00655 } 00656 // Spring length is within the limit 00657 else { 00658 } 00659 } 00660 //HELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHELPERHE 00661 00662 00663 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERME 00664 // 00665 // Cloth F U N C T I O N M E M B E R D E F I N I T I O N S 00666 // 00667 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERME 00668 //------------------------------------------------------------------------------------------------- 00669 template <typename T> 00670 Cloth<T>::Cloth( int rows, // number of rows (on world-y-axis) 00671 int cols, // number of cols (on world-x-axis) 00672 T Kvd, // viscous damping constant 00673 T Kvfm, // viscous fluid moving constant 00674 T Ks, // spring stiffness constant 00675 T Kd, // spring damping constant 00676 T lengthConstrain, // spring rest length 00677 const Vector3<T> &topLeftPos, // start position (should be top left cornor) 00678 const Vector3<T> &bottomRightPos, // end position (should be bottom right cornor) 00679 T mass, // the whole mass 00680 BitmapImage *img ) // Image Pointer 00681 : OpenGLSupport( img ), // parent class constructor 00682 m_iNoRows( rows ), m_iNoCols( cols ), m_tKvd( Kvd ), m_tKvfm( Kvfm ) 00683 { 00684 m_tKs[0] = m_tKs[1] = m_tKs[2] = Ks; 00685 m_tKd[0] = m_tKd[1] = m_tKd[2] = Kd; 00686 m_tLengthConstrain[0] = m_tLengthConstrain[1] = m_tLengthConstrain[2] = lengthConstrain; 00687 CreateParticles( topLeftPos, bottomRightPos, mass ); 00688 CreateSprings(); 00689 CalParticleNormals( 0 ); 00690 EnableTexture(); 00691 } 00692 //------------------------------------------------------------------------------------------------- 00693 template <typename T> 00694 Cloth<T>::Cloth( int rows, // number of rows (on world-y-axis) 00695 int cols, // number of cols (on world-x-axis) 00696 T Kvd, // viscous damping constant 00697 T Kvfm, // viscous fluid moving constant 00698 T Ks0, // structural spring stiffness constant 00699 T Ks1, // shear spring stiffness constant 00700 T Ks2, // flexion spring stiffness constant 00701 T Kd0, // structural spring damping constant 00702 T Kd1, // shear spring damping constant 00703 T Kd2, // flexion spring damping constant 00704 T lengthConstrain0, // structural spring rest length 00705 T lengthConstrain1, // shear spring rest length 00706 T lengthConstrain2, // flexion spring rest length 00707 const Vector3<T> &topLeftPos, // start position (should be top left cornor) 00708 const Vector3<T> &bottomRightPos, // end position (should be bottom right cornor) 00709 T mass, // the whole mass 00710 BitmapImage *img ) // Image Pointer 00711 : OpenGLSupport( img ), // parent class constructor 00712 m_iNoRows( rows ), m_iNoCols( cols ), m_tKvd( Kvd ), m_tKvfm( Kvfm ) 00713 { 00714 m_tKs[0] = Ks0; m_tKs[1] = Ks1; m_tKs[2] = Ks2; 00715 m_tKd[0] = Kd0; m_tKd[1] = Kd1; m_tKd[2] = Kd2; 00716 m_tLengthConstrain[0] = lengthConstrain0; 00717 m_tLengthConstrain[1] = lengthConstrain1; 00718 m_tLengthConstrain[2] = lengthConstrain2; 00719 CreateParticles( topLeftPos, bottomRightPos, mass ); 00720 CreateSprings(); 00721 CalParticleNormals( 0 ); 00722 } 00723 //------------------------------------------------------------------------------------------------- 00724 template <typename T> 00725 Cloth<T>::~Cloth() 00726 { 00727 DeleteParticles(); 00728 DeleteSprings(); 00729 } 00730 //------------------------------------------------------------------------------------------------- 00731 // Calculate Particle Normals 00732 template <typename T> 00733 void Cloth<T>::CalParticleNormals() 00734 { 00735 /* 00736 ----------------- 00737 | \ 3 | 2 / | 00738 | \ | / | 00739 | 4 \ | / 1 | Normal of the middle (m,n) particle is the sum of the eight normals. 00740 |<------+------>| E.g. normal 1 is the unit vector of the cross product of (m,n)-->(m,n+1) 00741 | 5 / | \ 8 | vector with (m,n)-->(m-1,n+1) vector (rotated counter clockwise). 00742 | / | \ | 00743 | / 6 | 7 \ | 00744 ----------------- 00745 */ 00746 // These particles have all 8 neighbors ------------------------------------ 00747 for ( m = 1; m < m_iNoRows-1; m++ ) { 00748 for ( n = 1; n < m_iNoCols-1; n++ ) { 00749 // (1) (m,n)-->(m,n+1) and (m,n)-->(m-1,n+1) 00750 m_pcParticle[m][n]->m_vtNormal 00751 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n+1]->m_vtPosit) 00752 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized(); 00753 // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n) 00754 m_pcParticle[m][n]->m_vtNormal 00755 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 00756 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n ]->m_vtPosit) ).Normalized(); 00757 // (3) (m,n)-->(m-1,n) and (m,n)-->(m-1,n-1) 00758 m_pcParticle[m][n]->m_vtNormal 00759 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n ]->m_vtPosit) 00760 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized(); 00761 // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1) 00762 m_pcParticle[m][n]->m_vtNormal 00763 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 00764 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n-1]->m_vtPosit) ).Normalized(); 00765 // (5) (m,n)-->(m,n-1) and (m,n)-->(m+1,n-1) 00766 m_pcParticle[m][n]->m_vtNormal 00767 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n-1]->m_vtPosit) 00768 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized(); 00769 // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n) 00770 m_pcParticle[m][n]->m_vtNormal 00771 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 00772 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n ]->m_vtPosit) ).Normalized(); 00773 // (7) (m,n)-->(m+1,n) and (m,n)-->(m+1,n+1) 00774 m_pcParticle[m][n]->m_vtNormal 00775 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n ]->m_vtPosit) 00776 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized(); 00777 // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1) 00778 m_pcParticle[m][n]->m_vtNormal 00779 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 00780 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n+1]->m_vtPosit) ).Normalized(); 00781 // normalize the sum result vector 00782 m_pcParticle[m][n]->m_vtNormal.Normalized(); 00783 } 00784 } 00785 00786 //------------------------------------------------------------------------- 00787 // Normals of Particles on the Top Row (Except the Cornor Particle) 00788 m = 0; 00789 for ( n = 1; n < m_iNoCols-1; n++ ) { 00790 // (5) (m,n)-->(m,n-1) and (m,n)-->(m+1,n-1) 00791 m_pcParticle[m][n]->m_vtNormal 00792 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n-1]->m_vtPosit) 00793 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized(); 00794 // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n) 00795 m_pcParticle[m][n]->m_vtNormal 00796 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 00797 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n ]->m_vtPosit) ).Normalized(); 00798 // (7) (m,n)-->(m+1,n) and (m,n)-->(m+1,n+1) 00799 m_pcParticle[m][n]->m_vtNormal 00800 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n ]->m_vtPosit) 00801 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized(); 00802 // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1) 00803 m_pcParticle[m][n]->m_vtNormal 00804 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 00805 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n+1]->m_vtPosit) ).Normalized(); 00806 // normalize the sum result vector 00807 m_pcParticle[m][n]->m_vtNormal.Normalized(); 00808 } 00809 //------------------------------------------------------------------------- 00810 // Normals of Particles on the Bottom Row (Except the Cornor Particle) 00811 m = m_iNoRows-1; 00812 for ( n = 1; n < m_iNoCols-1; n++ ) { 00813 // (1) (m,n)-->(m,n+1) and (m,n)-->(m-1,n+1) 00814 m_pcParticle[m][n]->m_vtNormal 00815 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n+1]->m_vtPosit) 00816 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized(); 00817 // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n) 00818 m_pcParticle[m][n]->m_vtNormal 00819 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 00820 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n ]->m_vtPosit) ).Normalized(); 00821 // (3) (m,n)-->(m-1,n) and (m,n)-->(m-1,n-1) 00822 m_pcParticle[m][n]->m_vtNormal 00823 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n ]->m_vtPosit) 00824 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized(); 00825 // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1) 00826 m_pcParticle[m][n]->m_vtNormal 00827 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 00828 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n-1]->m_vtPosit) ).Normalized(); 00829 // normalize the sum result vector 00830 m_pcParticle[m][n]->m_vtNormal.Normalized(); 00831 } 00832 //------------------------------------------------------------------------- 00833 // Normals of Particles on the Left Column (Except the Cornor Particle) 00834 n = 0; 00835 for ( m = 1; m < m_iNoRows-1; m++ ) { 00836 // (7) (m,n)-->(m+1,n) and (m,n)-->(m+1,n+1) 00837 m_pcParticle[m][n]->m_vtNormal 00838 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n ]->m_vtPosit) 00839 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized(); 00840 // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1) 00841 m_pcParticle[m][n]->m_vtNormal 00842 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 00843 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n+1]->m_vtPosit) ).Normalized(); 00844 // (1) (m,n)-->(m,n+1) and (m,n)-->(m-1,n+1) 00845 m_pcParticle[m][n]->m_vtNormal 00846 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n+1]->m_vtPosit) 00847 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized(); 00848 // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n) 00849 m_pcParticle[m][n]->m_vtNormal 00850 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 00851 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n ]->m_vtPosit) ).Normalized(); 00852 // normalize the sum result vector 00853 m_pcParticle[m][n]->m_vtNormal.Normalized(); 00854 } 00855 //------------------------------------------------------------------------- 00856 // Normals of Particles on the Right Row (Except the Cornor Particle) 00857 n = m_iNoCols-1; 00858 for ( m = 1; m < m_iNoRows-1; m++ ) { 00859 // (3) (m,n)-->(m-1,n) and (m,n)-->(m-1,n-1) 00860 m_pcParticle[m][n]->m_vtNormal 00861 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n ]->m_vtPosit) 00862 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized(); 00863 // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1) 00864 m_pcParticle[m][n]->m_vtNormal 00865 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 00866 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n-1]->m_vtPosit) ).Normalized(); 00867 // (5) (m,n)-->(m,n-1) and (m,n)-->(m+1,n-1) 00868 m_pcParticle[m][n]->m_vtNormal 00869 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n-1]->m_vtPosit) 00870 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized(); 00871 // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n) 00872 m_pcParticle[m][n]->m_vtNormal 00873 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 00874 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n ]->m_vtPosit) ).Normalized(); 00875 // normalize the sum result vector 00876 m_pcParticle[m][n]->m_vtNormal.Normalized(); 00877 } 00878 00879 // Top Left Cornor --------------------------------------------------------- 00880 m = 0; n = 0; 00881 // (7) (m,n)-->(m+1,n) and (m,n)-->(m+1,n+1) 00882 m_pcParticle[m][n]->m_vtNormal 00883 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n ]->m_vtPosit) 00884 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) ).Normalized(); 00885 // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1) 00886 m_pcParticle[m][n]->m_vtNormal 00887 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n+1]->m_vtPosit) 00888 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n+1]->m_vtPosit) ).Normalized(); 00889 m_pcParticle[m][n]->m_vtNormal.Normalized(); // normalize the sum result vector 00890 // Bottom Left Cornor ------------------------------------------------------ 00891 m = m_iNoRows-1; n = 0; 00892 // (1) (m,n)-->(m,n+1) and (m,n)-->(m-1,n+1) 00893 m_pcParticle[m][n]->m_vtNormal 00894 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n+1]->m_vtPosit) 00895 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) ).Normalized(); 00896 // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n) 00897 m_pcParticle[m][n]->m_vtNormal 00898 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n+1]->m_vtPosit) 00899 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n ]->m_vtPosit) ).Normalized(); 00900 m_pcParticle[m][n]->m_vtNormal.Normalized(); // normalize the sum result vector 00901 // Bottom Right Cornor ----------------------------------------------------- 00902 m = m_iNoRows-1; n = m_iNoCols-1; 00903 // (3) (m,n)-->(m-1,n) and (m,n)-->(m-1,n-1) 00904 m_pcParticle[m][n]->m_vtNormal 00905 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n ]->m_vtPosit) 00906 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) ).Normalized(); 00907 // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1) 00908 m_pcParticle[m][n]->m_vtNormal 00909 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m-1][n-1]->m_vtPosit) 00910 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n-1]->m_vtPosit) ).Normalized(); 00911 m_pcParticle[m][n]->m_vtNormal.Normalized(); // normalize the sum result vector 00912 // Top Right Cornor -------------------------------------------------------- 00913 m = 0; n = m_iNoCols-1; 00914 // (5) (m,n)-->(m,n-1) and (m,n)-->(m+1,n-1) 00915 m_pcParticle[m][n]->m_vtNormal 00916 = ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m ][n-1]->m_vtPosit) 00917 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) ).Normalized(); 00918 // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n) 00919 m_pcParticle[m][n]->m_vtNormal 00920 += ( (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n-1]->m_vtPosit) 00921 % (m_pcParticle[m][n]->m_vtPosit - m_pcParticle[m+1][n ]->m_vtPosit) ).Normalized(); 00922 m_pcParticle[m][n]->m_vtNormal.Normalized(); // normalize the sum result vector 00923 } 00924 //------------------------------------------------------------------------------------------------- 00925 // Calculate Particle Normals 00926 template <typename T> 00927 void Cloth<T>::CalParticleNormals( int i ) 00928 { 00929 /* 00930 ----------------- 00931 | \ 3 | 2 / | 00932 | \ | / | 00933 | 4 \ | / 1 | Normal of the middle (m,n) particle is the sum of the eight normals. 00934 |<------+------>| E.g. normal 1 is the unit vector of the cross product of (m,n)-->(m,n+1) 00935 | 5 / | \ 8 | vector with (m,n)-->(m-1,n+1) vector (rotated counter clockwise). 00936 | / | \ | 00937 | / 6 | 7 \ | 00938 ----------------- 00939 */ 00940 // These particles have all 8 neighbors ------------------------------------ 00941 for ( m = 1; m < m_iNoRows-1; m++ ) { 00942 for ( n = 1; n < m_iNoCols-1; n++ ) { 00943 // (1) (m,n)-->(m,n+1) and (m,n)-->(m-1,n+1) 00944 m_pcParticle[m ][n ]->m_vtNormal[0] = 0; 00945 m_pcParticle[m ][n ]->m_vtNormal[1] = 0; 00946 m_pcParticle[m ][n ]->m_vtNormal[2] = 0; 00947 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 00948 m_pcParticle[m ][n ]->m_vtPosit, 00949 m_pcParticle[m ][n+1]->m_vtPosit, 00950 m_pcParticle[m-1][n+1]->m_vtPosit ); 00951 // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n) 00952 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 00953 m_pcParticle[m ][n ]->m_vtPosit, 00954 m_pcParticle[m-1][n+1]->m_vtPosit, 00955 m_pcParticle[m-1][n ]->m_vtPosit ); 00956 // (3) (m,n)-->(m-1,n) and (m,n)-->(m-1,n-1) 00957 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 00958 m_pcParticle[m ][n ]->m_vtPosit, 00959 m_pcParticle[m-1][n ]->m_vtPosit, 00960 m_pcParticle[m-1][n-1]->m_vtPosit ); 00961 // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1) 00962 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 00963 m_pcParticle[m ][n ]->m_vtPosit, 00964 m_pcParticle[m-1][n-1]->m_vtPosit, 00965 m_pcParticle[m ][n-1]->m_vtPosit ); 00966 // (5) (m,n)-->(m,n-1) and (m,n)-->(m+1,n-1) 00967 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 00968 m_pcParticle[m ][n ]->m_vtPosit, 00969 m_pcParticle[m ][n-1]->m_vtPosit, 00970 m_pcParticle[m+1][n-1]->m_vtPosit ); 00971 // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n) 00972 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 00973 m_pcParticle[m ][n ]->m_vtPosit, 00974 m_pcParticle[m+1][n-1]->m_vtPosit, 00975 m_pcParticle[m+1][n ]->m_vtPosit ); 00976 // (7) (m,n)-->(m+1,n) and (m,n)-->(m+1,n+1) 00977 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 00978 m_pcParticle[m ][n ]->m_vtPosit, 00979 m_pcParticle[m+1][n ]->m_vtPosit, 00980 m_pcParticle[m+1][n+1]->m_vtPosit ); 00981 // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1) 00982 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 00983 m_pcParticle[m ][n ]->m_vtPosit, 00984 m_pcParticle[m+1][n+1]->m_vtPosit, 00985 m_pcParticle[m ][n+1]->m_vtPosit ); 00986 // normalize the sum result vector 00987 m_pcParticle[m][n]->m_vtNormal.Normalized(); 00988 } 00989 } 00990 00991 //------------------------------------------------------------------------- 00992 // Normals of Particles on the Top Row (Except the Cornor Particle) 00993 m = 0; 00994 for ( n = 1; n < m_iNoCols-1; n++ ) { 00995 // (5) (m,n)-->(m,n-1) and (m,n)-->(m+1,n-1) 00996 m_pcParticle[m][n]->m_vtNormal[0] = 0; 00997 m_pcParticle[m][n]->m_vtNormal[1] = 0; 00998 m_pcParticle[m][n]->m_vtNormal[2] = 0; 00999 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01000 m_pcParticle[m ][n ]->m_vtPosit, 01001 m_pcParticle[m ][n-1]->m_vtPosit, 01002 m_pcParticle[m+1][n-1]->m_vtPosit ); 01003 // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n) 01004 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01005 m_pcParticle[m ][n ]->m_vtPosit, 01006 m_pcParticle[m+1][n-1]->m_vtPosit, 01007 m_pcParticle[m+1][n ]->m_vtPosit ); 01008 // (7) (m,n)-->(m+1,n) and (m,n)-->(m+1,n+1) 01009 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01010 m_pcParticle[m ][n ]->m_vtPosit, 01011 m_pcParticle[m+1][n ]->m_vtPosit, 01012 m_pcParticle[m+1][n+1]->m_vtPosit ); 01013 // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1) 01014 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01015 m_pcParticle[m ][n ]->m_vtPosit, 01016 m_pcParticle[m+1][n+1]->m_vtPosit, 01017 m_pcParticle[m ][n+1]->m_vtPosit ); 01018 // normalize the sum result vector 01019 m_pcParticle[m][n]->m_vtNormal.Normalized(); 01020 } 01021 //------------------------------------------------------------------------- 01022 // Normals of Particles on the Bottom Row (Except the Cornor Particle) 01023 m = m_iNoRows-1; 01024 for ( n = 1; n < m_iNoCols-1; n++ ) { 01025 // (1) (m,n)-->(m,n+1) and (m,n)-->(m-1,n+1) 01026 m_pcParticle[m][n]->m_vtNormal[0] = 0; 01027 m_pcParticle[m][n]->m_vtNormal[1] = 0; 01028 m_pcParticle[m][n]->m_vtNormal[2] = 0; 01029 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01030 m_pcParticle[m ][n ]->m_vtPosit, 01031 m_pcParticle[m ][n+1]->m_vtPosit, 01032 m_pcParticle[m-1][n+1]->m_vtPosit ); 01033 // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n) 01034 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01035 m_pcParticle[m ][n ]->m_vtPosit, 01036 m_pcParticle[m-1][n+1]->m_vtPosit, 01037 m_pcParticle[m-1][n ]->m_vtPosit ); 01038 // (3) (m,n)-->(m-1,n) and (m,n)-->(m-1,n-1) 01039 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01040 m_pcParticle[m ][n ]->m_vtPosit, 01041 m_pcParticle[m-1][n ]->m_vtPosit, 01042 m_pcParticle[m-1][n-1]->m_vtPosit ); 01043 // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1) 01044 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01045 m_pcParticle[m ][n ]->m_vtPosit, 01046 m_pcParticle[m-1][n-1]->m_vtPosit, 01047 m_pcParticle[m ][n-1]->m_vtPosit ); 01048 // normalize the sum result vector 01049 m_pcParticle[m][n]->m_vtNormal.Normalized(); 01050 } 01051 //------------------------------------------------------------------------- 01052 // Normals of Particles on the Left Column (Except the Cornor Particle) 01053 n = 0; 01054 for ( m = 1; m < m_iNoRows-1; m++ ) { 01055 // (7) (m,n)-->(m+1,n) and (m,n)-->(m+1,n+1) 01056 m_pcParticle[m][n]->m_vtNormal[0] = 0; 01057 m_pcParticle[m][n]->m_vtNormal[1] = 0; 01058 m_pcParticle[m][n]->m_vtNormal[2] = 0; 01059 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01060 m_pcParticle[m ][n ]->m_vtPosit, 01061 m_pcParticle[m+1][n ]->m_vtPosit, 01062 m_pcParticle[m+1][n+1]->m_vtPosit ); 01063 // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1) 01064 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01065 m_pcParticle[m ][n ]->m_vtPosit, 01066 m_pcParticle[m+1][n+1]->m_vtPosit, 01067 m_pcParticle[m ][n+1]->m_vtPosit ); 01068 // (1) (m,n)-->(m,n+1) and (m,n)-->(m-1,n+1) 01069 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01070 m_pcParticle[m ][n ]->m_vtPosit, 01071 m_pcParticle[m ][n+1]->m_vtPosit, 01072 m_pcParticle[m-1][n+1]->m_vtPosit ); 01073 // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n) 01074 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01075 m_pcParticle[m ][n ]->m_vtPosit, 01076 m_pcParticle[m-1][n+1]->m_vtPosit, 01077 m_pcParticle[m-1][n ]->m_vtPosit ); 01078 // normalize the sum result vector 01079 m_pcParticle[m][n]->m_vtNormal.Normalized(); 01080 } 01081 //------------------------------------------------------------------------- 01082 // Normals of Particles on the Right Row (Except the Cornor Particle) 01083 n = m_iNoCols-1; 01084 for ( m = 1; m < m_iNoRows-1; m++ ) { 01085 // (3) (m,n)-->(m-1,n) and (m,n)-->(m-1,n-1) 01086 m_pcParticle[m][n]->m_vtNormal[0] = 0; 01087 m_pcParticle[m][n]->m_vtNormal[1] = 0; 01088 m_pcParticle[m][n]->m_vtNormal[2] = 0; 01089 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01090 m_pcParticle[m ][n ]->m_vtPosit, 01091 m_pcParticle[m-1][n ]->m_vtPosit, 01092 m_pcParticle[m-1][n-1]->m_vtPosit ); 01093 // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1) 01094 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01095 m_pcParticle[m ][n ]->m_vtPosit, 01096 m_pcParticle[m-1][n-1]->m_vtPosit, 01097 m_pcParticle[m ][n-1]->m_vtPosit ); 01098 // (5) (m,n)-->(m,n-1) and (m,n)-->(m+1,n-1) 01099 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01100 m_pcParticle[m ][n ]->m_vtPosit, 01101 m_pcParticle[m ][n-1]->m_vtPosit, 01102 m_pcParticle[m+1][n-1]->m_vtPosit ); 01103 // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n) 01104 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01105 m_pcParticle[m ][n ]->m_vtPosit, 01106 m_pcParticle[m+1][n-1]->m_vtPosit, 01107 m_pcParticle[m+1][n ]->m_vtPosit ); 01108 // normalize the sum result vector 01109 m_pcParticle[m][n]->m_vtNormal.Normalized(); 01110 } 01111 01112 // Top Left Cornor --------------------------------------------------------- 01113 m = 0; n = 0; 01114 // (7) (m,n)-->(m+1,n) and (m,n)-->(m+1,n+1) 01115 m_pcParticle[m][n]->m_vtNormal[0] = 0; 01116 m_pcParticle[m][n]->m_vtNormal[1] = 0; 01117 m_pcParticle[m][n]->m_vtNormal[2] = 0; 01118 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01119 m_pcParticle[m ][n ]->m_vtPosit, 01120 m_pcParticle[m+1][n ]->m_vtPosit, 01121 m_pcParticle[m+1][n+1]->m_vtPosit ); 01122 // (8) (m,n)-->(m+1,n+1) and (m,n)-->(m,n+1) 01123 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01124 m_pcParticle[m ][n ]->m_vtPosit, 01125 m_pcParticle[m+1][n+1]->m_vtPosit, 01126 m_pcParticle[m ][n+1]->m_vtPosit ); 01127 m_pcParticle[m][n]->m_vtNormal.Normalized(); // normalize the sum result vector 01128 // Bottom Left Cornor ------------------------------------------------------ 01129 m = m_iNoRows-1; n = 0; 01130 // (1) (m,n)-->(m,n+1) and (m,n)-->(m-1,n+1) 01131 m_pcParticle[m][n]->m_vtNormal[0] = 0; 01132 m_pcParticle[m][n]->m_vtNormal[1] = 0; 01133 m_pcParticle[m][n]->m_vtNormal[2] = 0; 01134 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01135 m_pcParticle[m ][n ]->m_vtPosit, 01136 m_pcParticle[m ][n+1]->m_vtPosit, 01137 m_pcParticle[m-1][n+1]->m_vtPosit ); 01138 // (2) (m,n)-->(m-1,n+1) and (m,n)-->(m-1,n) 01139 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01140 m_pcParticle[m ][n ]->m_vtPosit, 01141 m_pcParticle[m-1][n+1]->m_vtPosit, 01142 m_pcParticle[m-1][n ]->m_vtPosit ); 01143 m_pcParticle[m][n]->m_vtNormal.Normalized(); // normalize the sum result vector 01144 // Bottom Right Cornor ----------------------------------------------------- 01145 m = m_iNoRows-1; n = m_iNoCols-1; 01146 // (3) (m,n)-->(m-1,n) and (m,n)-->(m-1,n-1) 01147 m_pcParticle[m][n]->m_vtNormal[0] = 0; 01148 m_pcParticle[m][n]->m_vtNormal[1] = 0; 01149 m_pcParticle[m][n]->m_vtNormal[2] = 0; 01150 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01151 m_pcParticle[m ][n ]->m_vtPosit, 01152 m_pcParticle[m-1][n ]->m_vtPosit, 01153 m_pcParticle[m-1][n-1]->m_vtPosit ); 01154 // (4) (m,n)-->(m-1,n-1) and (m,n)-->(m,n-1) 01155 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01156 m_pcParticle[m ][n ]->m_vtPosit, 01157 m_pcParticle[m-1][n-1]->m_vtPosit, 01158 m_pcParticle[m ][n-1]->m_vtPosit ); 01159 m_pcParticle[m][n]->m_vtNormal.Normalized(); // normalize the sum result vector 01160 // Top Right Cornor -------------------------------------------------------- 01161 m = 0; n = m_iNoCols-1; 01162 // (5) (m,n)-->(m,n-1) and (m,n)-->(m+1,n-1) 01163 m_pcParticle[m][n]->m_vtNormal[0] = 0; 01164 m_pcParticle[m][n]->m_vtNormal[1] = 0; 01165 m_pcParticle[m][n]->m_vtNormal[2] = 0; 01166 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01167 m_pcParticle[m ][n ]->m_vtPosit, 01168 m_pcParticle[m ][n-1]->m_vtPosit, 01169 m_pcParticle[m+1][n-1]->m_vtPosit ); 01170 // (6) (m,n)-->(m+1,n-1) and (m,n)-->(m+1,n) 01171 AddNormal( m_pcParticle[m ][n ]->m_vtNormal, 01172 m_pcParticle[m ][n ]->m_vtPosit, 01173 m_pcParticle[m+1][n-1]->m_vtPosit, 01174 m_pcParticle[m+1][n ]->m_vtPosit ); 01175 m_pcParticle[m][n]->m_vtNormal.Normalized(); // normalize the sum result vector 01176 } 01177 /* 01178 //------------------------------------------------------------------------------------------------- 01179 // Clear Force of Particles to Zeros 01180 template <typename T> 01181 void Cloth<T>::ClearForce() 01182 { 01183 T x = 0, y = 0, z = 0; 01184 for ( m = 0; m < m_iNoRows; m++ ) { 01185 for ( n = 0; n < m_iNoCols; n++ ) { 01186 m_pcParticle[m][n]->m_vtForce( x, y, z ); 01187 } 01188 } 01189 } 01190 //------------------------------------------------------------------------------------------------- 01191 // Calculate (Weight) Force due to (Acceleration of) Gravity 01192 template <typename T> 01193 void Cloth<T>::ForceDueToGravity( T g ) 01194 { 01195 01196 } 01197 //------------------------------------------------------------------------------------------------- 01198 // Calculate (a Loss) Force due to Viscous Damping 01199 template <typename T> 01200 void Cloth<T>::ForceDueToViscousDamping() 01201 { 01202 } 01203 //------------------------------------------------------------------------------------------------- 01204 // Calculate (Wind) Force due to Viscous Fluid Moving 01205 template <typename T> 01206 void Cloth<T>::ForceDueToViscousFluidMoving() 01207 { 01208 } 01209 */ 01210 //------------------------------------------------------------------------------------------------- 01211 // Calculate All Forces Acting on Particles 01212 template <typename T> 01213 void Cloth<T>::CalForces( Vector3<T> vWind, T g ) 01214 { 01215 CalParticleNormals( 0 ); // calculate particle normals use for finding force due to wind 01216 01217 T zero = 0, y = 0; 01218 for ( m = 0; m < m_iNoRows; m++ ) { 01219 for ( n = 0; n < m_iNoCols; n++ ) { 01220 if ( m_pcParticle[m][n]->m_bFixed ) { // If the particle is fixed, skip it! 01221 m_pcParticle[m][n]->m_vtForce[0] = 01222 m_pcParticle[m][n]->m_vtForce[1] = 01223 m_pcParticle[m][n]->m_vtForce[2] = zero; 01224 continue; 01225 } 01226 // Clear and Calculate Force due to Acceleration of Gravity -------- 01227 // Fij = mass * g; where g is a vector 01228 y = m_pcParticle[m][n]->m_tMass * (-g); 01229 m_pcParticle[m][n]->m_vtForce[0] = zero; 01230 m_pcParticle[m][n]->m_vtForce[1] = y; 01231 m_pcParticle[m][n]->m_vtForce[2] = zero; 01232 // Add Force due to Viscous Damping -------------------------------- 01233 // Fij = -Kvd * Vij 01234 m_pcParticle[m][n]->m_vtForce += m_tKvd * m_pcParticle[m][n]->m_vtVeloc; 01235 // Add Force due to viscous fluid moving (wind) -------------------- 01236 // Fij = Kvfm * [Nij * (vWind - Vij)] * Nij 01237 // where Nij is the unit normal on the surface at particle Pij 01238 m_pcParticle[m][n]->m_vtForce += m_tKvfm 01239 * ( m_pcParticle[m][n]->m_vtNormal * ( vWind - m_pcParticle[m][n]->m_vtVeloc ) ) 01240 * m_pcParticle[m][n]->m_vtNormal; 01241 01242 // Dump 01243 //cout << "Mass: " << m_pcParticle[m][n]->m_tMass << " Force: " << m_pcParticle[m][n]->m_vtForce << "\n"; 01244 } 01245 } 01246 01247 AddSpringForces(); // calculate and add spring forces to particle forces 01248 } 01249 //------------------------------------------------------------------------------------------------- 01250 // Display Via OpenGL 01251 template <typename T> 01252 void Cloth<T>::DisplayGL( OpenGL::Enum::DrawMode DM ) 01253 { 01254 //int ptSize[1]; 01255 glColor3f( 1.0f, 1.0f, 1.0f ); 01256 01257 int count; 01258 for ( count = 0; count < 8; count++ ) { 01259 StepSimulation( 0.001 ); 01260 //StepSimulation( 0.0005 ); 01261 //StepSimulation( 0.0001 ); 01262 } 01263 01264 //SetMaterial( OpenGL::Enum::METAL_GOLD ); 01265 //SetMaterial( OpenGL::Enum::METAL_SILVER ); 01266 //SetMaterial( OpenGL::Enum::METAL_BRONZE ); 01267 SetMaterial( OpenGL::Enum::BLUE_01 ); 01268 ApplyMaterial( OpenGL::Enum::FRONT ); 01269 SetMaterial( OpenGL::Enum::METAL_GOLD ); 01270 material.ApplyMaterial( OpenGL::Enum::BACK ); 01271 01272 switch (DM) { 01273 // Draw Points for Cloth 01274 case OpenGL::Enum::POINT: 01275 // Set Point Size 01276 //glGetIntegerv( GL_POINT_SIZE, ptSize ); 01277 //glPointSize( 2 ); 01278 glBegin( GL_POINTS ); 01279 for ( m = 0; m < m_iNoRows; m++ ) { 01280 for ( n = 0; n < m_iNoCols; n++ ) { 01281 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 01282 m_pcParticle[m][n]->m_vtPosit[1], 01283 m_pcParticle[m][n]->m_vtPosit[2] ); 01284 } 01285 } 01286 glEnd(); 01287 // Restore Point Size 01288 //glPointSize( ptSize[0] ); 01289 break; 01290 01291 // Draw Wire Frame for Cloth 01292 case OpenGL::Enum::WIRE_FRAME: 01293 glColor3f(0,0,0.5); 01294 glDisable(GL_LIGHTING); 01295 // Draw Row Lines 01296 for ( m = 0; m < m_iNoRows; m++ ) { 01297 glBegin( GL_LINE_STRIP ); 01298 for ( n = 0; n < m_iNoCols; n++ ) { 01299 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 01300 m_pcParticle[m][n]->m_vtPosit[1], 01301 m_pcParticle[m][n]->m_vtPosit[2] ); 01302 } 01303 glEnd(); 01304 } 01305 // Draw Column Lines 01306 for ( n = 0; n < m_iNoCols; n++ ) { 01307 glBegin( GL_LINE_STRIP ); 01308 for ( m = 0; m < m_iNoRows; m++ ) { 01309 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 01310 m_pcParticle[m][n]->m_vtPosit[1], 01311 m_pcParticle[m][n]->m_vtPosit[2] ); 01312 } 01313 glEnd(); 01314 } 01315 // Draw Diagonal Lines 01316 glBegin( GL_LINES ); 01317 for ( m = 0; m < m_iNoRows-1; m++ ) { 01318 for ( n = 0; n < m_iNoCols-1; n++ ) { 01319 // Draw a line from [m][n] --- [m+1][n+1] 01320 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 01321 m_pcParticle[m][n]->m_vtPosit[1], 01322 m_pcParticle[m][n]->m_vtPosit[2] ); 01323 glVertex3f( m_pcParticle[m+1][n+1]->m_vtPosit[0], 01324 m_pcParticle[m+1][n+1]->m_vtPosit[1], 01325 m_pcParticle[m+1][n+1]->m_vtPosit[2] ); 01326 // Draw a line from [m+1][n] to [m][n+1] 01327 glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 01328 m_pcParticle[m+1][n]->m_vtPosit[1], 01329 m_pcParticle[m+1][n]->m_vtPosit[2] ); 01330 glVertex3f( m_pcParticle[m][n+1]->m_vtPosit[0], 01331 m_pcParticle[m][n+1]->m_vtPosit[1], 01332 m_pcParticle[m][n+1]->m_vtPosit[2] ); 01333 } 01334 } 01335 glEnd(); 01336 glEnable(GL_LIGHTING); 01337 break; 01338 01339 // Draw Polygons for Cloth 01340 case OpenGL::Enum::POLYGON: 01341 // With Texture 01342 if ( m_pcImg != NULL ) { 01343 01344 DrawTexture(); 01345 //EnableTexture(); 01346 01347 float tr, tc; 01348 float trStep = 1.0 / (m_iNoRows-1); 01349 float tcStep = 1.0 / (m_iNoCols-1); 01350 for ( m = 0, tr = 1.0; m < m_iNoRows-1; m++, tr -= trStep ) { 01351 glBegin( GL_QUAD_STRIP ); 01352 for ( n = 0, tc = 0.0; n < m_iNoCols; n++, tc += tcStep ) { 01353 glNormal3f( m_pcParticle[m][n]->m_vtNormal[0], 01354 m_pcParticle[m][n]->m_vtNormal[1], 01355 m_pcParticle[m][n]->m_vtNormal[2] ); 01356 glTexCoord2f(tc, tr); 01357 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 01358 m_pcParticle[m][n]->m_vtPosit[1], 01359 m_pcParticle[m][n]->m_vtPosit[2] ); 01360 01361 glNormal3f( m_pcParticle[m+1][n]->m_vtNormal[0], 01362 m_pcParticle[m+1][n]->m_vtNormal[1], 01363 m_pcParticle[m+1][n]->m_vtNormal[2] ); 01364 glTexCoord2f(tc, tr-trStep); 01365 glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 01366 m_pcParticle[m+1][n]->m_vtPosit[1], 01367 m_pcParticle[m+1][n]->m_vtPosit[2] ); 01368 } 01369 glEnd(); 01370 } 01371 } 01372 // Without Texture 01373 else { 01374 for ( m = 0; m < m_iNoRows-1; m++ ) { 01375 glBegin( GL_QUAD_STRIP ); 01376 for ( n = 0; n < m_iNoCols; n++ ) { 01377 glNormal3f( m_pcParticle[m][n]->m_vtNormal[0], 01378 m_pcParticle[m][n]->m_vtNormal[1], 01379 m_pcParticle[m][n]->m_vtNormal[2] ); 01380 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 01381 m_pcParticle[m][n]->m_vtPosit[1], 01382 m_pcParticle[m][n]->m_vtPosit[2] ); 01383 01384 glNormal3f( m_pcParticle[m+1][n]->m_vtNormal[0], 01385 m_pcParticle[m+1][n]->m_vtNormal[1], 01386 m_pcParticle[m+1][n]->m_vtNormal[2] ); 01387 glVertex3f( m_pcParticle[m+1][n]->m_vtPosit[0], 01388 m_pcParticle[m+1][n]->m_vtPosit[1], 01389 m_pcParticle[m+1][n]->m_vtPosit[2] ); 01390 } 01391 glEnd(); 01392 } 01393 } 01394 break; 01395 } 01396 01397 // TEST 01398 //DisplayGL_ParticleNormals(); 01399 01400 glDisable( GL_LIGHTING ); 01401 glColor3f( 0.0f, 1.0f, 0.0f ); 01402 glPointSize( 7 ); 01403 m = 0; n = 0; 01404 glBegin( GL_POINTS ); 01405 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 01406 m_pcParticle[m][n]->m_vtPosit[1], 01407 m_pcParticle[m][n]->m_vtPosit[2] ); 01408 glEnd(); 01409 glColor3f( 0.0f, 1.0f, 1.0f ); 01410 glPointSize( 5 ); 01411 m = 0; n = 1; 01412 glBegin( GL_POINTS ); 01413 glVertex3f( m_pcParticle[m][n]->m_vtPosit[0], 01414 m_pcParticle[m][n]->m_vtPosit[1], 01415 m_pcParticle[m][n]->m_vtPosit[2] ); 01416 glEnd(); 01417 glPointSize( 1 ); 01418 glEnable( GL_LIGHTING ); 01419 // END TEST 01420 } 01421 //------------------------------------------------------------------------------------------------- 01422 // Display Particle Normals Via OpenGL 01423 template <typename T> 01424 void Cloth<T>::DisplayGL_ParticleNormals() 01425 { 01426 T x, y, z; 01427 01428 // Draw Normal of each particle 01429 glDisable( GL_LIGHTING ); 01430 glColor3f( 1.0f, 0.0f, 0.0f ); 01431 glBegin( GL_LINES ); 01432 for ( m = 0; m < m_iNoRows; m++ ) { 01433 for ( n = 0; n < m_iNoCols; n++ ) { 01434 m_pcParticle[m][n]->m_vtPosit.GetXYZ( x, y, z ); 01435 glVertex3f( x, y, z ); 01436 glVertex3f( x + m_pcParticle[m][n]->m_vtNormal[0], 01437 y + m_pcParticle[m][n]->m_vtNormal[1], 01438 z + m_pcParticle[m][n]->m_vtNormal[2] ); 01439 } 01440 } 01441 glEnd(); 01442 glEnable( GL_LIGHTING ); 01443 } 01444 //================================================================================================ 01445 // FRIEND FUNCTIONS 01446 //------------------------------------------------------------------------------------------------- 01447 // put it through ostream 01448 /*template <typename T> 01449 ostream &operator<<( ostream &output, const Cloth<T> &Obj ) 01450 { 01451 output << "Cloth ==> " 01452 << "\n number of rows: " << Obj.m_iNoRows 01453 << "\n number of columns: " << Obj.m_iNoCols 01454 << "\n viscous damping: " << Obj.m_tKvd 01455 << "\n wind damping: " << Obj.m_tKvfm 01456 << "\n stiffness of structural, shear, and flexion springs: " 01457 << Obj.m_tKs[0] << ", " << Obj.m_tKs[1] << ", and " << Obj.m_tKs[2] 01458 << "\n damping constant for structural, shear, and flexion springs: " 01459 << Obj.m_tKd[0] << ", " << Obj.m_tKd[1] << ", and " << Obj.m_tKd[2] 01460 << "\n length constrain for structural, shear, and flextion springs: " 01461 << Obj.m_tLengthConstrain[0] << ", " 01462 << Obj.m_tLengthConstrain[1] << ", and " 01463 << Obj.m_tLengthConstrain[2] 01464 << "\n"; 01465 01466 return output; 01467 }*/ 01468 01469 template <typename T> 01470 void Cloth<T>::AddNormal( Vector3<T> & Dest, 01471 Vector3<T> const & A, Vector3<T> const & B, Vector3<T> const & C ) 01472 { 01473 T U[3] = { A[0]-B[0], A[1]-B[1], A[2]-B[2] }; 01474 T V[3] = { A[0]-C[0], A[1]-C[1], A[2]-C[2] }; 01475 T W[3] = { U[1]*V[2] - U[2]*V[1], U[2]*V[0] - U[0]*V[2], U[0]*V[1] - U[1]*V[0] }; 01476 T SqrtLength = Math<T>::Sqrt( W[0]*W[0] + W[1]*W[1] + W[2]*W[2] ); 01477 Dest[0] += W[0]/SqrtLength; 01478 Dest[1] += W[1]/SqrtLength; 01479 Dest[2] += W[2]/SqrtLength; 01480 } 01481 //MEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERMEMBERME 01482 01483 01484 //============================================================================= 01485 END_NAMESPACE_TAPs 01486 //----------------------------------------------------------------------------- 01487 #endif 01488 //345678901234567890123456789012345678901234567890123456789012345678901234567890 01489 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8