Terrain.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #include "../Container/ArrayPtr.h"
  5. #include "../Scene/Component.h"
  6. namespace Urho3D
  7. {
  8. class Image;
  9. class IndexBuffer;
  10. class Material;
  11. class Node;
  12. class TerrainPatch;
  13. /// Heightmap terrain component.
  14. class URHO3D_API Terrain : public Component
  15. {
  16. URHO3D_OBJECT(Terrain, Component);
  17. public:
  18. /// Construct.
  19. explicit Terrain(Context* context);
  20. /// Destruct.
  21. ~Terrain() override;
  22. /// Register object factory.
  23. /// @nobind
  24. static void RegisterObject(Context* context);
  25. /// Apply attribute changes that can not be applied immediately. Called after scene load or a network update.
  26. void ApplyAttributes() override;
  27. /// Handle enabled/disabled state change.
  28. void OnSetEnabled() override;
  29. /// Set patch quads per side. Must be a power of two.
  30. /// @property
  31. void SetPatchSize(int size);
  32. /// Set vertex (XZ) and height (Y) spacing.
  33. /// @property
  34. void SetSpacing(const Vector3& spacing);
  35. /// Set maximum number of LOD levels for terrain patches. This can be between 1-4.
  36. /// @property
  37. void SetMaxLodLevels(unsigned levels);
  38. /// Set LOD level used for terrain patch occlusion. By default (NINDEX) the coarsest. Since the LOD level used needs to be fixed, using finer LOD levels may result in false positive occlusion in cases where the actual rendered geometry is coarser, so use with caution.
  39. /// @property
  40. void SetOcclusionLodLevel(i32 level);
  41. /// Set smoothing of heightmap.
  42. /// @property
  43. void SetSmoothing(bool enable);
  44. /// Set heightmap image. Dimensions should be a power of two + 1. Uses 8-bit grayscale, or optionally red as MSB and green as LSB for 16-bit accuracy. Return true if successful.
  45. /// @property
  46. bool SetHeightMap(Image* image);
  47. /// Set material.
  48. /// @property
  49. void SetMaterial(Material* material);
  50. /// Set north (positive Z) neighbor terrain for seamless LOD changes across terrains.
  51. /// @property
  52. void SetNorthNeighbor(Terrain* north);
  53. /// Set south (negative Z) neighbor terrain for seamless LOD changes across terrains.
  54. /// @property
  55. void SetSouthNeighbor(Terrain* south);
  56. /// Set west (negative X) neighbor terrain for seamless LOD changes across terrains.
  57. /// @property
  58. void SetWestNeighbor(Terrain* west);
  59. /// Set east (positive X) neighbor terrain for seamless LOD changes across terrains.
  60. /// @property
  61. void SetEastNeighbor(Terrain* east);
  62. /// Set all neighbor terrains at once.
  63. void SetNeighbors(Terrain* north, Terrain* south, Terrain* west, Terrain* east);
  64. /// Set draw distance for patches.
  65. /// @property
  66. void SetDrawDistance(float distance);
  67. /// Set shadow draw distance for patches.
  68. /// @property
  69. void SetShadowDistance(float distance);
  70. /// Set LOD bias for patches. Affects which terrain LOD to display.
  71. /// @property
  72. void SetLodBias(float bias);
  73. /// Set view mask for patches. Is and'ed with camera's view mask to see if the object should be rendered.
  74. /// @property
  75. void SetViewMask(unsigned mask);
  76. /// Set light mask for patches. Is and'ed with light's and zone's light mask to see if the object should be lit.
  77. /// @property
  78. void SetLightMask(unsigned mask);
  79. /// Set shadow mask for patches. Is and'ed with light's light mask and zone's shadow mask to see if the object should be rendered to a shadow map.
  80. /// @property
  81. void SetShadowMask(unsigned mask);
  82. /// Set zone mask for patches. Is and'ed with zone's zone mask to see if the object should belong to the zone.
  83. /// @property
  84. void SetZoneMask(unsigned mask);
  85. /// Set maximum number of per-pixel lights for patches. Default 0 is unlimited.
  86. /// @property
  87. void SetMaxLights(unsigned num);
  88. /// Set shadowcaster flag for patches.
  89. /// @property
  90. void SetCastShadows(bool enable);
  91. /// Set occlusion flag for patches. Occlusion uses the coarsest LOD by default.
  92. /// @property
  93. void SetOccluder(bool enable);
  94. /// Set occludee flag for patches.
  95. /// @property
  96. void SetOccludee(bool enable);
  97. /// Apply changes from the heightmap image.
  98. void ApplyHeightMap();
  99. /// Return patch quads per side.
  100. /// @property
  101. int GetPatchSize() const { return patchSize_; }
  102. /// Return vertex and height spacing.
  103. /// @property
  104. const Vector3& GetSpacing() const { return spacing_; }
  105. /// Return heightmap size in vertices.
  106. /// @property
  107. const IntVector2& GetNumVertices() const { return numVertices_; }
  108. /// Return heightmap size in patches.
  109. /// @property
  110. const IntVector2& GetNumPatches() const { return numPatches_; }
  111. /// Return maximum number of LOD levels for terrain patches. This can be between 1-4.
  112. /// @property
  113. unsigned GetMaxLodLevels() const { return maxLodLevels_; }
  114. /// Return LOD level used for occlusion.
  115. /// @property
  116. i32 GetOcclusionLodLevel() const { return occlusionLodLevel_; }
  117. /// Return whether smoothing is in use.
  118. /// @property
  119. bool GetSmoothing() const { return smoothing_; }
  120. /// Return heightmap image.
  121. /// @property
  122. Image* GetHeightMap() const;
  123. /// Return material.
  124. /// @property
  125. Material* GetMaterial() const;
  126. /// Return patch by index.
  127. /// @property{get_patches}
  128. TerrainPatch* GetPatch(i32 index) const;
  129. /// Return patch by patch coordinates.
  130. TerrainPatch* GetPatch(int x, int z) const;
  131. /// Return patch by patch coordinates including neighbor terrains.
  132. TerrainPatch* GetNeighborPatch(int x, int z) const;
  133. /// Return height at world coordinates.
  134. float GetHeight(const Vector3& worldPosition) const;
  135. /// Return normal at world coordinates.
  136. Vector3 GetNormal(const Vector3& worldPosition) const;
  137. /// Convert world position to heightmap pixel position. Note that the internal height data representation is reversed vertically, but in the heightmap image north is at the top.
  138. IntVector2 WorldToHeightMap(const Vector3& worldPosition) const;
  139. /// Convert heightmap pixel position to world position.
  140. Vector3 HeightMapToWorld(const IntVector2& pixelPosition) const;
  141. /// Return north neighbor terrain.
  142. /// @property
  143. Terrain* GetNorthNeighbor() const { return north_; }
  144. /// Return south neighbor terrain.
  145. /// @property
  146. Terrain* GetSouthNeighbor() const { return south_; }
  147. /// Return west neighbor terrain.
  148. /// @property
  149. Terrain* GetWestNeighbor() const { return west_; }
  150. /// Return east neighbor terrain.
  151. /// @property
  152. Terrain* GetEastNeighbor() const { return east_; }
  153. /// Return raw height data.
  154. SharedArrayPtr<float> GetHeightData() const { return heightData_; }
  155. /// Return draw distance.
  156. /// @property
  157. float GetDrawDistance() const { return drawDistance_; }
  158. /// Return shadow draw distance.
  159. /// @property
  160. float GetShadowDistance() const { return shadowDistance_; }
  161. /// Return LOD bias.
  162. /// @property
  163. float GetLodBias() const { return lodBias_; }
  164. /// Return view mask.
  165. /// @property
  166. unsigned GetViewMask() const { return viewMask_; }
  167. /// Return light mask.
  168. /// @property
  169. unsigned GetLightMask() const { return lightMask_; }
  170. /// Return shadow mask.
  171. /// @property
  172. unsigned GetShadowMask() const { return shadowMask_; }
  173. /// Return zone mask.
  174. /// @property
  175. unsigned GetZoneMask() const { return zoneMask_; }
  176. /// Return maximum number of per-pixel lights.
  177. /// @property
  178. unsigned GetMaxLights() const { return maxLights_; }
  179. /// Return visible flag.
  180. bool IsVisible() const { return visible_; }
  181. /// Return shadowcaster flag.
  182. /// @property
  183. bool GetCastShadows() const { return castShadows_; }
  184. /// Return occluder flag.
  185. /// @property
  186. bool IsOccluder() const { return occluder_; }
  187. /// Return occludee flag.
  188. /// @property
  189. bool IsOccludee() const { return occludee_; }
  190. /// Regenerate patch geometry.
  191. void CreatePatchGeometry(TerrainPatch* patch);
  192. /// Update patch based on LOD and neighbor LOD.
  193. void UpdatePatchLod(TerrainPatch* patch);
  194. /// Set heightmap attribute.
  195. void SetHeightMapAttr(const ResourceRef& value);
  196. /// Set material attribute.
  197. void SetMaterialAttr(const ResourceRef& value);
  198. /// Set patch size attribute.
  199. void SetPatchSizeAttr(int value);
  200. /// Set max LOD levels attribute.
  201. void SetMaxLodLevelsAttr(unsigned value);
  202. /// Set occlusion LOD level attribute.
  203. void SetOcclusionLodLevelAttr(i32 value);
  204. /// Return heightmap attribute.
  205. ResourceRef GetHeightMapAttr() const;
  206. /// Return material attribute.
  207. ResourceRef GetMaterialAttr() const;
  208. private:
  209. /// Regenerate terrain geometry.
  210. void CreateGeometry();
  211. /// Create index data shared by all patches.
  212. void CreateIndexData();
  213. /// Return an uninterpolated terrain height value, clamping to edges.
  214. float GetRawHeight(int x, int z) const;
  215. /// Return a source terrain height value, clamping to edges. The source data is used for smoothing.
  216. float GetSourceHeight(int x, int z) const;
  217. /// Return interpolated height for a specific LOD level.
  218. float GetLodHeight(int x, int z, unsigned lodLevel) const;
  219. /// Get slope-based terrain normal at position.
  220. Vector3 GetRawNormal(int x, int z) const;
  221. /// Calculate LOD errors for a patch.
  222. void CalculateLodErrors(TerrainPatch* patch);
  223. /// Set neighbors for a patch.
  224. void SetPatchNeighbors(TerrainPatch* patch);
  225. /// Set heightmap image and optionally recreate the geometry immediately. Return true if successful.
  226. bool SetHeightMapInternal(Image* image, bool recreateNow);
  227. /// Handle heightmap image reload finished.
  228. void HandleHeightMapReloadFinished(StringHash eventType, VariantMap& eventData);
  229. /// Handle neighbor terrain geometry being created. Update the edge patch neighbors as necessary.
  230. void HandleNeighborTerrainCreated(StringHash eventType, VariantMap& eventData);
  231. /// Update edge patch neighbors when neighbor terrain(s) change or are recreated.
  232. void UpdateEdgePatchNeighbors();
  233. /// Mark neighbors dirty.
  234. void MarkNeighborsDirty() { neighborsDirty_ = true; }
  235. /// Mark terrain dirty.
  236. void MarkTerrainDirty() { recreateTerrain_ = true; }
  237. /// Shared index buffer.
  238. SharedPtr<IndexBuffer> indexBuffer_;
  239. /// Heightmap image.
  240. SharedPtr<Image> heightMap_;
  241. /// Height data.
  242. SharedArrayPtr<float> heightData_;
  243. /// Source height data for smoothing.
  244. SharedArrayPtr<float> sourceHeightData_;
  245. /// Material.
  246. SharedPtr<Material> material_;
  247. /// Terrain patches.
  248. Vector<WeakPtr<TerrainPatch>> patches_;
  249. /// Draw ranges for different LODs and stitching combinations.
  250. Vector<Pair<unsigned, unsigned>> drawRanges_;
  251. /// North neighbor terrain.
  252. WeakPtr<Terrain> north_;
  253. /// South neighbor terrain.
  254. WeakPtr<Terrain> south_;
  255. /// West neighbor terrain.
  256. WeakPtr<Terrain> west_;
  257. /// East neighbor terrain.
  258. WeakPtr<Terrain> east_;
  259. /// Vertex and height spacing.
  260. Vector3 spacing_;
  261. /// Vertex and height sacing at the time of last update.
  262. Vector3 lastSpacing_;
  263. /// Origin of patches on the XZ-plane.
  264. Vector2 patchWorldOrigin_;
  265. /// Size of a patch on the XZ-plane.
  266. Vector2 patchWorldSize_;
  267. /// Terrain size in vertices.
  268. IntVector2 numVertices_;
  269. /// Terrain size in vertices at the time of last update.
  270. IntVector2 lastNumVertices_;
  271. /// Terrain size in patches.
  272. IntVector2 numPatches_;
  273. /// Patch size, quads per side.
  274. int patchSize_;
  275. /// Patch size at the time of last update.
  276. int lastPatchSize_;
  277. /// Number of terrain LOD levels.
  278. unsigned numLodLevels_;
  279. /// Maximum number of LOD levels.
  280. unsigned maxLodLevels_;
  281. /// LOD level used for occlusion.
  282. i32 occlusionLodLevel_;
  283. /// Smoothing enable flag.
  284. bool smoothing_;
  285. /// Visible flag.
  286. bool visible_;
  287. /// Shadowcaster flag.
  288. bool castShadows_;
  289. /// Occluder flag.
  290. bool occluder_;
  291. /// Occludee flag.
  292. bool occludee_;
  293. /// View mask.
  294. unsigned viewMask_;
  295. /// Light mask.
  296. unsigned lightMask_;
  297. /// Shadow mask.
  298. unsigned shadowMask_;
  299. /// Zone mask.
  300. unsigned zoneMask_;
  301. /// Draw distance.
  302. float drawDistance_;
  303. /// Shadow distance.
  304. float shadowDistance_;
  305. /// LOD bias.
  306. float lodBias_;
  307. /// Maximum lights.
  308. unsigned maxLights_;
  309. /// Node ID of north neighbor.
  310. unsigned northID_;
  311. /// Node ID of south neighbor.
  312. unsigned southID_;
  313. /// Node ID of west neighbor.
  314. unsigned westID_;
  315. /// Node ID of east neighbor.
  316. unsigned eastID_;
  317. /// Terrain needs regeneration flag.
  318. bool recreateTerrain_;
  319. /// Terrain neighbor attributes dirty flag.
  320. bool neighborsDirty_;
  321. };
  322. }