WorldHeightMap.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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. // WorldHeightMap.h
  24. // Class to encapsulate height map.
  25. // Author: John Ahlquist, April 2001
  26. #pragma once
  27. #ifndef WorldHeightMap_H
  28. #define WorldHeightMap_H
  29. #include "Lib/BaseType.h"
  30. #include "WWLib/RefCount.h"
  31. #include "WWMath/Vector3.h"
  32. #include "W3DDevice/GameClient/TileData.h"
  33. #include "../../gameengine/include/common/MapObject.h"
  34. #include "Common/STLTypedefs.h"
  35. typedef std::vector<ICoord2D> VecICoord2D;
  36. /** MapObject class
  37. Not ref counted. Do not store pointers to this class. */
  38. #define K_MIN_HEIGHT 0
  39. #define K_MAX_HEIGHT 255
  40. #define NUM_SOURCE_TILES 1024
  41. #define NUM_BLEND_TILES 16192
  42. #define NUM_CLIFF_INFO 32384
  43. #define FLAG_VAL 0x7ADA0000
  44. // For backwards compatiblity.
  45. #define TEX_PATH_LEN 256
  46. /// Struct in memory.
  47. typedef struct {
  48. Int globalTextureClass;
  49. Int firstTile;
  50. Int numTiles;
  51. Int width;
  52. Int isBlendEdgeTile; ///< True if the texture contains blend edges.
  53. AsciiString name;
  54. ICoord2D positionInTexture;
  55. } TXTextureClass;
  56. typedef enum {POS_X, POS_Y, NEG_X, NEG_Y} TVDirection;
  57. /// Struct in memory.
  58. typedef struct {
  59. Real u0, v0; // Upper left uv
  60. Real u1, v1; // Lower left uv
  61. Real u2, v2; // Lower right uv
  62. Real u3, v3; // Upper right uv
  63. Bool flip;
  64. Bool mutant; // Mutant mapping needed to get this to fit.
  65. Short tileIndex; // Tile texture.
  66. } TCliffInfo;
  67. #define NUM_TEXTURE_CLASSES 256
  68. class TextureClass;
  69. class ChunkInputStream;
  70. class InputStream;
  71. class OutputStream;
  72. class DataChunkInput;
  73. struct DataChunkInfo;
  74. class AlphaEdgeTextureClass;
  75. #define NUM_ALPHA_TILES 12
  76. class WorldHeightMap : public RefCountClass,
  77. public WorldHeightMapInterfaceClass
  78. {
  79. friend class TerrainTextureClass;
  80. friend class AlphaTerrainTextureClass;
  81. friend class W3DCustomEdging;
  82. friend class AlphaEdgeTextureClass;
  83. #define NO_EVAL_TILING_MODES
  84. public:
  85. #ifdef EVAL_TILING_MODES
  86. enum {TILE_4x4, TILE_6x6, TILE_8x8} m_tileMode;
  87. #endif
  88. enum {
  89. NORMAL_DRAW_WIDTH = 129,
  90. NORMAL_DRAW_HEIGHT = 129,
  91. STRETCH_DRAW_WIDTH = 65,
  92. STRETCH_DRAW_HEIGHT = 65
  93. };
  94. protected:
  95. Int m_width; ///< Height map width.
  96. Int m_height; ///< Height map height (y size of array).
  97. Int m_borderSize; ///< Non-playable border area.
  98. VecICoord2D m_boundaries; ///< the in-game boundaries
  99. Int m_dataSize; ///< size of m_data.
  100. UnsignedByte *m_data; ///< array of z(height) values in the height map.
  101. UnsignedByte *m_seismicUpdateFlag; ///< array of bits to prevent ovelapping physics-update regions from doubling effects on shared cells
  102. UnsignedInt m_seismicUpdateWidth; ///< width of the array holding SeismicUpdateFlags
  103. Real *m_seismicZVelocities; ///< how fast is the dirt rising/falling at this location
  104. UnsignedByte *m_cellFlipState; ///< array of bits to indicate the flip state of each cell.
  105. Int m_flipStateWidth; ///< with of the array holding cellFlipState
  106. UnsignedByte *m_cellCliffState; ///< array of bits to indicate the cliff state of each cell.
  107. /// Texture indices.
  108. Short *m_tileNdxes; ///< matches m_Data, indexes into m_SourceTiles.
  109. Short *m_blendTileNdxes; ///< matches m_Data, indexes into m_blendedTiles. 0 means no blend info.
  110. Short *m_cliffInfoNdxes; ///< matches m_Data, indexes into m_cliffInfo. 0 means no cliff info.
  111. Short *m_extraBlendTileNdxes; ///< matches m_Data, indexes into m_extraBlendedTiles. 0 means no blend info.
  112. Int m_numBitmapTiles; // Number of tiles initialized from bitmaps in m_SourceTiles.
  113. Int m_numEdgeTiles; // Number of tiles initialized from bitmaps in m_SourceTiles.
  114. Int m_numBlendedTiles; // Number of blended tiles created from bitmap tiles.
  115. TileData *m_sourceTiles[NUM_SOURCE_TILES]; ///< Tiles for m_textureClasses
  116. TileData *m_edgeTiles[NUM_SOURCE_TILES]; ///< Tiles for m_textureClasses
  117. TBlendTileInfo m_blendedTiles[NUM_BLEND_TILES];
  118. TBlendTileInfo m_extraBlendedTiles[NUM_BLEND_TILES];
  119. TCliffInfo m_cliffInfo[NUM_CLIFF_INFO];
  120. Int m_numCliffInfo; ///< Number of cliffInfo's used in m_cliffInfo.
  121. // Texture classes. There is one texture class for each bitmap read in.
  122. // A class may have more than one tile. For example, if the grass bitmap is
  123. // 128x128, it creates 4 64x64 tiles, so the grass texture class will have 4 tiles.
  124. int m_numTextureClasses;
  125. TXTextureClass m_textureClasses[NUM_TEXTURE_CLASSES];
  126. // Edge Texture classes. There is one texture class for each bitmap read in.
  127. // An edge class will normally have 4 tiles.
  128. int m_numEdgeTextureClasses;
  129. TXTextureClass m_edgeTextureClasses[NUM_TEXTURE_CLASSES];
  130. /** The actual texture used to render the 3d mesh. Note that it is
  131. basically m_SourceTiles laid out in rows, so by itself it is not useful.
  132. Use GetUVData to get the mapping info for height cells to map into the
  133. texture. */
  134. TerrainTextureClass *m_terrainTex;
  135. Int m_terrainTexHeight; /// Height of m_terrainTex allocated.
  136. /** The texture that contains the alpha edge tiles that get blended on
  137. top of the base texture. getAlphaUVData does the mapping. */
  138. AlphaTerrainTextureClass *m_alphaTerrainTex;
  139. Int m_alphaTexHeight; /// Height of m_alphaTerrainTex allocated.
  140. /** The texture that contains custom blend edge tiles. */
  141. AlphaEdgeTextureClass *m_alphaEdgeTex;
  142. Int m_alphaEdgeHeight; /// Height of m_alphaEdgeTex allocated.
  143. /// Drawing info - re the part of the map that is being drawn.
  144. Int m_drawOriginX;
  145. Int m_drawOriginY;
  146. Int m_drawWidthX;
  147. Int m_drawHeightY;
  148. /// Tiles that hold the alpha channel info.
  149. static TileData *m_alphaTiles[NUM_ALPHA_TILES];
  150. protected:
  151. TileData *getSourceTile(UnsignedInt ndx) { if (ndx<NUM_SOURCE_TILES) return(m_sourceTiles[ndx]); return(NULL); };
  152. TileData *getEdgeTile(UnsignedInt ndx) { if (ndx<NUM_SOURCE_TILES) return(m_edgeTiles[ndx]); return(NULL); };
  153. /// UV mapping data for a cell to map into the terrain texture.
  154. void getUVForNdx(Int ndx, float *minU, float *minV, float *maxU, float*maxV, Bool fullTile);
  155. Bool getUVForTileIndex(Int ndx, Short tileNdx, float U[4], float V[4], Bool fullTile);
  156. Int getTextureClassFromNdx(Int tileNdx);
  157. void readTexClass(TXTextureClass *texClass, TileData **tileData);
  158. Int updateTileTexturePositions(Int *edgeHeight); ///< Places each tile in the texture.
  159. void initCliffFlagsFromHeights(void);
  160. void setCellCliffFlagFromHeights(Int xIndex, Int yIndex);
  161. protected: // file reader callbacks.
  162. static Bool ParseHeightMapDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData);
  163. Bool ParseHeightMapData(DataChunkInput &file, DataChunkInfo *info, void *userData);
  164. static Bool ParseSizeOnlyInChunk(DataChunkInput &file, DataChunkInfo *info, void *userData);
  165. Bool ParseSizeOnly(DataChunkInput &file, DataChunkInfo *info, void *userData);
  166. static Bool ParseBlendTileDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData);
  167. Bool ParseBlendTileData(DataChunkInput &file, DataChunkInfo *info, void *userData);
  168. static Bool ParseWorldDictDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData);
  169. static Bool ParseObjectsDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData);
  170. static Bool ParseObjectDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData);
  171. Bool ParseObjectData(DataChunkInput &file, DataChunkInfo *info, void *userData, Bool readDict);
  172. static Bool ParseLightingDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData);
  173. protected:
  174. WorldHeightMap(void); ///< Simple constructor for WorldHeightMapEdit class.
  175. public: // constructors/destructors
  176. WorldHeightMap(ChunkInputStream *pFile, Bool bHMapOnly=false); // read from file.
  177. ~WorldHeightMap(void); // destroy.
  178. public: // Boundary info
  179. const VecICoord2D& getAllBoundaries(void) const { return m_boundaries; }
  180. public: // height map info.
  181. static Int getMinHeightValue(void) {return K_MIN_HEIGHT;}
  182. static Int getMaxHeightValue(void) {return K_MAX_HEIGHT;}
  183. UnsignedByte *getDataPtr(void) {return m_data;}
  184. Int getXExtent(void) {return m_width;} ///<number of vertices in x
  185. Int getYExtent(void) {return m_height;} ///<number of vertices in y
  186. inline Int getDrawOrgX(void) {return m_drawOriginX;}
  187. inline Int getDrawOrgY(void) {return m_drawOriginY;}
  188. inline Int getDrawWidth(void) {return m_drawWidthX;}
  189. inline Int getDrawHeight(void) {return m_drawHeightY;}
  190. inline void setDrawWidth(Int width) {m_drawWidthX = width; if (m_drawWidthX>m_width) m_drawWidthX = m_width;}
  191. inline void setDrawHeight(Int height) {m_drawHeightY = height; if (m_drawHeightY>m_height) m_drawHeightY = m_height;}
  192. virtual Int getBorderSize(void) {return m_borderSize;}
  193. inline Int getBorderSizeInline(void) const { return m_borderSize; }
  194. /// Get height with the offset that HeightMapRenderObjClass uses built in.
  195. inline UnsignedByte getDisplayHeight(Int x, Int y) { return m_data[x+m_drawOriginX+m_width*(y+m_drawOriginY)];}
  196. /// Get height in normal coordinates.
  197. inline UnsignedByte getHeight(Int xIndex, Int yIndex)
  198. {
  199. Int ndx = (yIndex*m_width)+xIndex;
  200. if ((ndx>=0) && (ndx<m_dataSize) && m_data)
  201. return(m_data[ndx]);
  202. else
  203. return(0);
  204. };
  205. void getUVForBlend(Int edgeClass, Region2D *range);
  206. Bool setDrawOrg(Int xOrg, Int yOrg);
  207. static void freeListOfMapObjects(void);
  208. Int getTextureClassNoBlend(Int xIndex, Int yIndex, Bool baseClass=false);
  209. Int getTextureClass(Int xIndex, Int yIndex, Bool baseClass=false);
  210. TXTextureClass getTextureFromIndex( Int textureIndex );
  211. public: // tile and texture info.
  212. void setTextureLOD(Int lod); ///< set maximum lod level sent to the hardware.
  213. TextureClass *getTerrainTexture(void); //< generates if needed and returns the terrain texture
  214. TextureClass *getAlphaTerrainTexture(void); //< generates if needed and returns alpha terrain texture
  215. TextureClass *getEdgeTerrainTexture(void); //< generates if needed and returns blend edge texture
  216. /// UV mapping data for a cell to map into the terrain texture. Returns true if the textures had to be stretched for cliffs.
  217. Bool getUVData(Int xIndex, Int yIndex, float U[4], float V[4], Bool fullTile);
  218. Bool getFlipState(Int xIndex, Int yIndex) const;
  219. ///Faster version of above function without all the safety checks - For people that do checks externally.
  220. inline Bool getQuickFlipState(Int xIndex, Int yIndex) const
  221. {
  222. return m_cellFlipState[yIndex*m_flipStateWidth + (xIndex >> 3)] & (1<<(xIndex&0x7));
  223. }
  224. void setFlipState(Int xIndex, Int yIndex, Bool value);
  225. void clearFlipStates(void);
  226. Bool getCliffState(Int xIndex, Int yIndex) const;
  227. Bool getExtraAlphaUVData(Int xIndex, Int yIndex, float U[4], float V[4], UnsignedByte alpha[4], Bool *flip, Bool *cliff);
  228. /// UV mapping data for a cell to map into the alpha terrain texture.
  229. void getAlphaUVData(Int xIndex, Int yIndex, float U[4], float V[4], UnsignedByte alpha[4], Bool *flip, Bool fullTile);
  230. void getTerrainColorAt(Real x, Real y, RGBColor *pColor);
  231. AsciiString getTerrainNameAt(Real x, Real y);
  232. Bool isCliffMappedTexture(Int xIndex, Int yIndex);
  233. Bool getSeismicUpdateFlag(Int xIndex, Int yIndex) const;
  234. void setSeismicUpdateFlag(Int xIndex, Int yIndex, Bool value);
  235. void clearSeismicUpdateFlags(void) ;
  236. virtual Real getSeismicZVelocity(Int xIndex, Int yIndex) const;
  237. virtual void setSeismicZVelocity(Int xIndex, Int yIndex, Real value);
  238. void fillSeismicZVelocities( Real value );
  239. virtual Real getBilinearSampleSeismicZVelocity( Int x, Int y);
  240. public: // Flat tile texture info.
  241. TerrainTextureClass *getFlatTexture(Int xCell, Int yCell, Int cellWidth, Int pixelsPerCell); //< generates and returns the terrain texture
  242. static void setupAlphaTiles(void);
  243. UnsignedByte *getPointerToTileData(Int xIndex, Int yIndex, Int width);
  244. Bool getRawTileData(Short tileNdx, Int width, UnsignedByte *buffer, Int bufLen);
  245. UnsignedByte *getRGBAlphaDataForWidth(Int width, TBlendTileInfo *pBlend);
  246. public: // modify height value
  247. void setRawHeight(Int xIndex, Int yIndex, UnsignedByte height) {
  248. Int ndx = (yIndex*m_width)+xIndex;
  249. if ((ndx>=0) && (ndx<m_dataSize) && m_data) m_data[ndx]=height;
  250. };
  251. public: // Read tile utilities. jba [7/9/2003]
  252. static Bool readTiles(InputStream *pStrm, TileData **tiles, Int numRows);
  253. static Int countTiles(InputStream *pStrm, Bool *halfTile=NULL);
  254. protected:
  255. void setCliffState(Int xIndex, Int yIndex, Bool state);
  256. };
  257. #endif