![]() |
TAPs 0.7.7.3
|
00001 /******************************************************************************* 00002 TAPsModelSutureMath.cpp 00003 00004 A two-headed needle suture 00005 00006 SUKITTI PUNAK (01/30/2006) 00007 UPDATE (09/03/2010) 00008 *******************************************************************************/ 00009 #include "TAPsModelSutureMath.hpp" 00010 // Using Inclusion Model (i.e. definitions are included in declarations) 00011 // (this name.cpp is included in name.hpp) 00012 // Each friend is defined directly inside its declaration. 00013 00014 BEGIN_NAMESPACE_TAPs__OpenGL 00015 //============================================================================== 00016 //------------------------------------------------------------------------------ 00017 // Default constructor 00018 template <typename T> 00019 ModelSutureMath<T>::ModelSutureMath () 00020 : ModelStrandMath<T>( 128, 0.1, 0.1, Vector3<T>(), 0.05 ), 00021 m_iLevel( 3 ) 00022 { 00023 InitNeedles(); 00024 //---------------------------------------------------------------- 00025 #ifdef TAPs_ENABLE_DEBUG 00026 std::cout << "Default ModelSutureMath<" << typeid(T).name() << "> with:\n" 00027 << " " << m_iNoLinks << " links with each link of length " 00028 << m_tLinkLength << " and weight " << m_tPointWeight << "\n"; 00029 #endif//TAPs_DEBUG_MODE 00030 } 00031 //------------------------------------------------------------------------------ 00032 // Constructor 00033 template <typename T> 00034 ModelSutureMath<T>::ModelSutureMath ( int iNoLinks, T tLength, T tWeight, 00035 Vector3<T> & posOfVertex0, T tRadius ) 00036 00037 : ModelStrandMath<T>( iNoLinks, tLength, tWeight, posOfVertex0, tRadius ), 00038 m_iLevel( 3 ) 00039 { 00040 InitNeedles(); 00041 //---------------------------------------------------------------- 00042 #ifdef TAPs_ENABLE_DEBUG 00043 std::cout << "ModelSutureMath<" << typeid(T).name() << "> with:\n" 00044 << " " << m_iNoLinks << " links with each link of length " 00045 << m_tLinkLength << " and weight " << m_tPointWeight << "\n"; 00046 #endif//TAPs_DEBUG_MODE 00047 } 00048 //------------------------------------------------------------------------------ 00049 // Constructor 00050 template <typename T> 00051 ModelSutureMath<T>::ModelSutureMath ( int iNoLinks, T tLength, T tWeight, 00052 Vector3<T> & posOfVertex0, T tRadius, 00053 const char * needle1 00054 ) 00055 00056 : ModelStrandMath<T>( iNoLinks, tLength, tWeight, posOfVertex0, tRadius ), 00057 m_iLevel( 3 ) 00058 { 00059 InitNeedles( needle1 ); 00060 //---------------------------------------------------------------- 00061 #ifdef TAPs_ENABLE_DEBUG 00062 std::cout << "ModelSutureMath<" << typeid(T).name() << "> with:\n" 00063 << " " << m_iNoLinks << " links with each link of length " 00064 << m_tLinkLength << " and weight " << m_tPointWeight << "\n"; 00065 #endif//TAPs_DEBUG_MODE 00066 } 00067 //------------------------------------------------------------------------------ 00068 // Constructor 00069 template <typename T> 00070 ModelSutureMath<T>::ModelSutureMath ( int iNoLinks, T tLength, T tWeight, 00071 Vector3<T> & posOfVertex0, T tRadius, 00072 T tKRatioOfStretchingAllowed, 00073 T tKRatioOfCompressionAllowed, 00074 T tKStretching, 00075 T tKBending, 00076 T tKTwisting, 00077 T tKFriction, 00078 T tKContact, 00079 T tKGravity, 00080 const char * needle1 00081 ) 00082 00083 : ModelStrandMath<T>( iNoLinks, tLength, tWeight, posOfVertex0, tRadius, 00084 tKRatioOfStretchingAllowed, tKRatioOfCompressionAllowed, 00085 tKStretching, tKBending, tKTwisting, 00086 tKFriction, tKContact, tKGravity ), 00087 m_iLevel( 3 ) 00088 { 00089 InitNeedles( needle1 ); 00090 //---------------------------------------------------------------- 00091 #ifdef TAPs_ENABLE_DEBUG 00092 std::cout << "ModelSutureMath<" << typeid(T).name() << "> with:\n" 00093 << " " << m_iNoLinks << " links with each link of length " 00094 << m_tLinkLength << " and weight " << m_tPointWeight << "\n"; 00095 #endif//TAPs_DEBUG_MODE 00096 } 00097 //------------------------------------------------------------------------------ 00098 // Destructor 00099 template <typename T> 00100 ModelSutureMath<T>::~ModelSutureMath () 00101 { 00102 //if ( m_pNeedleLeft ) delete m_pNeedleLeft; // ERROR Deleting Object! FIX IT! 00103 //if ( m_pNeedleRight ) delete m_pNeedleRight; 00104 //---------------------------------------------------------------- 00105 if ( m_prPickPts ) delete [] m_prPickPts; 00106 if ( m_prbIsSharp ) delete [] m_prbIsSharp; 00107 //---------------------------------------------------------------- 00108 #ifdef TAPs_ENABLE_DEBUG 00109 std::cout << "ModelSutureMath<" << typeid(T).name() << "> Destructor\n"; 00110 #endif//TAPs_DEBUG_MODE 00111 } 00112 //------------------------------------------------------------------------------ 00113 // Initialize Needles 00114 template <typename T> 00115 void ModelSutureMath<T>::InitNeedles () 00116 { 00117 //char fileName1[] = "Data/3dsMax/HeadNeedle.ASE"; 00118 //char fileName1[] = "Data/3dsMax/HeadNeedle2.ASE"; 00119 char needle1[] = "Data/3dsMax/HeadNeedle3.ASE"; 00120 //char fileName2[] = "Data/3dsMax/HeadNeedle.ASE"; 00121 InitNeedles( needle1 ); 00122 } 00123 //------------------------------------------------------------------------------ 00124 // Initialize Needles 00125 template <typename T> 00126 void ModelSutureMath<T>::InitNeedles ( const char * needle1 ) 00127 { 00128 //m_pNeedleLeft = NULL; 00129 //m_pNeedleRight = NULL; 00130 //---------------------------------------------------------------- 00131 m_pNeedleLeft = new OpenGLHalfEdgeModel<T>(); 00132 //m_pNeedleRight = new OpenGLHalfEdgeModel<T>(); 00133 //---------------------------------------------------------------- 00134 00135 #ifdef TAPs_DEBUG_MODE 00136 std::cout << "Create Left Needle" << std::endl; 00137 #endif//TAPs_DEBUG_MODE 00138 00139 if ( !ReadModels<Real>::readFile( needle1, m_pNeedleLeft ) ) { 00140 std::cout << "ERROR: In File Reading for creating the left needle!" << std::endl; 00141 exit ( EXIT_FAILURE ); 00142 } 00143 else { 00144 #ifdef TAPs_DEBUG_MODE 00145 std::cout << "Creating Left Needle" << std::endl; 00146 #endif//TAPs_DEBUG_MODE 00147 00148 m_pNeedleLeft->SetMaterial( OpenGL::Enum::HEAD_NEEDLE ); 00149 m_pNeedleLeft->BuildBVHTree( TAPs::Enum::BVH_TREE_BINARY_SPHERE ); 00150 } 00151 //---------------------------------------------------------------- 00152 /* 00153 00154 #ifdef TAPs_DEBUG_MODE 00155 std::cout << "Create Right Needle" << std::endl; 00156 #endif//TAPs_DEBUG_MODE 00157 00158 if ( !ReadModels<Real>::readFile( needle2, m_pNeedleRight ) ) { 00159 std::cout << "ERROR: In File Reading for creating the right needle!" << std::endl; 00160 exit ( EXIT_FAILURE ); 00161 } 00162 else { 00163 #ifdef TAPs_DEBUG_MODE 00164 std::cout << "Creating Right Needle" << std::endl; 00165 #endif//TAPs_DEBUG_MODE 00166 00167 m_pNeedleRight->SetMaterial( OpenGL::Enum::HEAD_NEEDLE ); 00168 m_pNeedleRight->BuildBVHTree( TAPs::Enum::BVH_TREE_BINARY_SPHERE ); 00169 } 00170 //*/ 00171 //-------------------------------------------------------------------- 00172 InitNeedlesPickPts(); 00173 SetNeedlesPickPts(); 00174 InitNeedlesSharpPts(); 00175 } 00176 //------------------------------------------------------------------------------ 00177 // Initialize Needles Pick Points 00178 template <typename T> 00179 void ModelSutureMath<T>::InitNeedlesPickPts () 00180 { 00181 // SET Number of Pick Pts HERE! ==> 2^m_iLevel 00182 m_iLevel = 4; 00183 //---------------------------------------------------------------- 00184 // Set number of pick able points for needles 00185 //m_iNoPickPts = static_cast<int>( pow( 2.0, m_iLevel ) ); // * 2; 00186 m_iNoPickPts = 1 << m_iLevel; 00187 00188 #ifdef TAPs_DEBUG_MODE 00189 std::cout << "Number of pickable points for the needle is set at" << m_iNoPickPts << ".\n"; 00190 #endif//TAPs_DEBUG_MODE 00191 00192 m_prPickPts = new Vector3<T>*[ m_iNoPickPts ]; 00193 assert( m_prPickPts ); 00194 //---------------------------------------------------------------- 00195 // Use a recursive function 00196 BVHNode<T> ** L = new BVHNode<T>*[1]; 00197 L[0] = m_pNeedleLeft->GetBVHTree()->Root(); 00198 InitNeedlesPickPts( L, 0 ); // Node List and Level Number 00199 delete [] L; 00200 } 00201 //------------------------------------------------------------------------------ 00202 // Initialize Needles Pick Points 00203 template <typename T> 00204 void ModelSutureMath<T>::InitNeedlesPickPts ( BVHNode<T> ** node, int level ) 00205 { 00206 #ifdef TAPs_DEBUG_MODE 00207 std::cout << "InitNeedlesPickPts with LEVEL of " << level << std::endl; 00208 #endif//TAPs_DEBUG_MODE 00209 00210 if ( level > m_iLevel ) return; 00211 //---------------------------------------------------------------- 00212 //int size = static_cast<int>( pow( 2.0, level ) ); 00213 int size = 1 << level; 00214 BVHNode<T> ** L = new BVHNode<T>*[ size*2 ]; 00215 for ( int i = 0, j = 0; i < size; ++i, j+=2 ) { 00216 L[j ] = node[i]->Child(0); 00217 L[j+1] = node[i]->Child(1); 00218 } 00219 InitNeedlesPickPts( L, ++level ); 00220 //---------------------------------------------------------------- 00221 if ( level == m_iLevel ) { 00222 //---------------------------------------------------------------- 00223 #ifdef TAPs_DEBUG_MODE 00224 std::cout << "-------------------- NEEDLE PICK POINTS --------------------\n"; 00225 #endif//TAPs_DEBUG_MODE 00226 00227 for ( int i = 0; i < m_iNoPickPts; ++i ) { 00228 m_prPickPts[i] = &(L[i]->GetCenter()); 00229 00230 #ifdef TAPs_DEBUG_MODE 00231 std::cout << *(m_prPickPts[i]) << "\n"; 00232 #endif//TAPs_DEBUG_MODE 00233 } 00234 #ifdef TAPs_DEBUG_MODE 00235 std::cout << "-------------------- END NEEDLE PICK POINTS --------------------\n"; 00236 #endif//TAPs_DEBUG_MODE 00237 } 00238 delete [] L; 00239 } 00240 //------------------------------------------------------------------------------ 00241 // SetNeedlesPickPts 00242 // Align needles with the movement of the strand 00243 template <typename T> 00244 void ModelSutureMath<T>::SetNeedlesPickPts () 00245 { 00246 static int i; 00247 static T angle; 00248 static Vector3<T> dir, axis; 00249 00250 //-------------------------------------------------------------------- 00251 // Left Needle 00252 i = 0; 00253 dir = m_prVertex[i] - m_prVertex[i+1]; 00254 axis = dir ^ (-CGMath<T>::VectorY); 00255 angle = acos( (dir * (-CGMath<T>::VectorY)) / dir.Length() ) 00256 * Math<T>::RAD_TO_DEG; 00257 // Translation and Rotation 00258 //m_vTransForLeftNeedle = m_prVertex[i]; 00259 m_pNeedleLeft->GetTransform().SetTranslation( m_prVertex[i] ); 00260 //m_mRotMatForLeftNeedle = CGMath<T>::CreateRotationMatrix3x3( axis, -angle ); 00261 if ( !GetFixStatusOfPtNo( 0 ) ) 00262 m_pNeedleLeft->GetTransform().SetMatrixRotation( CGMath<T>::CreateRotationMatrix3x3( axis, -angle ) ); 00263 //std::cout << m_pNeedleLeft->GetTransform().GetMatrixRotation() << "\n"; 00264 /* 00265 //-------------------------------------------------------------------- 00266 // Get Rotation Matrix using OpenGL 00267 GLfloat m[16]; 00268 glPushMatrix(); 00269 glLoadIdentity(); 00270 glRotatef( -angle, axis[0], axis[1], axis[2] ); 00271 glGetFloatv( GL_MODELVIEW_MATRIX, m ); 00272 glPopMatrix(); 00273 m_vTransForLeftNeedle = m_prVertex[i]; 00274 m_mRotMatForLeftNeedle = Matrix3x3<T>( m[ 0], m[ 4], m[ 8], 00275 m[ 1], m[ 5], m[ 9], 00276 m[ 2], m[ 6], m[10] ); 00277 //*/ 00278 00279 //-------------------------------------------------------------------- 00280 //-------------------------------------------------------------------- 00281 //-------------------------------------------------------------------- 00282 //-------------------------------------------------------------------- 00283 } 00284 //------------------------------------------------------------------------------ 00285 // InitNeedlesSharpPts 00286 template <typename T> 00287 void ModelSutureMath<T>::InitNeedlesSharpPts () 00288 { 00289 //--------------------------------------------------------------- 00290 // For Left Needle 00291 m_prbIsSharp = new bool[ m_iNoPickPts ]; 00292 for ( int i = 0; i < m_iNoPickPts; ++i ) { 00293 m_prbIsSharp[i] = false; 00294 } 00295 00296 /* 00297 //--------------------------------------------------------------- 00298 // Sort Needle Points 00299 int * sortArray = new int[ m_iNoPickPts ]; 00300 for ( int i = 0; i < m_iNoPickPts; ++i ) { 00301 sortArray[i] = i; 00302 } 00303 T minDistance = (*(m_prPickPts[0]) - m_prVertex[0]).Length(); 00304 T distance; 00305 int minPt; 00306 //----------------------------------------------------- 00307 for ( int j = 0; j < m_iNoPickPts; ++j ) { 00308 distance = (*(m_prPickPts[j]) - m_prVertex[0]).Length(); 00309 if ( distance < minDistance ) { 00310 minPt = j; 00311 minDistance = distance; 00312 } 00313 } 00314 sortArray[0] = minPt; 00315 sortArray[minPt] = 0; 00316 /* 00317 //----------------------------------------------------- 00318 for ( int i = 1; i < m_iNoPickPts; ++i ) { 00319 minDistance = (*(m_prPickPts[sortArray[i]]) - *(m_prPickPts[sortArray[i-1]])).Length(); 00320 for ( int j = i+1; j < m_iNoPickPts; ++j ) { 00321 distance = (*(m_prPickPts[sortArray[j]]) - *(m_prPickPts[sortArray[i-1]])).Length(); 00322 if ( distance < minDistance ) { 00323 minPt = j; 00324 minDistance = distance; 00325 } 00326 } 00327 int tmp = sortArray[i]; 00328 sortArray[i] = sortArray[minPt]; 00329 sortArray[minPt] = tmp; 00330 } 00331 //*/ 00332 //----------------------------------------------------- 00333 //m_prbIsSharp[sortArray[m_iNoPickPts-1]] = true; 00334 //m_prbIsSharp[sortArray[0]] = true; 00335 //*/ 00336 00337 //--------------------------------------------------------------- 00338 int needleSharpPt = 0; 00339 T maxDistance = (*(m_prPickPts[0]) - m_prVertex[0]).Length(); 00340 T distance; 00341 for ( int i = 1; i < m_iNoPickPts; ++i ) { 00342 distance = (*(m_prPickPts[i]) - m_prVertex[0]).Length(); 00343 if ( distance > maxDistance ) { 00344 needleSharpPt = i; 00345 maxDistance = distance; 00346 } 00347 } 00348 m_prbIsSharp[needleSharpPt] = true; 00349 m_iNeedleSharpPt = needleSharpPt; 00350 } 00351 //------------------------------------------------------------------------------ 00352 template <typename T> 00353 inline Vector3<T> ModelSutureMath<T>::GetPointPosition ( int i ) const 00354 { 00355 if ( i <= m_iNoLinks ) return m_prVertex[i]; 00356 else return GetNeedlesPosition( i-m_iNoLinks-1 ); 00357 } 00358 //------------------------------------------------------------------------------ 00359 template <typename T> 00360 inline Vector3<T> ModelSutureMath<T>::GetNeedlesPosition ( int i ) const 00361 { 00362 assert( 0 <= i && i < m_iNoPickPts ); 00363 // Left Needle 00364 //return m_mRotMatForLeftNeedle * *(m_prPickPts[i]) + m_vTransForLeftNeedle; 00365 return m_pNeedleLeft->GetTransform().GetMatrixRotation() * 00366 *(m_prPickPts[i]) + m_pNeedleLeft->GetTransform().GetTranslation(); 00367 } 00368 //------------------------------------------------------------------------------ 00369 template <typename T> 00370 inline void ModelSutureMath<T>::SetPointPosition ( 00371 int i, const Vector3<T> & position ) 00372 { 00373 if ( i <= m_iNoLinks ) { 00374 ModelStrandMath<T>::SetPointPosition( i, position ); 00375 SetNeedlesPickPts(); 00376 } 00377 else { 00378 //SetNeedlesPosition( i-m_iNoLinks-1, position, m_mRotMatForLeftNeedle ); 00379 00380 SetNeedlesPosition( i-m_iNoLinks-1, position, m_pNeedleLeft->GetTransform().GetMatrixRotation() ); 00381 00382 //ModelStrandMath<T>::SetPointPosition( 0, m_vTransForLeftNeedle ); 00383 00384 //ModelStrandMath<T>::SetPointPosition( 1, position ); 00385 ModelStrandMath<T>::SetPointPosition( 0, m_pNeedleLeft->GetTransform().GetTranslation() ); 00386 } 00387 } 00388 //------------------------------------------------------------------------------ 00389 template <typename T> 00390 inline void ModelSutureMath<T>::SetPointPosition ( 00391 int i, const Vector3<T> & position, Matrix3x3<T> & rotation, 00392 //T tMoveDistanceLimit, 00393 MultiBoundingVolume<T> const * const pMBV, 00394 TransformationSupport<T> const * const pTransform 00395 ) 00396 { 00397 if ( i <= m_iNoLinks ) { 00398 ModelStrandMath<T>::SetPointPosition( i, position, pMBV, pTransform ); 00399 SetNeedlesPickPts(); 00400 } 00401 else { 00402 SetNeedlesPosition( i-m_iNoLinks-1, position, rotation ); 00403 //ModelStrandMath<T>::SetPointPosition( 0, m_vTransForLeftNeedle ); 00404 ModelStrandMath<T>::SetPointPosition( 0, m_pNeedleLeft->GetTransform().GetTranslation() ); 00405 } 00406 } 00407 //------------------------------------------------------------------------------ 00408 template <typename T> 00409 inline void ModelSutureMath<T>::SetNeedlesPosition ( 00410 int i, const Vector3<T> & position, Matrix3x3<T> & rotation ) 00411 { 00412 assert( 0 <= i && i < m_iNoPickPts ); 00413 //-------------------------------------------------------------------- 00414 // Left Needle 00415 //m_mRotMatForLeftNeedle = rotation; 00416 00417 //rotation.MakeIdentity(); 00418 00419 // Rotate with the first link of the strand 00420 m_pNeedleLeft->GetTransform().SetMatrixRotation( rotation ); 00421 00422 Vector3<T> translation = position - GetNeedlesPosition( i ); 00423 //m_vTransForLeftNeedle += translation; 00424 m_pNeedleLeft->GetTransform().SetTranslation( 00425 m_pNeedleLeft->GetTransform().GetTranslation() + translation 00426 ); 00427 } 00428 //------------------------------------------------------------------------------ 00429 //============================================================================== 00430 // Get/Set Fn(s) 00431 //------------------------------------------------------------------------------ 00432 //------------------------------------------------------------------------------ 00433 //============================================================================== 00434 // Helper Fn(s) 00435 //------------------------------------------------------------------------------ 00436 //------------------------------------------------------------------------------ 00437 //============================================================================== 00438 // For Simulation 00439 //------------------------------------------------------------------------------ 00440 // DxDt 00441 template <typename T> 00442 bool ModelSutureMath<T>::DxDt ( 00443 T dt, // i/p: time step 00444 Simulation::VectorSet<T> &x, // i/p: array x = {pos, vel} 00445 Simulation::VectorSet<T> &xdot, // o/p: array xdot = {vel, accel} 00446 void *userData // o/p: array of user data 00447 ) 00448 { 00449 return ModelStrandMath<T>::DxDt( dt, x, xdot, userData ); 00450 } 00451 //------------------------------------------------------------------------------ 00452 // StateToArray 00453 template <typename T> 00454 void ModelSutureMath<T>::StateToArray ( T *dst ) 00455 { 00456 ModelStrandMath<T>::StateToArray( dst ); 00457 } 00458 //------------------------------------------------------------------------------ 00459 // ArrayToState 00460 template <typename T> 00461 void ModelSutureMath<T>::ArrayToState ( T *src ) 00462 { 00463 ModelStrandMath<T>::ArrayToState( src ); 00464 } 00465 //------------------------------------------------------------------------------ 00466 // DdtStateToArray 00467 template <typename T> 00468 void ModelSutureMath<T>::DdtStateToArray ( T *xdot, T dt ) 00469 { 00470 ModelStrandMath<T>::DdtStateToArray( xdot, dt ); 00471 } 00472 //------------------------------------------------------------------------------ 00473 // AdvanceSimulation 00474 template <typename T> 00475 void ModelSutureMath<T>::AdvanceSimulation ( T tCurrent, T tNext ) 00476 { 00477 ModelStrandMath<T>::AdvanceSimulation( tCurrent, tNext ); 00478 SetNeedlesPickPts(); 00479 } 00480 //------------------------------------------------------------------------------ 00481 // AdvanceSimulation 00482 template <typename T> 00483 void ModelSutureMath<T>::AdvanceSimulation ( Simulation::SimClock<T> & simClock ) 00484 { 00485 ModelStrandMath<T>::AdvanceSimulation( simClock ); 00486 SetNeedlesPickPts(); 00487 } 00488 //------------------------------------------------------------------------------ 00489 00490 //------------------------------------------------------------------------------ 00491 // SetupShape Fn 00492 template <typename T> 00493 void ModelSutureMath<T>::SetupShape ( Vector3<T> startPosition ) 00494 { 00495 ModelStrandMath<T>::SetupShape( startPosition ); 00496 } 00497 //------------------------------------------------------------------------------ 00498 //============================================================================== 00499 END_NAMESPACE_TAPs__OpenGL 00500 //------------------------------------------------------------------------------ 00501 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00502 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8