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-2006 Torus Knot Software Ltd 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 00024 You may alternatively use this source under the terms of a specific version of 00025 the OGRE Unrestricted License provided you have obtained such a license from 00026 Torus Knot Software Ltd. 00027 ----------------------------------------------------------------------------- 00028 */ 00029 #ifndef __InstancedGeometry_H__ 00030 #define __InstancedGeometry_H__ 00031 00032 #include "OgrePrerequisites.h" 00033 #include "OgreMovableObject.h" 00034 #include "OgreSimpleRenderable.h" 00035 #include "OgreSkeleton.h" 00036 #include "OgreSkeletonInstance.h" 00037 #include "OgreAnimationTrack.h" 00038 #include "OgreBone.h" 00039 #include "OgreIteratorWrappers.h" 00040 00041 namespace Ogre { 00042 00098 class _OgreExport InstancedGeometry : public BatchedGeometryAlloc 00099 { 00100 public: 00113 class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc 00114 { 00115 public: 00116 OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {} 00117 ~OptimisedSubMeshGeometry() 00118 { 00119 delete vertexData; 00120 delete indexData; 00121 } 00122 VertexData *vertexData; 00123 IndexData *indexData; 00124 }; 00125 typedef std::list<OptimisedSubMeshGeometry*> OptimisedSubMeshGeometryList; 00128 struct SubMeshLodGeometryLink 00129 { 00130 VertexData* vertexData; 00131 IndexData* indexData; 00132 }; 00133 typedef std::vector<SubMeshLodGeometryLink> SubMeshLodGeometryLinkList; 00134 typedef std::map<SubMesh*, SubMeshLodGeometryLinkList*> SubMeshGeometryLookup; 00136 struct QueuedSubMesh : public BatchedGeometryAlloc 00137 { 00138 SubMesh* submesh; 00140 SubMeshLodGeometryLinkList* geometryLodList; 00141 String materialName; 00142 Vector3 position; 00143 Quaternion orientation; 00144 Vector3 scale; 00146 AxisAlignedBox worldBounds; 00147 unsigned int ID; 00148 }; 00149 typedef std::vector<QueuedSubMesh*> QueuedSubMeshList; 00150 typedef std::vector<String> QueuedSubMeshOriginList; 00152 struct QueuedGeometry : public BatchedGeometryAlloc 00153 { 00154 SubMeshLodGeometryLink* geometry; 00155 Vector3 position; 00156 Quaternion orientation; 00157 Vector3 scale; 00158 unsigned int ID; 00159 }; 00160 typedef std::vector<QueuedGeometry*> QueuedGeometryList; 00161 00162 // forward declarations 00163 class LODBucket; 00164 class MaterialBucket; 00165 class BatchInstance; 00166 class InstancedObject; 00167 00172 class _OgreExport GeometryBucket : public SimpleRenderable 00173 { 00174 protected: 00175 00177 QueuedGeometryList mQueuedGeometry; 00179 InstancedGeometry*mBatch; 00181 MaterialBucket* mParent; 00183 String mFormatString; 00186 VertexData* mVertexData; 00189 IndexData* mIndexData; 00191 HardwareIndexBuffer::IndexType mIndexType; 00193 size_t mMaxVertexIndex; 00195 unsigned short mTexCoordIndex; 00196 AxisAlignedBox mAABB; 00197 00198 template<typename T> 00199 void copyIndexes(const T* src, T* dst, size_t count, size_t indexOffset) 00200 { 00201 if (indexOffset == 0) 00202 { 00203 memcpy(dst, src, sizeof(T) * count); 00204 } 00205 else 00206 { 00207 while(count--) 00208 { 00209 *dst++ = static_cast<T>(*src++ + indexOffset); 00210 } 00211 } 00212 } 00213 public: 00214 GeometryBucket(MaterialBucket* parent, const String& formatString, 00215 const VertexData* vData, const IndexData* iData); 00216 GeometryBucket(MaterialBucket* parent,const String& formatString,GeometryBucket*bucket); 00217 virtual ~GeometryBucket(); 00218 MaterialBucket* getParent(void) { return mParent; } 00219 Real getBoundingRadius(void) const; 00221 const VertexData* getVertexData(void) const { return mVertexData; } 00223 const IndexData* getIndexData(void) const { return mIndexData; } 00225 const MaterialPtr& getMaterial(void) const; 00226 Technique* getTechnique(void) const; 00227 void getWorldTransforms(Matrix4* xform) const; 00228 virtual unsigned short getNumWorldTransforms(void) const ; 00229 Real getSquaredViewDepth(const Camera* cam) const; 00230 const LightList& getLights(void) const; 00231 bool getCastsShadows(void) const; 00232 String getFormatString(void) const; 00236 bool assign(QueuedGeometry* qsm); 00238 void build(); 00240 void dump(std::ofstream& of) const; 00242 AxisAlignedBox & getAABB(void){return mAABB;}; 00244 void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); 00245 00246 }; 00247 class _OgreExport InstancedObject : public BatchedGeometryAlloc 00248 { 00249 friend class GeometryBucket; 00250 public: 00251 enum TransformSpace 00252 { 00254 TS_LOCAL, 00256 TS_PARENT, 00258 TS_WORLD 00259 }; 00261 typedef std::vector<GeometryBucket*> GeometryBucketList; 00262 protected: 00263 GeometryBucketList mGeometryBucketList; 00264 unsigned short mIndex; 00265 Matrix4 mTransformation; 00266 Quaternion mOrientation; 00267 Vector3 mScale; 00268 Vector3 mPosition; 00269 SkeletonInstance* mSkeletonInstance; 00271 Matrix4 *mBoneWorldMatrices; 00273 Matrix4 *mBoneMatrices; 00275 AnimationStateSet* mAnimationState; 00276 unsigned short mNumBoneMatrices; 00278 unsigned long mFrameAnimationLastUpdated; 00279 public: 00280 InstancedObject(int index); 00281 InstancedObject(int index,SkeletonInstance *skeleton,AnimationStateSet*animations); 00282 ~InstancedObject(); 00283 void setPosition( Vector3 position); 00284 const Vector3& getPosition(void) const; 00285 void yaw(const Radian& angle); 00286 void pitch(const Radian& angle); 00287 void roll(const Radian& angle); 00288 void rotate(const Quaternion& q); 00289 void setScale(const Vector3& scale); 00290 const Vector3& getScale() const; 00291 void setOrientation(const Quaternion& q); 00292 void setPositionAndOrientation(Vector3 p, const Quaternion& q); 00293 Quaternion & getOrientation(void); 00294 void addBucketToList(GeometryBucket* bucket); 00295 void needUpdate(); 00296 GeometryBucketList&getGeometryBucketList(void){return mGeometryBucketList;} 00297 void translate(const Matrix3& axes, const Vector3& move); 00298 void translate(const Vector3& d); 00299 Matrix3 getLocalAxes(void) const; 00300 void updateAnimation(void); 00301 AnimationState* getAnimationState(const String& name) const; 00302 SkeletonInstance*getSkeletonInstance(void){return mSkeletonInstance;} 00303 00304 }; 00307 class _OgreExport MaterialBucket : public BatchedGeometryAlloc 00308 { 00309 public: 00311 typedef std::vector<GeometryBucket*> GeometryBucketList; 00312 protected: 00314 LODBucket* mParent; 00316 String mMaterialName; 00318 MaterialPtr mMaterial; 00320 Technique* mTechnique; 00321 int mLastIndex; 00323 GeometryBucketList mGeometryBucketList; 00324 // index to current Geometry Buckets for a given geometry format 00325 typedef std::map<String, GeometryBucket*> CurrentGeometryMap; 00326 CurrentGeometryMap mCurrentGeometryMap; 00328 String getGeometryFormatString(SubMeshLodGeometryLink* geom); 00329 00330 public: 00331 MaterialBucket(LODBucket* parent, const String& materialName); 00332 virtual ~MaterialBucket(); 00333 LODBucket* getParent(void) { return mParent; } 00335 const String& getMaterialName(void) const { return mMaterialName; } 00337 void assign(QueuedGeometry* qsm); 00339 void build(); 00341 void addRenderables(RenderQueue* queue, uint8 group, 00342 Real camSquaredDist); 00344 const MaterialPtr& getMaterial(void) const { return mMaterial; } 00346 typedef VectorIterator<GeometryBucketList> GeometryIterator; 00348 GeometryIterator getGeometryIterator(void); 00350 Technique* getCurrentTechnique(void) const { return mTechnique; } 00352 void dump(std::ofstream& of) const; 00354 MaterialBucket::CurrentGeometryMap* getMaterialBucketMap(void) const; 00356 MaterialBucket::GeometryBucketList*getGeometryBucketList(void) const; 00358 void updateContainers(GeometryBucket* bucket, const String &format); 00359 void setLastIndex(int index){mLastIndex=index;} 00360 int getLastIndex(){return mLastIndex;} 00361 void setMaterial(const String & name); 00362 void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); 00363 00364 }; 00370 class _OgreExport LODBucket : public BatchedGeometryAlloc 00371 { 00372 public: 00374 typedef std::map<String, MaterialBucket*> MaterialBucketMap; 00375 protected: 00377 BatchInstance* mParent; 00379 unsigned short mLod; 00381 Real mSquaredDistance; 00383 MaterialBucketMap mMaterialBucketMap; 00385 QueuedGeometryList mQueuedGeometryList; 00386 public: 00387 LODBucket(BatchInstance* parent, unsigned short lod, Real lodDist); 00388 virtual ~LODBucket(); 00389 BatchInstance* getParent(void) { return mParent; } 00391 ushort getLod(void) const { return mLod; } 00393 Real getSquaredDistance(void) const { return mSquaredDistance; } 00395 void assign(QueuedSubMesh* qsm, ushort atLod); 00397 void build(); 00399 void addRenderables(RenderQueue* queue, uint8 group, 00400 Real camSquaredDistance); 00402 typedef MapIterator<MaterialBucketMap> MaterialIterator; 00404 MaterialIterator getMaterialIterator(void); 00406 void dump(std::ofstream& of) const; 00408 void updateContainers(MaterialBucket* bucket, String& name ); 00409 void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); 00410 00411 }; 00420 class _OgreExport BatchInstance : public MovableObject 00421 { 00422 public: 00423 00424 00426 typedef std::vector<LODBucket*> LODBucketList; 00427 typedef std::map<int, InstancedObject*> ObjectsMap; 00428 typedef MapIterator<ObjectsMap> InstancedObjectIterator; 00429 protected: 00430 00432 InstancedGeometry* mParent; 00434 SceneManager* mSceneMgr; 00436 SceneNode* mNode; 00438 QueuedSubMeshList mQueuedSubMeshes; 00440 uint32 mBatchInstanceID; 00441 00442 ObjectsMap mInstancesMap; 00443 public: 00445 std::vector<Real> mLodSquaredDistances; 00447 AxisAlignedBox mAABB; 00449 Real mBoundingRadius; 00451 ushort mCurrentLod; 00453 Real mCamDistanceSquared; 00454 protected: 00456 LODBucketList mLodBucketList; 00457 00458 public: 00459 BatchInstance(InstancedGeometry* parent, const String& name, SceneManager* mgr, 00460 uint32 BatchInstanceID); 00461 virtual ~BatchInstance(); 00462 // more fields can be added in subclasses 00463 InstancedGeometry* getParent(void) const { return mParent;} 00465 void assign(QueuedSubMesh* qmesh); 00467 void build(); 00469 uint32 getID(void) const { return mBatchInstanceID; } 00471 // const Vector3& getCentre(void) const { return mCentre; } 00472 const String& getMovableType(void) const; 00473 void _notifyCurrentCamera(Camera* cam); 00474 const AxisAlignedBox& getBoundingBox(void) const; 00475 void setBoundingBox(AxisAlignedBox& box); 00476 Real getBoundingRadius(void) const; 00477 void _updateRenderQueue(RenderQueue* queue); 00478 bool isVisible(void) const; 00480 void visitRenderables(Renderable::Visitor* visitor, 00481 bool debugRenderables = false); 00482 00483 // uint32 getTypeFlags(void) const; 00484 00485 typedef VectorIterator<LODBucketList> LODIterator; 00487 LODIterator getLODIterator(void); 00489 const LightList& getLights(void) const; 00490 00492 void updateBoundingBox(); 00493 00495 void dump(std::ofstream& of) const; 00497 void updateContainers(LODBucket* bucket ); 00499 void attachToScene(); 00500 void addInstancedObject(int index, InstancedObject* object); 00501 InstancedObject* isInstancedObjectPresent(int index); 00502 InstancedObjectIterator getObjectIterator(); 00503 SceneNode*getSceneNode(void){return mNode;} 00504 ObjectsMap& getInstancesMap(void){return mInstancesMap;} 00506 00507 }; 00511 typedef std::map<uint32, BatchInstance*> BatchInstanceMap; 00517 typedef std::vector<RenderOperation*> RenderOperationVector; 00518 protected: 00519 // General state & settings 00520 SceneManager* mOwner; 00521 String mName; 00522 bool mBuilt; 00523 Real mUpperDistance; 00524 Real mSquaredUpperDistance; 00525 bool mCastShadows; 00526 Vector3 mBatchInstanceDimensions; 00527 Vector3 mHalfBatchInstanceDimensions; 00528 Vector3 mOrigin; 00529 bool mVisible; 00531 uint8 mRenderQueueID; 00533 bool mRenderQueueIDSet; 00535 unsigned int mObjectCount; 00536 QueuedSubMeshList mQueuedSubMeshes; 00537 BatchInstance*mInstancedGeometryInstance; 00541 SkeletonPtr mBaseSkeleton; 00542 SkeletonInstance *mSkeletonInstance; 00546 AnimationStateSet* mAnimationState; 00549 OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList; 00550 00555 SubMeshGeometryLookup mSubMeshGeometryLookup; 00556 00558 BatchInstanceMap mBatchInstanceMap; 00562 RenderOperationVector mRenderOps; 00566 virtual BatchInstance* getBatchInstance(const AxisAlignedBox& bounds, bool autoCreate); 00568 virtual BatchInstance* getBatchInstance(const Vector3& point, bool autoCreate); 00570 virtual BatchInstance* getBatchInstance(ushort x, ushort y, ushort z, bool autoCreate); 00572 virtual BatchInstance* getBatchInstance(uint32 index); 00575 virtual void getBatchInstanceIndexes(const Vector3& point, 00576 ushort& x, ushort& y, ushort& z); 00579 virtual BatchInstance* getInstancedGeometryInstance(void); 00582 virtual uint32 packIndex(ushort x, ushort y, ushort z); 00585 virtual Real getVolumeIntersection(const AxisAlignedBox& box, 00586 ushort x, ushort y, ushort z); 00589 virtual AxisAlignedBox getBatchInstanceBounds(ushort x, ushort y, ushort z); 00592 virtual Vector3 getBatchInstanceCentre(ushort x, ushort y, ushort z); 00594 virtual AxisAlignedBox calculateBounds(VertexData* vertexData, 00595 const Vector3& position, const Quaternion& orientation, 00596 const Vector3& scale); 00598 SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm); 00600 void splitGeometry(VertexData* vd, IndexData* id, 00601 SubMeshLodGeometryLink* targetGeomLink); 00602 00603 typedef std::map<size_t, size_t> IndexRemap; 00608 template <typename T> 00609 void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap) 00610 { 00611 remap.clear(); 00612 for (size_t i = 0; i < numIndexes; ++i) 00613 { 00614 // use insert since duplicates are silently discarded 00615 remap.insert(IndexRemap::value_type(*pBuffer++, remap.size())); 00616 // this will have mapped oldindex -> new index IF oldindex 00617 // wasn't already there 00618 } 00619 } 00621 template <typename T> 00622 void remapIndexes(T* src, T* dst, const IndexRemap& remap, 00623 size_t numIndexes) 00624 { 00625 for (size_t i = 0; i < numIndexes; ++i) 00626 { 00627 // look up original and map to target 00628 IndexRemap::const_iterator ix = remap.find(*src++); 00629 assert(ix != remap.end()); 00630 *dst++ = static_cast<T>(ix->second); 00631 } 00632 } 00633 00634 public: 00636 InstancedGeometry(SceneManager* owner, const String& name); 00638 virtual ~InstancedGeometry(); 00639 00641 const String& getName(void) const { return mName; } 00660 virtual void addEntity(Entity* ent, const Vector3& position, 00661 const Quaternion& orientation = Quaternion::IDENTITY, 00662 const Vector3& scale = Vector3::UNIT_SCALE); 00663 00682 virtual void addSceneNode(const SceneNode* node); 00683 00694 virtual void build(void); 00703 void addBatchInstance(void); 00709 virtual void destroy(void); 00710 00714 virtual void reset(void); 00715 00725 virtual void setRenderingDistance(Real dist) { 00726 mUpperDistance = dist; 00727 mSquaredUpperDistance = mUpperDistance * mUpperDistance; 00728 } 00729 00731 virtual Real getRenderingDistance(void) const { return mUpperDistance; } 00732 00734 virtual Real getSquaredRenderingDistance(void) const 00735 { return mSquaredUpperDistance; } 00736 00738 virtual void setVisible(bool visible); 00739 00741 virtual bool isVisible(void) const { return mVisible; } 00742 00760 virtual void setCastShadows(bool castShadows); 00762 virtual bool getCastShadows(void) { return mCastShadows; } 00763 00774 virtual void setBatchInstanceDimensions(const Vector3& size) { 00775 mBatchInstanceDimensions = size; 00776 mHalfBatchInstanceDimensions = size * 0.5; 00777 } 00779 virtual const Vector3& getBatchInstanceDimensions(void) const { return mBatchInstanceDimensions; } 00791 virtual void setOrigin(const Vector3& origin) { mOrigin = origin; } 00793 virtual const Vector3& getOrigin(void) const { return mOrigin; } 00794 00806 virtual void setRenderQueueGroup(uint8 queueID); 00807 00809 virtual uint8 getRenderQueueGroup(void) const; 00811 typedef MapIterator<BatchInstanceMap> BatchInstanceIterator; 00813 BatchInstanceIterator getBatchInstanceIterator(void); 00815 RenderOperationVector& getRenderOperationVector(){return mRenderOps;} 00817 void visitRenderables(Renderable::Visitor* visitor, 00818 bool debugRenderables = false); 00819 00823 virtual void dump(const String& filename) const; 00828 SkeletonInstance *getBaseSkeletonInstance(void){return mSkeletonInstance;} 00833 SkeletonPtr getBaseSkeleton(void){return mBaseSkeleton;} 00838 AnimationStateSet* getBaseAnimationState(void){return mAnimationState;} 00843 unsigned int getObjectCount(void){return mObjectCount;} 00844 00845 00846 00847 }; 00848 00849 } 00850 00851 #endif 00852
Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Dec 27 17:31:05 2009