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 __Ogre_Volume_MeshBuilder_H__
29 #define __Ogre_Volume_MeshBuilder_H__
30 
31 #include <vector>
32 #include "OgreManualObject.h"
33 #include "OgreVector3.h"
34 #include "OgreAxisAlignedBox.h"
35 #include "OgreVolumePrerequisites.h"
36 
37 namespace Ogre {
38 namespace Volume {
39     /** \addtogroup Optional
40     *  @{
41     */
42     /** \addtogroup Volume
43     *  @{
44     */
45     /** Lightweight struct to represent a mesh vertex.
46     */
47     typedef struct _OgreVolumeExport Vertex
48     {
49         /// X coordinate of the position
50         Real x;
51 
52         /// Y coordinate of the position
53         Real y;
54 
55         /// Z coordinate of the position
56         Real z;
57 
58         /// X component of the normal
59         Real nX;
60 
61         /// Y component of the normal
62         Real nY;
63 
64         /// Z component of the normal
65         Real nZ;
66 
67         /** Convenience constructor.
68         @param v
69             The vertex position.
70         @param n
71             The vertex normal.
72         */
VertexVertex73         Vertex(const Vector3 &v, const Vector3 &n) :
74             x(v.x), y(v.y), z(v.z),
75             nX(n.x), nY(n.y), nZ(n.z)
76         {
77         }
VertexVertex78         Vertex()
79         {
80         }
81     } Vertex;
82 
83     /** == operator for two vertices.
84     @param a
85         The first vertex to test.
86     @param b
87         The second vertex to test.
88     */
89     bool _OgreVolumeExport operator==(Vertex const& a, Vertex const& b);
90 
91     /** A less operator.
92     @note
93         This operator is needed so that Vertex can serve as the key in a map structrue
94     @param a
95         The first vertex to test.
96     @param b
97         The second vertex to test.
98     */
99     bool _OgreVolumeExport operator<(const Vertex& a, const Vertex& b);
100 
101     /** To hold vertices.
102     */
103     typedef std::vector<Vertex> VecVertex;
104 
105     /** To hold indices.
106     */
107     typedef std::vector<size_t> VecIndices;
108 
109     /** Callback class when the user needs information about the triangles of
110         chunks of a LOD level.
111     */
112     class _OgreVolumeExport MeshBuilderCallback
113     {
114     public:
~MeshBuilderCallback()115         virtual ~MeshBuilderCallback() {}
116 
117         /** To be called with the callback function of a MeshBuilder.
118         @param simpleRenderable
119             Contains the SimpleRenderable for which the triangles were built.
120         @param vertices
121             Contains the vertices of the triangles.
122         @param indices
123             Contains the indices of the triangles.
124         @param level
125             The LOD level of this mesh.
126         @param inProcess
127             The amount of other meshes/LOD-Chunks still to be loaded.
128         */
129         virtual void ready(const SimpleRenderable *simpleRenderable, const VecVertex &vertices, const VecIndices &indices, size_t level, int inProcess) = 0;
130     };
131 
132     /** Class to build up a mesh with vertices and indices.
133     */
134     class _OgreVolumeExport MeshBuilder : public UtilityAlloc
135     {
136     protected:
137 
138         /// The buffer binding.
139         static const unsigned short MAIN_BINDING;
140 
141         /// Map to get a vertex index.
142         typedef std::map<Vertex, size_t> UMapVertexIndex;
143         UMapVertexIndex mIndexMap;
144 
145          /// Holds the vertices of the mesh.
146         VecVertex mVertices;
147 
148         /// Holds the indices of the mesh.
149         VecIndices mIndices;
150 
151         /// Holds the bounding box.
152         AxisAlignedBox mBox;
153 
154         /// Holds whether the initial bounding box has been set
155         bool mBoxInit;
156 
157         /** Adds a vertex to the data structure, reusing the index if it is already known.
158         @param v
159             The vertex.
160         */
addVertex(const Vertex & v)161         inline void addVertex(const Vertex &v)
162         {
163             size_t i = 0;
164             if (mIndexMap.find(v) == mIndexMap.end())
165             {
166                 i = mVertices.size();
167                 mIndexMap[v] = i;
168                 mVertices.push_back(v);
169 
170                 // Update bounding box
171                 if (!mBoxInit)
172                 {
173                     mBox.setExtents(v.x, v.y, v.z, v.x, v.y, v.z);
174                     mBoxInit = true;
175                 }
176                 else
177                 {
178                     if (v.x < mBox.getMinimum().x)
179                     {
180                         mBox.setMinimumX(v.x);
181                     }
182                     if (v.y < mBox.getMinimum().y)
183                     {
184                         mBox.setMinimumY(v.y);
185                     }
186                     if (v.z < mBox.getMinimum().z)
187                     {
188                         mBox.setMinimumZ(v.z);
189                     }
190                     if (v.x > mBox.getMaximum().x)
191                     {
192                         mBox.setMaximumX(v.x);
193                     }
194                     if (v.y > mBox.getMaximum().y)
195                     {
196                         mBox.setMaximumY(v.y);
197                     }
198                     if (v.z > mBox.getMaximum().z)
199                     {
200                         mBox.setMaximumZ(v.z);
201                     }
202                 }
203             }
204             else
205             {
206                 i = mIndexMap[v];
207             }
208             mIndices.push_back(i);
209         }
210 
211     public:
212 
213         /** Adds a cube to a manual object rendering lines. Corner numeration:
214              4 5
215             7 6
216              0 1
217             3 2
218         @param manual
219             The manual for the cube lines.
220         @param c0
221             The corner 0.
222         @param c1
223             The corner 1.
224         @param c2
225             The corner 2.
226         @param c3
227             The corner 3.
228         @param c4
229             The corner 4.
230         @param c5
231             The corner 5.
232         @param c6
233             The corner 6.
234         @param c7
235             The corner 7.
236         @param baseIndex
237             The next free index of this manual object.
238             Is incremented by 8 in this function.
239         */
addCubeToManualObject(ManualObject * manual,const Vector3 & c0,const Vector3 & c1,const Vector3 & c2,const Vector3 & c3,const Vector3 & c4,const Vector3 & c5,const Vector3 & c6,const Vector3 & c7,uint32 & baseIndex)240         static inline void addCubeToManualObject(
241             ManualObject *manual,
242             const Vector3 &c0,
243             const Vector3 &c1,
244             const Vector3 &c2,
245             const Vector3 &c3,
246             const Vector3 &c4,
247             const Vector3 &c5,
248             const Vector3 &c6,
249             const Vector3 &c7,
250             uint32 &baseIndex
251             )
252         {
253             manual->position(c0);
254             manual->position(c1);
255             manual->position(c2);
256             manual->position(c3);
257             manual->position(c4);
258             manual->position(c5);
259             manual->position(c6);
260             manual->position(c7);
261 
262             manual->index(baseIndex + 0); manual->index(baseIndex + 1);
263             manual->index(baseIndex + 1); manual->index(baseIndex + 2);
264             manual->index(baseIndex + 2); manual->index(baseIndex + 3);
265             manual->index(baseIndex + 3); manual->index(baseIndex + 0);
266 
267             manual->index(baseIndex + 4); manual->index(baseIndex + 5);
268             manual->index(baseIndex + 5); manual->index(baseIndex + 6);
269             manual->index(baseIndex + 6); manual->index(baseIndex + 7);
270             manual->index(baseIndex + 7); manual->index(baseIndex + 4);
271 
272             manual->index(baseIndex + 0); manual->index(baseIndex + 4);
273             manual->index(baseIndex + 1); manual->index(baseIndex + 5);
274             manual->index(baseIndex + 2); manual->index(baseIndex + 6);
275             manual->index(baseIndex + 3); manual->index(baseIndex + 7);
276             baseIndex += 8;
277         }
278 
279         /** Constructor.
280         */
281         MeshBuilder(void);
282 
283         /** Adds a triangle to the mesh with reusing already existent vertices via their index.
284         @param v0
285             The first vertex of the triangle.
286         @param n0
287             The normal of the first vertex.
288         @param v1
289             The second vertex of the triangle.
290         @param n1
291             The normal of the second vertex.
292         @param v2
293             The third vertex of the triangle.
294         @param n2
295             The normal of the third vertex.
296         */
addTriangle(const Vector3 & v0,const Vector3 & n0,const Vector3 & v1,const Vector3 & n1,const Vector3 & v2,const Vector3 & n2)297         inline void addTriangle(const Vector3 &v0, const Vector3 &n0, const Vector3 &v1, const Vector3 &n1, const Vector3 &v2, const Vector3 &n2)
298         {
299             addVertex(Vertex(v0, n0));
300             addVertex(Vertex(v1, n1));
301             addVertex(Vertex(v2, n2));
302         }
303 
304         /** Generates the vertex- and indexbuffer of this mesh on the given
305             RenderOperation.
306         @param operation
307             The RenderOperation for the buffers.
308         @return
309             The amount of generated triangles.
310         */
311         size_t generateBuffers(RenderOperation &operation);
312 
313         /** Generates an entity via a ManualObject.
314         @param sceneManager
315             The creating sceneManager.
316         @param name
317             The name for the entity.
318         @param material
319             The material to use.
320         @return
321             The created entity.
322         */
323         Entity* generateWithManualObject(SceneManager *sceneManager, const String &name, const String &material);
324 
325         /** Gets the bounding box of the mesh.
326         @return
327             The bounding box.
328         */
329         AxisAlignedBox getBoundingBox(void);
330 
331         /** Executes a MeshBuilderCallback on this instance.
332         @param callback
333             The callback to execute.
334         @param simpleRenderable
335             Contains the SimpleRenderable for which the triangles were built.
336         @param level
337             The LOD level of this mesh.
338         @param inProcess
339             The amount of other meshes/LOD-Chunks still to be loaded.
340         */
341         void executeCallback(MeshBuilderCallback *callback, const SimpleRenderable *simpleRenderable, size_t level, int inProcess) const;
342 
343     };
344     /** @} */
345     /** @} */
346 }
347 }
348 
349 #endif
350