MeshLOD.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 
00022 // MeshLOD.cpp: implementation of the MeshLOD class.
00023 //
00024 //////////////////////////////////////////////////////////////////////
00025 
00026 #include <3dsparse/MeshLOD.h>
00027 #include <3dsparse/MeshLODVector.h>
00028 #include <3dsparse/MeshLODTri.h>
00029 
00030 //////////////////////////////////////////////////////////////////////
00031 // Construction/Destruction
00032 //////////////////////////////////////////////////////////////////////
00033 
00034 namespace MeshLOD
00035 {
00036 /* Start Namespace MeshLOD */
00037 
00038 void addVertices(std::vector<MeshLODVector *> &vertices,
00039                                  std::vector<Vertex *> &verts)
00040 {
00041         for(int i=0; i<(int) verts.size(); i++) 
00042         {
00043                 MeshLODVector *v = new MeshLODVector(verts[i]->position, i);
00044                 vertices.push_back(v);
00045         }
00046 }
00047 
00048 void addTriangles(std::vector<MeshLODVector *> &vertices,
00049                                   std::vector<MeshLODTri*> &triangles,
00050                                   std::vector<Face *> &tri)
00051 {
00052         for(int i=0; i<(int) tri.size(); i++) 
00053         {
00054                 MeshLODTri *t=new MeshLODTri(
00055                                               vertices[tri[i]->v[0]],
00056                                               vertices[tri[i]->v[1]],
00057                                               vertices[tri[i]->v[2]] );
00058                 triangles.push_back(t);
00059         }
00060 }
00061 
00062 MeshLODVector *minimumCostEdge(std::vector<MeshLODVector *> &vertices)
00063 {
00064         // Find the edge that when collapsed will affect model the least.
00065         // This funtion actually returns a Vertex, the second vertex
00066         // of the edge (collapse candidate) is stored in the vertex data.
00067         // Serious optimization opportunity here: this function currently
00068         // does a sequential search through an unsorted list :-(
00069         // Our algorithm could be O(n*lg(n)) instead of O(n*n)
00070         MeshLODVector *mn= vertices.front();
00071 
00072         std::vector<MeshLODVector *>::iterator itor;
00073         for (itor = vertices.begin();
00074                 itor != vertices.end();
00075                 itor++)
00076         {
00077                 if((*itor)->objdist < mn->objdist) 
00078                 {
00079                         mn = *itor;
00080                 }
00081         }
00082 
00083         return mn;
00084 }
00085 
00086 void computeAllEdgeCollapseCosts(std::vector<MeshLODVector *> &vertices)
00087 {
00088         // For all the edges, compute the difference it would make
00089         // to the model if it was collapsed.  The least of these
00090         // per vertex is cached in each vertex object.
00091         std::vector<MeshLODVector *>::iterator itor;
00092         for (itor = vertices.begin();
00093                 itor != vertices.end();
00094                 itor++)
00095         {
00096                 (*itor)->computeEdgeCostAtVertex();
00097         }
00098 }
00099 
00100 void removeVertex(std::vector<MeshLODVector *> &vertices, MeshLODVector *mn)
00101 {
00102         std::vector<MeshLODVector *>::iterator itor;
00103         for (itor = vertices.begin();
00104                 itor != vertices.end();
00105                 itor++)
00106         {
00107                 if (*itor == mn)
00108                 {
00109                         vertices.erase(itor);
00110                         return;
00111                 }
00112         }
00113 }
00114 
00115 void progressiveMesh(std::vector<Vertex *> &verts,
00116                                          std::vector<Face *> &tri,
00117                                          std::vector<int> &map)
00118 {
00119         std::vector<MeshLODVector *> vertices;
00120         std::vector<MeshLODTri*> triangles;
00121 
00122         addVertices(vertices, verts);
00123         addTriangles(vertices, triangles, tri);
00124 
00125         // cache all edge collapse costs
00126         computeAllEdgeCollapseCosts(vertices); 
00127 
00128         // reduce the object down to nothing:
00129         map.resize(vertices.size(), 0);
00130         std::vector<int> permutation;
00131         permutation.resize(vertices.size(), 0);
00132         while(!vertices.empty()) 
00133         {
00134                 // get the next vertex to collapse
00135                 MeshLODVector *mn = minimumCostEdge(vertices);
00136                 // keep track of this vertex, i.e. the collapse ordering
00137                 permutation[mn->id] = ((int) vertices.size()) - 1;
00138                 // keep track of vertex to which we collapse to
00139                 map[vertices.size() - 1] = (mn->collapse)?mn->collapse->id:-1;
00140                 // Collapse this edge
00141                 mn->collapseVertex();
00142 
00143                 removeVertex(vertices, mn);
00144                 delete mn;
00145         }
00146         triangles.clear();
00147 
00148         // reorder the map list based on the collapse ordering
00149         unsigned int i;
00150         for(i=0;i<map.size();i++) 
00151         {
00152                 map[i] = (map[i]==-1)?0:permutation[map[i]];
00153         }
00154 
00155         // Reorder the original vertex list
00156         std::vector<Vertex *> tmpVerts;
00157         for(i=0;i<verts.size();i++) 
00158         {
00159                 tmpVerts.push_back(verts[i]);
00160         }
00161         for(i=0; i<verts.size(); i++) 
00162         {
00163                 int j = permutation[i];
00164                 verts[j] = tmpVerts[i];
00165         }
00166 
00167         // Reindex the face list
00168         for (i=0; i<tri.size(); i++)
00169         {
00170                 for (int j=0; j<3; j++)
00171                 {
00172                         tri[i]->v[j] = permutation[tri[i]->v[j]];
00173                 }
00174         }
00175 }
00176 
00177 /* End Namespace MeshLOD */
00178 }

Generated on Mon Feb 16 15:14:48 2009 for Scorched3D by  doxygen 1.5.3