BaseHeightMap.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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 __BASE_HEIGHTMAP_H_
  25. #define __BASE_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 W3DAssetManager;
  46. class SimpleSceneClass;
  47. class W3DShroud;
  48. class W3DPropDrawModuleData;
  49. class W3DPropBuffer;
  50. class W3DTreeDrawModuleData;
  51. class GeometryInfo;
  52. #define no_TIMING_TESTS 1
  53. #define no_PRE_TRANSFORM_VERTEX // Don't do this, not a performance win. jba.
  54. typedef struct {
  55. Int minX, maxX;
  56. Int minY, maxY;
  57. } TBounds;
  58. class LightMapTerrainTextureClass;
  59. class CloudMapTerrainTextureClass;
  60. class W3DDynamicLight;
  61. #define DO_SCORCH 1
  62. #define DO_ROADS 1
  63. #ifdef DO_SCORCH
  64. typedef struct {
  65. Vector3 location;
  66. Real radius;
  67. Int scorchType;
  68. } TScorch;
  69. #endif
  70. #define VERTEX_FORMAT VertexFormatXYZDUV2
  71. #define DX8_VERTEX_FORMAT DX8_FVF_XYZDUV2
  72. /// Custom render object that draws the heightmap and handles intersection tests.
  73. /**
  74. Custom W3D render object that's used to process the terrain. It handles
  75. virtually everything to do with the terrain, including: drawing, lighting,
  76. scorchmarks and intersection tests.
  77. */
  78. class BaseHeightMapRenderObjClass : public RenderObjClass, public DX8_CleanupHook, public Snapshot
  79. {
  80. public:
  81. BaseHeightMapRenderObjClass(void);
  82. virtual ~BaseHeightMapRenderObjClass(void);
  83. // DX8_CleanupHook methods
  84. virtual void ReleaseResources(void); ///< Release all dx8 resources so the device can be reset.
  85. virtual void ReAcquireResources(void); ///< Reacquire all resources after device reset.
  86. /////////////////////////////////////////////////////////////////////////////
  87. // Render Object Interface (W3D methods)
  88. /////////////////////////////////////////////////////////////////////////////
  89. virtual RenderObjClass * Clone(void) const;
  90. virtual int Class_ID(void) const;
  91. virtual void Render(RenderInfoClass & rinfo) = 0;
  92. virtual bool Cast_Ray(RayCollisionTestClass & raytest); // This CANNOT be Bool, as it will not inherit properly if you make Bool == Int
  93. virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const;
  94. virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const;
  95. virtual void On_Frame_Update(void);
  96. virtual void Notify_Added(SceneClass * scene);
  97. // Other VIRTUAL methods. [3/20/2003]
  98. ///allocate resources needed to render heightmap
  99. virtual int initHeightData(Int width, Int height, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator, Bool updateExtraPassTiles=TRUE);
  100. virtual Int freeMapResources(void); ///< free resources used to render heightmap
  101. virtual void updateCenter(CameraClass *camera, RefRenderObjListIterator *pLightsIterator);
  102. virtual void adjustTerrainLOD(Int adj);
  103. virtual void doPartialUpdate(const IRegion2D &partialRange, WorldHeightMap *htMap, RefRenderObjListIterator *pLightsIterator) = 0;
  104. virtual void staticLightingChanged(void);
  105. virtual void oversizeTerrain(Int tilesToOversize);
  106. virtual void reset(void);
  107. void redirectToHeightmap( WorldHeightMap *pMap )
  108. {
  109. REF_PTR_RELEASE( m_map );
  110. REF_PTR_SET(m_map, pMap); //update our heightmap pointer in case it changed since last call.
  111. }
  112. inline UnsignedByte getClipHeight(Int x, Int y) const
  113. {
  114. Int xextent = m_map->getXExtent() - 1;
  115. Int yextent = m_map->getYExtent() - 1;
  116. if (x < 0)
  117. x = 0;
  118. else if (x > xextent)
  119. x = xextent;
  120. if (y < 0)
  121. y = 0;
  122. else if (y > yextent)
  123. y = yextent;
  124. return m_map->getDataPtr()[x + y*m_map->getXExtent()];
  125. }
  126. /// Update the macro texture (pass 3).
  127. void setTextureLOD(Int lod); ///<change the maximum mip-level sent to the hardware.
  128. void updateMacroTexture(AsciiString textureName);
  129. void doTextures(Bool flag) {m_disableTextures = !flag;};
  130. /// Update the diffuse value from static light info for one vertex.
  131. void doTheLight(VERTEX_FORMAT *vb, Vector3*light, Vector3*normal, RefRenderObjListIterator *pLightsIterator, UnsignedByte alpha);
  132. void addScorch(Vector3 location, Real radius, Scorches type);
  133. void addTree(DrawableID id, Coord3D location, Real scale, Real angle,
  134. Real randomScaleAmount, const W3DTreeDrawModuleData *data);
  135. void removeAllTrees(void);
  136. void removeTree(DrawableID id);
  137. Bool updateTreePosition(DrawableID id, Coord3D location, Real angle);
  138. void renderTrees(CameraClass * camera); ///< renders the tree buffer.
  139. void addProp(Int id, Coord3D location, Real angle, Real scale, const AsciiString &modelName);
  140. void removeProp(Int id);
  141. void removeAllProps(void);
  142. void unitMoved( Object *unit );
  143. void notifyShroudChanged(void);
  144. void removeTreesAndPropsForConstruction(
  145. const Coord3D* pos,
  146. const GeometryInfo& geom,
  147. Real angle
  148. );
  149. /// Add a bib at location.
  150. void addTerrainBib(Vector3 corners[4], ObjectID id, Bool highlight);
  151. void addTerrainBibDrawable(Vector3 corners[4], DrawableID id, Bool highlight);
  152. /// Remove a bib.
  153. void removeTerrainBib(ObjectID id);
  154. void removeTerrainBibDrawable(DrawableID id);
  155. /// Removes all bibs.
  156. void removeAllTerrainBibs(void);
  157. /// Remove all highlighting.
  158. void removeTerrainBibHighlighting(void);
  159. W3DShroud *getShroud() {return m_shroud;}
  160. void updateShorelineTiles(Int minX, Int minY, Int maxX, Int maxY, WorldHeightMap *pMap); ///<figure out which tiles on this map cross water plane
  161. void updateShorelineTile(Int X, Int Y, Int Border, WorldHeightMap *pMap); ///<figure out which tiles on this map cross water plane
  162. void recordShoreLineSortInfos(void);
  163. void updateViewImpassableAreas(Bool partial = FALSE, Int minX = 0, Int maxX = 0, Int minY = 0, Int maxY = 0);
  164. void clearAllScorches(void);
  165. void setTimeOfDay( TimeOfDay tod );
  166. void loadRoadsAndBridges(W3DTerrainLogic *pTerrainLogic, Bool saveGame); ///< Load the roads from the map objects.
  167. void worldBuilderUpdateBridgeTowers( W3DAssetManager *assetManager, SimpleSceneClass *scene ); ///< for the editor updating of bridge tower visuals
  168. Int getStaticDiffuse(Int x, Int y); ///< Gets the diffuse terrain lighting value for a point on the mesh.
  169. virtual Int getNumExtraBlendTiles(Bool visible) { return 0;}
  170. Int getNumShoreLineTiles(Bool visible) { return visible?m_numVisibleShoreLineTiles:m_numShoreLineTiles;}
  171. void setShoreLineDetail(void); ///<update shoreline tiles in case the feature was toggled by user.
  172. Bool getMaximumVisibleBox(const FrustumClass &frustum, AABoxClass *box, Bool ignoreMaxHeight); ///<3d extent of visible terrain.
  173. Real getHeightMapHeight(Real x, Real y, Coord3D* normal) const; ///<return height and normal at given point
  174. Bool isCliffCell(Real x, Real y); ///<return height and normal at given point
  175. Real getMinHeight(void) const {return m_minHeight;} ///<return minimum height of entire terrain
  176. Real getMaxHeight(void) const {return m_maxHeight;} ///<return maximum height of entire terrain
  177. Real getMaxCellHeight(Real x, Real y) const; ///< returns maximum height of the 4 cell corners.
  178. WorldHeightMap *getMap(void) {return m_map;} ///< returns object holding the heightmap samples - need this for fast access.
  179. Bool isClearLineOfSight(const Coord3D& pos, const Coord3D& posOther) const;
  180. Bool getShowImpassableAreas(void) {return m_showImpassableAreas;}
  181. void setShowImpassableAreas(Bool show) {m_showImpassableAreas = show;}
  182. Bool showAsVisibleCliff(Int xIndex, Int yIndex) const;
  183. Bool evaluateAsVisibleCliff(Int xIndex, Int yIndex, Real valuesGreaterThanRad);
  184. Real getViewImpassableAreaSlope(void) const { return m_curImpassableSlope; }
  185. void setViewImpassableAreaSlope(Real viewSlope) { m_curImpassableSlope = viewSlope; }
  186. Bool doesNeedFullUpdate(void) {return m_needFullUpdate;}
  187. virtual int updateBlock(Int x0, Int y0, Int x1, Int y1, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator) = 0;
  188. protected:
  189. // snapshot methods
  190. virtual void crc( Xfer *xfer );
  191. virtual void xfer( Xfer *xfer );
  192. virtual void loadPostProcess( void );
  193. protected:
  194. Int m_x; ///< dimensions of heightmap
  195. Int m_y; ///< dimensions of heightmap
  196. #ifdef DO_SCORCH
  197. enum { MAX_SCORCH_VERTEX=8194,
  198. MAX_SCORCH_INDEX=6*8194,
  199. MAX_SCORCH_MARKS=500,
  200. SCORCH_MARKS_IN_TEXTURE=9,
  201. SCORCH_PER_ROW = 3};
  202. DX8VertexBufferClass *m_vertexScorch; ///<Scorch vertex buffer.
  203. DX8IndexBufferClass *m_indexScorch; ///<indices defining a triangles for the scorch drawing.
  204. TextureClass *m_scorchTexture; ///<Scorch mark texture
  205. Int m_curNumScorchVertices; ///<number of vertices used in m_vertexScorch.
  206. Int m_curNumScorchIndices; ///<number of indices used in m_indexScorch.
  207. TScorch m_scorches[MAX_SCORCH_MARKS];
  208. Int m_numScorches;
  209. Int m_scorchesInBuffer; ///< how many are in the buffers. If less than numScorches, we need to update
  210. // NOTE: This argument (contrary to most of the rest of the engine), is in degrees, not radians.
  211. Real m_curImpassableSlope;
  212. void updateScorches(void); ///<Update m_vertexScorch and m_indexScorch so all scorches will be drawn.
  213. void allocateScorchBuffers(void); ///<allocate static buffers for drawing scorch marks.
  214. void freeScorchBuffers(void); ///< frees up scorch buffers.
  215. void drawScorches(void); ///< Draws the scorch mark polygons in m_vertexScorch.
  216. #endif
  217. WorldHeightMap *m_map;
  218. Bool m_useDepthFade; ///<fade terrain lighting under water
  219. Bool m_updating;
  220. Vector3 m_depthFade; ///<depth based fall off values for r,g,b
  221. Bool m_disableTextures;
  222. Bool m_needFullUpdate; ///< True if lighting changed, and we need to update all instead of what moved.
  223. Bool m_doXNextTime; ///< True if we updated y scroll, and need to do x scroll next frame.
  224. Real m_minHeight; ///<minimum value of height samples in heightmap
  225. Real m_maxHeight; ///<maximum value of height samples in heightmap
  226. Bool m_showImpassableAreas; ///< If true, shade impassable areas.
  227. // STL is "smart." This is a variable sized bitset. Very memory efficient.
  228. std::vector<bool> m_showAsVisibleCliff;
  229. ShaderClass m_shaderClass; ///<shader or rendering state for heightmap
  230. VertexMaterialClass *m_vertexMaterialClass; ///< vertex shader (lighting) for terrain
  231. TextureClass *m_stageZeroTexture; ///<primary texture
  232. TextureClass *m_stageOneTexture; ///<transparent edging texture
  233. CloudMapTerrainTextureClass *m_stageTwoTexture; ///<Cloud map texture
  234. TextureClass *m_stageThreeTexture; ///<light/noise map texture
  235. AsciiString m_macroTextureName; ///< Name for stage 3 texture.
  236. TextureClass *m_destAlphaTexture; ///< Texture holding destination alpha LUT for water depth.
  237. W3DTreeBuffer *m_treeBuffer; ///< Class for drawing trees and other alpha objects.
  238. W3DPropBuffer *m_propBuffer; ///< Class for drawing trees and other alpha objects.
  239. W3DBibBuffer *m_bibBuffer; ///< Class for drawing trees and other alpha objects.
  240. W3DWaypointBuffer *m_waypointBuffer; ///< Draws waypoints.
  241. #ifdef DO_ROADS
  242. W3DRoadBuffer *m_roadBuffer; ///< Class for drawing roads.
  243. #endif
  244. W3DBridgeBuffer *m_bridgeBuffer;
  245. W3DShroud *m_shroud; ///< Class for drawing the shroud over terrain.
  246. struct shoreLineTileInfo
  247. { Int m_xy; //x,y position of tile
  248. Real verts[4*3]; //position of tile vertices. 4 verts with 3 components.
  249. Real t0,t1,t2,t3; //index into water depth alpha LUT.
  250. };
  251. //at each x or y coordinate of the map (depending on major axis) we store a list of
  252. //shoreline blend tiles having the same x or y coordinate. This makes searching the
  253. //shoreline tiles much faster.
  254. struct shoreLineTileSortInfo
  255. {
  256. Int tileStartIndex; //index within m_shoreLineTilePositions where tiles start
  257. Int numTiles; //total tiles at this coordinate.
  258. UnsignedShort minTileCoordinate; //lowest coordinate in list
  259. UnsignedShort maxTileCoordinate; //highest coordinate in list.
  260. };
  261. shoreLineTileInfo *m_shoreLineTilePositions; ///<array holding x,y tile positions of all shoreline terrain.
  262. Int m_numShoreLineTiles; ///<number of tiles in m_shoreLineTilePositions.
  263. Int m_numVisibleShoreLineTiles; ///<number of visible tiles.
  264. Int m_shoreLineTilePositionsSize; ///<total size of array including unused memory.
  265. Real m_currentMinWaterOpacity; ///<current value inside the gradient lookup texture.
  266. shoreLineTileSortInfo *m_shoreLineSortInfos;
  267. Int m_shoreLineSortInfosSize;
  268. Int m_shoreLineSortInfosXMajor;
  269. Int m_shoreLineTileSortMaxCoordinate; ///<keep track of coordinate range along axis used for m_shoreLineSortInfos
  270. Int m_shoreLineTileSortMinCoordinate;
  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. void renderShoreLinesSorted(CameraClass *pCamera); ///<optimized version for game usage.
  274. };
  275. extern BaseHeightMapRenderObjClass *TheTerrainRenderObject;
  276. #endif // end __FLAT_HEIGHTMAP_H_