TAPs 0.7.7.3
TAPsHalfEdgeTrigonalModel.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines