![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 XPolygonalModel.cpp 00003 00004 (X <==> Extra) 00005 A (Generic) XPolygonal Model 00006 00007 SUKITTI PUNAK (11/01/2004) 00008 UPDATE (05/25/2006) 00009 ******************************************************************************/ 00010 #include "TAPsXPolygonalModel.hpp" 00011 // Using Inclusion Model (i.e. definitions are included in declarations) 00012 // (this name.cpp is included in name.hpp) 00013 // Each friend is defined directly inside its declaration. 00014 00015 BEGIN_NAMESPACE_TAPs__OpenGL 00016 //============================================================================= 00017 //----------------------------------------------------------------------------- 00018 // default constructor 00019 template <typename T> 00020 XPolygonalModel<T>::XPolygonalModel () 00021 : OpenGLMeshModel<T>(), 00022 m_prXVertex( NULL ), m_prFace( NULL ), m_pviVertexRing1List( NULL ) 00023 { 00024 #ifdef TAPs_DEBUG_MODE 00025 std::cout << "XPolygonalModel<" << typeid(T).name() << "> Constructor\n"; 00026 #endif//TAPs_ENABLE_DEBUG 00027 } 00028 //----------------------------------------------------------------------------- 00029 // destructor 00030 template <typename T> 00031 XPolygonalModel<T>::~XPolygonalModel () 00032 { 00033 if ( m_prXVertex != NULL ) { 00034 delete [] m_prXVertex; 00035 m_prXVertex = NULL; 00036 } 00037 if ( m_prFace != NULL ) { 00038 delete [] m_prFace; 00039 m_prFace = NULL; 00040 } 00041 if ( m_pviVertexRing1List != NULL ) { 00042 delete [] m_pviVertexRing1List; 00043 m_pviVertexRing1List = NULL; 00044 } 00045 00046 #ifdef TAPs_DEBUG_MODE 00047 std::cout << "XPolygonalModel<" << typeid(T).name() << "> Destructor\n"; 00048 #endif//TAPs_ENABLE_DEBUG 00049 } 00050 //----------------------------------------------------------------------------- 00051 // Initialize 00052 template <typename T> 00053 void XPolygonalModel<T>::Initialize () 00054 { 00055 // Model Initialization 00056 DetermineAndSortRings(); 00057 //DetermineFaceRings (); 00058 CalAndSetNormals(); 00059 // DetermineAndSortRings(); 00060 ApplyMaterial( Enum::FRONT ); 00061 //DetermineEdgeList(); 00062 CalBoundingAABB(); 00063 CalBoundingEllipsoid(); 00064 CalBoundingSphere(); 00065 } 00066 //----------------------------------------------------------------------------- 00067 // New/Delete Fn 00068 template <typename T> 00069 void XPolygonalModel<T>::NewVertexListByNoVertices () 00070 { 00071 if ( m_prXVertex != NULL ) { 00072 delete [] m_prXVertex; 00073 } 00074 m_prXVertex = new XVertex<T>[m_iNoVertices]; 00075 } 00076 //----------------------------------------------------------------------------- 00077 // New/Delete Fn 00078 template <typename T> 00079 void XPolygonalModel<T>::NewFaceListByNoFaces () 00080 { 00081 if ( m_prFace != NULL ) { 00082 delete [] m_prFace; 00083 } 00084 m_prFace = new Face<T>[m_iNoFaces]; 00085 } 00086 //----------------------------------------------------------------------------- 00087 // Get Half Length 00088 template <typename T> 00089 T XPolygonalModel<T>::GetMaxHalfLength () const 00090 { 00091 T maxHalfSize = 0.0; 00092 for ( int i = 0; i < m_iNoVertices; ++i ) 00093 { 00094 if ( fabs( m_prXVertex[i][0] ) > maxHalfSize ) 00095 maxHalfSize = fabs( m_prXVertex[i][0] ); 00096 if ( fabs( m_prXVertex[i][1] ) > maxHalfSize ) 00097 maxHalfSize = fabs( m_prXVertex[i][1] ); 00098 if ( fabs( m_prXVertex[i][2] ) > maxHalfSize ) 00099 maxHalfSize = fabs( m_prXVertex[i][2] ); 00100 } 00101 return maxHalfSize; 00102 } 00103 //----------------------------------------------------------------------------- 00104 // Calculate and set the normals 00105 template <typename T> 00106 void XPolygonalModel<T>::CalAndSetNormals () 00107 { 00108 CalAndSetFaceNormalsNotNormalized(); 00109 DetermineFaceRings(); 00110 CalAndSetVertexNormals(); 00111 NormalizeFaceNormals(); 00112 } 00113 //----------------------------------------------------------------------------- 00114 // Calculate and set the face normals (without normalized) 00115 template <typename T> 00116 inline void XPolygonalModel<T>::CalAndSetFaceNormalsNotNormalized () 00117 { 00118 // Calculate and set the normal of each face 00119 for ( int i = 0; i < m_iNoFaces; ++i ) { 00120 m_prFace[i].SetNormal( 00121 ( m_prXVertex[ m_prFace[i].GetVertexNo( 1 ) ].GetPosition() 00122 - m_prXVertex[ m_prFace[i].GetVertexNo( 0 ) ].GetPosition() ) 00123 ^ ( m_prXVertex[ m_prFace[i].GetVertexNo( 2 ) ].GetPosition() 00124 - m_prXVertex[ m_prFace[i].GetVertexNo( 1 ) ].GetPosition() ) 00125 ); 00126 } 00127 } 00128 //----------------------------------------------------------------------------- 00129 // Normalize the face normals 00130 template <typename T> 00131 inline void XPolygonalModel<T>::NormalizeFaceNormals () 00132 { 00133 for ( int i = 0; i < m_iNoFaces; ++i ) { 00134 const_cast< Vector3<T> * >( &m_prFace[i].GetNormal() )->Normalized(); 00135 //m_prFace[i].GetNormal().Normalized(); 00136 } 00137 } 00138 //----------------------------------------------------------------------------- 00139 // Determine the ring of each vertex 00140 template <typename T> 00141 inline void XPolygonalModel<T>::DetermineFaceRings () 00142 { 00143 bool notYetStored; 00144 // Insert the faces contain each vertex 00145 for ( int f = 0; f < m_iNoFaces; ++f ) { 00146 for ( int v = 0; v < m_prFace[f].GetNoVertices(); ++v ) { 00147 notYetStored = true; 00148 for ( int i = 0; i < static_cast<int>(m_prXVertex[m_prFace[f].GetVertexNo(v)].GetFaceRing().size()); ++i ) { 00149 if ( m_prXVertex[m_prFace[f].GetVertexNo(v)].GetFaceRing()[i] == f ) { 00150 notYetStored = false; 00151 break; 00152 } 00153 } 00154 if ( notYetStored ) { 00155 m_prXVertex[m_prFace[f].GetVertexNo(v)].GetFaceRing().push_back( f ); 00156 } 00157 } 00158 } 00159 } 00160 //----------------------------------------------------------------------------- 00161 // Calculate and set the vertex normals 00162 template <typename T> 00163 inline void XPolygonalModel<T>::CalAndSetVertexNormals () 00164 { 00165 for ( int v = 0; v < m_iNoVertices; ++v ) { 00166 Vector3<T> vNormal; 00167 for ( int f = 0; f < static_cast<int>( m_prXVertex[v].GetFaceRing().size() ); ++f ) { 00168 vNormal += m_prFace[ m_prXVertex[v].GetFaceRing()[f] ].GetNormal(); 00169 } 00170 m_prXVertex[v].SetNormal( vNormal.Normalized() ); 00171 } 00172 } 00173 //----------------------------------------------------------------------------- 00174 // Sort the face ring of each vertex 00175 template <typename T> 00176 void XPolygonalModel<T>::DetermineAndSortRings () 00177 { 00178 #ifdef TAPs_DEBUG_MODE_DETAIL_1 00179 std::cout << "Xpolygonal Model: Determine and sort the first rings" << std::endl; 00180 #endif//TAPs_DEBUG_MODE_DETAIL_1 00181 //---------------------------------------------------------------- 00182 /* CCW 00183 2 --------- 1 00184 / \ / \ 00185 / \ f_2 / \ 00186 / \ / \ 00187 / f_3 \ / f_1 \ 00188 / \ / \ 00189 3 --------- V --------- 0 00190 \ / \ / 00191 \ f_4 / \ f_0 / 00192 \ / \ / 00193 \ / f_5 \ / 00194 \ / \ / 00195 4 --------- 5 00196 */ 00197 //---------------------------------------------------------------- 00198 DetermineFaceRings (); 00199 //---------------------------------------------------------------- 00200 // Local Variables 00201 int v, f, i, t1, n, k; 00202 int vertexAt[128]; 00203 Face<T> * face; 00204 int lastVertexNo; 00205 //---------------------------------------------------------------- 00206 // For each vertex v 00207 m_pviVertexRing1List = new std::vector<int>[m_iNoVertices]; 00208 for ( v = 0; v < m_iNoVertices; ++v ) { 00209 //============================================================ 00210 // Find the vertex number in each face ring of this vertex 00211 //------------------------------------------------------------ 00212 int size = static_cast<int>( m_prXVertex[v].GetFaceRing().size() ); 00213 if ( size <= 0 ) { 00214 continue; // skip this vertex if it doesn't have a face ring 00215 } 00216 int current = 0; 00217 int noOfVertices; 00218 // For each face f in the ring of the vertex v 00219 // find the number of this v vertex in it 00220 for ( f = 0; f < size; ++f ) { 00221 face = &m_prFace[ m_prXVertex[v].GetFaceRing()[f] ]; 00222 noOfVertices = face->GetNoVertices(); 00223 // Get the number of this v vertex in the f face 00224 // keep the info in vertexAt[f] 00225 for ( i = 0; i < noOfVertices; ++i ) { 00226 if ( v == face->GetVertexNo(i) ) { 00227 vertexAt[f] = i; 00228 break; 00229 } 00230 } 00231 } 00232 //------------------------------------------------------------ 00233 //============================================================ 00234 // Arrange the face and vertex rings of this vertex 00235 //------------------------------------------------------------ 00236 //------------------------------------------------------------ 00237 // Face 0 00238 f = 0; 00239 face = &m_prFace[ m_prXVertex[v].GetFaceRing()[f] ]; 00240 lastVertexNo = -1; 00241 // Use the fact that the vertices are listed CCW 00242 for ( i = vertexAt[f]+1; i < face->GetNoVertices(); ++i ) { 00243 m_pviVertexRing1List[v].push_back( face->GetVertexNo(i) ); 00244 } 00245 for ( i = 0; i < vertexAt[f]; ++i ) { 00246 m_pviVertexRing1List[v].push_back( face->GetVertexNo(i) ); 00247 } 00248 lastVertexNo = ( vertexAt[f]-1 < 0 00249 ? face->GetVertexNo( face->GetNoVertices()-1 ) 00250 : face->GetVertexNo( vertexAt[f]-1 ) ); 00251 //------------------------------------------------------------ 00252 // Face 1 to size-1 00253 int iFaceNo; 00254 for ( f = 1; f < size; ++f ) { 00255 // Use the fact that only the next face contains 00256 // the last inserted vertex to find the next face 00257 i = f; 00258 bool search = true; 00259 while ( i < size && search ) { 00260 iFaceNo = m_prXVertex[v].GetFaceRing()[i]; // Face# 00261 face = &m_prFace[ iFaceNo ]; // Face 00262 00263 for ( n = 0; n < face->GetNoVertices(); ++n ) { 00264 if ( lastVertexNo == face->GetVertexNo(n) ) { 00265 search = false; 00266 00267 // Swap (sort) the face 00268 if ( f != i ) { 00269 t1 = m_prXVertex[v].GetFaceRing()[f]; 00270 m_prXVertex[v].GetFaceRing()[f] = m_prXVertex[v].GetFaceRing()[i]; 00271 m_prXVertex[v].GetFaceRing()[i] = t1; 00272 t1 = vertexAt[f]; 00273 vertexAt[f] = vertexAt[i]; 00274 vertexAt[i] = t1; 00275 } 00276 00277 // Use the fact that the vertices are listed CCW 00278 for ( k = vertexAt[f]+1; k < face->GetNoVertices(); ++k ) { 00279 if ( face->GetVertexNo(k) != v && face->GetVertexNo(k) != lastVertexNo ) { 00280 m_pviVertexRing1List[v].push_back( face->GetVertexNo(k) ); 00281 } 00282 } 00283 for ( k = 0; k < vertexAt[f]; ++k ) { 00284 if ( face->GetVertexNo(k) != v && face->GetVertexNo(k) != lastVertexNo ) { 00285 m_pviVertexRing1List[v].push_back( face->GetVertexNo(k) ); 00286 } 00287 } 00288 lastVertexNo = ( vertexAt[f]-1 < 0 00289 ? face->GetVertexNo( face->GetNoVertices()-1 ) 00290 : face->GetVertexNo( vertexAt[f]-1 ) ); 00291 break; 00292 } 00293 } 00294 ++i; 00295 } 00296 } 00297 m_pviVertexRing1List[v].pop_back(); 00298 //------------------------------------------------------------ 00299 } 00300 } 00301 00302 //****************************************************************************** 00303 // ApplyAndResetTransform 00304 //****************************************************************************** 00305 //----------------------------------------------------------------------------- 00306 template <typename T> 00307 void XPolygonalModel<T>::ApplyAndResetTransform () 00308 { 00309 for ( int i = 0; i < m_iNoVertices; ++i ) { 00310 m_prXVertex[i].SetPosition( 00311 ( GetTransform().RefToMatrixTransform() 00312 * Vector4<T>( m_prXVertex[i].GetPosition() ) 00313 ).GetVector3() 00314 ); 00315 } 00316 00317 00318 /* 00319 int i; 00320 //-------------------------------------------------------------------- 00321 Vector3<T> Center = GetTransform().GetTranslation(); 00322 if ( Center[0] != Math<T>::ZERO ) { 00323 for ( i = 0; i < m_iNoVertices; ++i ) 00324 m_prXVertex[i][0] += Center[0]; 00325 GetTransform().SetTranslation( 0, Math<T>::ZERO ); 00326 } 00327 if ( Center[1] != Math<T>::ZERO ) { 00328 for ( i = 0; i < m_iNoVertices; ++i ) 00329 m_prXVertex[i][1] += Center[1]; 00330 GetTransform().SetTranslation( 1, Math<T>::ZERO ); 00331 } 00332 if ( Center[2] != Math<T>::ZERO ) { 00333 for ( i = 0; i < m_iNoVertices; ++i ) 00334 m_prXVertex[i][2] += Center[2]; 00335 GetTransform().SetTranslation( 2, Math<T>::ZERO ); 00336 } 00337 //-------------------------------------------------------------------- 00338 Vector3<T> Rotation = GetTransform().GetRotationAngles(); 00339 if ( Rotation[0] != Math<T>::ZERO ) { 00340 T deg = static_cast<T>( Rotation[0] * Math<T>::PI / 180.0 ); 00341 T c = Math<T>::Cos( deg ); 00342 T s = Math<T>::Sin( deg ); 00343 T tmpX; 00344 for ( i = 0; i < m_iNoVertices; ++i ) { 00345 tmpX = m_prXVertex[i][1]*c - m_prXVertex[i][2]*s; 00346 m_prXVertex[i][2] = m_prXVertex[i][1]*s + m_prXVertex[i][2]*c; 00347 m_prXVertex[i][1] = tmpX; 00348 } 00349 GetTransform().SetRotationAxisAngle( 0, Math<T>::ZERO ); 00350 } 00351 if ( Rotation[1] != Math<T>::ZERO ) { 00352 T deg = static_cast<T>( Rotation[1] * Math<T>::PI / 180.0 ); 00353 T c = Math<T>::Cos( deg ); 00354 T s = Math<T>::Sin( deg ); 00355 T tmpX; 00356 for ( i = 0; i < m_iNoVertices; ++i ) { 00357 tmpX = m_prXVertex[i][0]*c + m_prXVertex[i][2]*s; 00358 m_prXVertex[i][2] = -(m_prXVertex[i][0]*s) + m_prXVertex[i][2]*c; 00359 m_prXVertex[i][0] = tmpX; 00360 } 00361 GetTransform().SetRotationAxisAngle( 1, Math<T>::ZERO ); 00362 } 00363 if ( Rotation[2] != Math<T>::ZERO ) { 00364 T deg = static_cast<T>( Rotation[2] * Math<T>::PI / 180.0 ); 00365 T c = Math<T>::Cos( deg ); 00366 T s = Math<T>::Sin( deg ); 00367 T tmpX; 00368 for ( i = 0; i < m_iNoVertices; ++i ) { 00369 tmpX = m_prXVertex[i][0]*c - m_prXVertex[i][1]*s; 00370 m_prXVertex[i][1] = m_prXVertex[i][0]*s + m_prXVertex[i][1]*c; 00371 m_prXVertex[i][0] = tmpX; 00372 } 00373 GetTransform().SetRotationAxisAngle( 2, Math<T>::ZERO ); 00374 } 00375 //-------------------------------------------------------------------- 00376 Vector3<T> Scale = GetTransform().GetScale(); 00377 for ( int d = 0; d < 3; ++d ) { 00378 if ( Scale[d] != Math<T>::ONE ) { 00379 for ( i = 0; i < m_iNoVertices; ++i ) 00380 m_prXVertex[i][d] *= Scale[d]; 00381 GetTransform().SetScale( d, Math<T>::ONE ); 00382 } 00383 } 00384 //-------------------------------------------------------------------- 00385 //*/ 00386 00387 //-------------------------------------------------------------------- 00388 // Set Transformation to Identity Matrix 00389 GetTransform().MakeIdentity(); 00390 //-------------------------------------------------------------------- 00391 // Recalculate Bounding Volume(s) 00392 CalBoundingAABB(); 00393 CalBoundingEllipsoid(); 00394 CalBoundingSphere(); 00395 } 00396 //----------------------------------------------------------------------------- 00397 //****************************************************************************** 00398 00399 //****************************************************************************** 00400 // Virtual Fns from Collision Detection from ColDetSupport class 00401 //****************************************************************************** 00402 //----------------------------------------------------------------------------- 00403 template <typename T> 00404 void XPolygonalModel<T>::CalBoundingAABB () 00405 { 00406 m_paBoundingAABB[0][0] = m_paBoundingAABB[1][0] = m_prXVertex[0][0]; 00407 m_paBoundingAABB[0][1] = m_paBoundingAABB[1][1] = m_prXVertex[0][1]; 00408 m_paBoundingAABB[0][2] = m_paBoundingAABB[1][2] = m_prXVertex[0][2]; 00409 for ( int i = 1; i < m_iNoVertices; ++i ) 00410 { 00411 // Find lowest x, y, and z 00412 if ( m_paBoundingAABB[0][0] > m_prXVertex[i][0] ) 00413 m_paBoundingAABB[0][0] = m_prXVertex[i][0]; 00414 if ( m_paBoundingAABB[0][1] > m_prXVertex[i][1] ) 00415 m_paBoundingAABB[0][1] = m_prXVertex[i][1]; 00416 if ( m_paBoundingAABB[0][2] > m_prXVertex[i][2] ) 00417 m_paBoundingAABB[0][2] = m_prXVertex[i][2]; 00418 // Find highest x, y, and z 00419 if ( m_paBoundingAABB[1][0] < m_prXVertex[i][0] ) 00420 m_paBoundingAABB[1][0] = m_prXVertex[i][0]; 00421 if ( m_paBoundingAABB[1][1] < m_prXVertex[i][1] ) 00422 m_paBoundingAABB[1][1] = m_prXVertex[i][1]; 00423 if ( m_paBoundingAABB[1][2] < m_prXVertex[i][2] ) 00424 m_paBoundingAABB[1][2] = m_prXVertex[i][2]; 00425 } 00426 // Find the bounding volume center 00427 m_pBoundingCenter[0] = ( m_paBoundingAABB[0][0] + m_paBoundingAABB[1][0] ) / 2.0; 00428 m_pBoundingCenter[1] = ( m_paBoundingAABB[0][1] + m_paBoundingAABB[1][1] ) / 2.0; 00429 m_pBoundingCenter[2] = ( m_paBoundingAABB[0][2] + m_paBoundingAABB[1][2] ) / 2.0; 00430 } 00431 //----------------------------------------------------------------------------- 00432 template <typename T> 00433 void XPolygonalModel<T>::CalBoundingEllipsoid () 00434 { 00435 /* 00436 m_pBoundingCenter[0] = ( m_paBoundingAABB[0][0] + m_paBoundingAABB[1][0] ) / 2.0; 00437 m_pBoundingCenter[1] = ( m_paBoundingAABB[0][1] + m_paBoundingAABB[1][1] ) / 2.0; 00438 m_pBoundingCenter[2] = ( m_paBoundingAABB[0][2] + m_paBoundingAABB[1][2] ) / 2.0; 00439 m_pBoundingEllipsoid[0] = fabs( (m_paBoundingAABB[0][0] - m_paBoundingAABB[1][0])/2.0 ); 00440 m_pBoundingEllipsoid[1] = fabs( (m_paBoundingAABB[0][1] - m_paBoundingAABB[1][1])/2.0 ); 00441 m_pBoundingEllipsoid[2] = fabs( (m_paBoundingAABB[0][2] - m_paBoundingAABB[1][2])/2.0 ); 00442 //*/ 00443 00444 /* 00445 T xLength = m_paBoundingAABB[0][0] - m_paBoundingAABB[1][0]; 00446 T yLength = m_paBoundingAABB[0][1] - m_paBoundingAABB[1][1]; 00447 T zLength = m_paBoundingAABB[0][2] - m_paBoundingAABB[1][2]; 00448 xLength *= xLength; 00449 yLength *= yLength; 00450 zLength *= zLength; 00451 m_pBoundingEllipsoid[0] = sqrt( yLength + zLength ) / 2.0; 00452 m_pBoundingEllipsoid[1] = sqrt( zLength + xLength ) / 2.0; 00453 m_pBoundingEllipsoid[2] = sqrt( xLength + yLength ) / 2.0; 00454 //*/ 00455 00456 T x = m_paBoundingAABB[1][0] - m_pBoundingCenter[0]; 00457 x *= x; 00458 T y = m_paBoundingAABB[1][1] - m_pBoundingCenter[1]; 00459 y *= y; 00460 T z = m_paBoundingAABB[1][2] - m_pBoundingCenter[2]; 00461 z *= z; 00462 m_pBoundingEllipsoid[1] = sqrt( y + z ); 00463 m_pBoundingEllipsoid[2] = sqrt( z + x ); 00464 m_pBoundingEllipsoid[0] = sqrt( x + y ); 00465 } 00466 //----------------------------------------------------------------------------- 00467 template <typename T> 00468 void XPolygonalModel<T>::CalBoundingSphere () 00469 { 00470 /* 00471 T xLength = m_paBoundingAABB[0][0] - m_paBoundingAABB[1][0]; 00472 T yLength = m_paBoundingAABB[0][1] - m_paBoundingAABB[1][1]; 00473 T zLength = m_paBoundingAABB[0][2] - m_paBoundingAABB[1][2]; 00474 xLength *= xLength; 00475 yLength *= yLength; 00476 zLength *= zLength; 00477 m_pBoundingSphere = sqrt( xLength + yLength + zLength ) / 2.0; 00478 //*/ 00479 T squaredLength; 00480 m_pBoundingSphere = 0; 00481 for ( int i = 0; i < m_iNoVertices; ++i ) { 00482 squaredLength = (m_prXVertex[i].GetPosition() - m_pBoundingCenter).SquaredLength(); 00483 if ( squaredLength > m_pBoundingSphere ) 00484 m_pBoundingSphere = squaredLength; 00485 } 00486 m_pBoundingSphere = sqrt( m_pBoundingSphere ); 00487 } 00488 //----------------------------------------------------------------------------- 00489 //****************************************************************************** 00490 00491 //----------------------------------------------------------------------------- 00492 //============================================================================= 00493 END_NAMESPACE_TAPs__OpenGL 00494 //----------------------------------------------------------------------------- 00495 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00496 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8