![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsHalfEdgeModel.cpp 00003 00004 HalfEdgeTrigonalModel, a subclass of HalfEdgeModel, is for a triangular mesh. 00005 (See HalfEdgeTrigonalModel.hpp for details) 00006 00007 SUKITTI PUNAK (06/15/2006) 00008 UPDATE (06/15/2006) 00009 ******************************************************************************/ 00010 #include "TAPsHalfEdgeTrigonalModel.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 //----------------------------------------------------------------------------- 00016 // DEBUG ENABLE 00017 #ifdef TAPs_ENABLE_DEBUG 00018 #define DEBUG_MESSAGE_TAPs_HALF_EDGE_TRIGONAL_MODEL 00019 #endif 00020 00021 //#ifndef 00022 //#define DEBUG_MESSAGE_TAPs_HALF_EDGE_MODEL 00023 //#endif 00024 //----------------------------------------------------------------------------- 00025 00026 BEGIN_NAMESPACE_TAPs__OpenGL 00027 //============================================================================= 00028 //----------------------------------------------------------------------------- 00029 // default constructor 00030 template <typename T> 00031 HalfEdgeTrigonalModel<T>::HalfEdgeTrigonalModel () 00032 : HalfEdgeModel<T>() 00033 {} 00034 //----------------------------------------------------------------------------- 00035 // destructor 00036 template <typename T> 00037 HalfEdgeTrigonalModel<T>::~HalfEdgeTrigonalModel () 00038 { 00039 #ifdef DEBUG_MESSAGE_TAPs_HALF_EDGE_TRIGONAL_MODEL 00040 std::cout << "HalfEdgeTrigonalModel<" << typeid(T).name() << "> Destructor\n"; 00041 #endif 00042 } 00043 //----------------------------------------------------------------------------- 00044 // Initialize 00045 // a virtual fn from Model class 00046 template <typename T> 00047 void HalfEdgeTrigonalModel<T>::Initialize () 00048 { 00049 // Model Initialization 00050 CalAndSetNormals(); 00051 ApplyMaterial(); 00052 CalBoundingAABB(); 00053 CalBoundingEllipsoid(); 00054 CalBoundingSphere(); 00055 00056 // For Fast Access 00057 //SetListOfVertexPositionsAndNormals(); 00058 00059 /* 00060 std::cout << *this << std::endl; 00061 //*/ 00062 } 00063 /* 00064 //----------------------------------------------------------------------------- 00065 // Get Half Length 00066 template <typename T> 00067 T HalfEdgeTrigonalModel<T>::GetMaxHalfLength () const 00068 { 00069 T maxHalfSize = 0.0; 00070 HEVertex<T> *ptr = m_listVertex->Head(); 00071 while ( ptr != NULL ) { 00072 if ( fabs( (*ptr)[0] ) > maxHalfSize ) 00073 maxHalfSize = fabs( (*ptr)[0] ); 00074 if ( fabs( (*ptr)[1] ) > maxHalfSize ) 00075 maxHalfSize = fabs( (*ptr)[1] ); 00076 if ( fabs( (*ptr)[2] ) > maxHalfSize ) 00077 maxHalfSize = fabs( (*ptr)[2] ); 00078 ptr = ptr->Next(); 00079 } 00080 return maxHalfSize; 00081 } 00082 //*/ 00083 //----------------------------------------------------------------------------- 00084 // Calculate and set the normals 00085 template <typename T> 00086 void HalfEdgeTrigonalModel<T>::CalAndSetNormals () 00087 { 00088 CalAndSetFaceNormalsNotNormalized(); 00089 // DetermineFaceRings(); 00090 CalAndSetVertexNormals(); 00091 NormalizeFaceNormals(); 00092 } 00093 //----------------------------------------------------------------------------- 00094 // Calculate and set the face normals (without normalized) 00095 template <typename T> 00096 void HalfEdgeTrigonalModel<T>::CalAndSetFaceNormalsNotNormalized () 00097 { 00098 // Calculate and set the normal of each face 00099 HEFace<T> * face = m_listFace->Head(); 00100 while ( face != NULL ) { 00101 Vector3<T> const & v0 = face->IncidentHalfEdge()->Prev()->Vertex()->GetPosition(); 00102 Vector3<T> const & v1 = face->IncidentHalfEdge()->Vertex()->GetPosition(); 00103 Vector3<T> const & v2 = face->IncidentHalfEdge()->Next()->Vertex()->GetPosition(); 00104 face->SetNormal( (v1 - v0) ^ (v2 - v1) ); 00105 face = face->Next(); 00106 } 00107 00108 /* 00109 for ( int i = 0; i < m_iNoFaces; ++i ) { 00110 m_prFace[i].SetNormal( 00111 ( m_prXVertex[ m_prFace[i].GetVertexNo( 1 ) ].GetPosition() 00112 - m_prXVertex[ m_prFace[i].GetVertexNo( 0 ) ].GetPosition() ) 00113 ^ ( m_prXVertex[ m_prFace[i].GetVertexNo( 2 ) ].GetPosition() 00114 - m_prXVertex[ m_prFace[i].GetVertexNo( 1 ) ].GetPosition() ) 00115 ); 00116 } 00117 */ 00118 } 00119 //----------------------------------------------------------------------------- 00120 // Normalize the face normals 00121 template <typename T> 00122 inline void HalfEdgeTrigonalModel<T>::NormalizeFaceNormals () 00123 { 00124 // Normalize the normal of each face 00125 HEFace<T> * face = m_listFace->Head(); 00126 while ( face != NULL ) { 00127 const_cast< Vector3<T> * >( &face->GetNormal() )->Normalized(); 00128 face = face->Next(); 00129 } 00130 00131 //for ( int i = 0; i < m_iNoFaces; ++i ) { 00132 // const_cast< Vector3<T> * >( &m_prFace[i].GetNormal() )->Normalized(); 00133 // //m_prFace[i].GetNormal().Normalized(); 00134 //} 00135 } 00136 //----------------------------------------------------------------------------- 00137 // Calculate and set the vertex normals 00138 template <typename T> 00139 inline void HalfEdgeTrigonalModel<T>::CalAndSetVertexNormals () 00140 { 00141 HEVertex<T> *vertex = m_listVertex->Head(); 00142 HEHalfEdge<T> *halfEdge; 00143 #ifdef DEBUG_MESSAGE_TAPs_HALF_EDGE_TRIGONAL_MODEL 00144 std::cout << "FIND VERTEX NORMAL" << std::endl; 00145 #endif 00146 while ( vertex ) { 00147 Vector3<T> vNormal; 00148 halfEdge = vertex->IncidentHalfEdge(); 00149 #ifdef DEBUG_MESSAGE_TAPs_HALF_EDGE_TRIGONAL_MODEL_HPP 00150 std::cout << *halfEdge << std::endl; 00151 #endif 00152 /* 00153 if ( halfEdge->Pair()->Next() != NULL ) { 00154 do { 00155 vNormal += halfEdge->Face()->GetNormal(); 00156 halfEdge = halfEdge->Pair()->Next(); 00157 } while ( halfEdge != vertex->IncidentHalfEdge() ); 00158 } 00159 else { 00160 do { 00161 vNormal += halfEdge->Face()->GetNormal(); 00162 halfEdge = halfEdge->Pair()->Prev(); 00163 } while ( halfEdge != vertex->IncidentHalfEdge() ); 00164 } 00165 //*/ 00166 //* 00167 vNormal = Vector3<T>(0,0,0); 00168 int count1 = 0; 00169 int count2 = 0; 00170 do { 00171 vNormal += halfEdge->Face()->GetNormal(); 00172 halfEdge = halfEdge->Pair()->Next(); 00173 // Cannot use previous, because of half-edge data structure 00174 //halfEdge = halfEdge->Pair()->Prev(); 00175 //if ( halfEdge == NULL ) { 00176 // std::cout << "--------------------=================>>>>>>> NULL\n"; 00177 //assert( false ); 00178 // break; 00179 //} 00180 } while ( halfEdge != vertex->IncidentHalfEdge() ); 00181 //*/ 00182 vertex->SetNormal( vNormal.Normalized() ); 00183 vertex = vertex->Next(); 00184 } 00185 00186 /* 00187 for ( int v = 0; v < m_iNoVertices; ++v ) { 00188 Vector3<T> vNormal; 00189 for ( int f = 0; f < static_cast<int>( m_prXVertex[v].GetFaceRing().size() ); ++f ) { 00190 vNormal += m_prFace[ m_prXVertex[v].GetFaceRing()[f] ].GetNormal(); 00191 } 00192 m_prXVertex[v].SetNormal( vNormal.Normalized() ); 00193 } 00194 */ 00195 } 00196 00197 /* 00198 //****************************************************************************** 00199 // Transformation by Model's translation, rotation, and scale 00200 //****************************************************************************** 00201 //----------------------------------------------------------------------------- 00202 template <typename T> 00203 void HalfEdgeTrigonalModel<T>::TransformByTranslationRatationAndScale () 00204 { 00205 HEVertex<T> * heVertex = GetVertexList()->Head(); 00206 //-------------------------------------------------------------------- 00207 // Adjust Center of X-, Y-, And Z-Axes 00208 Vector3<T> vTransform = GetTransform().GetTranslation(); 00209 if ( vTransform.SquaredLength() > Math<T>::ZERO ) { 00210 while ( heVertex ) { 00211 heVertex->SetPosition( heVertex->GetPosition() + vTransform ); 00212 heVertex = heVertex->Next(); 00213 } 00214 GetTransform().SetTranslation( Math<T>::ZERO, Math<T>::ZERO, Math<T>::ZERO ); 00215 } 00216 //-------------------------------------------------------------------- 00217 // Adjust Rotation of X-, Y-, And Z-Axes 00218 vTransform = GetTransform().GetRotationAngles(); 00219 Vector3<T> vPos; 00220 if ( vTransform[0] != Math<T>::ZERO ) { 00221 T deg = static_cast<T>( vTransform[0] * Math<T>::PI / 180.0 ); 00222 T c = Math<T>::Cos( deg ); 00223 T s = Math<T>::Sin( deg ); 00224 heVertex = GetVertexList()->Head(); 00225 while ( heVertex ) { 00226 vPos = heVertex->GetPosition(); 00227 heVertex->SetPosition( vPos[0], vPos[1]*c - vPos[2]*s, vPos[1]*s + vPos[2]*c ) ; 00228 heVertex = heVertex->Next(); 00229 } 00230 //GetTransform().SetRotationAxisAngle( 0, Math<T>::ZERO ); 00231 } 00232 if ( vTransform[1] != Math<T>::ZERO ) { 00233 T deg = static_cast<T>( vTransform[1] * Math<T>::PI / 180.0 ); 00234 T c = Math<T>::Cos( deg ); 00235 T s = Math<T>::Sin( deg ); 00236 heVertex = GetVertexList()->Head(); 00237 while ( heVertex ) { 00238 vPos = heVertex->GetPosition(); 00239 heVertex->SetPosition( vPos[0]*c + vPos[2]*s, vPos[1], vPos[2]*c - vPos[0]*s ); 00240 heVertex = heVertex->Next(); 00241 } 00242 //GetTransform().SetRotationAxisAngle( 1, Math<T>::ZERO ); 00243 } 00244 if ( vTransform[2] != Math<T>::ZERO ) { 00245 T deg = static_cast<T>( vTransform[2] * Math<T>::PI / 180.0 ); 00246 T c = Math<T>::Cos( deg ); 00247 T s = Math<T>::Sin( deg ); 00248 heVertex = GetVertexList()->Head(); 00249 while ( heVertex ) { 00250 vPos = heVertex->GetPosition(); 00251 heVertex->SetPosition( vPos[0]*c - vPos[1]*s, vPos[0]*s + vPos[1]*c, vPos[2] ); 00252 heVertex = heVertex->Next(); 00253 } 00254 //GetTransform().SetRotationAxisAngle( 2, Math<T>::ZERO ); 00255 } 00256 //-------------------------------------------------------------------- 00257 // Adjust Scale of X-, Y-, And Z-Axes 00258 vTransform = GetTransform().GetScale(); 00259 heVertex = GetVertexList()->Head(); 00260 //if ( vTransform.SquaredLength() > Math<T>::ZERO ) {} 00261 while ( heVertex ) { 00262 heVertex->SetPosition( 00263 heVertex->GetPosition()[0] * vTransform[0], 00264 heVertex->GetPosition()[1] * vTransform[1], 00265 heVertex->GetPosition()[2] * vTransform[2] 00266 ); 00267 heVertex = heVertex->Next(); 00268 } 00269 //-------------------------------------------------------------------- 00270 // Reset Transformation 00271 GetTransform().Reset(); 00272 //-------------------------------------------------------------------- 00273 // Recalculate Bounding Volume(s) 00274 CalBoundingAABB(); 00275 CalBoundingEllipsoid(); 00276 CalBoundingSphere(); 00277 } 00278 //----------------------------------------------------------------------------- 00279 //****************************************************************************** 00280 //*/ 00281 00282 //****************************************************************************** 00283 // Virtual Fns from Collision Detection from ColDetSupport class 00284 //****************************************************************************** 00285 /* 00286 //----------------------------------------------------------------------------- 00287 template <typename T> 00288 void HalfEdgeTrigonalModel<T>::CalBoundingAABB () 00289 { 00290 HEVertex<T> *vertex = m_listVertex->Head(); 00291 m_paBoundingAABB[0] = m_paBoundingAABB[1] = vertex->GetPosition(); 00292 while ( vertex ) { 00293 // Find lowest x, y, and z 00294 if ( m_paBoundingAABB[0][0] > (*vertex)[0] ) 00295 m_paBoundingAABB[0][0] = (*vertex)[0]; 00296 if ( m_paBoundingAABB[0][1] > (*vertex)[1] ) 00297 m_paBoundingAABB[0][1] = (*vertex)[1]; 00298 if ( m_paBoundingAABB[0][2] > (*vertex)[2] ) 00299 m_paBoundingAABB[0][2] = (*vertex)[2]; 00300 // Find highest x, y, and z 00301 if ( m_paBoundingAABB[1][0] < (*vertex)[0] ) 00302 m_paBoundingAABB[1][0] = (*vertex)[0]; 00303 if ( m_paBoundingAABB[1][1] < (*vertex)[1] ) 00304 m_paBoundingAABB[1][1] = (*vertex)[1]; 00305 if ( m_paBoundingAABB[1][2] < (*vertex)[2] ) 00306 m_paBoundingAABB[1][2] = (*vertex)[2]; 00307 // Next vertex 00308 vertex = vertex->Next(); 00309 } 00310 // Find the bounding volume center 00311 m_pBoundingCenter[0] = ( m_paBoundingAABB[0][0] + m_paBoundingAABB[1][0] ) / 2.0; 00312 m_pBoundingCenter[1] = ( m_paBoundingAABB[0][1] + m_paBoundingAABB[1][1] ) / 2.0; 00313 m_pBoundingCenter[2] = ( m_paBoundingAABB[0][2] + m_paBoundingAABB[1][2] ) / 2.0; 00314 } 00315 //----------------------------------------------------------------------------- 00316 template <typename T> 00317 void HalfEdgeTrigonalModel<T>::CalBoundingEllipsoid () 00318 { 00319 T x = m_paBoundingAABB[1][0] - m_pBoundingCenter[0]; 00320 x *= x; 00321 T y = m_paBoundingAABB[1][1] - m_pBoundingCenter[1]; 00322 y *= y; 00323 T z = m_paBoundingAABB[1][2] - m_pBoundingCenter[2]; 00324 z *= z; 00325 m_pBoundingEllipsoid[1] = sqrt( y + z ); 00326 m_pBoundingEllipsoid[2] = sqrt( z + x ); 00327 m_pBoundingEllipsoid[0] = sqrt( x + y ); 00328 } 00329 //----------------------------------------------------------------------------- 00330 template <typename T> 00331 void HalfEdgeTrigonalModel<T>::CalBoundingSphere () 00332 { 00333 T squaredLength; 00334 m_pBoundingSphere = 0; 00335 HEVertex<T> *vertex = m_listVertex->Head(); 00336 while ( vertex ) { 00337 squaredLength = (vertex->GetPosition() - m_pBoundingCenter).SquaredLength(); 00338 if ( squaredLength > m_pBoundingSphere ) 00339 m_pBoundingSphere = squaredLength; 00340 // Next vertex 00341 vertex = vertex->Next(); 00342 } 00343 m_pBoundingSphere = sqrt( m_pBoundingSphere ); 00344 } 00345 //*/ 00346 //----------------------------------------------------------------------------- 00347 // Create BVHTree 00348 template <typename T> 00349 void HalfEdgeTrigonalModel<T>::BuildBVHTree ( TAPs::Enum::CD treeType ) 00350 { 00351 // Call a static fn from BVHTree class 00352 // m_pBVHTree is inherited from ColDetSupport class 00353 m_pBVHTree = TAPs::CD::BuildBVHTree<T>( GetTransform(), m_listFace, treeType ); 00354 } 00355 //----------------------------------------------------------------------------- 00356 //****************************************************************************** 00357 00358 /* 00359 //****************************************************************************** 00360 // For Fast Access (e.g. for OpenGL Drawing) 00361 //****************************************************************************** 00362 //----------------------------------------------------------------------------- 00363 // SetListOfVertexPositions 00364 template <typename T> 00365 void HalfEdgeTrigonalModel<T>::SetListOfVertexPositionsAndNormals () 00366 { 00367 m_vListOfVertexPositions.clear(); 00368 m_vListOfVertexNormals.clear(); 00369 HEVertex<T> * vertex = m_listVertex->Head(); 00370 while ( vertex ) { 00371 m_vListOfVertexPositions.push_back( &(vertex->GetPosition()) ); 00372 m_vListOfVertexNormals.push_back( &(vertex->GetNormal()) ); 00373 vertex = vertex->Next(); 00374 } 00375 } 00376 //----------------------------------------------------------------------------- 00377 //****************************************************************************** 00378 //*/ 00379 00380 //----------------------------------------------------------------------------- 00381 //============================================================================= 00382 END_NAMESPACE_TAPs__OpenGL 00383 //----------------------------------------------------------------------------- 00384 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00385 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8