K3dConvex.cpp

Go to the documentation of this file.
00001 
00013 /***************************************************************************
00014  *   Copyright (C) 2007 by Jan Koci   *
00015  *   honza.koci@email.cz   *
00016  *   http://kengine.sourceforge.net/tutorial/
00017  *                                                                         *
00018  *   This program is free software; you can redistribute it and/or modify  *
00019  *   it under the terms of the GNU General Public License as published by  *
00020  *   the Free Software Foundation; either version 2 of the License, or     *
00021  *   (at your option) any later version.                                   *
00022  *                                                                         *
00023  *   This program is distributed in the hope that it will be useful,       *
00024  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00025  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00026  *   GNU General Public License for more details.                          *
00027  *                                                                         *
00028  *   You should have received a copy of the GNU General Public License     *
00029  *   along with this program; if not, write to the                         *
00030  *   Free Software Foundation, Inc.,                                       *
00031  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00032  ***************************************************************************/
00033 
00034 
00035 
00036 #include "K3dConvex.h"
00037 
00038 K3dConvex::K3dConvex(K3dGameData *_pGameData)
00039 {
00040         m_pGameData = _pGameData;
00041         m_vPolyPlane.clear();
00042         m_vEdge.clear();
00043         m_vVertex.clear();
00044         m_pPolyPlane = NULL;
00045         m_pEdgePlane = NULL;
00046         InitConvex();
00047 }
00048 
00049 K3dConvex::~K3dConvex()
00050 {
00051 }
00052 
00054 void K3dConvex::InitConvex()
00055 {
00056         if(m_pGameData->GetPlaneObjSP().FindPointer(m_pEdgePlane) == false)
00057         {
00058                 m_pEdgePlane = m_pGameData->GetPlaneBuild()->CreateNewPlaneObj();
00059         }       
00060 }
00061 
00064 bool K3dConvex::CheckConvexPlane()
00065 {
00066         // Delete on plane vertex array
00067         m_pPolyPlane->GetOnPlaneVertexArray().clear();
00068         // Go through all vertices
00069         for(size_t i=0; i<m_vVertex.size(); i++)
00070         {
00071                 // Get vertex
00072                 K3dVertexObj *pVertex = m_vVertex[i];
00073                 // Calculate distance between plane and point
00074                 int iDistance = (int) m_pGameData->GetIntersection()->PointPlane(*m_pPolyPlane, *pVertex->GetPosition());
00075                 // If distance is positive, vertex is on the front side of the plane, return false
00076                 if(iDistance > 0)
00077                 {
00078                         return false;
00079                 }
00080                 // If distance is zero, add vertex to the on plane vertex array
00081                 else if(iDistance == 0)
00082                 {
00083                         m_pPolyPlane->GetOnPlaneVertexArray().push_back(pVertex->GetPosition());
00084                 }
00085         }
00086         // Return true if all vertices are on the plane or on the back side of the plane
00087         return true;
00088 }
00089 
00094 void K3dConvex::CreateConvexPlane(const K3dVector3Obj &_rkV0,const K3dVector3Obj &_rkV1,const K3dVector3Obj &_rkV2)
00095 {
00096         // Create plane from three vertices
00097         m_pPolyPlane = m_pGameData->GetPolyPlaneBuild()->CreateNewPolyPlaneObj(_rkV0,_rkV1,_rkV2);
00098         // Add plane to the plane array if plane distance doesn`t zero
00099         if(m_pPolyPlane->GetDistance() != (float) 0)
00100         {
00101                 // Compare plane with plane array if plane doesnt`t exist in plane array
00102                 if(!m_pGameData->GetPlaneWork()->ComparePlane(m_pPolyPlane, m_vPolyPlane))
00103                 {
00104                         // If plane is convex plane
00105                         if(CheckConvexPlane())
00106                         {
00107                                 m_vPolyPlane.push_back(m_pPolyPlane);
00108                         }
00109                 }
00110         }
00111 }
00112 
00114 void K3dConvex::CheckEdge(const K3dVector3Obj *_pV0,const K3dVector3Obj *_pV1)
00115 {
00116         // Front and back side switches
00117         bool bIsFront = false;
00118         bool bIsBack = false;
00119         // Go through all other vertices
00120         for(size_t i=0; i<m_pPolyPlane->GetOnPlaneVertexArray().size(); i++)
00121         {
00122                 K3dVector3Obj *pV2 = m_pPolyPlane->GetOnPlaneVertexArray()[i];
00123                 if((pV2 != _pV0) && (pV2 != _pV1))
00124                 {
00125                         // Calculate distance between point and plane
00126                         float fDistance = m_pGameData->GetIntersection()->PointPlane(*m_pEdgePlane, *pV2);
00127                         if(fDistance > 0)
00128                         {
00129                                 bIsFront = true;
00130                         }
00131                         if(fDistance < 0)
00132                         {
00133                                 bIsBack = true;
00134                         }
00135                 }
00136         }
00137         // If all vertices are on front or back side
00138         if(bIsFront != bIsBack)
00139         {
00140                 // Create front edge
00141                 K3dLineObj *pEdge = m_pGameData->GetLineBuild()->CreateNewLineObj(*_pV0, *_pV1);
00142                 // Add edge to the edge array
00143                 m_vEdge.push_back(pEdge);
00144         }
00145 }
00146 
00148 void K3dConvex::CreateOnPlaneEdges()
00149 {
00150         // Go through all other vertices
00151         for(size_t iV0=0; iV0<m_pPolyPlane->GetOnPlaneVertexArray().size(); iV0++)
00152         {
00153                 // Get first vertex
00154                 K3dVector3Obj *pV0 = m_pPolyPlane->GetOnPlaneVertexArray()[iV0];
00155                 for(size_t iV1=iV0+1; iV1<m_pPolyPlane->GetOnPlaneVertexArray().size(); iV1++)
00156                 {
00157                         // Get second vertex
00158                         K3dVector3Obj *pV1 = m_pPolyPlane->GetOnPlaneVertexArray()[iV1];
00159                         // Calculate direction vector
00160                         K3dVector3Obj kDirection = *pV1 - *pV0;
00161                         // Calculate cross product between direction and plane normal
00162                         kDirection = m_pGameData->GetVector3Work()->UnitCross(kDirection, *m_pPolyPlane->GetNormal());
00163                         kDirection = m_pGameData->GetVector3Work()->Normalize(kDirection);
00164                         // Create plane from line origin direction normal vector
00165                         m_pGameData->GetPlaneWork()->CalcPlane(m_pEdgePlane, *pV0, kDirection);
00166                         // Test edge. If all other vertices are on front or back plane side, than add edge to the edge array
00167                         CheckEdge(pV0, pV1);
00168                 }
00169         }
00170 }
00171 
00173 void K3dConvex::CreateEdgesFromVertexArray()
00174 {
00175         // Clear previous edge array
00176         m_vEdge.clear();
00177         // Go through all convex planes and create edges from on plane vertices
00178         for(size_t i=0; i<m_vPolyPlane.size(); i++)
00179         {
00180                 m_pPolyPlane = m_vPolyPlane[i];
00181                 CreateOnPlaneEdges();
00182         }
00183 }
00184 
00187 void K3dConvex::CreateResultVertexArray()
00188 {
00189         TVertexArray vResultVertex;
00190         // Go through all verices
00191         for(size_t iV=0; iV<m_vVertex.size(); iV++)
00192         {
00193                 // Get vertex
00194                 K3dVertexObj *pV = m_vVertex[iV];
00195                 // Compare vertex with line origin and direction vector
00196                 for(size_t iE=0; iE<m_vEdge.size(); iE++)
00197                 {
00198                         K3dLineObj *pEdge = m_vEdge[iE];
00199                         if((*pV->GetPosition() == *pEdge->GetOrigin()) || (*pV->GetPosition() == *pEdge->GetDirection()))
00200                         {
00201                                 // Add Vertex to the result vertex
00202                                 vResultVertex.push_back(pV);
00203                                 break;
00204                         }
00205                         
00206                 }
00207         }
00208         // Set new vertex array from result vertex array
00209         m_vVertex = vResultVertex;
00210 }
00211 
00214 K3dPolyObj *K3dConvex::CreatePolyFromVertexArray(const TVertexArray &_rvVertex)
00215 {
00216         // Create temp vertex array
00217         m_vVertex = _rvVertex;
00218         // Delete duplicated vertices from vertex array
00219         m_pGameData->GetVertexWork()->DeleteDupVerts(m_vVertex);
00220         K3dPolyObj *pPoly = m_pGameData->GetPolyBuild()->CreateNewPolyObj();
00221         //Get arbitrary three vertices from vertex array and create planes.
00222         for(size_t iV0=0; iV0<m_vVertex.size(); iV0++)
00223         {
00224                 // Get first vertex
00225                 K3dVertexObj *pVertex0 = m_vVertex[iV0];
00226                 for(size_t iV1=iV0+1; iV1<m_vVertex.size(); iV1++)
00227                 {
00228                         // Get second vertex
00229                         K3dVertexObj *pVertex1 = m_vVertex[iV1];
00230                         for(size_t iV2=iV1+1; iV2<m_vVertex.size(); iV2++)
00231                         {
00232                                 // Get third vertex
00233                                 K3dVertexObj *pVertex2 = m_vVertex[iV2];
00234                                 // Create convex plane from three vertices
00235                                 CreateConvexPlane(*pVertex0->GetPosition(),*pVertex1->GetPosition(),*pVertex2->GetPosition());
00236                                 // Create oposite convex plane from three vertices 
00237                                 CreateConvexPlane(*pVertex1->GetPosition(),*pVertex0->GetPosition(),*pVertex2->GetPosition());
00238                         }
00239                 }
00240         }
00241         // Create polyhedron edges from vertex array
00242         CreateEdgesFromVertexArray();
00243         // Delete duplicated edges from edge array
00244         m_pGameData->GetLineWork()->DeleteDupLines(m_vEdge);
00245         // Compare vertex array with all edges and if vertex is equal with one of edge origin
00246         // or direction vector add this vertex to result vertex array
00247         CreateResultVertexArray();
00248         // Set result polyhedron
00249         pPoly->GetVertexArray() = m_vVertex;
00250         pPoly->GetEdgeArray() = m_vEdge;
00251         pPoly->GetPlaneArray() = m_vPolyPlane;
00252         m_pGameData->GetPolyWork()->CheckPoly(pPoly);
00253         m_pGameData->GetPolyWork()->VisiblePoly(pPoly);
00254         return pPoly;
00255 }
00256 
00257 

Generated on Thu Aug 16 23:53:29 2007 for K3dEngine by  doxygen 1.5.0