/src/ogre/OgreMain/include/OgreStaticGeometry.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 __StaticGeometry_H__ |
29 | | #define __StaticGeometry_H__ |
30 | | |
31 | | #include "OgrePrerequisites.h" |
32 | | #include "OgreMovableObject.h" |
33 | | #include "OgreRenderable.h" |
34 | | #include "OgreMesh.h" |
35 | | #include "OgreHeaderPrefix.h" |
36 | | |
37 | | namespace Ogre { |
38 | | |
39 | | /** \addtogroup Core |
40 | | * @{ |
41 | | */ |
42 | | /** \addtogroup Scene |
43 | | * @{ |
44 | | */ |
45 | | /** Pre-transforms and batches up meshes on the CPU for efficient use as static |
46 | | geometry in a scene. |
47 | | |
48 | | This class allows you to build a batched object from a series of entities. |
49 | | Batching has implications of it's own though: |
50 | | - Batched geometry cannot be subdivided; that means that the whole |
51 | | group will be displayed, or none of it will. This obivously has |
52 | | culling issues. |
53 | | - A single world transform must apply to the entire batch. Therefore |
54 | | once you have batched things, you can't move them around relative to |
55 | | each other. That's why this class is most useful when dealing with |
56 | | static geometry (hence the name). In addition, geometry is |
57 | | effectively duplicated, so if you add 3 entities based on the same |
58 | | mesh in different positions, they will use 3 times the geometry |
59 | | space than the movable version (which re-uses the same geometry). |
60 | | So you trade memory and flexibility of movement for pure speed when |
61 | | using this class. |
62 | | - A single material must apply for each batch. In fact this class |
63 | | allows you to use multiple materials, but you should be aware that |
64 | | internally this means that there is one batch per material. |
65 | | Therefore you won't gain as much benefit from the batching if you |
66 | | use many different materials; try to keep the number down. |
67 | | |
68 | | In order to retain some sort of culling, this class will batch up |
69 | | meshes in localised regions. The size and shape of these blocks is |
70 | | controlled by the SceneManager which constructs this object, since it |
71 | | makes sense to batch things up in the most appropriate way given the |
72 | | existing partitioning of the scene. |
73 | | |
74 | | The LOD settings of both the Mesh and the Materials used in |
75 | | constructing this static geometry will be respected. This means that |
76 | | if you use meshes/materials which have LOD, batches in the distance |
77 | | will have a lower polygon count or material detail to those in the |
78 | | foreground. Since each mesh might have different LOD distances, during |
79 | | build the furthest distance at each LOD level from all meshes |
80 | | in that region is used. This means all the LOD levels change at the |
81 | | same time, but at the furthest distance of any of them (so quality is |
82 | | not degraded). Be aware that using Mesh LOD in this class will |
83 | | further increase the memory required. Only generated LOD |
84 | | is supported for meshes. |
85 | | |
86 | | There are 2 ways you can add geometry to this class; you can add |
87 | | Entity objects directly with predetermined positions, scales and |
88 | | orientations, or you can add an entire SceneNode and it's subtree, |
89 | | including all the objects attached to it. Once you've added everything |
90 | | you need to, you have to call build() the fix the geometry in place. |
91 | | @note |
92 | | This class is not a replacement for world geometry (@ref |
93 | | Ogre::SceneManager::setWorldGeometry). The single most efficient way to |
94 | | render large amounts of static geometry is to use a SceneManager which |
95 | | is specialised for dealing with that particular world structure. |
96 | | However, this class does provide you with a good 'halfway house' |
97 | | between generalised movable geometry (Entity) which works with all |
98 | | SceneManagers but isn't efficient when using very large numbers, and |
99 | | highly specialised world geometry which is extremely fast but not |
100 | | generic and typically requires custom world editors. |
101 | | @attention |
102 | | this class only works with indexed triangle lists at the moment, |
103 | | do not pass it triangle strips, fans or lines / points, or unindexed geometry. |
104 | | */ |
105 | | class _OgreExport StaticGeometry : public BatchedGeometryAlloc |
106 | | { |
107 | | public: |
108 | | /** Struct holding geometry optimised per SubMesh / LOD level, ready |
109 | | for copying to instances. |
110 | | |
111 | | Since we're going to be duplicating geometry lots of times, it's |
112 | | far more important that we don't have redundant vertex data. If a |
113 | | SubMesh uses shared geometry, or we're looking at a lower LOD, not |
114 | | all the vertices are being referenced by faces on that submesh. |
115 | | Therefore to duplicate them, potentially hundreds or even thousands |
116 | | of times, would be extremely wasteful. Therefore, if a SubMesh at |
117 | | a given LOD has wastage, we create an optimised version of it's |
118 | | geometry which is ready for copying with no wastage. |
119 | | */ |
120 | | class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc |
121 | | { |
122 | | public: |
123 | 0 | OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {} |
124 | | ~OptimisedSubMeshGeometry() |
125 | 0 | { |
126 | 0 | OGRE_DELETE vertexData; |
127 | 0 | OGRE_DELETE indexData; |
128 | 0 | } |
129 | | VertexData *vertexData; |
130 | | IndexData *indexData; |
131 | | }; |
132 | | typedef std::list<OptimisedSubMeshGeometry*> OptimisedSubMeshGeometryList; |
133 | | /// Saved link between SubMesh at a LOD and vertex/index data |
134 | | /// May point to original or optimised geometry |
135 | | struct SubMeshLodGeometryLink |
136 | | { |
137 | | VertexData* vertexData; |
138 | | IndexData* indexData; |
139 | | }; |
140 | | typedef std::vector<SubMeshLodGeometryLink> SubMeshLodGeometryLinkList; |
141 | | typedef std::map<SubMesh*, SubMeshLodGeometryLinkList*> SubMeshGeometryLookup; |
142 | | /// Structure recording a queued submesh for the build |
143 | | struct QueuedSubMesh : public BatchedGeometryAlloc |
144 | | { |
145 | | SubMesh* submesh; |
146 | | MaterialPtr material; |
147 | | /// Link to LOD list of geometry, potentially optimised |
148 | | SubMeshLodGeometryLinkList* geometryLodList; |
149 | | Vector3 position; |
150 | | Quaternion orientation; |
151 | | Vector3 scale; |
152 | | /// Pre-transformed world AABB |
153 | | AxisAlignedBox worldBounds; |
154 | | }; |
155 | | typedef std::vector<QueuedSubMesh*> QueuedSubMeshList; |
156 | | /// Structure recording a queued geometry for low level builds |
157 | | struct QueuedGeometry : public BatchedGeometryAlloc |
158 | | { |
159 | | SubMeshLodGeometryLink* geometry; |
160 | | Vector3 position; |
161 | | Quaternion orientation; |
162 | | Vector3 scale; |
163 | | }; |
164 | | typedef std::vector<QueuedGeometry*> QueuedGeometryList; |
165 | | |
166 | | // forward declarations |
167 | | class LODBucket; |
168 | | class MaterialBucket; |
169 | | class Region; |
170 | | |
171 | | /** A GeometryBucket is a the lowest level bucket where geometry with |
172 | | the same vertex & index format is stored. It also acts as the |
173 | | renderable. |
174 | | */ |
175 | | class _OgreExport GeometryBucket : public Renderable, public BatchedGeometryAlloc |
176 | | { |
177 | | /// Geometry which has been queued up pre-build (not for deallocation) |
178 | | QueuedGeometryList mQueuedGeometry; |
179 | | /// Pointer to parent bucket |
180 | | MaterialBucket* mParent; |
181 | | /// Vertex information, includes current number of vertices |
182 | | /// committed to be a part of this bucket |
183 | | VertexData* mVertexData; |
184 | | /// Index information, includes index type which limits the max |
185 | | /// number of vertices which are allowed in one bucket |
186 | | IndexData* mIndexData; |
187 | | /// Maximum vertex indexable |
188 | | size_t mMaxVertexIndex; |
189 | | public: |
190 | | GeometryBucket(MaterialBucket* parent, const VertexData* vData, const IndexData* iData); |
191 | | virtual ~GeometryBucket(); |
192 | 0 | MaterialBucket* getParent(void) { return mParent; } |
193 | | /// Get the vertex data for this geometry |
194 | 0 | const VertexData* getVertexData(void) const { return mVertexData; } |
195 | | /// Get the index data for this geometry |
196 | 0 | const IndexData* getIndexData(void) const { return mIndexData; } |
197 | | /// @copydoc Renderable::getMaterial |
198 | | const MaterialPtr& getMaterial(void) const override; |
199 | | Technique* getTechnique(void) const override; |
200 | | void getRenderOperation(RenderOperation& op) override; |
201 | | void getWorldTransforms(Matrix4* xform) const override; |
202 | | Real getSquaredViewDepth(const Camera* cam) const override; |
203 | | const LightList& getLights(void) const override; |
204 | | bool getCastsShadows(void) const override; |
205 | | |
206 | | /** Try to assign geometry to this bucket. |
207 | | @return false if there is no room left in this bucket |
208 | | */ |
209 | | bool assign(QueuedGeometry* qsm); |
210 | | /// Build |
211 | | void build(bool stencilShadows); |
212 | | /// Dump contents for diagnostics |
213 | | _OgreExport friend std::ostream& operator<<(std::ostream& o, const GeometryBucket& b); |
214 | | }; |
215 | | /** A MaterialBucket is a collection of smaller buckets with the same |
216 | | Material (and implicitly the same LOD). */ |
217 | | class _OgreExport MaterialBucket : public BatchedGeometryAlloc |
218 | | { |
219 | | public: |
220 | | /// list of Geometry Buckets in this region |
221 | | typedef std::vector<GeometryBucket*> GeometryBucketList; |
222 | | private: |
223 | | /// Pointer to parent LODBucket |
224 | | LODBucket* mParent; |
225 | | /// Pointer to material being used |
226 | | MaterialPtr mMaterial; |
227 | | /// Active technique |
228 | | Technique* mTechnique; |
229 | | |
230 | | /// list of Geometry Buckets in this region |
231 | | GeometryBucketList mGeometryBucketList; |
232 | | // index to current Geometry Buckets for a given geometry format |
233 | | typedef std::map<uint32, GeometryBucket*> CurrentGeometryMap; |
234 | | CurrentGeometryMap mCurrentGeometryMap; |
235 | | |
236 | | public: |
237 | | MaterialBucket(LODBucket* parent, const MaterialPtr& material); |
238 | | virtual ~MaterialBucket(); |
239 | 0 | LODBucket* getParent(void) { return mParent; } |
240 | | /// Get the material name |
241 | 0 | const String& getMaterialName(void) const { return mMaterial->getName(); } |
242 | | /// Assign geometry to this bucket |
243 | | void assign(QueuedGeometry* qsm); |
244 | | /// Build |
245 | | void build(bool stencilShadows); |
246 | | /// Add children to the render queue |
247 | | void addRenderables(RenderQueue* queue, uint8 group, |
248 | | Real lodValue); |
249 | | /// Get the material for this bucket |
250 | 0 | const MaterialPtr& getMaterial(void) const { return mMaterial; } |
251 | | /// Override Material without changing the partitioning. For advanced use only. |
252 | | void _setMaterial(const MaterialPtr& material); |
253 | | /// Iterator over geometry |
254 | | typedef VectorIterator<GeometryBucketList> GeometryIterator; |
255 | | /// Get a list of the contained geometry |
256 | 0 | const GeometryBucketList& getGeometryList() const { return mGeometryBucketList; } |
257 | | /// @deprecated use getGeometryList() |
258 | | OGRE_DEPRECATED GeometryIterator getGeometryIterator(void); |
259 | | /// Get the current Technique |
260 | 0 | Technique* getCurrentTechnique(void) const { return mTechnique; } |
261 | | /// Dump contents for diagnostics |
262 | | _OgreExport friend std::ostream& operator<<(std::ostream& o, const MaterialBucket& b); |
263 | | void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); |
264 | | }; |
265 | | /** A LODBucket is a collection of smaller buckets with the same LOD. |
266 | | |
267 | | LOD refers to Mesh LOD here. Material LOD can change separately |
268 | | at the next bucket down from this. |
269 | | */ |
270 | | class _OgreExport LODBucket : public BatchedGeometryAlloc |
271 | | { |
272 | | public: |
273 | | /// Lookup of Material Buckets in this region |
274 | | typedef std::map<String, MaterialBucket*> MaterialBucketMap; |
275 | | private: |
276 | | /// Pointer to parent region |
277 | | Region* mParent; |
278 | | /// LOD level (0 == full LOD) |
279 | | unsigned short mLod; |
280 | | /// LOD value at which this LOD starts to apply (squared) |
281 | | Real mLodValue; |
282 | | /// Lookup of Material Buckets in this region |
283 | | MaterialBucketMap mMaterialBucketMap; |
284 | | /// Geometry queued for a single LOD (deallocated here) |
285 | | QueuedGeometryList mQueuedGeometryList; |
286 | | /// Edge list, used if stencil shadow casting is enabled |
287 | | EdgeData* mEdgeList; |
288 | | /// Is a vertex program in use somewhere in this group? |
289 | | bool mVertexProgramInUse; |
290 | | /// List of shadow renderables |
291 | | ShadowCaster::ShadowRenderableList mShadowRenderables; |
292 | | public: |
293 | | LODBucket(Region* parent, unsigned short lod, Real lodValue); |
294 | | virtual ~LODBucket(); |
295 | 0 | Region* getParent(void) { return mParent; } |
296 | | /// Get the LOD index |
297 | 0 | ushort getLod(void) const { return mLod; } |
298 | | /// Get the LOD value |
299 | 0 | Real getLodValue(void) const { return mLodValue; } |
300 | | /// Assign a queued submesh to this bucket, using specified mesh LOD |
301 | | void assign(QueuedSubMesh* qsm, ushort atLod); |
302 | | /// Build |
303 | | void build(bool stencilShadows); |
304 | | /// Add children to the render queue |
305 | | void addRenderables(RenderQueue* queue, uint8 group, |
306 | | Real lodValue); |
307 | | /// Iterator over the materials in this LOD |
308 | | typedef MapIterator<MaterialBucketMap> MaterialIterator; |
309 | | /// Get an iterator over the materials in this LOD |
310 | 0 | const MaterialBucketMap& getMaterialBuckets() const { return mMaterialBucketMap; } |
311 | | /// @deprecated use getMaterialBuckets() |
312 | | OGRE_DEPRECATED MaterialIterator getMaterialIterator(void); |
313 | | /// Dump contents for diagnostics |
314 | | _OgreExport friend std::ostream& operator<<(std::ostream& o, const LODBucket& b); |
315 | | void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); |
316 | 0 | EdgeData* getEdgeList() const { return mEdgeList; } |
317 | 0 | ShadowCaster::ShadowRenderableList& getShadowRenderableList() { return mShadowRenderables; } |
318 | 0 | bool isVertexProgramInUse() const { return mVertexProgramInUse; } |
319 | | void updateShadowRenderables(const Vector4& lightPos, const HardwareIndexBufferPtr& indexBuffer, |
320 | | Real extrusionDistance, int flags = 0); |
321 | | }; |
322 | | /** The details of a topological region which is the highest level of |
323 | | partitioning for this class. |
324 | | |
325 | | The size & shape of regions entirely depends on the SceneManager |
326 | | specific implementation. It is a MovableObject since it will be |
327 | | attached to a node based on the local centre - in practice it |
328 | | won't actually move (although in theory it could). |
329 | | */ |
330 | | class _OgreExport Region : public MovableObject |
331 | | { |
332 | | friend class MaterialBucket; |
333 | | friend class GeometryBucket; |
334 | | public: |
335 | | /// list of LOD Buckets in this region |
336 | | typedef std::vector<LODBucket*> LODBucketList; |
337 | | private: |
338 | | /// Parent static geometry |
339 | | StaticGeometry* mParent; |
340 | | /// Local list of queued meshes (not used for deallocation) |
341 | | QueuedSubMeshList mQueuedSubMeshes; |
342 | | /// Unique identifier for the region |
343 | | uint32 mRegionID; |
344 | | /// Center of the region |
345 | | Vector3 mCentre; |
346 | | /// LOD values as built up - use the max at each level |
347 | | Mesh::LodValueList mLodValues; |
348 | | /// Local AABB relative to region centre |
349 | | AxisAlignedBox mAABB; |
350 | | /// Local bounding radius |
351 | | Real mBoundingRadius; |
352 | | /// The current LOD level, as determined from the last camera |
353 | | ushort mCurrentLod; |
354 | | /// Current LOD value, passed on to do material LOD later |
355 | | Real mLodValue; |
356 | | /// List of LOD buckets |
357 | | LODBucketList mLodBucketList; |
358 | | /// List of lights for this region |
359 | | mutable LightList mLightList; |
360 | | /// LOD strategy reference |
361 | | const LodStrategy *mLodStrategy; |
362 | | /// Current camera |
363 | | Camera *mCamera; |
364 | | /// Cached squared view depth value to avoid recalculation by GeometryBucket |
365 | | Real mSquaredViewDepth; |
366 | | |
367 | | public: |
368 | | Region(StaticGeometry* parent, const String& name, SceneManager* mgr, |
369 | | uint32 regionID, const Vector3& centre); |
370 | | virtual ~Region(); |
371 | | // more fields can be added in subclasses |
372 | 0 | StaticGeometry* getParent(void) const { return mParent;} |
373 | | /// Assign a queued mesh to this region, read for final build |
374 | | void assign(QueuedSubMesh* qmesh); |
375 | | /// Build this region |
376 | | void build(bool stencilShadows); |
377 | | /// Get the region ID of this region |
378 | 0 | uint32 getID(void) const { return mRegionID; } |
379 | | /// Get the centre point of the region |
380 | 0 | const Vector3& getCentre(void) const { return mCentre; } |
381 | | const String& getMovableType(void) const override; |
382 | | void _notifyCurrentCamera(Camera* cam) override; |
383 | | const AxisAlignedBox& getBoundingBox(void) const override; |
384 | | Real getBoundingRadius(void) const override; |
385 | | void _updateRenderQueue(RenderQueue* queue) override; |
386 | | /// @copydoc MovableObject::visitRenderables |
387 | | void visitRenderables(Renderable::Visitor* visitor, |
388 | | bool debugRenderables = false) override; |
389 | | bool isVisible(void) const override; |
390 | | uint32 getTypeFlags(void) const override; |
391 | | |
392 | | typedef VectorIterator<LODBucketList> LODIterator; |
393 | | /// @deprecated use getLODBuckets() |
394 | | OGRE_DEPRECATED LODIterator getLODIterator(void); |
395 | | /// Get an list of the LODs in this region |
396 | 0 | const LODBucketList& getLODBuckets() const { return mLodBucketList; } |
397 | | const ShadowRenderableList& |
398 | | getShadowVolumeRenderableList(const Light* light, const HardwareIndexBufferPtr& indexBuffer, |
399 | | size_t& indexBufferUsedSize, float extrusionDistance, |
400 | | int flags = 0) override; |
401 | | EdgeData* getEdgeList(void) override; |
402 | | |
403 | | void _releaseManualHardwareResources() override; |
404 | | void _restoreManualHardwareResources() override; |
405 | | |
406 | | /// Dump contents for diagnostics |
407 | | _OgreExport friend std::ostream& operator<<(std::ostream& o, const Region& r); |
408 | | |
409 | | }; |
410 | | /** Indexed region map based on packed x/y/z region index, 10 bits for |
411 | | each axis. |
412 | | |
413 | | Regions are indexed 0-1023 in all axes, where for example region |
414 | | 0 in the x axis begins at mOrigin.x + (mRegionDimensions.x * -512), |
415 | | and region 1023 ends at mOrigin + (mRegionDimensions.x * 512). |
416 | | */ |
417 | | typedef std::map<uint32, Region*> RegionMap; |
418 | | private: |
419 | | // General state & settings |
420 | | SceneManager* mOwner; |
421 | | String mName; |
422 | | Real mUpperDistance; |
423 | | Real mSquaredUpperDistance; |
424 | | bool mCastShadows; |
425 | | Vector3 mRegionDimensions; |
426 | | Vector3 mHalfRegionDimensions; |
427 | | Vector3 mOrigin; |
428 | | bool mVisible; |
429 | | /// The render queue to use when rendering this object |
430 | | uint8 mRenderQueueID; |
431 | | /// Flags whether the RenderQueue's default should be used. |
432 | | bool mRenderQueueIDSet; |
433 | | /// Stores the visibility flags for the regions |
434 | | uint32 mVisibilityFlags; |
435 | | |
436 | | QueuedSubMeshList mQueuedSubMeshes; |
437 | | |
438 | | /// List of geometry which has been optimised for SubMesh use |
439 | | /// This is the primary storage used for cleaning up later |
440 | | OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList; |
441 | | |
442 | | /** Cached links from SubMeshes to (potentially optimised) geometry |
443 | | This is not used for deletion since the lookup may reference |
444 | | original vertex data |
445 | | */ |
446 | | SubMeshGeometryLookup mSubMeshGeometryLookup; |
447 | | |
448 | | /// Map of regions |
449 | | RegionMap mRegionMap; |
450 | | |
451 | | /** Virtual method for getting a region most suitable for the |
452 | | passed in bounds. Can be overridden by subclasses. |
453 | | */ |
454 | | virtual Region* getRegion(const AxisAlignedBox& bounds, bool autoCreate); |
455 | | /** Get the region within which a point lies */ |
456 | | virtual Region* getRegion(const Vector3& point, bool autoCreate); |
457 | | /** Get the region using indexes */ |
458 | | virtual Region* getRegion(ushort x, ushort y, ushort z, bool autoCreate); |
459 | | /** Get the region using a packed index, returns null if it doesn't exist. */ |
460 | | virtual Region* getRegion(uint32 index); |
461 | | /** Get the region indexes for a point. |
462 | | */ |
463 | | virtual void getRegionIndexes(const Vector3& point, |
464 | | ushort& x, ushort& y, ushort& z); |
465 | | /** Pack 3 indexes into a single index value |
466 | | */ |
467 | | virtual uint32 packIndex(ushort x, ushort y, ushort z); |
468 | | /** Get the volume intersection for an indexed region with some bounds. |
469 | | */ |
470 | | virtual Real getVolumeIntersection(const AxisAlignedBox& box, |
471 | | ushort x, ushort y, ushort z); |
472 | | /** Get the bounds of an indexed region. |
473 | | */ |
474 | | virtual AxisAlignedBox getRegionBounds(ushort x, ushort y, ushort z); |
475 | | /** Get the centre of an indexed region. |
476 | | */ |
477 | | virtual Vector3 getRegionCentre(ushort x, ushort y, ushort z); |
478 | | /** Calculate world bounds from a set of vertex data. */ |
479 | | virtual AxisAlignedBox calculateBounds(VertexData* vertexData, |
480 | | const Vector3& position, const Quaternion& orientation, |
481 | | const Vector3& scale); |
482 | | /** Look up or calculate the geometry data to use for this SubMesh */ |
483 | | SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm); |
484 | | /** Split some shared geometry into dedicated geometry. */ |
485 | | void splitGeometry(VertexData* vd, IndexData* id, |
486 | | SubMeshLodGeometryLink* targetGeomLink); |
487 | | |
488 | | typedef std::map<size_t, size_t> IndexRemap; |
489 | | /** Method for figuring out which vertices are used by an index buffer |
490 | | and calculating a remap lookup for a vertex buffer just containing |
491 | | those vertices. |
492 | | */ |
493 | | template <typename T> |
494 | | void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap) |
495 | 0 | { |
496 | 0 | remap.clear(); |
497 | 0 | for (size_t i = 0; i < numIndexes; ++i) |
498 | 0 | { |
499 | | // use insert since duplicates are silently discarded |
500 | 0 | remap.emplace(*pBuffer++, remap.size()); |
501 | | // this will have mapped oldindex -> new index IF oldindex |
502 | | // wasn't already there |
503 | 0 | } |
504 | 0 | } Unexecuted instantiation: void Ogre::StaticGeometry::buildIndexRemap<unsigned int>(unsigned int*, unsigned long, std::__1::map<unsigned long, unsigned long, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, unsigned long> > >&) Unexecuted instantiation: void Ogre::StaticGeometry::buildIndexRemap<unsigned short>(unsigned short*, unsigned long, std::__1::map<unsigned long, unsigned long, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, unsigned long> > >&) |
505 | | /** Method for altering indexes based on a remap. */ |
506 | | template <typename T> |
507 | | void remapIndexes(T* src, T* dst, const IndexRemap& remap, |
508 | | size_t numIndexes) |
509 | 0 | { |
510 | 0 | for (size_t i = 0; i < numIndexes; ++i) |
511 | 0 | { |
512 | | // look up original and map to target |
513 | 0 | IndexRemap::const_iterator ix = remap.find(*src++); |
514 | 0 | assert(ix != remap.end()); |
515 | 0 | *dst++ = static_cast<T>(ix->second); |
516 | 0 | } |
517 | 0 | } Unexecuted instantiation: void Ogre::StaticGeometry::remapIndexes<unsigned int>(unsigned int*, unsigned int*, std::__1::map<unsigned long, unsigned long, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, unsigned long> > > const&, unsigned long) Unexecuted instantiation: void Ogre::StaticGeometry::remapIndexes<unsigned short>(unsigned short*, unsigned short*, std::__1::map<unsigned long, unsigned long, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, unsigned long> > > const&, unsigned long) |
518 | | |
519 | | public: |
520 | | /** |
521 | | You should not construct instances of this class directly; instead, call |
522 | | SceneManager::createStaticGeometry, which gives the SceneManager the |
523 | | option of providing you with a specialised version of this class if it |
524 | | wishes, and also handles the memory management for you like other classes. |
525 | | */ |
526 | | StaticGeometry(SceneManager* owner, const String& name); |
527 | | /// Destructor |
528 | | virtual ~StaticGeometry(); |
529 | | |
530 | | /// Get the name of this object |
531 | 0 | const String& getName(void) const { return mName; } |
532 | | /** Adds an Entity to the static geometry. |
533 | | |
534 | | This method takes an existing Entity and adds its details to the |
535 | | list of elements to include when building. Note that the Entity |
536 | | itself is not copied or referenced in this method; an Entity is |
537 | | passed simply so that you can change the materials of attached |
538 | | SubEntity objects if you want. You can add the same Entity |
539 | | instance multiple times with different material settings |
540 | | completely safely, and destroy the Entity before destroying |
541 | | this StaticGeometry if you like. The Entity passed in is simply |
542 | | used as a definition. |
543 | | @note Must be called before 'build'. |
544 | | @param ent The Entity to use as a definition (the Mesh and Materials |
545 | | referenced will be recorded for the build call). |
546 | | @param position The world position at which to add this Entity |
547 | | @param orientation The world orientation at which to add this Entity |
548 | | @param scale The scale at which to add this entity |
549 | | @attention Do not unload the Mesh used by the Entity until after you have |
550 | | called build(), as the geometry is read at that time. |
551 | | */ |
552 | | virtual void addEntity(Entity* ent, const Vector3& position, |
553 | | const Quaternion& orientation = Quaternion::IDENTITY, |
554 | | const Vector3& scale = Vector3::UNIT_SCALE); |
555 | | |
556 | | /** Adds all the Entity objects attached to a SceneNode and all it's |
557 | | children to the static geometry. |
558 | | |
559 | | This method performs just like addEntity, except it adds all the |
560 | | entities attached to an entire sub-tree to the geometry. |
561 | | The position / orientation / scale parameters are taken from the |
562 | | node structure instead of being specified manually. |
563 | | @note |
564 | | The SceneNode you pass in will not be automatically detached from |
565 | | it's parent, so if you have this node already attached to the scene |
566 | | graph, you will need to remove it if you wish to avoid the overhead |
567 | | of rendering <i>both</i> the original objects and their new static |
568 | | versions! We don't do this for you in case you are preparing this |
569 | | in advance and so don't want the originals detached yet. |
570 | | @note Must be called before 'build'. |
571 | | @attention Do not unload the Mesh used by the Entities until after you have |
572 | | called build(), as the geometry is read at that time. |
573 | | @param node Pointer to the node to use to provide a set of Entity |
574 | | templates |
575 | | */ |
576 | | virtual void addSceneNode(const SceneNode* node); |
577 | | |
578 | | /** Build the geometry. |
579 | | |
580 | | Based on all the entities which have been added, and the batching |
581 | | options which have been set, this method constructs the batched |
582 | | geometry structures required. The batches are added to the scene |
583 | | and will be rendered unless you specifically hide them. |
584 | | @note |
585 | | Once you have called this method, you can no longer add any more |
586 | | entities. |
587 | | */ |
588 | | virtual void build(void); |
589 | | |
590 | | /** Destroys all the built geometry state (reverse of build). |
591 | | |
592 | | You can call build() again after this and it will pick up all the |
593 | | same entities / nodes you queued last time. |
594 | | */ |
595 | | void destroy(void); |
596 | | |
597 | | /** Clears any of the entities / nodes added to this geometry and |
598 | | destroys anything which has already been built. |
599 | | */ |
600 | | void reset(void); |
601 | | |
602 | | /** Sets the distance at which batches are no longer rendered. |
603 | | |
604 | | This lets you turn off batches at a given distance. This can be |
605 | | useful for things like detail meshes (grass, foliage etc) and could |
606 | | be combined with a shader which fades the geometry out beforehand |
607 | | to lessen the effect. |
608 | | @param dist Distance beyond which the batches will not be rendered |
609 | | (the default is 0, which means batches are always rendered). |
610 | | */ |
611 | 0 | virtual void setRenderingDistance(Real dist) { |
612 | 0 | mUpperDistance = dist; |
613 | 0 | mSquaredUpperDistance = mUpperDistance * mUpperDistance; |
614 | 0 | } |
615 | | |
616 | | /** Gets the distance at which batches are no longer rendered. */ |
617 | 0 | virtual Real getRenderingDistance(void) const { return mUpperDistance; } |
618 | | |
619 | | /** Gets the squared distance at which batches are no longer rendered. */ |
620 | | virtual Real getSquaredRenderingDistance(void) const |
621 | 0 | { return mSquaredUpperDistance; } |
622 | | |
623 | | /** Hides or shows all the batches. */ |
624 | | virtual void setVisible(bool visible); |
625 | | |
626 | | /** Are the batches visible? */ |
627 | 0 | virtual bool isVisible(void) const { return mVisible; } |
628 | | |
629 | | /** Sets whether this geometry should cast shadows. |
630 | | |
631 | | No matter what the settings on the original entities, |
632 | | the StaticGeometry class defaults to not casting shadows. |
633 | | This is because, being static, unless you have moving lights |
634 | | you'd be better to use precalculated shadows of some sort. |
635 | | However, if you need them, you can enable them using this |
636 | | method. If the SceneManager is set up to use stencil shadows, |
637 | | edge lists will be copied from the underlying meshes on build. |
638 | | It is essential that all meshes support stencil shadows in this |
639 | | case. |
640 | | @note If you intend to use stencil shadows, you must set this to |
641 | | true before calling 'build' as well as making sure you set the |
642 | | scene's shadow type (that should always be the first thing you do |
643 | | anyway). You can turn shadows off temporarily but they can never |
644 | | be turned on if they were not at the time of the build. |
645 | | */ |
646 | | virtual void setCastShadows(bool castShadows); |
647 | | /// Will the geometry from this object cast shadows? |
648 | 0 | virtual bool getCastShadows(void) { return mCastShadows; } |
649 | | |
650 | | /** Sets the size of a single region of geometry. |
651 | | |
652 | | This method allows you to configure the physical world size of |
653 | | each region, so you can balance culling against batch size. Entities |
654 | | will be fitted within the batch they most closely fit, and the |
655 | | eventual bounds of each batch may well be slightly larger than this |
656 | | if they overlap a little. The default is Vector3(1000, 1000, 1000). |
657 | | @note Must be called before 'build'. |
658 | | @param size Vector3 expressing the 3D size of each region. |
659 | | */ |
660 | 0 | virtual void setRegionDimensions(const Vector3& size) { |
661 | 0 | mRegionDimensions = size; |
662 | 0 | mHalfRegionDimensions = size * 0.5; |
663 | 0 | } |
664 | | /** Gets the size of a single batch of geometry. */ |
665 | 0 | virtual const Vector3& getRegionDimensions(void) const { return mRegionDimensions; } |
666 | | /** Sets the origin of the geometry. |
667 | | |
668 | | This method allows you to configure the world centre of the geometry, |
669 | | thus the place which all regions surround. You probably don't need |
670 | | to mess with this unless you have a seriously large world, since the |
671 | | default set up can handle an area 1024 * mRegionDimensions, and |
672 | | the sparseness of population is no issue when it comes to rendering. |
673 | | The default is Vector3(0,0,0). |
674 | | @note Must be called before 'build'. |
675 | | @param origin Vector3 expressing the 3D origin of the geometry. |
676 | | */ |
677 | 0 | virtual void setOrigin(const Vector3& origin) { mOrigin = origin; } |
678 | | /** Gets the origin of this geometry. */ |
679 | 0 | virtual const Vector3& getOrigin(void) const { return mOrigin; } |
680 | | |
681 | | /// Sets the visibility flags of all the regions at once |
682 | | void setVisibilityFlags(uint32 flags); |
683 | | /// Returns the visibility flags of the regions |
684 | | uint32 getVisibilityFlags() const; |
685 | | |
686 | | /** Sets the render queue group this object will be rendered through. |
687 | | |
688 | | Render queues are grouped to allow you to more tightly control the ordering |
689 | | of rendered objects. If you do not call this method, all objects default |
690 | | to the default queue (RenderQueue::getDefaultQueueGroup), which is fine for |
691 | | most objects. You may want to alter this if you want to perform more complex |
692 | | rendering. |
693 | | @par |
694 | | See RenderQueue for more details. |
695 | | @param queueID Enumerated value of the queue group to use. |
696 | | */ |
697 | | virtual void setRenderQueueGroup(uint8 queueID); |
698 | | |
699 | | /** Gets the queue group for this entity, see setRenderQueueGroup for full details. */ |
700 | | virtual uint8 getRenderQueueGroup(void) const; |
701 | | /// @copydoc MovableObject::visitRenderables |
702 | | void visitRenderables(Renderable::Visitor* visitor, |
703 | | bool debugRenderables = false); |
704 | | |
705 | | /// Iterator for iterating over contained regions |
706 | | typedef MapIterator<RegionMap> RegionIterator; |
707 | | /// Get an list of the regions in this geometry |
708 | 0 | const RegionMap& getRegions() const { return mRegionMap; } |
709 | | /// @deprecated use getRegions() |
710 | | OGRE_DEPRECATED RegionIterator getRegionIterator(void); |
711 | | |
712 | | /** Dump the contents of this StaticGeometry for diagnostic |
713 | | purposes. |
714 | | */ |
715 | | _OgreExport friend std::ostream& operator<<(std::ostream& o, const StaticGeometry& g); |
716 | | }; |
717 | | /** @} */ |
718 | | /** @} */ |
719 | | |
720 | | } |
721 | | |
722 | | #include "OgreHeaderSuffix.h" |
723 | | |
724 | | #endif |
725 | | |