PageRenderTime 87ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Core/Dependencies/OgreSource/OgreMain/include/OgreInstancedGeometry.h

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