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-2011 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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sat Jan 14 2012 18:40:43