HeightMap.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. #pragma once
  24. #ifndef __HEIGHTMAP_H_
  25. #define __HEIGHTMAP_H_
  26. #include "always.h"
  27. #include "rendobj.h"
  28. #include "w3d_file.h"
  29. #include "dx8vertexbuffer.h"
  30. #include "dx8indexbuffer.h"
  31. #include "dx8wrapper.h"
  32. #include "shader.h"
  33. #include "vertmaterial.h"
  34. #include "Lib/BaseType.h"
  35. #include "common/GameType.h"
  36. #include "WorldHeightMap.h"
  37. #define MAX_ENABLED_DYNAMIC_LIGHTS 20
  38. typedef UnsignedByte HeightSampleType; //type of data to store in heightmap
  39. class W3DTreeBuffer;
  40. class W3DBibBuffer;
  41. class W3DRoadBuffer;
  42. class W3DBridgeBuffer;
  43. class W3DWaypointBuffer;
  44. class W3DTerrainLogic;
  45. class W3DCustomEdging;
  46. class W3DAssetManager;
  47. class SimpleSceneClass;
  48. class W3DShroud;
  49. #define no_TIMING_TESTS 1
  50. #define no_PRE_TRANSFORM_VERTEX // Don't do this, not a performance win. jba.
  51. #define no_USE_TREE_BUFFER ///@todoRe-enable this optimization later... jba.
  52. typedef struct {
  53. Int minX, maxX;
  54. Int minY, maxY;
  55. } TBounds;
  56. #define VERTEX_BUFFER_TILE_LENGTH 32 //tiles of side length 32 (grid of 33x33 vertices).
  57. class LightMapTerrainTextureClass;
  58. class CloudMapTerrainTextureClass;
  59. class W3DDynamicLight;
  60. #if 0
  61. #define USE_NORMALS 1
  62. #define VERTEX_FORMAT VertexFormatXYZNUV2
  63. #else
  64. #define USE_DIFFUSE 1
  65. #define VERTEX_FORMAT VertexFormatXYZDUV2
  66. #define DX8_VERTEX_FORMAT DX8_FVF_XYZDUV2
  67. #endif
  68. #define DO_SCORCH 1
  69. #define DO_ROADS 1
  70. #define TEST_CUSTOM_EDGING 1
  71. // Adjust the triangles to make cliff sides most attractive. jba.
  72. #define FLIP_TRIANGLES 1
  73. #ifdef DO_SCORCH
  74. typedef struct {
  75. Vector3 location;
  76. Real radius;
  77. Int scorchType;
  78. } TScorch;
  79. #endif
  80. /// Custom render object that draws the heightmap and handles intersection tests.
  81. /**
  82. Custom W3D render object that's used to process the terrain. It handles
  83. virtually everything to do with the terrain, including: drawing, lighting,
  84. scorchmarks and intersection tests.
  85. */
  86. class HeightMapRenderObjClass : public RenderObjClass, public DX8_CleanupHook
  87. {
  88. public:
  89. HeightMapRenderObjClass(void);
  90. ~HeightMapRenderObjClass(void);
  91. // DX8_CleanupHook methods
  92. virtual void ReleaseResources(void); ///< Release all dx8 resources so the device can be reset.
  93. virtual void ReAcquireResources(void); ///< Reacquire all resources after device reset.
  94. /////////////////////////////////////////////////////////////////////////////
  95. // Render Object Interface (W3D methods)
  96. /////////////////////////////////////////////////////////////////////////////
  97. virtual RenderObjClass * Clone(void) const;
  98. virtual int Class_ID(void) const;
  99. virtual void Render(RenderInfoClass & rinfo);
  100. virtual bool Cast_Ray(RayCollisionTestClass & raytest); // This CANNOT be Bool, as it will not inherit properly if you make Bool == Int
  101. ///@todo: Add methods for collision detection with terrain
  102. // virtual Bool Cast_AABox(AABoxCollisionTestClass & boxtest);
  103. // virtual Bool Cast_OBBox(OBBoxCollisionTestClass & boxtest);
  104. // virtual Bool Intersect_AABox(AABoxIntersectionTestClass & boxtest);
  105. // virtual Bool Intersect_OBBox(OBBoxIntersectionTestClass & boxtest);
  106. virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const;
  107. virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const;
  108. virtual void On_Frame_Update(void);
  109. virtual void Notify_Added(SceneClass * scene);
  110. ///allocate resources needed to render heightmap
  111. int initHeightData(Int width, Int height, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator);
  112. Int freeMapResources(void); ///< free resources used to render heightmap
  113. inline UnsignedByte getClipHeight(Int x, Int y) const
  114. {
  115. Int xextent = m_map->getXExtent() - 1;
  116. Int yextent = m_map->getYExtent() - 1;
  117. if (x < 0)
  118. x = 0;
  119. else if (x > xextent)
  120. x = xextent;
  121. if (y < 0)
  122. y = 0;
  123. else if (y > yextent)
  124. y = yextent;
  125. return m_map->getDataPtr()[x + y*m_map->getXExtent()];
  126. }
  127. void updateCenter(CameraClass *camera, RefRenderObjListIterator *pLightsIterator);
  128. /// Update the macro texture (pass 3).
  129. void updateMacroTexture(AsciiString textureName);
  130. void doTextures(Bool flag) {m_disableTextures = !flag;};
  131. /// Update the diffuse value from static light info for one vertex.
  132. void doTheLight(VERTEX_FORMAT *vb, Vector3*light, Vector3*normal, RefRenderObjListIterator *pLightsIterator, UnsignedByte alpha);
  133. void addScorch(Vector3 location, Real radius, Scorches type);
  134. void addTree(Coord3D location, Real scale, Real angle, AsciiString name, Bool visibleInMirror);
  135. void renderTrees(CameraClass * camera); ///< renders the tree buffer.
  136. /// Add a bib at location.
  137. void addTerrainBib(Vector3 corners[4], ObjectID id, Bool highlight);
  138. void addTerrainBibDrawable(Vector3 corners[4], DrawableID id, Bool highlight);
  139. /// Remove a bib.
  140. void removeTerrainBib(ObjectID id);
  141. void removeTerrainBibDrawable(DrawableID id);
  142. /// Removes all bibs.
  143. void removeAllTerrainBibs(void);
  144. /// Remove all highlighting.
  145. void removeTerrainBibHighlighting(void);
  146. void renderTerrainPass(CameraClass *pCamera); ///< renders additional terrain pass.
  147. W3DShroud *getShroud() {return m_shroud;}
  148. void renderExtraBlendTiles(void); ///< render 3-way blend tiles that have blend of 3 textures.
  149. void updateShorelineTiles(Int minX, Int minY, Int maxX, Int maxY, WorldHeightMap *pMap); ///<figure out which tiles on this map cross water plane
  150. void updateViewImpassableAreas(Bool partial = FALSE, Int minX = 0, Int maxX = 0, Int minY = 0, Int maxY = 0);
  151. void clearAllScorches(void);
  152. void setTimeOfDay( TimeOfDay tod );
  153. void staticLightingChanged(void);
  154. void loadRoadsAndBridges(W3DTerrainLogic *pTerrainLogic, Bool saveGame); ///< Load the roads from the map objects.
  155. void worldBuilderUpdateBridgeTowers( W3DAssetManager *assetManager, SimpleSceneClass *scene ); ///< for the editor updating of bridge tower visuals
  156. Int getStaticDiffuse(Int x, Int y); ///< Gets the diffuse terrain lighting value for a point on the mesh.
  157. void adjustTerrainLOD(Int adj);
  158. void reset(void);
  159. void doPartialUpdate(const IRegion2D &partialRange, WorldHeightMap *htMap, RefRenderObjListIterator *pLightsIterator);
  160. Int getNumExtraBlendTiles(void) { return m_numExtraBlendTiles;}
  161. Int getNumShoreLineTiles(void) { return m_numShoreLineTiles;}
  162. void setShoreLineDetail(void); ///<update shoreline tiles in case the feature was toggled by user.
  163. Bool getMaximumVisibleBox(const FrustumClass &frustum, AABoxClass *box, Bool ignoreMaxHeight); ///<3d extent of visible terrain.
  164. Real getHeightMapHeight(Real x, Real y, Coord3D* normal) const; ///<return height and normal at given point
  165. Bool isCliffCell(Real x, Real y); ///<return height and normal at given point
  166. Real getMinHeight(void) const {return m_minHeight;} ///<return minimum height of entire terrain
  167. Real getMaxHeight(void) const {return m_maxHeight;} ///<return maximum height of entire terrain
  168. Real getMaxCellHeight(Real x, Real y) const; ///< returns maximum height of the 4 cell corners.
  169. WorldHeightMap *getMap(void) {return m_map;} ///< returns object holding the heightmap samples - need this for fast access.
  170. Bool isClearLineOfSight(const Coord3D& pos, const Coord3D& posOther) const;
  171. Bool getShowImpassableAreas(void) {return m_showImpassableAreas;}
  172. void setShowImpassableAreas(Bool show) {m_showImpassableAreas = show;}
  173. Bool showAsVisibleCliff(Int xIndex, Int yIndex) const;
  174. Bool evaluateAsVisibleCliff(Int xIndex, Int yIndex, Real valuesGreaterThanRad);
  175. void oversizeTerrain(Int tilesToOversize);
  176. Real getViewImpassableAreaSlope(void) const { return m_curImpassableSlope; }
  177. void setViewImpassableAreaSlope(Real viewSlope) { m_curImpassableSlope = viewSlope; }
  178. Bool doesNeedFullUpdate(void) {return m_needFullUpdate;}
  179. protected:
  180. #ifdef DO_SCORCH
  181. enum { MAX_SCORCH_VERTEX=8194,
  182. MAX_SCORCH_INDEX=6*8194,
  183. MAX_SCORCH_MARKS=500,
  184. SCORCH_MARKS_IN_TEXTURE=9,
  185. SCORCH_PER_ROW = 3};
  186. DX8VertexBufferClass *m_vertexScorch; ///<Scorch vertex buffer.
  187. DX8IndexBufferClass *m_indexScorch; ///<indices defining a triangles for the scorch drawing.
  188. TextureClass *m_scorchTexture; ///<Scorch mark texture
  189. Int m_curNumScorchVertices; ///<number of vertices used in m_vertexScorch.
  190. Int m_curNumScorchIndices; ///<number of indices used in m_indexScorch.
  191. TScorch m_scorches[MAX_SCORCH_MARKS];
  192. Int m_numScorches;
  193. Int m_scorchesInBuffer; ///< how many are in the buffers. If less than numScorches, we need to update
  194. // NOTE: This argument (contrary to most of the rest of the engine), is in degrees, not radians.
  195. Real m_curImpassableSlope;
  196. void updateScorches(void); ///<Update m_vertexScorch and m_indexScorch so all scorches will be drawn.
  197. void allocateScorchBuffers(void); ///<allocate static buffers for drawing scorch marks.
  198. void freeScorchBuffers(void); ///< frees up scorch buffers.
  199. void drawScorches(void); ///< Draws the scorch mark polygons in m_vertexScorch.
  200. #endif
  201. WorldHeightMap *m_map;
  202. Int m_x; ///< dimensions of heightmap
  203. Int m_y; ///< dimensions of heightmap
  204. Int m_originX; ///< Origin point in the grid. Slides around.
  205. Int m_originY; ///< Origin point in the grid. Slides around.
  206. Bool m_useDepthFade; ///<fade terrain lighting under water
  207. Vector3 m_depthFade; ///<depth based fall off values for r,g,b
  208. Bool m_disableTextures;
  209. Bool m_needFullUpdate; ///< True if lighting changed, and we need to update all instead of what moved.
  210. Bool m_updating; ///< True if we are updating vertex buffers. (can't draw while buffers are locked.)
  211. Bool m_halfResMesh; ///< True if we are doing half resolution mesh of the terrain.
  212. Bool m_doXNextTime; ///< True if we updated y scroll, and need to do x scroll next frame.
  213. Real m_minHeight; ///<minimum value of height samples in heightmap
  214. Real m_maxHeight; ///<maximum value of height samples in heightmap
  215. Int m_numVBTilesX; ///<dimensions of array containing all the vertex buffers
  216. Int m_numVBTilesY; ///<dimensions of array containing all the vertex buffers
  217. Int m_numVertexBufferTiles; ///<number of vertex buffers needed to store this heightmap
  218. Int m_numBlockColumnsInLastVB;///<a VB tile may be partially filled, this indicates how many 2x2 vertex blocks are filled.
  219. Int m_numBlockRowsInLastVB;///<a VB tile may be partially filled, this indicates how many 2x2 vertex blocks are filled.
  220. Bool m_showImpassableAreas; ///< If true, shade impassable areas.
  221. // STL is "smart." This is a variable sized bitset. Very memory efficient.
  222. std::vector<bool> m_showAsVisibleCliff;
  223. DX8IndexBufferClass *m_indexBuffer; ///<indices defining triangles in a VB tile.
  224. #ifdef PRE_TRANSFORM_VERTEX
  225. IDirect3DVertexBuffer8 **m_xformedVertexBuffer;
  226. #endif
  227. ShaderClass m_shaderClass; ///<shader or rendering state for heightmap
  228. VertexMaterialClass *m_vertexMaterialClass; ///< vertex shader (lighting) for terrain
  229. TextureClass *m_stageZeroTexture; ///<primary texture
  230. TextureClass *m_stageOneTexture; ///<transparent edging texture
  231. CloudMapTerrainTextureClass *m_stageTwoTexture; ///<Cloud map texture
  232. TextureClass *m_stageThreeTexture; ///<light/noise map texture
  233. AsciiString m_macroTextureName; ///< Name for stage 3 texture.
  234. TextureClass *m_destAlphaTexture; ///< Texture holding destination alpha LUT for water depth.
  235. DX8VertexBufferClass **m_vertexBufferTiles; ///<collection of smaller vertex buffers that make up 1 heightmap
  236. char **m_vertexBufferBackup; ///< In memory copy of the vertex buffer data for quick update of dynamic lighting.
  237. W3DTreeBuffer *m_treeBuffer; ///< Class for drawing trees and other alpha objects.
  238. W3DBibBuffer *m_bibBuffer; ///< Class for drawing trees and other alpha objects.
  239. W3DWaypointBuffer *m_waypointBuffer; ///< Draws waypoints.
  240. #ifdef TEST_CUSTOM_EDGING
  241. W3DCustomEdging *m_customEdging; ///< Class for drawing custom edging.
  242. #endif
  243. #ifdef DO_ROADS
  244. W3DRoadBuffer *m_roadBuffer; ///< Class for drawing roads.
  245. #endif
  246. W3DBridgeBuffer *m_bridgeBuffer;
  247. W3DShroud *m_shroud; ///< Class for drawing the shroud over terrain.
  248. Int *m_extraBlendTilePositions; ///<array holding x,y tile positions of all extra blend tiles. (used for 3 textures per tile).
  249. Int m_numExtraBlendTiles; ///<number of blend tiles in m_extraBlendTilePositions.
  250. Int m_extraBlendTilePositionsSize; //<total size of array including unused memory.
  251. struct shoreLineTileInfo
  252. { Int m_xy; //x,y position of tile
  253. Real t0,t1,t2,t3; //index into water depth alpha LUT.
  254. };
  255. shoreLineTileInfo *m_shoreLineTilePositions; ///<array holding x,y tile positions of all shoreline terrain.
  256. Int m_numShoreLineTiles; ///<number of tiles in m_shoreLineTilePositions.
  257. Int m_shoreLineTilePositionsSize; ///<total size of array including unused memory.
  258. Real m_currentMinWaterOpacity; ///<current value inside the gradient lookup texture.
  259. /// Update the diffuse value from dynamic light info for one vertex.
  260. UnsignedInt doTheDynamicLight(VERTEX_FORMAT *vb, VERTEX_FORMAT *vbMirror, Vector3*light, Vector3*normal, W3DDynamicLight *pLights[], Int numLights);
  261. Int getXWithOrigin(Int x);
  262. Int getYWithOrigin(Int x);
  263. ///update vertex diffuse color for dynamic lights inside given rectangle
  264. Int updateVBForLight(DX8VertexBufferClass *pVB, char *data, Int x0, Int y0, Int x1, Int y1, Int originX, Int originY, W3DDynamicLight *pLights[], Int numLights);
  265. Int updateVBForLightOptimized(DX8VertexBufferClass *pVB, char *data, Int x0, Int y0, Int x1, Int y1, Int originX, Int originY, W3DDynamicLight *pLights[], Int numLights);
  266. ///update vertex buffer vertices inside given rectangle
  267. Int updateVB(DX8VertexBufferClass *pVB, char *data, Int x0, Int y0, Int x1, Int y1, Int originX, Int originY, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator);
  268. ///upate vertex buffers associated with the given rectangle
  269. int updateBlock(Int x0, Int y0, Int x1, Int y1, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator);
  270. AABoxClass & getTileBoundingBox(AABoxClass *aabox, Int x, Int y); ///<Vertex buffer bounding box
  271. void initDestAlphaLUT(void); ///<initialize water depth LUT stored in m_destAlphaTexture
  272. void renderShoreLines(CameraClass *pCamera); ///<re-render parts of terrain that need custom blending into water edge
  273. };
  274. extern HeightMapRenderObjClass *TheTerrainRenderObject;
  275. #endif // end __HEIGHTMAP_H_