Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreInstancedGeometry.h @ 1

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