/*
** 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