source: GTP/trunk/App/Demos/Geom/OgreStuff/include/OgreStaticGeometry.h @ 1812

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