# OgreInstancedGeometry.h

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004 (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright (c) 2000-2009 Torus Knot Software Ltd
    00008
    00009 Permission is hereby granted, free of charge, to any person obtaining a copy
    00010 of this software and associated documentation files (the "Software"), to deal
    00011 in the Software without restriction, including without limitation the rights
    00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    00013 copies of the Software, and to permit persons to whom the Software is
    00014 furnished to do so, subject to the following conditions:
    00015
    00016 The above copyright notice and this permission notice shall be included in
    00017 all copies or substantial portions of the Software.
    00018
    00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    00025 THE SOFTWARE.
    00026 -----------------------------------------------------------------------------
    00027 */
    00028 #ifndef __InstancedGeometry_H__
    00029 #define __InstancedGeometry_H__
    00030
    00031 #include "OgrePrerequisites.h"
    00032 #include "OgreMovableObject.h"
    00033 #include "OgreSimpleRenderable.h"
    00034 #include "OgreSkeleton.h"
    00035 #include "OgreSkeletonInstance.h"
    00036 #include "OgreAnimationTrack.h"
    00037 #include "OgreBone.h"
    00038 #include "OgreIteratorWrappers.h"
    00039 #include "OgreMesh.h"
    00040
    00041 namespace Ogre {
    00042
    00104     class _OgreExport  InstancedGeometry : public BatchedGeometryAlloc
    00105     {
    00106     public:
    00119         class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc
    00120         {
    00121         public:
    00122             OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {}
    00123             ~OptimisedSubMeshGeometry()
    00124             {
    00125                 delete vertexData;
    00126                 delete indexData;
    00127             }
    00128             VertexData *vertexData;
    00129             IndexData *indexData;
    00130         };
    00131         typedef list<OptimisedSubMeshGeometry*>::type OptimisedSubMeshGeometryList;
    00134         struct SubMeshLodGeometryLink
    00135         {
    00136             VertexData* vertexData;
    00137             IndexData* indexData;
    00138         };
    00139         typedef vector<SubMeshLodGeometryLink>::type SubMeshLodGeometryLinkList;
    00140         typedef map<SubMesh*, SubMeshLodGeometryLinkList*>::type SubMeshGeometryLookup;
    00142         struct QueuedSubMesh : public BatchedGeometryAlloc
    00143         {
    00144             SubMesh* submesh;
    00146             SubMeshLodGeometryLinkList* geometryLodList;
    00147             String materialName;
    00148             Vector3 position;
    00149             Quaternion orientation;
    00150             Vector3 scale;
    00152             AxisAlignedBox worldBounds;
    00153             unsigned int ID;
    00154         };
    00155         typedef vector<QueuedSubMesh*>::type QueuedSubMeshList;
    00156         typedef vector<String>::type QueuedSubMeshOriginList;
    00158         struct QueuedGeometry : public BatchedGeometryAlloc
    00159         {
    00160             SubMeshLodGeometryLink* geometry;
    00161             Vector3 position;
    00162             Quaternion orientation;
    00163             Vector3 scale;
    00164             unsigned int ID;
    00165         };
    00166         typedef vector<QueuedGeometry*>::type QueuedGeometryList;
    00167
    00168         // forward declarations
    00169         class LODBucket;
    00170         class MaterialBucket;
    00171         class BatchInstance;
    00172         class InstancedObject;
    00173
    00178         class _OgreExport  GeometryBucket : public SimpleRenderable
    00179         {
    00180         protected:
    00181
    00183             QueuedGeometryList mQueuedGeometry;
    00185             InstancedGeometry*mBatch;
    00187             MaterialBucket* mParent;
    00189             String mFormatString;
    00192             VertexData* mVertexData;
    00195             IndexData* mIndexData;
    00197             HardwareIndexBuffer::IndexType mIndexType;
    00199             size_t mMaxVertexIndex;
    00201             unsigned short mTexCoordIndex;
    00202             AxisAlignedBox mAABB;
    00203
    00204             template<typename T>
    00205             void copyIndexes(const T* src, T* dst, size_t count, size_t indexOffset)
    00206             {
    00207                 if (indexOffset == 0)
    00208                 {
    00209                     memcpy(dst, src, sizeof(T) * count);
    00210                 }
    00211                 else
    00212                 {
    00213                     while(count--)
    00214                     {
    00215                         *dst++ = static_cast<T>(*src++ + indexOffset);
    00216                     }
    00217                 }
    00218             }
    00219         public:
    00220             GeometryBucket(MaterialBucket* parent, const String& formatString,
    00221                 const VertexData* vData, const IndexData* iData);
    00222             GeometryBucket(MaterialBucket* parent,const String& formatString,GeometryBucket*bucket);
    00223             virtual ~GeometryBucket();
    00224             MaterialBucket* getParent(void) { return mParent; }
    00225             Real getBoundingRadius(void) const;
    00227             const VertexData* getVertexData(void) const { return mVertexData; }
    00229             const IndexData* getIndexData(void) const { return mIndexData; }
    00231             const MaterialPtr& getMaterial(void) const;
    00232             Technique* getTechnique(void) const;
    00233             void getWorldTransforms(Matrix4* xform) const;
    00234             virtual unsigned short getNumWorldTransforms(void) const ;
    00235             Real getSquaredViewDepth(const Camera* cam) const;
    00236             const LightList& getLights(void) const;
    00237             bool getCastsShadows(void) const;
    00238             String getFormatString(void) const;
    00242             bool assign(QueuedGeometry* qsm);
    00244             void build();
    00246             void dump(std::ofstream& of) const;
    00248             AxisAlignedBox & getAABB(void){return mAABB;}
    00250             void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables);
    00251
    00252         };
    00253         class _OgreExport  InstancedObject : public BatchedGeometryAlloc
    00254         {
    00255             friend class GeometryBucket;
    00256         public:
    00257              enum TransformSpace
    00258         {
    00260             TS_LOCAL,
    00262             TS_PARENT,
    00264             TS_WORLD
    00265         };
    00267             typedef vector<GeometryBucket*>::type GeometryBucketList;
    00268         protected:
    00269             GeometryBucketList mGeometryBucketList;
    00270             unsigned short mIndex;
    00271             Matrix4  mTransformation;
    00272             Quaternion mOrientation;
    00273             Vector3 mScale;
    00274             Vector3 mPosition;
    00275             SkeletonInstance* mSkeletonInstance;
    00277             Matrix4 *mBoneWorldMatrices;
    00279             Matrix4 *mBoneMatrices;
    00281             AnimationStateSet* mAnimationState;
    00282             unsigned short mNumBoneMatrices;
    00284             unsigned long mFrameAnimationLastUpdated;
    00285         public:
    00286             InstancedObject(unsigned short index);
    00287             InstancedObject(unsigned short index,SkeletonInstance *skeleton,AnimationStateSet*animations);
    00288             ~InstancedObject();
    00289             void setPosition( Vector3  position);
    00290             const Vector3& getPosition(void) const;
    00291             void yaw(const Radian& angle);
    00292             void pitch(const Radian& angle);
    00293             void roll(const Radian& angle);
    00294             void rotate(const Quaternion& q);
    00295             void setScale(const Vector3& scale);
    00296             const Vector3& getScale() const;
    00297             void setOrientation(const Quaternion& q);
    00298             void setPositionAndOrientation(Vector3 p, const Quaternion& q);
    00299             Quaternion & getOrientation(void);
    00300             void addBucketToList(GeometryBucket* bucket);
    00301             void needUpdate();
    00302             GeometryBucketList&getGeometryBucketList(void){return mGeometryBucketList;}
    00303             void translate(const Matrix3& axes, const Vector3& move);
    00304             void translate(const Vector3& d);
    00305             Matrix3 getLocalAxes(void) const;
    00306             void updateAnimation(void);
    00307             AnimationState* getAnimationState(const String& name) const;
    00308             SkeletonInstance*getSkeletonInstance(void){return mSkeletonInstance;}
    00309
    00310         };
    00313         class _OgreExport  MaterialBucket : public BatchedGeometryAlloc
    00314         {
    00315         public:
    00317             typedef vector<GeometryBucket*>::type GeometryBucketList;
    00318         protected:
    00320             LODBucket* mParent;
    00322             String mMaterialName;
    00324             MaterialPtr mMaterial;
    00326             Technique* mTechnique;
    00327             int mLastIndex;
    00329             GeometryBucketList mGeometryBucketList;
    00330             // index to current Geometry Buckets for a given geometry format
    00331             typedef map<String, GeometryBucket*>::type CurrentGeometryMap;
    00332             CurrentGeometryMap mCurrentGeometryMap;
    00334             String getGeometryFormatString(SubMeshLodGeometryLink* geom);
    00335
    00336         public:
    00337             MaterialBucket(LODBucket* parent, const String& materialName);
    00338             virtual ~MaterialBucket();
    00339             LODBucket* getParent(void) { return mParent; }
    00341             const String& getMaterialName(void) const { return mMaterialName; }
    00343             void assign(QueuedGeometry* qsm);
    00345             void build();
    00347             void addRenderables(RenderQueue* queue, uint8 group,
    00348                 Real lodValue);
    00350             const MaterialPtr& getMaterial(void) const { return mMaterial; }
    00352             typedef VectorIterator<GeometryBucketList> GeometryIterator;
    00354             GeometryIterator getGeometryIterator(void);
    00356             Technique* getCurrentTechnique(void) const { return mTechnique; }
    00358             void dump(std::ofstream& of) const;
    00360             MaterialBucket::CurrentGeometryMap* getMaterialBucketMap(void) const;
    00362             MaterialBucket::GeometryBucketList*getGeometryBucketList(void) const;
    00364             void updateContainers(GeometryBucket* bucket, const String &format);
    00365             void setLastIndex(int index){mLastIndex=index;}
    00366             int getLastIndex(){return mLastIndex;}
    00367             void setMaterial(const String & name);
    00368             void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables);
    00369
    00370         };
    00376         class _OgreExport  LODBucket : public BatchedGeometryAlloc
    00377         {
    00378         public:
    00380             typedef map<String, MaterialBucket*>::type MaterialBucketMap;
    00381         protected:
    00383             BatchInstance* mParent;
    00385             unsigned short mLod;
    00387             Real mLodValue;
    00389             MaterialBucketMap mMaterialBucketMap;
    00391             QueuedGeometryList mQueuedGeometryList;
    00392         public:
    00393             LODBucket(BatchInstance* parent, unsigned short lod, Real lodValue);
    00394             virtual ~LODBucket();
    00395             BatchInstance* getParent(void) { return mParent; }
    00397             ushort getLod(void) const { return mLod; }
    00399             Real getLodValue(void) const { return mLodValue; }
    00401             void assign(QueuedSubMesh* qsm, ushort atLod);
    00403             void build();
    00405             void addRenderables(RenderQueue* queue, uint8 group,
    00406                 Real lodValue);
    00408             typedef MapIterator<MaterialBucketMap> MaterialIterator;
    00410             MaterialIterator getMaterialIterator(void);
    00412             void dump(std::ofstream& of) const;
    00414             void updateContainers(MaterialBucket* bucket, String& name );
    00415             void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables);
    00416
    00417         };
    00426         class _OgreExport  BatchInstance : public MovableObject
    00427         {
    00428             friend class MaterialBucket;
    00429             public:
    00430
    00431
    00433             typedef vector<LODBucket*>::type LODBucketList;
    00434             typedef map<unsigned short, InstancedObject*>::type ObjectsMap;
    00435             typedef MapIterator<ObjectsMap> InstancedObjectIterator;
    00436         protected:
    00437
    00439             InstancedGeometry* mParent;
    00441             SceneManager* mSceneMgr;
    00443             SceneNode* mNode;
    00445             QueuedSubMeshList mQueuedSubMeshes;
    00447             uint32 mBatchInstanceID;
    00448
    00449             ObjectsMap mInstancesMap;
    00450         public:
    00452             Mesh::LodValueList mLodValues;
    00454             AxisAlignedBox mAABB;
    00456             Real mBoundingRadius;
    00458             ushort mCurrentLod;
    00460             Real mLodValue;
    00462             Camera *mCamera;
    00464             Real mSquaredViewDepth;
    00465         protected:
    00467             LODBucketList mLodBucketList;
    00469             const LodStrategy *mLodStrategy;
    00470
    00471         public:
    00472             BatchInstance(InstancedGeometry* parent, const String& name, SceneManager* mgr,
    00473                 uint32 BatchInstanceID);
    00474             virtual ~BatchInstance();
    00475             // more fields can be added in subclasses
    00476             InstancedGeometry* getParent(void) const { return mParent;}
    00478             void assign(QueuedSubMesh* qmesh);
    00480             void build();
    00482             uint32 getID(void) const { return mBatchInstanceID; }
    00484 //          const Vector3& getCentre(void) const { return mCentre; }
    00485             const String& getMovableType(void) const;
    00486             void _notifyCurrentCamera(Camera* cam);
    00487             const AxisAlignedBox& getBoundingBox(void) const;
    00488             void  setBoundingBox(AxisAlignedBox& box);
    00489             Real getBoundingRadius(void) const;
    00490             void _updateRenderQueue(RenderQueue* queue);
    00491             bool isVisible(void) const;
    00493             void visitRenderables(Renderable::Visitor* visitor,
    00494                 bool debugRenderables = false);
    00495
    00496         //  uint32 getTypeFlags(void) const;
    00497
    00498             typedef VectorIterator<LODBucketList> LODIterator;
    00500             LODIterator getLODIterator(void);
    00502             const LightList& getLights(void) const;
    00503
    00505             void updateBoundingBox();
    00506
    00508             void dump(std::ofstream& of) const;
    00510             void updateContainers(LODBucket* bucket );
    00512             void attachToScene();
    00513             void addInstancedObject(unsigned short index, InstancedObject* object);
    00514             InstancedObject*  isInstancedObjectPresent(unsigned short index);
    00515             InstancedObjectIterator getObjectIterator();
    00516             SceneNode*getSceneNode(void){return mNode;}
    00517             ObjectsMap& getInstancesMap(void){return  mInstancesMap;}
    00519
    00520         };
    00524         typedef map<uint32, BatchInstance*>::type BatchInstanceMap;
    00530         typedef vector<RenderOperation*>::type RenderOperationVector;
    00531     protected:
    00532         // General state & settings
    00533         SceneManager* mOwner;
    00534         String mName;
    00535         bool mBuilt;
    00536         Real mUpperDistance;
    00537         Real mSquaredUpperDistance;
    00538         bool mCastShadows;
    00539         Vector3 mBatchInstanceDimensions;
    00540         Vector3 mHalfBatchInstanceDimensions;
    00541         Vector3 mOrigin;
    00542         bool mVisible;
    00544         bool mProvideWorldInverses;
    00546         uint8 mRenderQueueID;
    00548         bool mRenderQueueIDSet;
    00550         unsigned int mObjectCount;
    00551         QueuedSubMeshList mQueuedSubMeshes;
    00552         BatchInstance*mInstancedGeometryInstance;
    00556         SkeletonPtr mBaseSkeleton;
    00557         SkeletonInstance *mSkeletonInstance;
    00561         AnimationStateSet* mAnimationState;
    00564         OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList;
    00565
    00570         SubMeshGeometryLookup mSubMeshGeometryLookup;
    00571
    00573         BatchInstanceMap mBatchInstanceMap;
    00577         RenderOperationVector mRenderOps;
    00581         virtual BatchInstance* getBatchInstance(const AxisAlignedBox& bounds, bool autoCreate);
    00583         virtual BatchInstance* getBatchInstance(const Vector3& point, bool autoCreate);
    00585         virtual BatchInstance* getBatchInstance(ushort x, ushort y, ushort z, bool autoCreate);
    00587         virtual BatchInstance* getBatchInstance(uint32 index);
    00590         virtual void getBatchInstanceIndexes(const Vector3& point,
    00591             ushort& x, ushort& y, ushort& z);
    00594         virtual BatchInstance* getInstancedGeometryInstance(void);
    00597         virtual uint32 packIndex(ushort x, ushort y, ushort z);
    00600         virtual Real getVolumeIntersection(const AxisAlignedBox& box,
    00601             ushort x, ushort y, ushort z);
    00604         virtual AxisAlignedBox getBatchInstanceBounds(ushort x, ushort y, ushort z);
    00607         virtual Vector3 getBatchInstanceCentre(ushort x, ushort y, ushort z);
    00609         virtual AxisAlignedBox calculateBounds(VertexData* vertexData,
    00610             const Vector3& position, const Quaternion& orientation,
    00611             const Vector3& scale);
    00613         SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm);
    00615         void splitGeometry(VertexData* vd, IndexData* id,
    00616             SubMeshLodGeometryLink* targetGeomLink);
    00617
    00618         typedef map<size_t, size_t>::type IndexRemap;
    00623         template <typename T>
    00624         void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap)
    00625         {
    00626             remap.clear();
    00627             for (size_t i = 0; i < numIndexes; ++i)
    00628             {
    00629                 // use insert since duplicates are silently discarded
    00630                 remap.insert(IndexRemap::value_type(*pBuffer++, remap.size()));
    00631                 // this will have mapped oldindex -> new index IF oldindex
    00632                 // wasn't already there
    00633             }
    00634         }
    00636         template <typename T>
    00637         void remapIndexes(T* src, T* dst, const IndexRemap& remap,
    00638                 size_t numIndexes)
    00639         {
    00640             for (size_t i = 0; i < numIndexes; ++i)
    00641             {
    00642                 // look up original and map to target
    00643                 IndexRemap::const_iterator ix = remap.find(*src++);
    00644                 assert(ix != remap.end());
    00645                 *dst++ = static_cast<T>(ix->second);
    00646             }
    00647         }
    00648
    00649     public:
    00651         InstancedGeometry(SceneManager* owner, const String& name);
    00653         virtual ~InstancedGeometry();
    00654
    00656         const String& getName(void) const { return mName; }
    00676         virtual void addEntity(Entity* ent, const Vector3& position,
    00677             const Quaternion& orientation = Quaternion::IDENTITY,
    00678             const Vector3& scale = Vector3::UNIT_SCALE);
    00679
    00699         virtual void addSceneNode(const SceneNode* node);
    00700
    00711         virtual void build(void);
    00720         void addBatchInstance(void);
    00726         virtual void destroy(void);
    00727
    00731         virtual void reset(void);
    00732
    00742         virtual void setRenderingDistance(Real dist) {
    00743             mUpperDistance = dist;
    00744             mSquaredUpperDistance = mUpperDistance * mUpperDistance;
    00745         }
    00746
    00748         virtual Real getRenderingDistance(void) const { return mUpperDistance; }
    00749
    00751         virtual Real getSquaredRenderingDistance(void) const
    00752         { return mSquaredUpperDistance; }
    00753
    00755         virtual void setVisible(bool visible);
    00756
    00758         virtual bool isVisible(void) const { return mVisible; }
    00759
    00777         virtual void setCastShadows(bool castShadows);
    00779         virtual bool getCastShadows(void) { return mCastShadows; }
    00780
    00791         virtual void setBatchInstanceDimensions(const Vector3& size) {
    00792             mBatchInstanceDimensions = size;
    00793             mHalfBatchInstanceDimensions = size * 0.5;
    00794         }
    00796         virtual const Vector3& getBatchInstanceDimensions(void) const { return mBatchInstanceDimensions; }
    00808         virtual void setOrigin(const Vector3& origin) { mOrigin = origin; }
    00810         virtual const Vector3& getOrigin(void) const { return mOrigin; }
    00811
    00823         virtual void setRenderQueueGroup(uint8 queueID);
    00824
    00826         virtual uint8 getRenderQueueGroup(void) const;
    00828         typedef MapIterator<BatchInstanceMap> BatchInstanceIterator;
    00830         BatchInstanceIterator getBatchInstanceIterator(void);
    00832         RenderOperationVector& getRenderOperationVector(){return mRenderOps;}
    00834         void visitRenderables(Renderable::Visitor* visitor,
    00835             bool debugRenderables = false);
    00836
    00840         virtual void dump(const String& filename) const;
    00845         SkeletonInstance *getBaseSkeletonInstance(void){return mSkeletonInstance;}
    00850         SkeletonPtr getBaseSkeleton(void){return mBaseSkeleton;}
    00855         AnimationStateSet* getBaseAnimationState(void){return mAnimationState;}
    00860         unsigned int getObjectCount(void){return mObjectCount;}
    00861
    00868         virtual void setProvideWorldInverses(bool flag);
    00869
    00875         virtual bool getProvideWorldInverses(void) const { return mProvideWorldInverses; }
    00876     };
    00877
    00880 }
    00881
    00882 #endif
    00883

Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sun May 8 2011 20:28:08