/* ** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// // WorldHeightMap.h // Class to encapsulate height map. // Author: John Ahlquist, April 2001 #pragma once #ifndef WorldHeightMap_H #define WorldHeightMap_H #include "Lib/BaseType.h" #include "WWLib/RefCount.h" #include "WWMath/Vector3.h" #include "W3DDevice/GameClient/TileData.h" #include "../../gameengine/include/common/MapObject.h" #include "Common/STLTypedefs.h" typedef std::vector VecICoord2D; /** MapObject class Not ref counted. Do not store pointers to this class. */ #define K_MIN_HEIGHT 0 #define K_MAX_HEIGHT 255 #define NUM_SOURCE_TILES 1024 #define NUM_BLEND_TILES 16192 #define NUM_CLIFF_INFO 32384 #define FLAG_VAL 0x7ADA0000 // For backwards compatiblity. #define TEX_PATH_LEN 256 /// Struct in memory. typedef struct { Int globalTextureClass; Int firstTile; Int numTiles; Int width; Int isBlendEdgeTile; ///< True if the texture contains blend edges. AsciiString name; ICoord2D positionInTexture; } TXTextureClass; typedef enum {POS_X, POS_Y, NEG_X, NEG_Y} TVDirection; /// Struct in memory. typedef struct { Real u0, v0; // Upper left uv Real u1, v1; // Lower left uv Real u2, v2; // Lower right uv Real u3, v3; // Upper right uv Bool flip; Bool mutant; // Mutant mapping needed to get this to fit. Short tileIndex; // Tile texture. } TCliffInfo; #define NUM_TEXTURE_CLASSES 256 class TextureClass; class ChunkInputStream; class InputStream; class OutputStream; class DataChunkInput; struct DataChunkInfo; class AlphaEdgeTextureClass; #define NUM_ALPHA_TILES 12 class WorldHeightMap : public RefCountClass, public WorldHeightMapInterfaceClass { friend class TerrainTextureClass; friend class AlphaTerrainTextureClass; friend class W3DCustomEdging; friend class AlphaEdgeTextureClass; #define NO_EVAL_TILING_MODES public: #ifdef EVAL_TILING_MODES enum {TILE_4x4, TILE_6x6, TILE_8x8} m_tileMode; #endif enum { NORMAL_DRAW_WIDTH = 129, NORMAL_DRAW_HEIGHT = 129, STRETCH_DRAW_WIDTH = 65, STRETCH_DRAW_HEIGHT = 65 }; protected: Int m_width; ///< Height map width. Int m_height; ///< Height map height (y size of array). Int m_borderSize; ///< Non-playable border area. VecICoord2D m_boundaries; ///< the in-game boundaries Int m_dataSize; ///< size of m_data. UnsignedByte *m_data; ///< array of z(height) values in the height map. UnsignedByte *m_seismicUpdateFlag; ///< array of bits to prevent ovelapping physics-update regions from doubling effects on shared cells UnsignedInt m_seismicUpdateWidth; ///< width of the array holding SeismicUpdateFlags Real *m_seismicZVelocities; ///< how fast is the dirt rising/falling at this location UnsignedByte *m_cellFlipState; ///< array of bits to indicate the flip state of each cell. Int m_flipStateWidth; ///< with of the array holding cellFlipState UnsignedByte *m_cellCliffState; ///< array of bits to indicate the cliff state of each cell. /// Texture indices. Short *m_tileNdxes; ///< matches m_Data, indexes into m_SourceTiles. Short *m_blendTileNdxes; ///< matches m_Data, indexes into m_blendedTiles. 0 means no blend info. Short *m_cliffInfoNdxes; ///< matches m_Data, indexes into m_cliffInfo. 0 means no cliff info. Short *m_extraBlendTileNdxes; ///< matches m_Data, indexes into m_extraBlendedTiles. 0 means no blend info. Int m_numBitmapTiles; // Number of tiles initialized from bitmaps in m_SourceTiles. Int m_numEdgeTiles; // Number of tiles initialized from bitmaps in m_SourceTiles. Int m_numBlendedTiles; // Number of blended tiles created from bitmap tiles. TileData *m_sourceTiles[NUM_SOURCE_TILES]; ///< Tiles for m_textureClasses TileData *m_edgeTiles[NUM_SOURCE_TILES]; ///< Tiles for m_textureClasses TBlendTileInfo m_blendedTiles[NUM_BLEND_TILES]; TBlendTileInfo m_extraBlendedTiles[NUM_BLEND_TILES]; TCliffInfo m_cliffInfo[NUM_CLIFF_INFO]; Int m_numCliffInfo; ///< Number of cliffInfo's used in m_cliffInfo. // Texture classes. There is one texture class for each bitmap read in. // A class may have more than one tile. For example, if the grass bitmap is // 128x128, it creates 4 64x64 tiles, so the grass texture class will have 4 tiles. int m_numTextureClasses; TXTextureClass m_textureClasses[NUM_TEXTURE_CLASSES]; // Edge Texture classes. There is one texture class for each bitmap read in. // An edge class will normally have 4 tiles. int m_numEdgeTextureClasses; TXTextureClass m_edgeTextureClasses[NUM_TEXTURE_CLASSES]; /** The actual texture used to render the 3d mesh. Note that it is basically m_SourceTiles laid out in rows, so by itself it is not useful. Use GetUVData to get the mapping info for height cells to map into the texture. */ TerrainTextureClass *m_terrainTex; Int m_terrainTexHeight; /// Height of m_terrainTex allocated. /** The texture that contains the alpha edge tiles that get blended on top of the base texture. getAlphaUVData does the mapping. */ AlphaTerrainTextureClass *m_alphaTerrainTex; Int m_alphaTexHeight; /// Height of m_alphaTerrainTex allocated. /** The texture that contains custom blend edge tiles. */ AlphaEdgeTextureClass *m_alphaEdgeTex; Int m_alphaEdgeHeight; /// Height of m_alphaEdgeTex allocated. /// Drawing info - re the part of the map that is being drawn. Int m_drawOriginX; Int m_drawOriginY; Int m_drawWidthX; Int m_drawHeightY; /// Tiles that hold the alpha channel info. static TileData *m_alphaTiles[NUM_ALPHA_TILES]; protected: TileData *getSourceTile(UnsignedInt ndx) { if (ndxm_width) m_drawWidthX = m_width;} inline void setDrawHeight(Int height) {m_drawHeightY = height; if (m_drawHeightY>m_height) m_drawHeightY = m_height;} virtual Int getBorderSize(void) {return m_borderSize;} inline Int getBorderSizeInline(void) const { return m_borderSize; } /// Get height with the offset that HeightMapRenderObjClass uses built in. inline UnsignedByte getDisplayHeight(Int x, Int y) { return m_data[x+m_drawOriginX+m_width*(y+m_drawOriginY)];} /// Get height in normal coordinates. inline UnsignedByte getHeight(Int xIndex, Int yIndex) { Int ndx = (yIndex*m_width)+xIndex; if ((ndx>=0) && (ndx> 3)] & (1<<(xIndex&0x7)); } void setFlipState(Int xIndex, Int yIndex, Bool value); void clearFlipStates(void); Bool getCliffState(Int xIndex, Int yIndex) const; Bool getExtraAlphaUVData(Int xIndex, Int yIndex, float U[4], float V[4], UnsignedByte alpha[4], Bool *flip, Bool *cliff); /// UV mapping data for a cell to map into the alpha terrain texture. void getAlphaUVData(Int xIndex, Int yIndex, float U[4], float V[4], UnsignedByte alpha[4], Bool *flip, Bool fullTile); void getTerrainColorAt(Real x, Real y, RGBColor *pColor); AsciiString getTerrainNameAt(Real x, Real y); Bool isCliffMappedTexture(Int xIndex, Int yIndex); Bool getSeismicUpdateFlag(Int xIndex, Int yIndex) const; void setSeismicUpdateFlag(Int xIndex, Int yIndex, Bool value); void clearSeismicUpdateFlags(void) ; virtual Real getSeismicZVelocity(Int xIndex, Int yIndex) const; virtual void setSeismicZVelocity(Int xIndex, Int yIndex, Real value); void fillSeismicZVelocities( Real value ); virtual Real getBilinearSampleSeismicZVelocity( Int x, Int y); public: // Flat tile texture info. TerrainTextureClass *getFlatTexture(Int xCell, Int yCell, Int cellWidth, Int pixelsPerCell); //< generates and returns the terrain texture static void setupAlphaTiles(void); UnsignedByte *getPointerToTileData(Int xIndex, Int yIndex, Int width); Bool getRawTileData(Short tileNdx, Int width, UnsignedByte *buffer, Int bufLen); UnsignedByte *getRGBAlphaDataForWidth(Int width, TBlendTileInfo *pBlend); public: // modify height value void setRawHeight(Int xIndex, Int yIndex, UnsignedByte height) { Int ndx = (yIndex*m_width)+xIndex; if ((ndx>=0) && (ndx