Coverage Report

Created: 2025-08-28 06:19

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