1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://www.ogre3d.org/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software; you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | #ifndef __EdgeListBuilder_H__
|
---|
26 | #define __EdgeListBuilder_H__
|
---|
27 |
|
---|
28 | #include "OgrePrerequisites.h"
|
---|
29 | #include "OgreVector4.h"
|
---|
30 | #include "OgreHardwareVertexBuffer.h"
|
---|
31 | #include "OgreRenderOperation.h"
|
---|
32 |
|
---|
33 | namespace Ogre {
|
---|
34 |
|
---|
35 |
|
---|
36 | /** This class contains the information required to describe the edge connectivity of a
|
---|
37 | given set of vertices and indexes.
|
---|
38 | @remarks
|
---|
39 | This information is built using the EdgeListBuilder class. Note that for a given mesh,
|
---|
40 | which can be made up of multiple submeshes, there are separate edge lists for when
|
---|
41 | */
|
---|
42 | class _OgreExport EdgeData
|
---|
43 | {
|
---|
44 | public:
|
---|
45 | /** Basic triangle structure. */
|
---|
46 | struct Triangle {
|
---|
47 | /** The set of indexes this triangle came from (NB it is possible that the triangles on
|
---|
48 | one side of an edge are using a different vertex buffer from those on the other side.) */
|
---|
49 | size_t indexSet;
|
---|
50 | /** The vertex set these vertices came from. */
|
---|
51 | size_t vertexSet;
|
---|
52 | size_t vertIndex[3];/// Vertex indexes, relative to the original buffer
|
---|
53 | size_t sharedVertIndex[3]; /// Vertex indexes, relative to a shared vertex buffer with
|
---|
54 | // duplicates eliminated (this buffer is not exposed)
|
---|
55 | Vector4 normal; // unit vector othogonal to this face, plus distance from origin
|
---|
56 | bool lightFacing; // Working vector used when calculating the silhouette
|
---|
57 | };
|
---|
58 | /** Edge data. */
|
---|
59 | struct Edge {
|
---|
60 | /** The indexes of the 2 tris attached, note that tri 0 is the one where the
|
---|
61 | indexes run _anti_ clockwise along the edge. Indexes must be
|
---|
62 | reversed for tri 1. */
|
---|
63 | size_t triIndex[2];
|
---|
64 | /** The vertex indices for this edge. Note that both vertices will be in the vertex
|
---|
65 | set as specified in 'vertexSet', which will also be the same as tri 0 */
|
---|
66 | size_t vertIndex[2];
|
---|
67 | /** Vertex indices as used in the shared vertex list, not exposed. */
|
---|
68 | size_t sharedVertIndex[2];
|
---|
69 | /** Indicates if this is a degenerate edge, ie it does not have 2 triangles */
|
---|
70 | bool degenerate;
|
---|
71 | };
|
---|
72 |
|
---|
73 | typedef std::vector<Triangle> TriangleList;
|
---|
74 | typedef std::vector<Edge> EdgeList;
|
---|
75 |
|
---|
76 | /** A group of edges sharing the same vertex data. */
|
---|
77 | struct EdgeGroup
|
---|
78 | {
|
---|
79 | /** The vertex set index that contains the vertices for this edge group. */
|
---|
80 | size_t vertexSet;
|
---|
81 | /** Pointer to vertex data used by this edge group. */
|
---|
82 | const VertexData* vertexData;
|
---|
83 | /** The edges themselves. */
|
---|
84 | EdgeList edges;
|
---|
85 |
|
---|
86 | };
|
---|
87 |
|
---|
88 | typedef std::vector<EdgeGroup> EdgeGroupList;
|
---|
89 | TriangleList triangles;
|
---|
90 | EdgeGroupList edgeGroups;
|
---|
91 | // manifold? NB This value is not stored in the binary Mesh format yet so
|
---|
92 | // cannot be relied upon unless this has been calculated interactively.
|
---|
93 | //bool isClosed; // manifold?
|
---|
94 |
|
---|
95 |
|
---|
96 | /** Calculate the light facing state of the triangles in this edge list
|
---|
97 | @remarks
|
---|
98 | This is normally the first stage of calculating a silhouette, ie
|
---|
99 | establishing which tris are facing the light and which are facing
|
---|
100 | away. This state is stored in the 'lightFacing' flag in each
|
---|
101 | Triangle.
|
---|
102 | @param lightPos 4D position of the light in object space, note that
|
---|
103 | for directional lights (which have no position), the w component
|
---|
104 | is 0 and the x/y/z position are the direction.
|
---|
105 | */
|
---|
106 | void updateTriangleLightFacing(const Vector4& lightPos);
|
---|
107 | /** Updates the face normals for this edge list based on (changed)
|
---|
108 | position information, useful for animated objects.
|
---|
109 | @param vertexSet The vertex set we are updating
|
---|
110 | @param positionBuffer The updated position buffer, must contain ONLY xyz
|
---|
111 | */
|
---|
112 | void updateFaceNormals(size_t vertexSet, HardwareVertexBufferSharedPtr positionBuffer);
|
---|
113 |
|
---|
114 |
|
---|
115 |
|
---|
116 | // Debugging method
|
---|
117 | void log(Log* log);
|
---|
118 |
|
---|
119 | };
|
---|
120 |
|
---|
121 | /** General utility class for building edge lists for geometry.
|
---|
122 | @remarks
|
---|
123 | You can add multiple sets of vertex and index data to build and edge list.
|
---|
124 | Edges will be built between the various sets as well as within sets; this allows
|
---|
125 | you to use a model which is built from multiple SubMeshes each using
|
---|
126 | separate index and (optionally) vertex data and still get the same connectivity
|
---|
127 | information. It's important to note that the indexes for the edge will be constrained
|
---|
128 | to a single vertex buffer though (this is required in order to render the edge).
|
---|
129 | */
|
---|
130 | class _OgreExport EdgeListBuilder
|
---|
131 | {
|
---|
132 | public:
|
---|
133 |
|
---|
134 | EdgeListBuilder();
|
---|
135 | virtual ~EdgeListBuilder();
|
---|
136 | /** Add a set of vertex geometry data to the edge builder.
|
---|
137 | @remarks
|
---|
138 | You must add at least one set of vertex data to the builder before invoking the
|
---|
139 | build method.
|
---|
140 | */
|
---|
141 | void addVertexData(const VertexData* vertexData);
|
---|
142 | /** Add a set of index geometry data to the edge builder.
|
---|
143 | @remarks
|
---|
144 | You must add at least one set of index data to the builder before invoking the
|
---|
145 | build method.
|
---|
146 | @param indexData The index information which describes the triangles.
|
---|
147 | @param vertexSet The vertex data set this index data refers to; you only need to alter this
|
---|
148 | if you have added multiple sets of vertices
|
---|
149 | @param opType The operation type used to render these indexes. Only triangle types
|
---|
150 | are supported (no point or line types)
|
---|
151 | */
|
---|
152 | void addIndexData(const IndexData* indexData, size_t vertexSet = 0,
|
---|
153 | RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST);
|
---|
154 |
|
---|
155 | /** Builds the edge information based on the information built up so far.
|
---|
156 | @remarks
|
---|
157 | The caller takes responsibility for deleting the returned structure.
|
---|
158 | */
|
---|
159 | EdgeData* build(void);
|
---|
160 |
|
---|
161 | /// Debugging method
|
---|
162 | void log(Log* l);
|
---|
163 | protected:
|
---|
164 |
|
---|
165 | /** A vertex can actually represent several vertices in the final model, because
|
---|
166 | vertices along texture seams etc will have been duplicated. In order to properly
|
---|
167 | evaluate the surface properties, a single common vertex is used for these duplicates,
|
---|
168 | and the faces hold the detail of the duplicated vertices.
|
---|
169 | */
|
---|
170 | struct CommonVertex {
|
---|
171 | Vector3 position; // location of point in euclidean space
|
---|
172 | size_t index; // place of vertex in common vertex list
|
---|
173 | size_t vertexSet; // The vertex set this came from
|
---|
174 | size_t indexSet; // The index set this was referenced (first) from
|
---|
175 | size_t originalIndex; // place of vertex in original vertex set
|
---|
176 | };
|
---|
177 | /** A set of indexed geometry data */
|
---|
178 | struct Geometry {
|
---|
179 | size_t vertexSet; // The vertex data set this geometry data refers to
|
---|
180 | size_t indexSet; // The index data set this geometry data refers to
|
---|
181 | const IndexData* indexData; // The index information which describes the triangles.
|
---|
182 | RenderOperation::OperationType opType; // The operation type used to render this geometry
|
---|
183 | };
|
---|
184 | /** Comparator for sorting geometries by vertex set */
|
---|
185 | struct geometryLess {
|
---|
186 | bool operator()(const Geometry& a, const Geometry& b) const
|
---|
187 | {
|
---|
188 | if (a.vertexSet < b.vertexSet) return true;
|
---|
189 | if (a.vertexSet > b.vertexSet) return false;
|
---|
190 | return a.indexSet < b.indexSet;
|
---|
191 | }
|
---|
192 | };
|
---|
193 | /** Comparator for unique vertex list */
|
---|
194 | struct vectorLess {
|
---|
195 | bool operator()(const Vector3& a, const Vector3& b) const
|
---|
196 | {
|
---|
197 | if (a.x < b.x) return true;
|
---|
198 | if (a.x > b.x) return false;
|
---|
199 | if (a.y < b.y) return true;
|
---|
200 | if (a.y > b.y) return false;
|
---|
201 | return a.z < b.z;
|
---|
202 | }
|
---|
203 | };
|
---|
204 |
|
---|
205 | typedef std::vector<const VertexData*> VertexDataList;
|
---|
206 | typedef std::vector<Geometry> GeometryList;
|
---|
207 | typedef std::vector<CommonVertex> CommonVertexList;
|
---|
208 |
|
---|
209 | GeometryList mGeometryList;
|
---|
210 | VertexDataList mVertexDataList;
|
---|
211 | CommonVertexList mVertices;
|
---|
212 | EdgeData* mEdgeData;
|
---|
213 | /// Map for identifying common vertices
|
---|
214 | typedef std::map<Vector3, size_t, vectorLess> CommonVertexMap;
|
---|
215 | CommonVertexMap mCommonVertexMap;
|
---|
216 | /** Edge map, used to connect edges. Note we allow many triangles on an edge,
|
---|
217 | after connected an existing edge, we will remove it and never used again.
|
---|
218 | */
|
---|
219 | typedef std::multimap< std::pair<size_t, size_t>, std::pair<size_t, size_t> > EdgeMap;
|
---|
220 | EdgeMap mEdgeMap;
|
---|
221 |
|
---|
222 | void buildTrianglesEdges(const Geometry &geometry);
|
---|
223 |
|
---|
224 | /// Finds an existing common vertex, or inserts a new one
|
---|
225 | size_t findOrCreateCommonVertex(const Vector3& vec, size_t vertexSet,
|
---|
226 | size_t indexSet, size_t originalIndex);
|
---|
227 | /// Connect existing edge or create a new edge - utility method during building
|
---|
228 | void connectOrCreateEdge(size_t vertexSet, size_t triangleIndex, size_t vertIndex0, size_t vertIndex1,
|
---|
229 | size_t sharedVertIndex0, size_t sharedVertIndex1);
|
---|
230 | };
|
---|
231 |
|
---|
232 | }
|
---|
233 | #endif
|
---|
234 |
|
---|