OgreProgressiveMeshGenerator.h
Go to the documentation of this file.
00001 /*
00002  * -----------------------------------------------------------------------------
00003  * This source file is part of OGRE
00004  * (Object-oriented Graphics Rendering Engine)
00005  * For the latest info, see http://www.ogre3d.org/
00006  *
00007  * Copyright (c) 2000-2013 Torus Knot Software Ltd
00008  *
00009  * Permission is hereby granted, free of charge, to any person obtaining a copy
00010  * of this software and associated documentation files (the "Software"), to deal
00011  * in the Software without restriction, including without limitation the rights
00012  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00013  * copies of the Software, and to permit persons to whom the Software is
00014  * furnished to do so, subject to the following conditions:
00015  *
00016  * The above copyright notice and this permission notice shall be included in
00017  * all copies or substantial portions of the Software.
00018  *
00019  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00020  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00022  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00023  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00024  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00025  * THE SOFTWARE.
00026  * -----------------------------------------------------------------------------
00027  */
00028 
00029 #ifndef __ProgressiveMeshGenerator_H_
00030 #define __ProgressiveMeshGenerator_H_
00031 
00032 #include "OgrePrerequisites.h"
00033 #include "OgreVector3.h"
00034 #include "OgreSmallVector.h"
00035 #include "OgreMesh.h"
00036 #include "OgreLodConfig.h"
00037 #include "OgreLogManager.h"
00038 
00039 namespace Ogre
00040 {
00041 
00042 class _OgreExport ProgressiveMeshGeneratorBase
00043 {
00044 public:
00050     virtual void generateLodLevels(LodConfig& lodConfig) = 0;
00051 
00057     virtual void generateAutoconfiguredLodLevels(MeshPtr& mesh);
00058 
00065     virtual void getAutoconfig(MeshPtr& inMesh, LodConfig& outLodConfig);
00066 
00067     virtual ~ProgressiveMeshGeneratorBase() { }
00068 };
00069 
00073 class _OgreExport ProgressiveMeshGenerator :
00074     public ProgressiveMeshGeneratorBase
00075 {
00076 public:
00077 
00078     ProgressiveMeshGenerator();
00079     virtual ~ProgressiveMeshGenerator();
00080 
00082     void generateLodLevels(LodConfig& lodConfig);
00083 
00084 protected:
00085 
00086     // VectorSet is basically a helper to use a vector as a small set container.
00087     // Also these functions keep the code clean and fast.
00088     // You can insert in O(1) time, if you know that it doesn't exists.
00089     // You can remove in O(1) time, if you know the position of the item.
00090     template<typename T, unsigned S>
00091     struct _OgrePrivate VectorSet :
00092         public SmallVector<T, S> {
00093         typedef typename SmallVector<T, S>::iterator iterator;
00094 
00095         void addNotExists(const T& item); // Complexity: O(1)!!
00096         void remove(iterator it); // Complexity: O(1)!!
00097         iterator add(const T& item); // Complexity: O(N)
00098         void removeExists(const T& item); // Complexity: O(N)
00099         bool remove(const T& item); // Complexity: O(N)
00100         void replaceExists(const T& oldItem, const T& newItem); // Complexity: O(N)
00101         bool has(const T& item); // Complexity: O(N)
00102         iterator find(const T& item); // Complexity: O(N)
00103         iterator findExists(const T& item); // Complexity: O(N)
00104     };
00105 
00106     struct PMEdge;
00107     struct PMVertex;
00108     struct PMTriangle;
00109     struct PMVertexHash;
00110     struct PMVertexEqual;
00111     struct PMCollapseCostLess;
00112     struct PMCollapsedEdge;
00113     struct PMIndexBufferInfo;
00114 
00115     typedef vector<PMVertex>::type VertexList;
00116     typedef vector<PMTriangle>::type TriangleList;
00117     typedef HashSet<PMVertex*, PMVertexHash, PMVertexEqual> UniqueVertexSet;
00118     typedef multimap<Real, PMVertex*>::type CollapseCostHeap;
00119     typedef vector<PMVertex*>::type VertexLookupList;
00120 
00121     typedef VectorSet<PMEdge, 8> VEdges;
00122     typedef VectorSet<PMTriangle*, 7> VTriangles;
00123 
00124     typedef vector<PMCollapsedEdge>::type CollapsedEdges;
00125     typedef vector<PMIndexBufferInfo>::type IndexBufferInfoList;
00126 
00127     // Hash function for UniqueVertexSet.
00128     struct _OgrePrivate PMVertexHash {
00129         ProgressiveMeshGenerator* mGen;
00130 
00131         PMVertexHash() { assert(0); }
00132         PMVertexHash(ProgressiveMeshGenerator* gen) { mGen = gen; }
00133         size_t operator() (const PMVertex* v) const;
00134     };
00135 
00136     // Equality function for UniqueVertexSet.
00137     struct _OgrePrivate PMVertexEqual {
00138         bool operator() (const PMVertex* lhs, const PMVertex* rhs) const;
00139     };
00140 
00141     // Directed edge
00142     struct _OgrePrivate PMEdge {
00143         PMVertex* dst;
00144         Real collapseCost;
00145         int refCount;
00146 
00147         explicit PMEdge(PMVertex* destination);
00148         bool operator== (const PMEdge& other) const;
00149         PMEdge& operator= (const PMEdge& b);
00150         PMEdge(const PMEdge& b);
00151         bool operator< (const PMEdge& other) const;
00152     };
00153 
00154     struct _OgrePrivate PMVertex {
00155         Vector3 position;
00156         VEdges edges;
00157         VTriangles triangles; 
00158 
00159         PMVertex* collapseTo;
00160         bool seam;
00161         CollapseCostHeap::iterator costHeapPosition; 
00162     };
00163 
00164     struct _OgrePrivate PMTriangle {
00165         PMVertex* vertex[3];
00166         Vector3 normal;
00167         bool isRemoved;
00168         unsigned short submeshID; 
00169         unsigned int vertexID[3]; 
00170 
00171         void computeNormal();
00172         bool hasVertex(const PMVertex* v) const;
00173         unsigned int getVertexID(const PMVertex* v) const;
00174         bool isMalformed();
00175     };
00176 
00177     struct _OgrePrivate PMIndexBufferInfo {
00178         size_t indexSize;
00179         size_t indexCount;
00180     };
00181 
00182     union _OgrePrivate IndexBufferPointer {
00183         unsigned short* pshort;
00184         unsigned int* pint;
00185     };
00186 
00187     struct _OgrePrivate PMCollapsedEdge {
00188         unsigned int srcID;
00189         unsigned int dstID;
00190         unsigned short submeshID;
00191     };
00192 
00193     VertexLookupList mSharedVertexLookup;
00194     VertexLookupList mVertexLookup;
00195     VertexList mVertexList;
00196     TriangleList mTriangleList;
00197     UniqueVertexSet mUniqueVertexSet;
00198     CollapseCostHeap mCollapseCostHeap;
00199     CollapsedEdges tmpCollapsedEdges; // Tmp container used in collapse().
00200     IndexBufferInfoList mIndexBufferInfoList;
00201 
00202     MeshPtr mMesh;
00203 
00204 #ifndef NDEBUG
00205 
00210     String mMeshName;
00211 #endif
00212     Real mMeshBoundingSphereRadius;
00213     Real mCollapseCostLimit;
00214 
00215     size_t calcLodVertexCount(const LodLevel& lodConfig);
00216     void tuneContainerSize();
00217     void addVertexData(VertexData* vertexData, bool useSharedVertexLookup);
00218     void addIndexData(IndexData* indexData, bool useSharedVertexLookup, unsigned short submeshID);
00219     template<typename IndexType>
00220     void addIndexDataImpl(IndexType* iPos, const IndexType* iEnd,
00221                                                     VertexLookupList& lookup,
00222                                                     unsigned short submeshID)
00223     {
00224 
00225         // Loop through all triangles and connect them to the vertices.
00226         for (; iPos < iEnd; iPos += 3) {
00227             // It should never reallocate or every pointer will be invalid.
00228             OgreAssert(mTriangleList.capacity() > mTriangleList.size(), "");
00229             mTriangleList.push_back(PMTriangle());
00230             PMTriangle* tri = &mTriangleList.back();
00231             tri->isRemoved = false;
00232             tri->submeshID = submeshID;
00233             for (int i = 0; i < 3; i++) {
00234                 // Invalid index: Index is bigger then vertex buffer size.
00235                 OgreAssert(iPos[i] < lookup.size(), "");
00236                 tri->vertexID[i] = iPos[i];
00237                 tri->vertex[i] = lookup[iPos[i]];
00238             }
00239             if (tri->isMalformed()) {
00240 #if OGRE_DEBUG_MODE
00241                 stringstream str;
00242                 str << "In " << mMeshName << " malformed triangle found with ID: " << getTriangleID(tri) << ". " <<
00243                 std::endl;
00244                 printTriangle(tri, str);
00245                 str << "It will be excluded from LOD level calculations.";
00246                 LogManager::getSingleton().stream() << str.str();
00247 #endif
00248                 tri->isRemoved = true;
00249                 mIndexBufferInfoList[tri->submeshID].indexCount -= 3;
00250                 continue;
00251             }
00252             tri->computeNormal();
00253             addTriangleToEdges(tri);
00254         }
00255     }
00256 
00257     void computeCosts();
00258     bool isBorderVertex(const PMVertex* vertex) const;
00259     PMEdge* getPointer(VEdges::iterator it);
00260     void computeVertexCollapseCost(PMVertex* vertex);
00261     Real computeEdgeCollapseCost(PMVertex* src, PMEdge* dstEdge);
00262     virtual void bakeLods();
00263     void collapse(PMVertex* vertex);
00264     void initialize();
00265     void computeLods(LodConfig& lodConfigs);
00266     void updateVertexCollapseCost(PMVertex* src);
00267 
00268     bool hasSrcID(unsigned int srcID, unsigned short submeshID);
00269     size_t findDstID(unsigned int srcID, unsigned short submeshID);
00270     void replaceVertexID(PMTriangle* triangle, unsigned int oldID, unsigned int newID, PMVertex* dst);
00271 
00272 #ifndef NDEBUG
00273     void assertValidVertex(PMVertex* v);
00274     void assertValidMesh();
00275     void assertOutdatedCollapseCost(PMVertex* vertex);
00276 #endif // ifndef NDEBUG
00277 
00278     void addTriangleToEdges(PMTriangle* triangle);
00279     void removeTriangleFromEdges(PMTriangle* triangle, PMVertex* skip = NULL);
00280     void addEdge(PMVertex* v, const PMEdge& edge);
00281     void removeEdge(PMVertex* v, const PMEdge& edge);
00282     void printTriangle(PMTriangle* triangle, stringstream& str);
00283     PMTriangle* findSideTriangle(const PMVertex* v1, const PMVertex* v2);
00284     bool isDuplicateTriangle(PMTriangle* triangle, PMTriangle* triangle2);
00285     PMTriangle* isDuplicateTriangle(PMTriangle* triangle);
00286     int getTriangleID(PMTriangle* triangle);
00287     void cleanupMemory();
00288 };
00289 
00290 }
00291 #endif

Copyright © 2012 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Mon Jul 27 2020 13:40:45