source: GTP/trunk/App/Demos/Geom/OgreStuff/include/OgreProgressiveMesh.h @ 1092

Revision 1092, 10.3 KB checked in by gumbau, 18 years ago (diff)

LodStrips? and LODTrees demos

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25// The underlying algorithms in this class are based heavily on:
26/*
27 *  Progressive Mesh type Polygon Reduction Algorithm
28 *  by Stan Melax (c) 1998
29 */
30
31#ifndef __ProgressiveMesh_H_
32#define __ProgressiveMesh_H_
33
34#include "OgrePrerequisites.h"
35#include "OgreVector3.h"
36#include "OgreHardwareVertexBuffer.h"
37#include "OgreHardwareIndexBuffer.h"
38#include "OgreRenderOperation.h"
39
40namespace Ogre {
41
42    /** This class reduces the complexity of the geometry it is given.
43        This class is dedicated to reducing the number of triangles in a given mesh
44        taking into account seams in both geometry and texture co-ordinates and meshes
45        which have multiple frames.
46    @par
47        The primary use for this is generating LOD versions of Mesh objects, but it can be
48        used by any geometry provider. The only limitation at the moment is that the
49        provider uses a common vertex buffer for all LODs and one index buffer per LOD.
50        Therefore at the moment this class can only handle indexed geometry.
51    @par
52        NB the interface of this class will certainly change when compiled vertex buffers are
53        supported.
54    */
55    class _OgreExport ProgressiveMesh
56    {
57    public:
58
59                /** The way to derive the quota of vertices which are reduced at each LOD. */
60        enum VertexReductionQuota
61                {
62                        /// A set number of vertices are removed at each reduction
63                        VRQ_CONSTANT,
64                        /// A proportion of the remaining number of vertices are removed at each reduction
65                        VRQ_PROPORTIONAL
66                };
67
68        typedef std::vector<IndexData*> LODFaceList;
69
70        /** Constructor, takes the geometry data and index buffer.
71                @remarks
72                        DO NOT pass write-only, unshadowed buffers to this method! They will not
73                        work. Pass only shadowed buffers, or better yet perform mesh reduction as
74                        an offline process using DefaultHardwareBufferManager to manage vertex
75                        buffers in system memory.
76                */
77        ProgressiveMesh(const VertexData* vertexData, const IndexData* indexData);
78        virtual ~ProgressiveMesh();
79
80        /** Adds an extra vertex position buffer.
81        @remarks
82            As well as the main vertex buffer, the client of this class may add extra versions
83            of the vertex buffer which will also be taken into account when the cost of
84            simplifying the mesh is taken into account. This is because the cost of
85            simplifying an animated mesh cannot be calculated from just the reference position,
86            multiple positions needs to be assessed in order to find the best simplification option.
87                @par
88                        DO NOT pass write-only, unshadowed buffers to this method! They will not
89                        work. Pass only shadowed buffers, or better yet perform mesh reduction as
90                        an offline process using DefaultHardwareBufferManager to manage vertex
91                        buffers in system memory.
92        @param buffer Pointer to x/y/z buffer with vertex positions. The number of vertices
93            must be the same as in the original GeometryData passed to the constructor.
94        */
95        virtual void addExtraVertexPositionBuffer(const VertexData* vertexData);
96
97        /** Builds the progressive mesh with the specified number of levels.
98        @param numLevels The number of levels to include in the output excluding the full detail version.
99        @param outList Pointer to a list of LOD geometry data which will be completed by the application.
100                        Each entry is a reduced form of the mesh, in decreasing order of detail.
101                @param quota The way to derive the number of vertices removed at each LOD
102                @param reductionValue Either the proportion of vertices to remove at each level, or a fixed
103                        number of vertices to remove at each level, depending on the value of quota
104        */
105        virtual void build(ushort numLevels, LODFaceList* outList,
106                        VertexReductionQuota quota = VRQ_PROPORTIONAL, Real reductionValue = 0.5f );
107
108    protected:
109        const VertexData *mpVertexData;
110        const IndexData *mpIndexData;
111
112        size_t mCurrNumIndexes;
113                size_t mNumCommonVertices;
114
115        // Internal classes
116        class PMTriangle;
117        class PMVertex;
118
119        public: // VC6 hack
120
121        /** A vertex as used by a face. This records the index of the actual vertex which is used
122                by the face, and a pointer to the common vertex used for surface evaluation. */
123                class _OgrePrivate PMFaceVertex {
124                public:
125                        size_t realIndex;
126                        PMVertex* commonVertex;
127                };
128
129        protected:
130
131        /** A triangle in the progressive mesh, holds extra info like face normal. */
132        class _OgrePrivate PMTriangle {
133        public:
134            PMTriangle();
135            void setDetails(size_t index, PMFaceVertex *v0, PMFaceVertex *v1, PMFaceVertex *v2);
136                void computeNormal(void);
137                void replaceVertex(PMFaceVertex *vold, PMFaceVertex *vnew);
138                bool hasCommonVertex(PMVertex *v) const;
139                bool hasFaceVertex(PMFaceVertex *v) const;
140                        PMFaceVertex* getFaceVertexFromCommon(PMVertex* commonVert);
141                void notifyRemoved(void);
142
143                PMFaceVertex* vertex[3]; // the 3 points that make this tri
144                Vector3   normal;    // unit vector othogonal to this face
145            bool      removed;   // true if this tri is now removed
146                        size_t index;
147        };
148
149        /** A vertex in the progressive mesh, holds info like collapse cost etc.
150                This vertex can actually represent several vertices in the final model, because
151                vertices along texture seams etc will have been duplicated. In order to properly
152                evaluate the surface properties, a single common vertex is used for these duplicates,
153                and the faces hold the detail of the duplicated vertices.
154                */
155        class _OgrePrivate PMVertex {
156        public:
157            PMVertex();
158                void setDetails(const Vector3& v, size_t index);
159                void removeIfNonNeighbor(PMVertex *n);
160                        bool isBorder(void);/// true if this vertex is on the edge of an open geometry patch
161                        bool isManifoldEdgeWith(PMVertex* v); // is edge this->src a manifold edge?
162                        void notifyRemoved(void);
163
164            Vector3  position;  // location of point in euclidean space
165                size_t index;       // place of vertex in original list
166            typedef std::set<PMVertex *> NeighborList;
167            typedef std::set<PMVertex *> DuplicateList;
168            NeighborList neighbor; // adjacent vertices
169                typedef std::set<PMTriangle *> FaceList;
170            FaceList face;     // adjacent triangles
171
172                Real collapseCost;  // cached cost of collapsing edge
173                PMVertex * collapseTo; // candidate vertex for collapse
174            bool      removed;   // true if this vert is now removed
175                        bool      toBeRemoved; // denug
176
177                        bool seam;      /// true if this vertex is on a model seam where vertices are duplicated
178
179        };
180
181        typedef std::vector<PMTriangle> TriangleList;
182        typedef std::vector<PMFaceVertex> FaceVertexList;
183        typedef std::vector<PMVertex> CommonVertexList;
184        typedef std::vector<Real> WorstCostList;
185
186        /// Data used to calculate the collapse costs
187        struct PMWorkingData
188        {
189            TriangleList mTriList; /// List of faces
190            FaceVertexList mFaceVertList; // The vertex details referenced by the triangles
191                        CommonVertexList mVertList; // The master list of common vertices
192        };
193
194        typedef std::vector<PMWorkingData> WorkingDataList;
195        /// Multiple copies, 1 per vertex buffer
196        WorkingDataList mWorkingData;
197
198        /// The worst collapse cost from all vertex buffers for each vertex
199        WorstCostList mWorstCosts;
200
201        /// Internal method for building PMWorkingData from geometry data
202        void addWorkingData(const VertexData* vertexData, const IndexData* indexData);
203
204        /// Internal method for initialising the edge collapse costs
205        void initialiseEdgeCollapseCosts(void);
206        /// Internal calculation method for deriving a collapse cost  from u to v
207        Real computeEdgeCollapseCost(PMVertex *src, PMVertex *dest);
208        /// Internal method evaluates all collapse costs from this vertex and picks the lowest for a single buffer
209        Real computeEdgeCostAtVertexForBuffer(WorkingDataList::iterator idata, size_t vertIndex);
210        /// Internal method evaluates all collapse costs from this vertex for every buffer and returns the worst
211        void computeEdgeCostAtVertex(size_t vertIndex);
212        /// Internal method to compute edge collapse costs for all buffers /
213        void computeAllCosts(void);
214        /// Internal method for getting the index of next best vertex to collapse
215        size_t getNextCollapser(void);
216        /// Internal method builds an new LOD based on the current state
217        void bakeNewLOD(IndexData* pData);
218
219        /** Internal method, collapses vertex onto it's saved collapse target.
220        @remarks
221            This updates the working triangle list to drop a triangle and recalculates
222            the edge collapse costs around the collapse target.
223            This also updates all the working vertex lists for the relevant buffer.
224        */
225        void collapse(PMVertex *collapser);
226
227                /** Internal debugging method */
228                void dumpContents(const String& log);
229
230
231
232
233
234
235
236
237
238    };
239
240
241
242}
243
244#endif
Note: See TracBrowser for help on using the repository browser.