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

This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Mon Jul 27 2020 13:40:45