PageRenderTime 27ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/barakianc/nvidia-physx-and-apex-in-gge
C Header | 781 lines | 326 code | 45 blank | 410 comment | 5 complexity | d54cf0815cd2c61041c1070092e65fdc 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 __StaticGeometry_H__
  25. #define __StaticGeometry_H__
  26. #include "OgrePrerequisites.h"
  27. #include "OgreMovableObject.h"
  28. #include "OgreRenderable.h"
  29. #include "OgreMesh.h"
  30. #include "OgreLodStrategy.h"
  31. namespace Ogre {
  32. /** \addtogroup Core
  33. * @{
  34. */
  35. /** \addtogroup Scene
  36. * @{
  37. */
  38. /** Pre-transforms and batches up meshes for efficient use as static
  39. geometry in a scene.
  40. @remarks
  41. Modern graphics cards (GPUs) prefer to receive geometry in large
  42. batches. It is orders of magnitude faster to render 10 batches
  43. of 10,000 triangles than it is to render 10,000 batches of 10
  44. triangles, even though both result in the same number of on-screen
  45. triangles.
  46. @par
  47. Therefore it is important when you are rendering a lot of geometry to
  48. batch things up into as few rendering calls as possible. This
  49. class allows you to build a batched object from a series of entities
  50. in order to benefit from this behaviour.
  51. Batching has implications of it's own though:
  52. @li Batched geometry cannot be subdivided; that means that the whole
  53. group will be displayed, or none of it will. This obivously has
  54. culling issues.
  55. @li A single world transform must apply to the entire batch. Therefore
  56. once you have batched things, you can't move them around relative to
  57. each other. That's why this class is most useful when dealing with
  58. static geometry (hence the name). In addition, geometry is
  59. effectively duplicated, so if you add 3 entities based on the same
  60. mesh in different positions, they will use 3 times the geometry
  61. space than the movable version (which re-uses the same geometry).
  62. So you trade memory and flexibility of movement for pure speed when
  63. using this class.
  64. @li A single material must apply for each batch. In fact this class
  65. allows you to use multiple materials, but you should be aware that
  66. internally this means that there is one batch per material.
  67. Therefore you won't gain as much benefit from the batching if you
  68. use many different materials; try to keep the number down.
  69. @par
  70. In order to retain some sort of culling, this class will batch up
  71. meshes in localised regions. The size and shape of these blocks is
  72. controlled by the SceneManager which constructs this object, since it
  73. makes sense to batch things up in the most appropriate way given the
  74. existing partitioning of the scene.
  75. @par
  76. The LOD settings of both the Mesh and the Materials used in
  77. constructing this static geometry will be respected. This means that
  78. if you use meshes/materials which have LOD, batches in the distance
  79. will have a lower polygon count or material detail to those in the
  80. foreground. Since each mesh might have different LOD distances, during
  81. build the furthest distance at each LOD level from all meshes
  82. in that region is used. This means all the LOD levels change at the
  83. same time, but at the furthest distance of any of them (so quality is
  84. not degraded). Be aware that using Mesh LOD in this class will
  85. further increase the memory required. Only generated LOD
  86. is supported for meshes.
  87. @par
  88. There are 2 ways you can add geometry to this class; you can add
  89. Entity objects directly with predetermined positions, scales and
  90. orientations, or you can add an entire SceneNode and it's subtree,
  91. including all the objects attached to it. Once you've added everything
  92. you need to, you have to call build() the fix the geometry in place.
  93. @note
  94. This class is not a replacement for world geometry (@see
  95. SceneManager::setWorldGeometry). The single most efficient way to
  96. render large amounts of static geometry is to use a SceneManager which
  97. is specialised for dealing with that particular world structure.
  98. However, this class does provide you with a good 'halfway house'
  99. between generalised movable geometry (Entity) which works with all
  100. SceneManagers but isn't efficient when using very large numbers, and
  101. highly specialised world geometry which is extremely fast but not
  102. generic and typically requires custom world editors.
  103. @par
  104. You should not construct instances of this class directly; instead, cal
  105. SceneManager::createStaticGeometry, which gives the SceneManager the
  106. option of providing you with a specialised version of this class if it
  107. wishes, and also handles the memory management for you like other
  108. classes.
  109. @note
  110. Warning: this class only works with indexed triangle lists at the moment,
  111. do not pass it triangle strips, fans or lines / points, or unindexed geometry.
  112. */
  113. class _OgreExport StaticGeometry : public BatchedGeometryAlloc
  114. {
  115. public:
  116. /** Struct holding geometry optimised per SubMesh / lod level, ready
  117. for copying to instances.
  118. @remarks
  119. Since we're going to be duplicating geometry lots of times, it's
  120. far more important that we don't have redundant vertex data. If a
  121. SubMesh uses shared geometry, or we're looking at a lower LOD, not
  122. all the vertices are being referenced by faces on that submesh.
  123. Therefore to duplicate them, potentially hundreds or even thousands
  124. of times, would be extremely wasteful. Therefore, if a SubMesh at
  125. a given LOD has wastage, we create an optimised version of it's
  126. geometry which is ready for copying with no wastage.
  127. */
  128. class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc
  129. {
  130. public:
  131. OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {}
  132. ~OptimisedSubMeshGeometry()
  133. {
  134. OGRE_DELETE vertexData;
  135. OGRE_DELETE indexData;
  136. }
  137. VertexData *vertexData;
  138. IndexData *indexData;
  139. };
  140. typedef list<OptimisedSubMeshGeometry*>::type OptimisedSubMeshGeometryList;
  141. /// Saved link between SubMesh at a LOD and vertex/index data
  142. /// May point to original or optimised geometry
  143. struct SubMeshLodGeometryLink
  144. {
  145. VertexData* vertexData;
  146. IndexData* indexData;
  147. };
  148. typedef vector<SubMeshLodGeometryLink>::type SubMeshLodGeometryLinkList;
  149. typedef map<SubMesh*, SubMeshLodGeometryLinkList*>::type SubMeshGeometryLookup;
  150. /// Structure recording a queued submesh for the build
  151. struct QueuedSubMesh : public BatchedGeometryAlloc
  152. {
  153. SubMesh* submesh;
  154. /// Link to LOD list of geometry, potentially optimised
  155. SubMeshLodGeometryLinkList* geometryLodList;
  156. String materialName;
  157. Vector3 position;
  158. Quaternion orientation;
  159. Vector3 scale;
  160. /// Pre-transformed world AABB
  161. AxisAlignedBox worldBounds;
  162. };
  163. typedef vector<QueuedSubMesh*>::type QueuedSubMeshList;
  164. /// Structure recording a queued geometry for low level builds
  165. struct QueuedGeometry : public BatchedGeometryAlloc
  166. {
  167. SubMeshLodGeometryLink* geometry;
  168. Vector3 position;
  169. Quaternion orientation;
  170. Vector3 scale;
  171. };
  172. typedef vector<QueuedGeometry*>::type QueuedGeometryList;
  173. // forward declarations
  174. class LODBucket;
  175. class MaterialBucket;
  176. class Region;
  177. /** A GeometryBucket is a the lowest level bucket where geometry with
  178. the same vertex & index format is stored. It also acts as the
  179. renderable.
  180. */
  181. class _OgreExport GeometryBucket : public Renderable, public BatchedGeometryAlloc
  182. {
  183. protected:
  184. /// Geometry which has been queued up pre-build (not for deallocation)
  185. QueuedGeometryList mQueuedGeometry;
  186. /// Pointer to parent bucket
  187. MaterialBucket* mParent;
  188. /// String identifying the vertex / index format
  189. String mFormatString;
  190. /// Vertex information, includes current number of vertices
  191. /// committed to be a part of this bucket
  192. VertexData* mVertexData;
  193. /// Index information, includes index type which limits the max
  194. /// number of vertices which are allowed in one bucket
  195. IndexData* mIndexData;
  196. /// Size of indexes
  197. HardwareIndexBuffer::IndexType mIndexType;
  198. /// Maximum vertex indexable
  199. size_t mMaxVertexIndex;
  200. template<typename T>
  201. void copyIndexes(const T* src, T* dst, size_t count, size_t indexOffset)
  202. {
  203. if (indexOffset == 0)
  204. {
  205. memcpy(dst, src, sizeof(T) * count);
  206. }
  207. else
  208. {
  209. while(count--)
  210. {
  211. *dst++ = static_cast<T>(*src++ + indexOffset);
  212. }
  213. }
  214. }
  215. public:
  216. GeometryBucket(MaterialBucket* parent, const String& formatString,
  217. const VertexData* vData, const IndexData* iData);
  218. virtual ~GeometryBucket();
  219. MaterialBucket* getParent(void) { return mParent; }
  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 getRenderOperation(RenderOperation& op);
  228. void getWorldTransforms(Matrix4* xform) const;
  229. Real getSquaredViewDepth(const Camera* cam) const;
  230. const LightList& getLights(void) const;
  231. bool getCastsShadows(void) const;
  232. /** Try to assign geometry to this bucket.
  233. @return false if there is no room left in this bucket
  234. */
  235. bool assign(QueuedGeometry* qsm);
  236. /// Build
  237. void build(bool stencilShadows);
  238. /// Dump contents for diagnostics
  239. void dump(std::ofstream& of) const;
  240. };
  241. /** A MaterialBucket is a collection of smaller buckets with the same
  242. Material (and implicitly the same LOD). */
  243. class _OgreExport MaterialBucket : public BatchedGeometryAlloc
  244. {
  245. public:
  246. /// list of Geometry Buckets in this region
  247. typedef vector<GeometryBucket*>::type GeometryBucketList;
  248. protected:
  249. /// Pointer to parent LODBucket
  250. LODBucket* mParent;
  251. /// Material being used
  252. String mMaterialName;
  253. /// Pointer to material being used
  254. MaterialPtr mMaterial;
  255. /// Active technique
  256. Technique* mTechnique;
  257. /// list of Geometry Buckets in this region
  258. GeometryBucketList mGeometryBucketList;
  259. // index to current Geometry Buckets for a given geometry format
  260. typedef map<String, GeometryBucket*>::type CurrentGeometryMap;
  261. CurrentGeometryMap mCurrentGeometryMap;
  262. /// Get a packed string identifying the geometry format
  263. String getGeometryFormatString(SubMeshLodGeometryLink* geom);
  264. public:
  265. MaterialBucket(LODBucket* parent, const String& materialName);
  266. virtual ~MaterialBucket();
  267. LODBucket* getParent(void) { return mParent; }
  268. /// Get the material name
  269. const String& getMaterialName(void) const { return mMaterialName; }
  270. /// Assign geometry to this bucket
  271. void assign(QueuedGeometry* qsm);
  272. /// Build
  273. void build(bool stencilShadows);
  274. /// Add children to the render queue
  275. void addRenderables(RenderQueue* queue, uint8 group,
  276. Real lodValue);
  277. /// Get the material for this bucket
  278. const MaterialPtr& getMaterial(void) const { return mMaterial; }
  279. /// Iterator over geometry
  280. typedef VectorIterator<GeometryBucketList> GeometryIterator;
  281. /// Get an iterator over the contained geometry
  282. GeometryIterator getGeometryIterator(void);
  283. /// Get the current Technique
  284. Technique* getCurrentTechnique(void) const { return mTechnique; }
  285. /// Dump contents for diagnostics
  286. void dump(std::ofstream& of) const;
  287. void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables);
  288. };
  289. /** A LODBucket is a collection of smaller buckets with the same LOD.
  290. @remarks
  291. LOD refers to Mesh LOD here. Material LOD can change separately
  292. at the next bucket down from this.
  293. */
  294. class _OgreExport LODBucket : public BatchedGeometryAlloc
  295. {
  296. public:
  297. /// Lookup of Material Buckets in this region
  298. typedef map<String, MaterialBucket*>::type MaterialBucketMap;
  299. protected:
  300. /** Nested class to allow shadows. */
  301. class _OgreExport LODShadowRenderable : public ShadowRenderable
  302. {
  303. protected:
  304. LODBucket* mParent;
  305. // Shared link to position buffer
  306. HardwareVertexBufferSharedPtr mPositionBuffer;
  307. // Shared link to w-coord buffer (optional)
  308. HardwareVertexBufferSharedPtr mWBuffer;
  309. public:
  310. LODShadowRenderable(LODBucket* parent,
  311. HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData,
  312. bool createSeparateLightCap, bool isLightCap = false);
  313. ~LODShadowRenderable();
  314. /// Overridden from ShadowRenderable
  315. void getWorldTransforms(Matrix4* xform) const;
  316. HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; }
  317. HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; }
  318. /// Overridden from ShadowRenderable
  319. virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer);
  320. };
  321. /// Pointer to parent region
  322. Region* mParent;
  323. /// LOD level (0 == full LOD)
  324. unsigned short mLod;
  325. /// lod value at which this LOD starts to apply (squared)
  326. Real mLodValue;
  327. /// Lookup of Material Buckets in this region
  328. MaterialBucketMap mMaterialBucketMap;
  329. /// Geometry queued for a single LOD (deallocated here)
  330. QueuedGeometryList mQueuedGeometryList;
  331. /// Edge list, used if stencil shadow casting is enabled
  332. EdgeData* mEdgeList;
  333. /// Is a vertex program in use somewhere in this group?
  334. bool mVertexProgramInUse;
  335. /// List of shadow renderables
  336. ShadowCaster::ShadowRenderableList mShadowRenderables;
  337. public:
  338. LODBucket(Region* parent, unsigned short lod, Real lodValue);
  339. virtual ~LODBucket();
  340. Region* getParent(void) { return mParent; }
  341. /// Get the lod index
  342. ushort getLod(void) const { return mLod; }
  343. /// Get the lod value
  344. Real getLodValue(void) const { return mLodValue; }
  345. /// Assign a queued submesh to this bucket, using specified mesh LOD
  346. void assign(QueuedSubMesh* qsm, ushort atLod);
  347. /// Build
  348. void build(bool stencilShadows);
  349. /// Add children to the render queue
  350. void addRenderables(RenderQueue* queue, uint8 group,
  351. Real lodValue);
  352. /// Iterator over the materials in this LOD
  353. typedef MapIterator<MaterialBucketMap> MaterialIterator;
  354. /// Get an iterator over the materials in this LOD
  355. MaterialIterator getMaterialIterator(void);
  356. /// Dump contents for diagnostics
  357. void dump(std::ofstream& of) const;
  358. void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables);
  359. EdgeData* getEdgeList() const { return mEdgeList; }
  360. ShadowCaster::ShadowRenderableList& getShadowRenderableList() { return mShadowRenderables; }
  361. bool isVertexProgramInUse() const { return mVertexProgramInUse; }
  362. void updateShadowRenderables(
  363. ShadowTechnique shadowTechnique, const Vector4& lightPos,
  364. HardwareIndexBufferSharedPtr* indexBuffer,
  365. bool extrudeVertices, Real extrusionDistance, unsigned long flags = 0 );
  366. };
  367. /** The details of a topological region which is the highest level of
  368. partitioning for this class.
  369. @remarks
  370. The size & shape of regions entirely depends on the SceneManager
  371. specific implementation. It is a MovableObject since it will be
  372. attached to a node based on the local centre - in practice it
  373. won't actually move (although in theory it could).
  374. */
  375. class _OgreExport Region : public MovableObject
  376. {
  377. friend class MaterialBucket;
  378. friend class GeometryBucket;
  379. public:
  380. /// list of LOD Buckets in this region
  381. typedef vector<LODBucket*>::type LODBucketList;
  382. protected:
  383. /// Parent static geometry
  384. StaticGeometry* mParent;
  385. /// Scene manager link
  386. SceneManager* mSceneMgr;
  387. /// Scene node
  388. SceneNode* mNode;
  389. /// Local list of queued meshes (not used for deallocation)
  390. QueuedSubMeshList mQueuedSubMeshes;
  391. /// Unique identifier for the region
  392. uint32 mRegionID;
  393. /// Center of the region
  394. Vector3 mCentre;
  395. /// Lod values as built up - use the max at each level
  396. Mesh::LodValueList mLodValues;
  397. /// Local AABB relative to region centre
  398. AxisAlignedBox mAABB;
  399. /// Local bounding radius
  400. Real mBoundingRadius;
  401. /// The current lod level, as determined from the last camera
  402. ushort mCurrentLod;
  403. /// Current lod value, passed on to do material lod later
  404. Real mLodValue;
  405. /// List of LOD buckets
  406. LODBucketList mLodBucketList;
  407. /// List of lights for this region
  408. mutable LightList mLightList;
  409. /// The last frame that this light list was updated in
  410. mutable ulong mLightListUpdated;
  411. /// Lod strategy reference
  412. const LodStrategy *mLodStrategy;
  413. /// Current camera
  414. Camera *mCamera;
  415. /// Cached squared view depth value to avoid recalculation by GeometryBucket
  416. Real mSquaredViewDepth;
  417. public:
  418. Region(StaticGeometry* parent, const String& name, SceneManager* mgr,
  419. uint32 regionID, const Vector3& centre);
  420. virtual ~Region();
  421. // more fields can be added in subclasses
  422. StaticGeometry* getParent(void) const { return mParent;}
  423. /// Assign a queued mesh to this region, read for final build
  424. void assign(QueuedSubMesh* qmesh);
  425. /// Build this region
  426. void build(bool stencilShadows);
  427. /// Get the region ID of this region
  428. uint32 getID(void) const { return mRegionID; }
  429. /// Get the centre point of the region
  430. const Vector3& getCentre(void) const { return mCentre; }
  431. const String& getMovableType(void) const;
  432. void _notifyCurrentCamera(Camera* cam);
  433. const AxisAlignedBox& getBoundingBox(void) const;
  434. Real getBoundingRadius(void) const;
  435. void _updateRenderQueue(RenderQueue* queue);
  436. /// @copydoc MovableObject::visitRenderables
  437. void visitRenderables(Renderable::Visitor* visitor,
  438. bool debugRenderables = false);
  439. bool isVisible(void) const;
  440. uint32 getTypeFlags(void) const;
  441. typedef VectorIterator<LODBucketList> LODIterator;
  442. /// Get an iterator over the LODs in this region
  443. LODIterator getLODIterator(void);
  444. /// @copydoc ShadowCaster::getShadowVolumeRenderableIterator
  445. ShadowRenderableListIterator getShadowVolumeRenderableIterator(
  446. ShadowTechnique shadowTechnique, const Light* light,
  447. HardwareIndexBufferSharedPtr* indexBuffer,
  448. bool extrudeVertices, Real extrusionDistance, unsigned long flags = 0 );
  449. /// Overridden from MovableObject
  450. EdgeData* getEdgeList(void);
  451. /** Overridden member from ShadowCaster. */
  452. bool hasEdgeList(void);
  453. /// Dump contents for diagnostics
  454. void dump(std::ofstream& of) const;
  455. };
  456. /** Indexed region map based on packed x/y/z region index, 10 bits for
  457. each axis.
  458. @remarks
  459. Regions are indexed 0-1023 in all axes, where for example region
  460. 0 in the x axis begins at mOrigin.x + (mRegionDimensions.x * -512),
  461. and region 1023 ends at mOrigin + (mRegionDimensions.x * 512).
  462. */
  463. typedef map<uint32, Region*>::type RegionMap;
  464. protected:
  465. // General state & settings
  466. SceneManager* mOwner;
  467. String mName;
  468. bool mBuilt;
  469. Real mUpperDistance;
  470. Real mSquaredUpperDistance;
  471. bool mCastShadows;
  472. Vector3 mRegionDimensions;
  473. Vector3 mHalfRegionDimensions;
  474. Vector3 mOrigin;
  475. bool mVisible;
  476. /// The render queue to use when rendering this object
  477. uint8 mRenderQueueID;
  478. /// Flags whether the RenderQueue's default should be used.
  479. bool mRenderQueueIDSet;
  480. /// Stores the visibility flags for the regions
  481. uint32 mVisibilityFlags;
  482. QueuedSubMeshList mQueuedSubMeshes;
  483. /// List of geometry which has been optimised for SubMesh use
  484. /// This is the primary storage used for cleaning up later
  485. OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList;
  486. /** Cached links from SubMeshes to (potentially optimised) geometry
  487. This is not used for deletion since the lookup may reference
  488. original vertex data
  489. */
  490. SubMeshGeometryLookup mSubMeshGeometryLookup;
  491. /// Map of regions
  492. RegionMap mRegionMap;
  493. /** Virtual method for getting a region most suitable for the
  494. passed in bounds. Can be overridden by subclasses.
  495. */
  496. virtual Region* getRegion(const AxisAlignedBox& bounds, bool autoCreate);
  497. /** Get the region within which a point lies */
  498. virtual Region* getRegion(const Vector3& point, bool autoCreate);
  499. /** Get the region using indexes */
  500. virtual Region* getRegion(ushort x, ushort y, ushort z, bool autoCreate);
  501. /** Get the region using a packed index, returns null if it doesn't exist. */
  502. virtual Region* getRegion(uint32 index);
  503. /** Get the region indexes for a point.
  504. */
  505. virtual void getRegionIndexes(const Vector3& point,
  506. ushort& x, ushort& y, ushort& z);
  507. /** Pack 3 indexes into a single index value
  508. */
  509. virtual uint32 packIndex(ushort x, ushort y, ushort z);
  510. /** Get the volume intersection for an indexed region with some bounds.
  511. */
  512. virtual Real getVolumeIntersection(const AxisAlignedBox& box,
  513. ushort x, ushort y, ushort z);
  514. /** Get the bounds of an indexed region.
  515. */
  516. virtual AxisAlignedBox getRegionBounds(ushort x, ushort y, ushort z);
  517. /** Get the centre of an indexed region.
  518. */
  519. virtual Vector3 getRegionCentre(ushort x, ushort y, ushort z);
  520. /** Calculate world bounds from a set of vertex data. */
  521. virtual AxisAlignedBox calculateBounds(VertexData* vertexData,
  522. const Vector3& position, const Quaternion& orientation,
  523. const Vector3& scale);
  524. /** Look up or calculate the geometry data to use for this SubMesh */
  525. SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm);
  526. /** Split some shared geometry into dedicated geometry. */
  527. void splitGeometry(VertexData* vd, IndexData* id,
  528. SubMeshLodGeometryLink* targetGeomLink);
  529. typedef map<size_t, size_t>::type IndexRemap;
  530. /** Method for figuring out which vertices are used by an index buffer
  531. and calculating a remap lookup for a vertex buffer just containing
  532. those vertices.
  533. */
  534. template <typename T>
  535. void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap)
  536. {
  537. remap.clear();
  538. for (size_t i = 0; i < numIndexes; ++i)
  539. {
  540. // use insert since duplicates are silently discarded
  541. remap.insert(IndexRemap::value_type(*pBuffer++, remap.size()));
  542. // this will have mapped oldindex -> new index IF oldindex
  543. // wasn't already there
  544. }
  545. }
  546. /** Method for altering indexes based on a remap. */
  547. template <typename T>
  548. void remapIndexes(T* src, T* dst, const IndexRemap& remap,
  549. size_t numIndexes)
  550. {
  551. for (size_t i = 0; i < numIndexes; ++i)
  552. {
  553. // look up original and map to target
  554. IndexRemap::const_iterator ix = remap.find(*src++);
  555. assert(ix != remap.end());
  556. *dst++ = static_cast<T>(ix->second);
  557. }
  558. }
  559. public:
  560. /// Constructor; do not use directly (@see SceneManager::createStaticGeometry)
  561. StaticGeometry(SceneManager* owner, const String& name);
  562. /// Destructor
  563. virtual ~StaticGeometry();
  564. /// Get the name of this object
  565. const String& getName(void) const { return mName; }
  566. /** Adds an Entity to the static geometry.
  567. @remarks
  568. This method takes an existing Entity and adds its details to the
  569. list of elements to include when building. Note that the Entity
  570. itself is not copied or referenced in this method; an Entity is
  571. passed simply so that you can change the materials of attached
  572. SubEntity objects if you want. You can add the same Entity
  573. instance multiple times with different material settings
  574. completely safely, and destroy the Entity before destroying
  575. this StaticGeometry if you like. The Entity passed in is simply
  576. used as a definition.
  577. @note Must be called before 'build'.
  578. @param ent The Entity to use as a definition (the Mesh and Materials
  579. referenced will be recorded for the build call).
  580. @param position The world position at which to add this Entity
  581. @param orientation The world orientation at which to add this Entity
  582. @param scale The scale at which to add this entity
  583. */
  584. virtual void addEntity(Entity* ent, const Vector3& position,
  585. const Quaternion& orientation = Quaternion::IDENTITY,
  586. const Vector3& scale = Vector3::UNIT_SCALE);
  587. /** Adds all the Entity objects attached to a SceneNode and all it's
  588. children to the static geometry.
  589. @remarks
  590. This method performs just like addEntity, except it adds all the
  591. entities attached to an entire sub-tree to the geometry.
  592. The position / orientation / scale parameters are taken from the
  593. node structure instead of being specified manually.
  594. @note
  595. The SceneNode you pass in will not be automatically detached from
  596. it's parent, so if you have this node already attached to the scene
  597. graph, you will need to remove it if you wish to avoid the overhead
  598. of rendering <i>both</i> the original objects and their new static
  599. versions! We don't do this for you incase you are preparing this
  600. in advance and so don't want the originals detached yet.
  601. @note Must be called before 'build'.
  602. @param node Pointer to the node to use to provide a set of Entity
  603. templates
  604. */
  605. virtual void addSceneNode(const SceneNode* node);
  606. /** Build the geometry.
  607. @remarks
  608. Based on all the entities which have been added, and the batching
  609. options which have been set, this method constructs the batched
  610. geometry structures required. The batches are added to the scene
  611. and will be rendered unless you specifically hide them.
  612. @note
  613. Once you have called this method, you can no longer add any more
  614. entities.
  615. */
  616. virtual void build(void);
  617. /** Destroys all the built geometry state (reverse of build).
  618. @remarks
  619. You can call build() again after this and it will pick up all the
  620. same entities / nodes you queued last time.
  621. */
  622. virtual void destroy(void);
  623. /** Clears any of the entities / nodes added to this geometry and
  624. destroys anything which has already been built.
  625. */
  626. virtual void reset(void);
  627. /** Sets the distance at which batches are no longer rendered.
  628. @remarks
  629. This lets you turn off batches at a given distance. This can be
  630. useful for things like detail meshes (grass, foliage etc) and could
  631. be combined with a shader which fades the geometry out beforehand
  632. to lessen the effect.
  633. @param dist Distance beyond which the batches will not be rendered
  634. (the default is 0, which means batches are always rendered).
  635. */
  636. virtual void setRenderingDistance(Real dist) {
  637. mUpperDistance = dist;
  638. mSquaredUpperDistance = mUpperDistance * mUpperDistance;
  639. }
  640. /** Gets the distance at which batches are no longer rendered. */
  641. virtual Real getRenderingDistance(void) const { return mUpperDistance; }
  642. /** Gets the squared distance at which batches are no longer rendered. */
  643. virtual Real getSquaredRenderingDistance(void) const
  644. { return mSquaredUpperDistance; }
  645. /** Hides or shows all the batches. */
  646. virtual void setVisible(bool visible);
  647. /** Are the batches visible? */
  648. virtual bool isVisible(void) const { return mVisible; }
  649. /** Sets whether this geometry should cast shadows.
  650. @remarks
  651. No matter what the settings on the original entities,
  652. the StaticGeometry class defaults to not casting shadows.
  653. This is because, being static, unless you have moving lights
  654. you'd be better to use precalculated shadows of some sort.
  655. However, if you need them, you can enable them using this
  656. method. If the SceneManager is set up to use stencil shadows,
  657. edge lists will be copied from the underlying meshes on build.
  658. It is essential that all meshes support stencil shadows in this
  659. case.
  660. @note If you intend to use stencil shadows, you must set this to
  661. true before calling 'build' as well as making sure you set the
  662. scene's shadow type (that should always be the first thing you do
  663. anyway). You can turn shadows off temporarily but they can never
  664. be turned on if they were not at the time of the build.
  665. */
  666. virtual void setCastShadows(bool castShadows);
  667. /// Will the geometry from this object cast shadows?
  668. virtual bool getCastShadows(void) { return mCastShadows; }
  669. /** Sets the size of a single region of geometry.
  670. @remarks
  671. This method allows you to configure the physical world size of
  672. each region, so you can balance culling against batch size. Entities
  673. will be fitted within the batch they most closely fit, and the
  674. eventual bounds of each batch may well be slightly larger than this
  675. if they overlap a little. The default is Vector3(1000, 1000, 1000).
  676. @note Must be called before 'build'.
  677. @param size Vector3 expressing the 3D size of each region.
  678. */
  679. virtual void setRegionDimensions(const Vector3& size) {
  680. mRegionDimensions = size;
  681. mHalfRegionDimensions = size * 0.5;
  682. }
  683. /** Gets the size of a single batch of geometry. */
  684. virtual const Vector3& getRegionDimensions(void) const { return mRegionDimensions; }
  685. /** Sets the origin of the geometry.
  686. @remarks
  687. This method allows you to configure the world centre of the geometry,
  688. thus the place which all regions surround. You probably don't need
  689. to mess with this unless you have a seriously large world, since the
  690. default set up can handle an area 1024 * mRegionDimensions, and
  691. the sparseness of population is no issue when it comes to rendering.
  692. The default is Vector3(0,0,0).
  693. @note Must be called before 'build'.
  694. @param size Vector3 expressing the 3D origin of the geometry.
  695. */
  696. virtual void setOrigin(const Vector3& origin) { mOrigin = origin; }
  697. /** Gets the origin of this geometry. */
  698. virtual const Vector3& getOrigin(void) const { return mOrigin; }
  699. /// Sets the visibility flags of all the regions at once
  700. void setVisibilityFlags(uint32 flags);
  701. /// Returns the visibility flags of the regions
  702. uint32 getVisibilityFlags() const;
  703. /** Sets the render queue group this object will be rendered through.
  704. @remarks
  705. Render queues are grouped to allow you to more tightly control the ordering
  706. of rendered objects. If you do not call this method, all objects default
  707. to the default queue (RenderQueue::getDefaultQueueGroup), which is fine for
  708. most objects. You may want to alter this if you want to perform more complex
  709. rendering.
  710. @par
  711. See RenderQueue for more details.
  712. @param queueID Enumerated value of the queue group to use.
  713. */
  714. virtual void setRenderQueueGroup(uint8 queueID);
  715. /** Gets the queue group for this entity, see setRenderQueueGroup for full details. */
  716. virtual uint8 getRenderQueueGroup(void) const;
  717. /// @copydoc MovableObject::visitRenderables
  718. void visitRenderables(Renderable::Visitor* visitor,
  719. bool debugRenderables = false);
  720. /// Iterator for iterating over contained regions
  721. typedef MapIterator<RegionMap> RegionIterator;
  722. /// Get an iterator over the regions in this geometry
  723. RegionIterator getRegionIterator(void);
  724. /** Dump the contents of this StaticGeometry to a file for diagnostic
  725. purposes.
  726. */
  727. virtual void dump(const String& filename) const;
  728. };
  729. /** @} */
  730. /** @} */
  731. }
  732. #endif