Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreStaticGeometry.h @ 148

Last change on this file since 148 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

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