CTerrainSceneNode.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. // The code for the TerrainSceneNode is based on the GeoMipMapSceneNode
  5. // developed by Spintz. He made it available for Irrlicht and allowed it to be
  6. // distributed under this licence. I only modified some parts. A lot of thanks go to him.
  7. #ifndef __C_TERRAIN_SCENE_NODE_H__
  8. #define __C_TERRAIN_SCENE_NODE_H__
  9. #include "ITerrainSceneNode.h"
  10. #include "IDynamicMeshBuffer.h"
  11. #include "path.h"
  12. namespace irr
  13. {
  14. namespace io
  15. {
  16. class IFileSystem;
  17. class IReadFile;
  18. }
  19. namespace scene
  20. {
  21. struct SMesh;
  22. class ITextSceneNode;
  23. //! A scene node for displaying terrain using the geo mip map algorithm.
  24. class CTerrainSceneNode : public ITerrainSceneNode
  25. {
  26. public:
  27. //! constructor
  28. //! \param parent: The node which this node is a child of. Making this node a child of another node, or
  29. //! making it a parent of another node is yet untested and most likely does not work properly.
  30. //! \param mgr: Pointer to the scene manager.
  31. //! \param id: The id of the node
  32. //! \param maxLOD: The maximum LOD ( Level of Detail ) for the node.
  33. //! \param patchSize: An E_GEOMIPMAP_PATCH_SIZE enumeration defining the size of each patch of the terrain.
  34. //! \param position: The absolute position of this node.
  35. //! \param rotation: The absolute rotation of this node. ( NOT YET IMPLEMENTED )
  36. //! \param scale: The scale factor for the terrain. If you're using a heightmap of size 128x128 and would like
  37. //! your terrain to be 12800x12800 in game units, then use a scale factor of ( core::vector ( 100.0f, 100.0f, 100.0f ).
  38. //! If you use a Y scaling factor of 0.0f, then your terrain will be flat.
  39. CTerrainSceneNode(ISceneNode* parent, ISceneManager* mgr, io::IFileSystem* fs, s32 id,
  40. s32 maxLOD = 4, E_TERRAIN_PATCH_SIZE patchSize = ETPS_17,
  41. const core::vector3df& position = core::vector3df(0.0f, 0.0f, 0.0f),
  42. const core::vector3df& rotation = core::vector3df(0.0f, 0.0f, 0.0f),
  43. const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
  44. virtual ~CTerrainSceneNode();
  45. //! Initializes the terrain data. Loads the vertices from the heightMapFile.
  46. virtual bool loadHeightMap(io::IReadFile* file,
  47. video::SColor vertexColor = video::SColor ( 255, 255, 255, 255 ), s32 smoothFactor = 0 );
  48. //! Initializes the terrain data. Loads the vertices from the heightMapFile.
  49. virtual bool loadHeightMapRAW(io::IReadFile* file, s32 bitsPerPixel = 16,
  50. bool signedData=true, bool floatVals=false, s32 width=0, video::SColor vertexColor = video::SColor ( 255, 255, 255, 255 ), s32 smoothFactor = 0 );
  51. //! Returns the material based on the zero based index i. This scene node only uses
  52. //! 1 material.
  53. //! \param i: Zero based index i. UNUSED, left in for virtual purposes.
  54. //! \return Returns the single material this scene node uses.
  55. virtual video::SMaterial& getMaterial(u32 i);
  56. //! Returns amount of materials used by this scene node ( always 1 )
  57. //! \return Returns current count of materials used by this scene node ( always 1 )
  58. virtual u32 getMaterialCount() const;
  59. //! Gets the last scaling factor applied to the scene node. This value only represents the
  60. //! last scaling factor presented to the node. For instance, if you make create the node
  61. //! with a scale factor of ( 1.0f, 1.0f, 1.0f ) then call setScale ( 50.0f, 5.0f, 50.0f ),
  62. //! then make another call to setScale with the values ( 2.0f, 2.0f, 2.0f ), this will return
  63. //! core::vector3df ( 2.0f, 2.0f, 2.0f ), although the total scaling of the scene node is
  64. //! core::vector3df ( 100.0f, 10.0f, 100.0f ).
  65. //! \return Returns the last scaling factor passed to the scene node.
  66. virtual const core::vector3df& getScale() const
  67. {
  68. return TerrainData.Scale;
  69. }
  70. //! Scales the scene nodes vertices by the vector specified.
  71. //! \param scale: Scaling factor to apply to the node.
  72. virtual void setScale(const core::vector3df& scale);
  73. //! Gets the last rotation factor applied to the scene node.
  74. //! \return Returns the last rotation factor applied to the scene node.
  75. virtual const core::vector3df& getRotation() const
  76. {
  77. return TerrainData.Rotation;
  78. }
  79. //! Rotates the node. This only modifies the relative rotation of the node.
  80. //! \param rotation: New rotation of the node in degrees.
  81. virtual void setRotation(const core::vector3df& rotation);
  82. //! Sets the pivot point for rotation of this node.
  83. //! NOTE: The default for the RotationPivot will be the center of the individual tile.
  84. virtual void setRotationPivot( const core::vector3df& pivot );
  85. //! Gets the last positioning vector applied to the scene node.
  86. //! \return Returns the last position vector applied to the scene node.
  87. virtual const core::vector3df& getPosition() const
  88. {
  89. return TerrainData.Position;
  90. }
  91. //! Moves the scene nodes vertices by the vector specified.
  92. //! \param newpos: Vector specifying how much to move each vertex of the scene node.
  93. virtual void setPosition(const core::vector3df& newpos);
  94. //! Updates the scene nodes indices if the camera has moved or rotated by a certain
  95. //! threshold, which can be changed using the SetCameraMovementDeltaThreshold and
  96. //! SetCameraRotationDeltaThreshold functions. This also determines if a given patch
  97. //! for the scene node is within the view frustum and if it's not the indices are not
  98. //! generated for that patch.
  99. virtual void OnRegisterSceneNode();
  100. //! Render the scene node
  101. virtual void render();
  102. //! Return the bounding box of the entire terrain.
  103. virtual const core::aabbox3d<f32>& getBoundingBox() const;
  104. //! Return the bounding box of a patch
  105. virtual const core::aabbox3d<f32>& getBoundingBox(s32 patchX, s32 patchZ) const;
  106. //! Return the number of indices currently used to draw the scene node.
  107. virtual u32 getIndexCount() const { return IndicesToRender; }
  108. //! Returns the mesh
  109. virtual IMesh* getMesh();
  110. //! Returns a pointer to the buffer used by the terrain (most users will not need this)
  111. virtual IMeshBuffer* getRenderBuffer() { return RenderBuffer; }
  112. //! Gets the meshbuffer data based on a specified Level of Detail.
  113. //! \param mb: A reference to an IDynamicMeshBuffer object
  114. //! \param LOD: The Level Of Detail you want the indices from.
  115. virtual void getMeshBufferForLOD(IDynamicMeshBuffer& mb, s32 LOD=0) const;
  116. //! Gets the indices for a specified patch at a specified Level of Detail.
  117. //! \param indices: A reference to an array of u32 indices.
  118. //! \param patchX: Patch x coordinate.
  119. //! \param patchZ: Patch z coordinate.
  120. //! \param LOD: The level of detail to get for that patch. If -1, then get
  121. //! the CurrentLOD. If the CurrentLOD is set to -1, meaning it's not shown,
  122. //! then it will retrieve the triangles at the highest LOD (0).
  123. //! \return: Number of indices put into the buffer.
  124. virtual s32 getIndicesForPatch(core::array<u32>& indices,
  125. s32 patchX, s32 patchZ, s32 LOD=0);
  126. //! Populates an array with the CurrentLOD of each patch.
  127. //! \param LODs: A reference to a core::array<s32> to hold the values
  128. //! \return Returns the number of elements in the array
  129. virtual s32 getCurrentLODOfPatches(core::array<s32>& LODs) const;
  130. //! Manually sets the LOD of a patch
  131. //! \param patchX: Patch x coordinate.
  132. //! \param patchZ: Patch z coordinate.
  133. //! \param LOD: The level of detail to set the patch to.
  134. virtual void setLODOfPatch(s32 patchX, s32 patchZ, s32 LOD=0);
  135. //! Returns center of terrain.
  136. virtual const core::vector3df& getTerrainCenter() const
  137. {
  138. return TerrainData.Center;
  139. }
  140. //! Returns center of terrain.
  141. virtual f32 getHeight( f32 x, f32 y ) const;
  142. //! Sets the movement camera threshold which is used to determine when to recalculate
  143. //! indices for the scene node. The default value is 10.0f.
  144. virtual void setCameraMovementDelta(f32 delta)
  145. {
  146. CameraMovementDelta = delta;
  147. }
  148. //! Sets the rotation camera threshold which is used to determine when to recalculate
  149. //! indices for the scene node. The default value is 1.0f.
  150. virtual void setCameraRotationDelta(f32 delta)
  151. {
  152. CameraRotationDelta = delta;
  153. }
  154. //! Sets whether or not the node should dynamically update it its associated selector when
  155. //! the geomipmap data changes.
  156. //! param bVal: Boolean value representing whether or not to update selector dynamically.
  157. //! NOTE: Temporarily disabled while working out issues with DynamicSelectorUpdate
  158. virtual void setDynamicSelectorUpdate(bool bVal ) { DynamicSelectorUpdate = false; }
  159. //! Override the default generation of distance thresholds for determining the LOD a patch
  160. //! is rendered at. If any LOD is overridden, then the scene node will no longer apply
  161. //! scaling factors to these values. If you override these distances and then apply
  162. //! a scale to the scene node, it is your responsibility to update the new distances to
  163. //! work best with your new terrain size.
  164. virtual bool overrideLODDistance( s32 LOD, f64 newDistance );
  165. //! Scales the two textures
  166. virtual void scaleTexture(f32 scale = 1.0f, f32 scale2 = 0.0f);
  167. //! Returns type of the scene node
  168. virtual ESCENE_NODE_TYPE getType() const {return ESNT_TERRAIN;}
  169. //! Writes attributes of the scene node.
  170. virtual void serializeAttributes(io::IAttributes* out,
  171. io::SAttributeReadWriteOptions* options=0) const;
  172. //! Reads attributes of the scene node.
  173. virtual void deserializeAttributes(io::IAttributes* in,
  174. io::SAttributeReadWriteOptions* options=0);
  175. //! Creates a clone of this scene node and its children.
  176. virtual ISceneNode* clone(ISceneNode* newParent,
  177. ISceneManager* newManager);
  178. private:
  179. friend class CTerrainTriangleSelector;
  180. struct SPatch
  181. {
  182. SPatch()
  183. : Top(0), Bottom(0), Right(0), Left(0), CurrentLOD(-1)
  184. {
  185. }
  186. SPatch* Top;
  187. SPatch* Bottom;
  188. SPatch* Right;
  189. SPatch* Left;
  190. s32 CurrentLOD;
  191. core::aabbox3df BoundingBox;
  192. core::vector3df Center;
  193. };
  194. struct STerrainData
  195. {
  196. STerrainData(s32 patchSize, s32 maxLOD, const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
  197. : Patches(0), Size(0), Position(position), Rotation(rotation),
  198. Scale(scale), PatchSize(patchSize), CalcPatchSize(patchSize-1),
  199. PatchCount(0), MaxLOD(maxLOD)
  200. {
  201. }
  202. SPatch* Patches;
  203. s32 Size;
  204. core::vector3df Position;
  205. core::vector3df Rotation;
  206. core::vector3df RotationPivot;
  207. core::vector3df Scale;
  208. core::vector3df Center;
  209. s32 PatchSize;
  210. s32 CalcPatchSize;
  211. s32 PatchCount;
  212. s32 MaxLOD;
  213. core::aabbox3df BoundingBox;
  214. core::array<f64> LODDistanceThreshold;
  215. };
  216. virtual void preRenderCalculationsIfNeeded();
  217. virtual void preRenderLODCalculations();
  218. virtual void preRenderIndicesCalculations();
  219. //! get indices when generating index data for patches at varying levels of detail.
  220. u32 getIndex(const s32 PatchX, const s32 PatchZ, const s32 PatchIndex, u32 vX, u32 vZ) const;
  221. //! smooth the terrain
  222. void smoothTerrain(IDynamicMeshBuffer* mb, s32 smoothFactor);
  223. //! calculate smooth normals
  224. void calculateNormals(IDynamicMeshBuffer* mb);
  225. //! create patches, stuff that needs to only be done once for patches goes here.
  226. void createPatches();
  227. //! calculate the internal STerrainData structure
  228. void calculatePatchData();
  229. //! calculate or recalculate the distance thresholds
  230. void calculateDistanceThresholds(bool scalechanged = false);
  231. //! sets the CurrentLOD of all patches to the specified LOD
  232. void setCurrentLODOfPatches(s32 i);
  233. //! sets the CurrentLOD of TerrainData patches to the LODs specified in the array
  234. void setCurrentLODOfPatches(const core::array<s32>& lodarray);
  235. //! Apply transformation changes( scale, position, rotation )
  236. void applyTransformation();
  237. STerrainData TerrainData;
  238. SMesh* Mesh;
  239. IDynamicMeshBuffer *RenderBuffer;
  240. u32 VerticesToRender;
  241. u32 IndicesToRender;
  242. bool DynamicSelectorUpdate;
  243. bool OverrideDistanceThreshold;
  244. bool UseDefaultRotationPivot;
  245. bool ForceRecalculation;
  246. core::vector3df OldCameraPosition;
  247. core::vector3df OldCameraRotation;
  248. core::vector3df OldCameraUp;
  249. f32 OldCameraFOV;
  250. f32 CameraMovementDelta;
  251. f32 CameraRotationDelta;
  252. f32 CameraFOVDelta;
  253. // needed for (de)serialization
  254. f32 TCoordScale1;
  255. f32 TCoordScale2;
  256. s32 SmoothFactor;
  257. io::path HeightmapFile;
  258. io::IFileSystem* FileSystem;
  259. };
  260. } // end namespace scene
  261. } // end namespace irr
  262. #endif // __C_TERRAIN_SCENE_NODE_H__