/src/ogre/OgreMain/include/OgreEdgeListBuilder.h
Line | Count | Source |
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-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #ifndef __EdgeListBuilder_H__ |
29 | | #define __EdgeListBuilder_H__ |
30 | | |
31 | | #include "OgrePrerequisites.h" |
32 | | #include "OgreRenderOperation.h" |
33 | | #include "OgreVector.h" |
34 | | #include "OgreHeaderPrefix.h" |
35 | | |
36 | | namespace Ogre { |
37 | | |
38 | | /** \addtogroup Core |
39 | | * @{ |
40 | | */ |
41 | | /** \addtogroup Math |
42 | | * @{ |
43 | | */ |
44 | | |
45 | | |
46 | | /** This class contains the information required to describe the edge connectivity of a |
47 | | given set of vertices and indexes. |
48 | | |
49 | | This information is built using the EdgeListBuilder class. Note that for a given mesh, |
50 | | which can be made up of multiple submeshes, there are separate edge lists for when |
51 | | */ |
52 | | class _OgreExport EdgeData : public EdgeDataAlloc |
53 | | { |
54 | | public: |
55 | | |
56 | | EdgeData(); |
57 | | |
58 | | /** Basic triangle structure. */ |
59 | | struct Triangle { |
60 | | /** The set of indexes this triangle came from (NB it is possible that the triangles on |
61 | | one side of an edge are using a different vertex buffer from those on the other side.) */ |
62 | | uint32 indexSet; |
63 | | /** The vertex set these vertices came from. */ |
64 | | uint32 vertexSet; |
65 | | /// Vertex indexes, relative to the original buffer |
66 | | uint32 vertIndex[3]; |
67 | | /** Vertex indexes, relative to a shared vertex buffer with |
68 | | duplicates eliminated (this buffer is not exposed) */ |
69 | | uint32 sharedVertIndex[3]; |
70 | | |
71 | 0 | Triangle() :indexSet(0), vertexSet(0) {} |
72 | | }; |
73 | | /** Edge data. */ |
74 | | struct Edge { |
75 | | /** The indexes of the 2 tris attached, note that tri 0 is the one where the |
76 | | indexes run _anti_ clockwise along the edge. Indexes must be |
77 | | reversed for tri 1. */ |
78 | | uint32 triIndex[2]; |
79 | | /** The vertex indices for this edge. Note that both vertices will be in the vertex |
80 | | set as specified in 'vertexSet', which will also be the same as tri 0 */ |
81 | | uint32 vertIndex[2]; |
82 | | /** Vertex indices as used in the shared vertex list, not exposed. */ |
83 | | uint32 sharedVertIndex[2]; |
84 | | /** Indicates if this is a degenerate edge, ie it does not have 2 triangles */ |
85 | | bool degenerate; |
86 | | }; |
87 | | |
88 | | /** Array of 4D vector of triangle face normal, which is unit vector orthogonal |
89 | | to the triangles, plus distance from origin. |
90 | | Use aligned policy here because we are intended to use in SIMD optimised routines. */ |
91 | | typedef aligned_vector<Vector4> TriangleFaceNormalList; |
92 | | |
93 | | /** Working vector used when calculating the silhouette. |
94 | | Use std::vector<char> instead of std::vector<bool> which might implemented |
95 | | similar bit-fields causing loss performance. */ |
96 | | typedef std::vector<char> TriangleLightFacingList; |
97 | | |
98 | | typedef std::vector<Triangle> TriangleList; |
99 | | typedef std::vector<Edge> EdgeList; |
100 | | |
101 | | /** A group of edges sharing the same vertex data. */ |
102 | | struct EdgeGroup |
103 | | { |
104 | | /** The vertex set index that contains the vertices for this edge group. */ |
105 | | uint32 vertexSet; |
106 | | /** Pointer to vertex data used by this edge group. */ |
107 | | const VertexData* vertexData; |
108 | | /** Index to main triangles array, indicate the first triangle of this edge |
109 | | group, and all triangles of this edge group are stored continuous in |
110 | | main triangles array. |
111 | | */ |
112 | | uint32 triStart; |
113 | | /** Number triangles of this edge group. */ |
114 | | uint32 triCount; |
115 | | /** The edges themselves. */ |
116 | | EdgeList edges; |
117 | | |
118 | | }; |
119 | | |
120 | | typedef std::vector<EdgeGroup> EdgeGroupList; |
121 | | |
122 | | /** Main triangles array, stores all triangles of this edge list. Note that |
123 | | triangles are grouping against edge group. |
124 | | */ |
125 | | TriangleList triangles; |
126 | | /** All triangle face normals. It should be 1:1 with triangles. */ |
127 | | TriangleFaceNormalList triangleFaceNormals; |
128 | | /** Triangle light facing states. It should be 1:1 with triangles. */ |
129 | | TriangleLightFacingList triangleLightFacings; |
130 | | /** All edge groups of this edge list. */ |
131 | | EdgeGroupList edgeGroups; |
132 | | /** Flag indicate the mesh is manifold. */ |
133 | | bool isClosed; |
134 | | |
135 | | |
136 | | /** Calculate the light facing state of the triangles in this edge list |
137 | | |
138 | | This is normally the first stage of calculating a silhouette, i.e. |
139 | | establishing which tris are facing the light and which are facing |
140 | | away. This state is stored in the 'triangleLightFacings'. |
141 | | @param lightPos 4D position of the light in object space, note that |
142 | | for directional lights (which have no position), the w component |
143 | | is 0 and the x/y/z position are the direction. |
144 | | */ |
145 | | void updateTriangleLightFacing(const Vector4& lightPos); |
146 | | /** Updates the face normals for this edge list based on (changed) |
147 | | position information, useful for animated objects. |
148 | | @param vertexSet The vertex set we are updating |
149 | | @param positionBuffer The updated position buffer, must contain ONLY xyz |
150 | | */ |
151 | | void updateFaceNormals(size_t vertexSet, const HardwareVertexBufferSharedPtr& positionBuffer); |
152 | | |
153 | | EdgeData* clone() OGRE_NODISCARD; |
154 | | |
155 | | |
156 | | /// Debugging method |
157 | | void log(Log* log); |
158 | | |
159 | | }; |
160 | | |
161 | | /** General utility class for building edge lists for geometry. |
162 | | |
163 | | You can add multiple sets of vertex and index data to build and edge list. |
164 | | Edges will be built between the various sets as well as within sets; this allows |
165 | | you to use a model which is built from multiple SubMeshes each using |
166 | | separate index and (optionally) vertex data and still get the same connectivity |
167 | | information. It's important to note that the indexes for the edge will be constrained |
168 | | to a single vertex buffer though (this is required in order to render the edge). |
169 | | */ |
170 | | class _OgreExport EdgeListBuilder |
171 | | { |
172 | | public: |
173 | | |
174 | | EdgeListBuilder(); |
175 | | /** Add a set of vertex geometry data to the edge builder. |
176 | | |
177 | | You must add at least one set of vertex data to the builder before invoking the |
178 | | build method. |
179 | | */ |
180 | | void addVertexData(const VertexData* vertexData); |
181 | | /** Add a set of index geometry data to the edge builder. |
182 | | |
183 | | You must add at least one set of index data to the builder before invoking the |
184 | | build method. |
185 | | @param indexData The index information which describes the triangles. |
186 | | @param vertexSet The vertex data set this index data refers to; you only need to alter this |
187 | | if you have added multiple sets of vertices |
188 | | @param opType The operation type used to render these indexes. Only triangle types |
189 | | are supported (no point or line types) |
190 | | */ |
191 | | void addIndexData(const IndexData* indexData, size_t vertexSet = 0, |
192 | | RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST); |
193 | | |
194 | | /** Builds the edge information based on the information built up so far. |
195 | | |
196 | | The caller takes responsibility for deleting the returned structure. |
197 | | */ |
198 | | EdgeData* build(void); |
199 | | |
200 | | /// Debugging method |
201 | | void log(Log* l); |
202 | | private: |
203 | | |
204 | | /** A vertex can actually represent several vertices in the final model, because |
205 | | vertices along texture seams etc will have been duplicated. In order to properly |
206 | | evaluate the surface properties, a single common vertex is used for these duplicates, |
207 | | and the faces hold the detail of the duplicated vertices. |
208 | | */ |
209 | | struct CommonVertex { |
210 | | Vector3f position; /// Location of point in euclidean space |
211 | | uint32 index; /// Place of vertex in common vertex list |
212 | | uint32 vertexSet; /// The vertex set this came from |
213 | | uint32 indexSet; /// The index set this was referenced (first) from |
214 | | uint32 originalIndex; /// Place of vertex in original vertex set |
215 | | }; |
216 | | /** A set of indexed geometry data */ |
217 | | struct Geometry { |
218 | | uint32 vertexSet; /// The vertex data set this geometry data refers to |
219 | | uint32 indexSet; /// The index data set this geometry data refers to |
220 | | const IndexData* indexData; /// The index information which describes the triangles. |
221 | | RenderOperation::OperationType opType; /// The operation type used to render this geometry |
222 | | }; |
223 | | friend struct geometryLess; |
224 | | /** Comparator for unique vertex list */ |
225 | | struct vectorLess { |
226 | | bool operator()(const Vector3f& a, const Vector3f& b) const |
227 | 0 | { |
228 | 0 | if (a[0] < b[0]) return true; |
229 | 0 | if (a[0] > b[0]) return false; |
230 | 0 | if (a[1] < b[1]) return true; |
231 | 0 | if (a[1] > b[1]) return false; |
232 | 0 | return a[2] < b[2]; |
233 | 0 | } |
234 | | }; |
235 | | |
236 | | typedef std::vector<const VertexData*> VertexDataList; |
237 | | typedef std::vector<Geometry> GeometryList; |
238 | | typedef std::vector<CommonVertex> CommonVertexList; |
239 | | |
240 | | GeometryList mGeometryList; |
241 | | VertexDataList mVertexDataList; |
242 | | CommonVertexList mVertices; |
243 | | EdgeData* mEdgeData; |
244 | | /// Map for identifying common vertices |
245 | | typedef std::map<Vector3f, size_t, vectorLess> CommonVertexMap; |
246 | | CommonVertexMap mCommonVertexMap; |
247 | | /** Edge map, used to connect edges. Note we allow many triangles on an edge, |
248 | | after connected an existing edge, we will remove it and never used again. |
249 | | */ |
250 | | typedef std::multimap< std::pair<uint32, uint32>, std::pair<uint32, uint32> > EdgeMap; |
251 | | EdgeMap mEdgeMap; |
252 | | |
253 | | void buildTrianglesEdges(const Geometry &geometry); |
254 | | |
255 | | /// Finds an existing common vertex, or inserts a new one |
256 | | uint32 findOrCreateCommonVertex(const Vector3f& vec, uint32 vertexSet, |
257 | | uint32 indexSet, uint32 originalIndex); |
258 | | /// Connect existing edge or create a new edge - utility method during building |
259 | | void connectOrCreateEdge(uint32 vertexSet, uint32 triangleIndex, uint32 vertIndex0, uint32 vertIndex1, |
260 | | uint32 sharedVertIndex0, uint32 sharedVertIndex1); |
261 | | }; |
262 | | /** @} */ |
263 | | /** @} */ |
264 | | |
265 | | } |
266 | | |
267 | | #include "OgreHeaderSuffix.h" |
268 | | |
269 | | #endif |
270 | | |