Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreInstancedGeometry.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: 35.8 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 __InstancedGeometry_H__
29#define __InstancedGeometry_H__
30
31#include "OgrePrerequisites.h"
32#include "OgreMovableObject.h"
33#include "OgreSimpleRenderable.h"
34#include "OgreSkeleton.h"
35#include "OgreSkeletonInstance.h"
36#include "OgreAnimationTrack.h"
37#include "OgreBone.h"
38#include "OgreIteratorWrappers.h"
39#include "OgreMesh.h"
40#include "OgreHeaderPrefix.h"
41
42namespace Ogre {
43
44        /** \addtogroup Core
45        *  @{
46        */
47        /** \addtogroup Scene
48        *  @{
49        */
50        /** Pre-transforms and batches up meshes for efficient use as instanced geometry
51                in a scene
52        @remarks
53                Shader instancing allows to save both memory and draw calls. While
54                StaticGeometry stores 500 times the same object in a batch to display 500
55                objects, this shader instancing implementation stores only 80 times the object,
56                and then re-uses the vertex data with different shader parameter.
57                Although you save memory, you make more draw call. However, you still
58                make less draw calls than if you were rendering each object independently.
59                Plus, you can move the batched objects independently of one another which
60                you cannot do with StaticGeometry.
61        @par
62                Therefore it is important when you are rendering a lot of geometry to
63                batch things up into as few rendering calls as possible. This
64                class allows you to build a batched object from a series of entities
65                in order to benefit from this behaviour.
66                Batching has implications of it's own though:
67                @li Batched geometry cannot be subdivided; that means that the whole
68                        group will be displayed, or none of it will. This obivously has
69                        culling issues.
70                @li A single material must apply for each batch. In fact this class
71                        allows you to use multiple materials, but you should be aware that
72                        internally this means that there is one batch per material.
73                        Therefore you won't gain as much benefit from the batching if you
74                        use many different materials; try to keep the number down.
75        @par
76                The bounding box information is computed with object position only.
77                It doesn't take account of the object orientation.
78        @par
79                The LOD settings of both the Mesh and the Materials used in
80                constructing this instanced geometry will be respected. This means that
81                if you use meshes/materials which have LOD, batches in the distance
82                will have a lower polygon count or material detail to those in the
83                foreground. Since each mesh might have different LOD distances, during
84                build the furthest distance at each LOD level from all meshes 
85                in that BatchInstance is used. This means all the LOD levels change at the
86                same time, but at the furthest distance of any of them (so quality is
87                not degraded). Be aware that using Mesh LOD in this class will
88                further increase the memory required. Only generated LOD
89                is supported for meshes.
90        @par
91                There are 2 ways you can add geometry to this class; you can add
92                Entity objects directly with predetermined positions, scales and
93                orientations, or you can add an entire SceneNode and it's subtree,
94                including all the objects attached to it. Once you've added everything
95                you need to, you have to call build() the fix the geometry in place.
96        @par
97                You should not construct instances of this class directly; instead, call
98                SceneManager::createInstancedGeometry, which gives the SceneManager the
99                option of providing you with a specialised version of this class if it
100                wishes, and also handles the memory management for you like other
101                classes.
102    @note
103                Warning: this class only works with indexed triangle lists at the moment,               do not pass it triangle strips, fans or lines / points, or unindexed geometry.
104        */
105        class _OgreExport  InstancedGeometry : public BatchedGeometryAlloc
106        {
107        public:
108                /** Struct holding geometry optimised per SubMesh / LOD level, ready
109                        for copying to instances.
110                @remarks
111                        Since we're going to be duplicating geometry lots of times, it's
112                        far more important that we don't have redundant vertex data. If a
113                        SubMesh uses shared geometry, or we're looking at a lower LOD, not
114                        all the vertices are being referenced by faces on that submesh.
115                        Therefore to duplicate them, potentially hundreds or even thousands
116                        of times, would be extremely wasteful. Therefore, if a SubMesh at
117                        a given LOD has wastage, we create an optimised version of it's
118                        geometry which is ready for copying with no wastage.
119                */
120                class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc
121                {
122                public:
123                        OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {}
124                        ~OptimisedSubMeshGeometry() 
125                        {
126                                delete vertexData;
127                                delete indexData;
128                        }
129                        VertexData *vertexData;
130                        IndexData *indexData;
131                };
132                typedef list<OptimisedSubMeshGeometry*>::type OptimisedSubMeshGeometryList;
133                /// Saved link between SubMesh at a LOD and vertex/index data
134                /// May point to original or optimised geometry
135                struct SubMeshLodGeometryLink
136                {
137                        VertexData* vertexData;
138                        IndexData* indexData;
139                };
140                typedef vector<SubMeshLodGeometryLink>::type SubMeshLodGeometryLinkList;
141                typedef map<SubMesh*, SubMeshLodGeometryLinkList*>::type SubMeshGeometryLookup;
142                /// Structure recording a queued submesh for the build
143                struct QueuedSubMesh : public BatchedGeometryAlloc
144                {
145                        SubMesh* submesh;
146                        /// Link to LOD list of geometry, potentially optimised
147                        SubMeshLodGeometryLinkList* geometryLodList;
148                        String materialName;
149                        Vector3 position;
150                        Quaternion orientation;
151                        Vector3 scale;
152                        /// Pre-transformed world AABB
153                        AxisAlignedBox worldBounds;
154                        unsigned int ID;
155                };
156                typedef vector<QueuedSubMesh*>::type QueuedSubMeshList;
157                typedef vector<String>::type QueuedSubMeshOriginList;
158                /// Structure recording a queued geometry for low level builds
159                struct QueuedGeometry : public BatchedGeometryAlloc
160                {
161                        SubMeshLodGeometryLink* geometry;
162                        Vector3 position;
163                        Quaternion orientation;
164                        Vector3 scale;
165                        unsigned int ID;
166                };
167                typedef vector<QueuedGeometry*>::type QueuedGeometryList;
168               
169                // forward declarations
170                class LODBucket;
171                class MaterialBucket;
172                class BatchInstance;
173                class InstancedObject;
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 SimpleRenderable
180                {
181                protected:
182                       
183                        /// Geometry which has been queued up pre-build (not for deallocation)
184                        QueuedGeometryList mQueuedGeometry;
185                        /// Pointer to the Batch
186                        InstancedGeometry*mBatch;
187                        /// Pointer to parent bucket
188                        MaterialBucket* mParent;
189                        /// String identifying the vertex / index format
190                        String mFormatString;
191                        /// Vertex information, includes current number of vertices
192                        /// committed to be a part of this bucket
193                        VertexData* mVertexData;
194                        /// Index information, includes index type which limits the max
195                        /// number of vertices which are allowed in one bucket
196                        IndexData* mIndexData;
197                        /// Size of indexes
198                        HardwareIndexBuffer::IndexType mIndexType;
199                        /// Maximum vertex indexable
200                        size_t mMaxVertexIndex;
201                        ///     Index of the Texcoord where the index is stored
202                        unsigned short mTexCoordIndex;
203                        AxisAlignedBox mAABB;
204
205                        template<typename T>
206                        void copyIndexes(const T* src, T* dst, size_t count, size_t indexOffset)
207                        {
208                                if (indexOffset == 0)
209                                {
210                                        memcpy(dst, src, sizeof(T) * count);
211                                }
212                                else
213                                {
214                                        while(count--)
215                                        {
216                                                *dst++ = static_cast<T>(*src++ + indexOffset);
217                                        }
218                                }
219                        }
220
221                        void _initGeometryBucket(const VertexData* vData, const IndexData* iData);
222                        void _initGeometryBucket(GeometryBucket* bucket);
223
224                public:
225                        GeometryBucket(MaterialBucket* parent, const String& formatString, 
226                                const VertexData* vData, const IndexData* iData);
227                        GeometryBucket(const String& name, MaterialBucket* parent, const String& formatString, 
228                                const VertexData* vData, const IndexData* iData);
229                        GeometryBucket(MaterialBucket* parent,const String& formatString,GeometryBucket*bucket);
230                        GeometryBucket(const String& name, MaterialBucket* parent,const String& formatString,GeometryBucket*bucket);
231                        virtual ~GeometryBucket();
232                        MaterialBucket* getParent(void) { return mParent; }
233                        Real getBoundingRadius(void) const;
234                        /// Get the vertex data for this geometry
235                        const VertexData* getVertexData(void) const { return mVertexData; }
236                        /// Get the index data for this geometry
237                        const IndexData* getIndexData(void) const { return mIndexData; }
238                        /// @copydoc Renderable::getMaterial
239                        const MaterialPtr& getMaterial(void) const;
240                        Technique* getTechnique(void) const;
241                void getWorldTransforms(Matrix4* xform) const;
242                        virtual unsigned short getNumWorldTransforms(void) const ;
243                        Real getSquaredViewDepth(const Camera* cam) const;
244                const LightList& getLights(void) const;
245                        bool getCastsShadows(void) const;
246                        String getFormatString(void) const;
247                        /** Try to assign geometry to this bucket.
248                        @return false if there is no room left in this bucket
249                        */
250                        bool assign(QueuedGeometry* qsm);
251                        /// Build
252                        void build();
253                        /// Dump contents for diagnostics
254                        void dump(std::ofstream& of) const;
255                        /// Return the BoundingBox information. Useful when cloning the batch instance.
256                        AxisAlignedBox & getAABB(void){return mAABB;}
257                        /// @copydoc MovableObject::visitRenderables
258                        void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables);
259
260                };
261                class _OgreExport  InstancedObject : public BatchedGeometryAlloc
262                {
263                        friend class GeometryBucket;
264                public:
265                         enum TransformSpace
266        {
267            /// Transform is relative to the local space
268            TS_LOCAL,
269            /// Transform is relative to the space of the parent node
270            TS_PARENT,
271            /// Transform is relative to world space
272            TS_WORLD
273        };
274                        /// list of Geometry Buckets that contains the instanced object
275                        typedef vector<GeometryBucket*>::type GeometryBucketList;
276                protected:
277                        GeometryBucketList mGeometryBucketList;
278                        unsigned short mIndex;
279                        Matrix4  mTransformation;
280                        Quaternion mOrientation;
281                        Vector3 mScale;
282                        Vector3 mPosition;
283                        SkeletonInstance* mSkeletonInstance;
284                        /// Cached bone matrices, including any world transform
285                        Matrix4 *mBoneWorldMatrices;
286                        /// Cached bone matrices in skeleton local space
287                        Matrix4 *mBoneMatrices;
288                        /// State of animation for animable meshes
289                        AnimationStateSet* mAnimationState;
290                        unsigned short mNumBoneMatrices;
291                        /// Records the last frame in which animation was updated
292                        unsigned long mFrameAnimationLastUpdated;
293                public:
294                        InstancedObject(unsigned short index);
295                        InstancedObject(unsigned short index,SkeletonInstance *skeleton,AnimationStateSet*animations);
296                        ~InstancedObject();
297                        void setPosition( Vector3  position);
298                        const Vector3& getPosition(void) const;
299                        void yaw(const Radian& angle);
300                        void pitch(const Radian& angle);
301                        void roll(const Radian& angle);
302                        void rotate(const Quaternion& q);
303                        void setScale(const Vector3& scale);
304                        const Vector3& getScale() const;
305                void setOrientation(const Quaternion& q);
306                void setPositionAndOrientation(Vector3 p, const Quaternion& q);
307            Quaternion & getOrientation(void);
308                        void addBucketToList(GeometryBucket* bucket);
309                        void needUpdate();
310                        GeometryBucketList&getGeometryBucketList(void){return mGeometryBucketList;}
311                        void translate(const Matrix3& axes, const Vector3& move);
312                        void translate(const Vector3& d);
313                        Matrix3 getLocalAxes(void) const;
314                        void updateAnimation(void);
315                        AnimationState* getAnimationState(const String& name) const;
316                        SkeletonInstance*getSkeletonInstance(void){return mSkeletonInstance;}
317
318                };
319                /** A MaterialBucket is a collection of smaller buckets with the same
320                        Material (and implicitly the same LOD). */
321                class _OgreExport  MaterialBucket : public BatchedGeometryAlloc
322                {
323                public:
324                        /// list of Geometry Buckets in this BatchInstance
325                        typedef vector<GeometryBucket*>::type GeometryBucketList;
326                protected:
327                        /// Pointer to parent LODBucket
328                        LODBucket* mParent;
329                        /// Material being used
330                        String mMaterialName;
331                        /// Pointer to material being used
332                        MaterialPtr mMaterial;
333                        /// Active technique
334                        Technique* mTechnique;
335                        int mLastIndex;
336                        /// list of Geometry Buckets in this BatchInstance
337                        GeometryBucketList mGeometryBucketList;
338                        // index to current Geometry Buckets for a given geometry format
339                        typedef map<String, GeometryBucket*>::type CurrentGeometryMap;
340                        CurrentGeometryMap mCurrentGeometryMap;
341                        /// Get a packed string identifying the geometry format
342                        String getGeometryFormatString(SubMeshLodGeometryLink* geom);
343                       
344                public:
345                        MaterialBucket(LODBucket* parent, const String& materialName);
346                        virtual ~MaterialBucket();
347                        LODBucket* getParent(void) { return mParent; }
348                        /// Get the material name
349                        const String& getMaterialName(void) const { return mMaterialName; }
350                        /// Assign geometry to this bucket
351                        void assign(QueuedGeometry* qsm);
352                        /// Build
353                        void build();
354                        /// Add children to the render queue
355                        void addRenderables(RenderQueue* queue, uint8 group, 
356                                Real lodValue);
357                        /// Get the material for this bucket
358                        const MaterialPtr& getMaterial(void) const { return mMaterial; }
359                        /// Iterator over geometry
360                        typedef VectorIterator<GeometryBucketList> GeometryIterator;
361                        /// Get an iterator over the contained geometry
362                        GeometryIterator getGeometryIterator(void);
363                        /// Get the current Technique
364                        Technique* getCurrentTechnique(void) const { return mTechnique; }
365                        /// Dump contents for diagnostics
366                        void dump(std::ofstream& of) const;
367                        /// Return the geometry map
368                        MaterialBucket::CurrentGeometryMap* getMaterialBucketMap(void) const;
369                        /// Return the geometry list
370                        MaterialBucket::GeometryBucketList*getGeometryBucketList(void) const;
371                        /// fill in the map and the list
372                        void updateContainers(GeometryBucket* bucket, const String &format);
373                        void setLastIndex(int index){mLastIndex=index;}
374                        int getLastIndex(){return mLastIndex;}
375                        void setMaterial(const String & name);
376                        void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables);
377               
378                };
379                /** A LODBucket is a collection of smaller buckets with the same LOD.
380                @remarks
381                        LOD refers to Mesh LOD here. Material LOD can change separately
382                        at the next bucket down from this.
383                */
384                class _OgreExport  LODBucket : public BatchedGeometryAlloc
385                {
386                public:
387                        /// Lookup of Material Buckets in this BatchInstance
388                        typedef map<String, MaterialBucket*>::type MaterialBucketMap;
389                protected:
390                        /// Pointer to parent BatchInstance
391                        BatchInstance* mParent;
392                        /// LOD level (0 == full LOD)
393                        unsigned short mLod;
394                        /// LOD value at which this LOD starts to apply (squared)
395                        Real mLodValue;
396                        /// Lookup of Material Buckets in this BatchInstance
397                        MaterialBucketMap mMaterialBucketMap;
398                        /// Geometry queued for a single LOD (deallocated here)
399                        QueuedGeometryList mQueuedGeometryList;
400                public:
401                        LODBucket(BatchInstance* parent, unsigned short lod, Real lodValue);
402                        virtual ~LODBucket();
403                        BatchInstance* getParent(void) { return mParent; }
404                        /// Get the LOD index
405                        ushort getLod(void) const { return mLod; }
406                        /// Get the LOD value
407                        Real getLodValue(void) const { return mLodValue; }
408                        /// Assign a queued submesh to this bucket, using specified mesh LOD
409                        void assign(QueuedSubMesh* qsm, ushort atLod);
410                        /// Build
411                        void build();
412                        /// Add children to the render queue
413                        void addRenderables(RenderQueue* queue, uint8 group, 
414                                Real lodValue);
415                        /// Iterator over the materials in this LOD
416                        typedef MapIterator<MaterialBucketMap> MaterialIterator;
417                        /// Get an iterator over the materials in this LOD
418                        MaterialIterator getMaterialIterator(void);
419                        /// Dump contents for diagnostics
420                        void dump(std::ofstream& of) const;
421                        /// fill the map
422                        void updateContainers(MaterialBucket* bucket, String& name );
423                        void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables);
424                       
425                };
426                /** The details of a topological BatchInstance which is the highest level of
427                        partitioning for this class.
428                @remarks
429                        The size & shape of BatchInstances entirely depends on the SceneManager
430                        specific implementation. It is a MovableObject since it will be
431                        attached to a node based on the local centre - in practice it
432                        won't actually move (although in theory it could).
433                */
434                class _OgreExport  BatchInstance : public MovableObject
435                {
436            friend class MaterialBucket;
437                        public:
438               
439
440                        /// list of LOD Buckets in this BatchInstance
441                        typedef vector<LODBucket*>::type LODBucketList;
442                        typedef map<unsigned short, InstancedObject*>::type ObjectsMap;
443                        typedef MapIterator<ObjectsMap> InstancedObjectIterator;
444                protected:
445                       
446                        /// Parent static geometry
447                        InstancedGeometry* mParent;
448                        /// Scene manager link
449                        SceneManager* mSceneMgr;
450                        /// Scene node
451                        SceneNode* mNode;
452                        /// Local list of queued meshes (not used for deallocation)
453                        QueuedSubMeshList mQueuedSubMeshes;
454                        /// Unique identifier for the BatchInstance
455                        uint32 mBatchInstanceID;
456
457                        ObjectsMap mInstancesMap;
458                public:
459                        /// LOD values as built up - use the max at each level
460                        Mesh::LodValueList mLodValues;
461                        /// Local AABB relative to BatchInstance centre
462                        AxisAlignedBox mAABB;
463                        /// Local bounding radius
464                        Real mBoundingRadius;
465                        /// The current LOD level, as determined from the last camera
466                        ushort mCurrentLod;
467                        /// Current LOD value, passed on to do material LOD later
468                        Real mLodValue;
469            /// Current camera, passed on to do material LOD later
470            Camera *mCamera;
471            /// Cached squared view depth value to avoid recalculation by GeometryBucket
472            Real mSquaredViewDepth;
473                protected:
474                        /// List of LOD buckets                 
475                        LODBucketList mLodBucketList;
476            /// LOD strategy reference
477            const LodStrategy *mLodStrategy;
478
479                public:
480                        BatchInstance(InstancedGeometry* parent, const String& name, SceneManager* mgr, 
481                                uint32 BatchInstanceID);
482                        virtual ~BatchInstance();
483                        // more fields can be added in subclasses
484                        InstancedGeometry* getParent(void) const { return mParent;}
485                        /// Assign a queued mesh to this BatchInstance, read for final build
486                        void assign(QueuedSubMesh* qmesh);
487                        /// Build this BatchInstance
488                        void build();
489                        /// Get the BatchInstance ID of this BatchInstance
490                        uint32 getID(void) const { return mBatchInstanceID; }
491                        /// Get the centre point of the BatchInstance
492//                      const Vector3& getCentre(void) const { return mCentre; }
493                        const String& getMovableType(void) const;
494                        void _notifyCurrentCamera(Camera* cam);
495                        const AxisAlignedBox& getBoundingBox(void) const;
496                        void  setBoundingBox(AxisAlignedBox& box);
497                        Real getBoundingRadius(void) const;
498                        void _updateRenderQueue(RenderQueue* queue);
499                        bool isVisible(void) const;
500                        /// @copydoc MovableObject::visitRenderables
501                        void visitRenderables(Renderable::Visitor* visitor, 
502                                bool debugRenderables = false);
503
504                //      uint32 getTypeFlags(void) const;
505
506                        typedef VectorIterator<LODBucketList> LODIterator;
507                        /// Get an iterator over the LODs in this BatchInstance
508                        LODIterator getLODIterator(void);
509                        /// Shared set of lights for all GeometryBuckets
510                        const LightList& getLights(void) const;
511
512                        /// update the bounding box of the BatchInstance according to the positions of the objects
513                        void updateBoundingBox();
514
515                        /// Dump contents for diagnostics
516                        void dump(std::ofstream& of) const;
517                        /// fill in the list
518                        void updateContainers(LODBucket* bucket );
519                        /// attach the BatchInstance to the scene
520                        void attachToScene();
521                        void addInstancedObject(unsigned short index, InstancedObject* object);
522                        InstancedObject*  isInstancedObjectPresent(unsigned short index);
523                        InstancedObjectIterator getObjectIterator();
524                        SceneNode*getSceneNode(void){return mNode;}
525                        ObjectsMap& getInstancesMap(void){return  mInstancesMap;}
526                        /// change the shader used to render the batch instance
527                       
528                };
529                /** Indexed BatchInstance map based on packed x/y/z BatchInstance index, 10 bits for
530                        each axis.
531                */
532                typedef map<uint32, BatchInstance*>::type BatchInstanceMap;
533                /** Simple vectors where are stored all the render operations of the Batch.
534                        This vector is used when we want to delete the batch, in order to delete only one time each
535                        render operation.
536
537                */
538                typedef vector<RenderOperation*>::type RenderOperationVector;
539        protected:
540                // General state & settings
541                SceneManager* mOwner;
542                String mName;
543                bool mBuilt;
544                Real mUpperDistance;
545                Real mSquaredUpperDistance;
546                bool mCastShadows;
547                Vector3 mBatchInstanceDimensions;
548                Vector3 mHalfBatchInstanceDimensions;
549                Vector3 mOrigin;
550                bool mVisible;
551        /// Flags to indicate whether the World Transform Inverse matrices are passed to the shaders
552        bool mProvideWorldInverses;
553        /// The render queue to use when rendering this object
554        uint8 mRenderQueueID;
555                /// Flags whether the RenderQueue's default should be used.
556                bool mRenderQueueIDSet;
557                /// number of objects in the batch
558                unsigned int mObjectCount;
559                QueuedSubMeshList mQueuedSubMeshes;
560                BatchInstance*mInstancedGeometryInstance;
561                /**this is just a pointer to the base skeleton that will be used for each animated object in the batches
562                This pointer has a value only during the creation of the InstancedGeometry
563                */
564                SkeletonPtr mBaseSkeleton;
565                SkeletonInstance *mSkeletonInstance;
566                /**This is the main animation state. All "objects" in the batch will use an instance of this animation
567                state
568                */
569                AnimationStateSet* mAnimationState;
570                /// List of geometry which has been optimised for SubMesh use
571                /// This is the primary storage used for cleaning up later
572                OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList;
573
574                /** Cached links from SubMeshes to (potentially optimised) geometry
575                        This is not used for deletion since the lookup may reference
576                        original vertex data
577                */
578                SubMeshGeometryLookup mSubMeshGeometryLookup;
579                       
580                /// Map of BatchInstances
581                BatchInstanceMap mBatchInstanceMap;
582                /** This vector stores all the renderOperation used in the batch.
583                See the type definition for more details.
584                */
585                RenderOperationVector mRenderOps;
586                /** Virtual method for getting a BatchInstance most suitable for the
587                        passed in bounds. Can be overridden by subclasses.
588                */
589                virtual BatchInstance* getBatchInstance(const AxisAlignedBox& bounds, bool autoCreate);
590                /** Get the BatchInstance within which a point lies */
591                virtual BatchInstance* getBatchInstance(const Vector3& point, bool autoCreate);
592                /** Get the BatchInstance using indexes */
593                virtual BatchInstance* getBatchInstance(ushort x, ushort y, ushort z, bool autoCreate);
594                /** Get the BatchInstance using a packed index, returns null if it doesn't exist. */
595                virtual BatchInstance* getBatchInstance(uint32 index);
596                /** Get the BatchInstance indexes for a point.
597                */
598                virtual void getBatchInstanceIndexes(const Vector3& point, 
599                        ushort& x, ushort& y, ushort& z);
600                /** get the first BatchInstance or create on if it does not exists.
601                */
602                virtual BatchInstance* getInstancedGeometryInstance(void);
603                /** Pack 3 indexes into a single index value
604                */
605                virtual uint32 packIndex(ushort x, ushort y, ushort z);
606                /** Get the volume intersection for an indexed BatchInstance with some bounds.
607                */
608                virtual Real getVolumeIntersection(const AxisAlignedBox& box, 
609                        ushort x, ushort y, ushort z);
610                /** Get the bounds of an indexed BatchInstance.
611                */
612                virtual AxisAlignedBox getBatchInstanceBounds(ushort x, ushort y, ushort z);
613                /** Get the centre of an indexed BatchInstance.
614                */
615                virtual Vector3 getBatchInstanceCentre(ushort x, ushort y, ushort z);
616                /** Calculate world bounds from a set of vertex data. */
617                virtual AxisAlignedBox calculateBounds(VertexData* vertexData, 
618                        const Vector3& position, const Quaternion& orientation, 
619                        const Vector3& scale);
620                /** Look up or calculate the geometry data to use for this SubMesh */
621                SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm);
622                /** Split some shared geometry into dedicated geometry. */
623                void splitGeometry(VertexData* vd, IndexData* id, 
624                        SubMeshLodGeometryLink* targetGeomLink);
625
626                typedef map<size_t, size_t>::type IndexRemap;
627                /** Method for figuring out which vertices are used by an index buffer
628                        and calculating a remap lookup for a vertex buffer just containing
629                        those vertices.
630                */
631                template <typename T>
632                void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap)
633                {
634                        remap.clear();
635                        for (size_t i = 0; i < numIndexes; ++i)
636                        {
637                                // use insert since duplicates are silently discarded
638                                remap.insert(IndexRemap::value_type(*pBuffer++, remap.size()));
639                                // this will have mapped oldindex -> new index IF oldindex
640                                // wasn't already there
641                        }
642                }
643                /** Method for altering indexes based on a remap. */
644                template <typename T>
645                void remapIndexes(T* src, T* dst, const IndexRemap& remap, 
646                                size_t numIndexes)
647                {
648                        for (size_t i = 0; i < numIndexes; ++i)
649                        {
650                                // look up original and map to target
651                                IndexRemap::const_iterator ix = remap.find(*src++);
652                                assert(ix != remap.end());
653                                *dst++ = static_cast<T>(ix->second);
654                        }
655                }
656               
657        public:
658                /// Constructor; do not use directly (@see SceneManager::createInstancedGeometry)
659                InstancedGeometry(SceneManager* owner, const String& name);
660                /// Destructor
661                virtual ~InstancedGeometry();
662
663                /// Get the name of this object
664                const String& getName(void) const { return mName; }
665                /** Adds an Entity to the static geometry.
666                @remarks
667                        This method takes an existing Entity and adds its details to the
668                        list of elements to include when building. Note that the Entity
669                        itself is not copied or referenced in this method; an Entity is
670                        passed simply so that you can change the materials of attached
671                        SubEntity objects if you want. You can add the same Entity
672                        instance multiple times with different material settings
673                        completely safely, and destroy the Entity before destroying
674                        this InstancedGeometry if you like. The Entity passed in is simply
675                        used as a definition.
676                @note Must be called before 'build'.
677        @note All added entities must use the same LOD strategy.
678                @param ent The Entity to use as a definition (the Mesh and Materials
679                        referenced will be recorded for the build call).
680                @param position The world position at which to add this Entity
681                @param orientation The world orientation at which to add this Entity
682                @param scale The scale at which to add this entity
683                */
684                virtual void addEntity(Entity* ent, const Vector3& position,
685                        const Quaternion& orientation = Quaternion::IDENTITY, 
686                        const Vector3& scale = Vector3::UNIT_SCALE);
687
688                /** Adds all the Entity objects attached to a SceneNode and all it's
689                        children to the static geometry.
690                @remarks
691                        This method performs just like addEntity, except it adds all the
692                        entities attached to an entire sub-tree to the geometry.
693                        The position / orientation / scale parameters are taken from the
694                        node structure instead of being specified manually.
695                @note
696                        The SceneNode you pass in will not be automatically detached from
697                        it's parent, so if you have this node already attached to the scene
698                        graph, you will need to remove it if you wish to avoid the overhead
699                        of rendering <i>both</i> the original objects and their new static
700                        versions! We don't do this for you incase you are preparing this
701                        in advance and so don't want the originals detached yet.
702                @note Must be called before 'build'.
703        @note All added entities must use the same LOD strategy.
704                @param node Pointer to the node to use to provide a set of Entity
705                        templates
706                */
707                virtual void addSceneNode(const SceneNode* node);
708
709                /** Build the geometry.
710                @remarks
711                        Based on all the entities which have been added, and the batching
712                        options which have been set, this method constructs     the batched
713                        geometry structures required. The batches are added to the scene
714                        and will be rendered unless you specifically hide them.
715                @note
716                        Once you have called this method, you can no longer add any more
717                        entities.
718                */
719                virtual void build(void);
720                        /** Add a new batch instance
721                @remarks
722                                This method add a new instance of the whole batch, by creating a new
723                                BatchInstance, containing new LOD buckets, material buckets and geometry buckets.
724                                The new geometry buckets will use the same buffers as the base bucket.
725                @note
726                        no note
727                */
728                void addBatchInstance(void);
729                /** Destroys all the built geometry state (reverse of build).
730                @remarks
731                        You can call build() again after this and it will pick up all the
732                        same entities / nodes you queued last time.
733                */
734                virtual void destroy(void);
735
736                /** Clears any of the entities / nodes added to this geometry and
737                        destroys anything which has already been built.
738                */
739                virtual void reset(void);
740
741                /** Sets the distance at which batches are no longer rendered.
742                @remarks
743                        This lets you turn off batches at a given distance. This can be
744                        useful for things like detail meshes (grass, foliage etc) and could
745                        be combined with a shader which fades the geometry out beforehand
746                        to lessen the effect.
747                @param dist Distance beyond which the batches will not be rendered
748                        (the default is 0, which means batches are always rendered).
749                */
750                virtual void setRenderingDistance(Real dist) { 
751                        mUpperDistance = dist; 
752                        mSquaredUpperDistance = mUpperDistance * mUpperDistance;
753                }
754
755                /** Gets the distance at which batches are no longer rendered. */
756                virtual Real getRenderingDistance(void) const { return mUpperDistance; }
757
758                /** Gets the squared distance at which batches are no longer rendered. */
759                virtual Real getSquaredRenderingDistance(void) const 
760                { return mSquaredUpperDistance; }
761
762                /** Hides or shows all the batches. */
763                virtual void setVisible(bool visible);
764
765                /** Are the batches visible? */
766                virtual bool isVisible(void) const { return mVisible; }
767
768                /** Sets whether this geometry should cast shadows.
769                @remarks
770                        No matter what the settings on the original entities,
771                        the InstancedGeometry class defaults to not casting shadows.
772                        This is because, being static, unless you have moving lights
773                        you'd be better to use precalculated shadows of some sort.
774                        However, if you need them, you can enable them using this
775                        method. If the SceneManager is set up to use stencil shadows,
776                        edge lists will be copied from the underlying meshes on build.
777                        It is essential that all meshes support stencil shadows in this
778                        case.
779                @note If you intend to use stencil shadows, you must set this to
780                        true before calling 'build' as well as making sure you set the
781                        scene's shadow type (that should always be the first thing you do
782                        anyway). You can turn shadows off temporarily but they can never
783                        be turned on if they were not at the time of the build.
784                */
785                virtual void setCastShadows(bool castShadows);
786                /// Will the geometry from this object cast shadows?
787                virtual bool getCastShadows(void) { return mCastShadows; }
788
789                /** Sets the size of a single BatchInstance of geometry.
790                @remarks
791                        This method allows you to configure the physical world size of
792                        each BatchInstance, so you can balance culling against batch size. Entities
793                        will be fitted within the batch they most closely fit, and the
794                        eventual bounds of each batch may well be slightly larger than this
795                        if they overlap a little. The default is Vector3(1000, 1000, 1000).
796                @note Must be called before 'build'.
797                @param size Vector3 expressing the 3D size of each BatchInstance.
798                */
799                virtual void setBatchInstanceDimensions(const Vector3& size) { 
800                        mBatchInstanceDimensions = size; 
801                        mHalfBatchInstanceDimensions = size * 0.5;
802                }
803                /** Gets the size of a single batch of geometry. */
804                virtual const Vector3& getBatchInstanceDimensions(void) const { return mBatchInstanceDimensions; }
805                /** Sets the origin of the geometry.
806                @remarks
807                        This method allows you to configure the world centre of the geometry,
808                        thus the place which all BatchInstances surround. You probably don't need
809                        to mess with this unless you have a seriously large world, since the
810                        default set up can handle an area 1024 * mBatchInstanceDimensions, and
811                        the sparseness of population is no issue when it comes to rendering.
812                        The default is Vector3(0,0,0).
813                @note Must be called before 'build'.
814                @param origin Vector3 expressing the 3D origin of the geometry.
815                */
816                virtual void setOrigin(const Vector3& origin) { mOrigin = origin; }
817                /** Gets the origin of this geometry. */
818                virtual const Vector3& getOrigin(void) const { return mOrigin; }
819
820        /** Sets the render queue group this object will be rendered through.
821        @remarks
822            Render queues are grouped to allow you to more tightly control the ordering
823            of rendered objects. If you do not call this method, all  objects default
824            to the default queue (RenderQueue::getDefaultQueueGroup), which is fine for
825                        most objects. You may want to alter this if you want to perform more complex
826                        rendering.
827        @par
828            See RenderQueue for more details.
829        @param queueID Enumerated value of the queue group to use.
830        */
831        virtual void setRenderQueueGroup(uint8 queueID);
832
833        /** Gets the queue group for this entity, see setRenderQueueGroup for full details. */
834        virtual uint8 getRenderQueueGroup(void) const;
835                /// Iterator for iterating over contained BatchInstances
836                typedef MapIterator<BatchInstanceMap> BatchInstanceIterator;
837                /// Get an iterator over the BatchInstances in this geometry
838                BatchInstanceIterator getBatchInstanceIterator(void);
839                /// get the mRenderOps vector.
840                RenderOperationVector& getRenderOperationVector(){return mRenderOps;}
841                /// @copydoc MovableObject::visitRenderables
842                void visitRenderables(Renderable::Visitor* visitor, 
843                        bool debugRenderables = false);
844
845                /** Dump the contents of this InstancedGeometry to a file for diagnostic
846                        purposes.
847                */
848                virtual void dump(const String& filename) const;
849                /**
850                @remarks
851                Return the skeletonInstance that will be used
852                */
853                SkeletonInstance *getBaseSkeletonInstance(void){return mSkeletonInstance;}
854                /**
855                @remarks
856                Return the skeleton that is shared by all instanced objects.
857                */
858                SkeletonPtr getBaseSkeleton(void){return mBaseSkeleton;}
859                /**
860                @remarks
861                Return the animation state that will be cloned each time an InstancedObject is made
862                */
863                AnimationStateSet* getBaseAnimationState(void){return mAnimationState;}
864                /**
865                @remarks
866                return the total number of object that are in all the batches
867                */
868                unsigned int getObjectCount(void){return mObjectCount;}
869
870        /**
871        @remarks
872        Allows World Transform Inverse matrices to be passed as shader constants along with the world
873        transform matrix list. Reduces the number of usable geometries in an instance to 40 instead of 80.
874                The inverse matrices are interleaved with the world matrices at n+1.
875        */
876        virtual void setProvideWorldInverses(bool flag);
877
878        /**
879        @remarks
880        Returns the toggle state indicating whether the World Transform INVERSE matrices would
881        be passed to the shaders.
882        */
883        virtual bool getProvideWorldInverses(void) const { return mProvideWorldInverses; }
884        };
885
886        /** @} */
887        /** @} */
888}
889
890#include "OgreHeaderSuffix.h"
891
892#endif
893
Note: See TracBrowser for help on using the repository browser.