1
0
forked from 0ad/0ad
0ad/source/graphics/Terrain.h
janwas c0ed950657 had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).

it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.

after several hours, the code now requires fewer casts and less
guesswork.

other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.

This was SVN commit r5942.
2008-05-11 18:48:32 +00:00

146 lines
5.0 KiB
C++

/**
* =========================================================================
* File : Terrain.h
* Project : 0 A.D.
* Description : Describes ground via heightmap and array of CPatch.
* =========================================================================
*/
#ifndef INCLUDED_TERRAIN
#define INCLUDED_TERRAIN
#include "maths/Vector3D.h"
#include "graphics/SColor.h"
#include "lib/sysdep/cpu.h"
class HEntity;
class CEntity;
class CPatch;
class CMiniPatch;
class CVector2D;
///////////////////////////////////////////////////////////////////////////////
// Terrain Constants:
//
// CELL_SIZE: size of each tile in x and z
const ssize_t CELL_SIZE = 4;
// HEIGHT_SCALE: vertical scale of terrain - terrain has a coordinate range of
// 0 to 65536*HEIGHT_SCALE
const float HEIGHT_SCALE = 0.35f/256.0f;
///////////////////////////////////////////////////////////////////////////////
// CTerrain: main terrain class; contains the heightmap describing elevation
// data, and the smaller subpatches that form the terrain
class CTerrain
{
public:
CTerrain();
~CTerrain();
// Coordinate naming convention: world-space coordinates are float x,z;
// tile-space coordinates are ssize_t i,j. rationale: signed types can
// more efficiently be converted to/from floating point. use ssize_t
// instead of int/long because these are sizes.
bool Initialize(ssize_t size, const u16* ptr);
// return number of vertices along edge of the terrain
ssize_t GetVerticesPerSide() const { return m_MapSize; }
// return number of tiles along edge of the terrain
ssize_t GetTilesPerSide() const { return GetVerticesPerSide()-1; }
// return number of patches along edge of the terrain
ssize_t GetPatchesPerSide() const { return m_MapSizePatches; }
bool IsOnMap(float x, float z) const
{
return ((x >= 0.0f) && (x < (float)((m_MapSize-1) * CELL_SIZE))
&& (z >= 0.0f) && (z < (float)((m_MapSize-1) * CELL_SIZE)));
}
bool IsOnMap(const CVector2D& v) const;
bool IsPassable(const CVector2D& tileSpaceLoc, HEntity entity) const;
void ClampCoordToMap(int& index) const
{
if(index < 0)
index = 0;
else if(index >= (int)m_MapSize-1)
index = m_MapSize - 2;
}
float GetVertexGroundLevel(ssize_t i, ssize_t j) const;
float GetExactGroundLevel(float x, float z) const;
float GetExactGroundLevel(const CVector2D& v) const;
float GetSlope(float x, float z) const ;
//Find the slope of in X and Z axes depending on the way the entity is facing
CVector2D GetSlopeAngleFace(CEntity* entity) const;
// resize this terrain such that each side has given number of patches
void Resize(ssize_t size);
// set up a new heightmap from 16 bit data; assumes heightmap matches current terrain size
void SetHeightMap(u16* heightmap);
// return a pointer to the heightmap
u16* GetHeightMap() const { return m_Heightmap; }
// get patch at given coordinates, expressed in patch-space; return 0 if
// coordinates represent patch off the edge of the map
CPatch* GetPatch(ssize_t i, ssize_t j) const;
// get tile at given coordinates, expressed in tile-space; return 0 if
// coordinates represent tile off the edge of the map
CMiniPatch* GetTile(ssize_t i, ssize_t j) const;
// calculate the position of a given vertex
void CalcPosition(ssize_t i, ssize_t j, CVector3D& pos) const;
// calculate the vertex under a given position (rounding down coordinates)
static void CalcFromPosition(const CVector3D& pos, ssize_t& i, ssize_t& j)
{
i = (ssize_t)(pos.X/CELL_SIZE);
j = (ssize_t)(pos.Z/CELL_SIZE);
}
// calculate the vertex under a given position (rounding down coordinates)
static void CalcFromPosition(float x, float z, ssize_t& i, ssize_t& j)
{
i = (ssize_t)(x/CELL_SIZE);
j = (ssize_t)(z/CELL_SIZE);
}
// calculate the normal at a given vertex
void CalcNormal(ssize_t i, ssize_t j, CVector3D& normal) const;
// flatten out an area of terrain (specified in world space coords); return
// the average height of the flattened area
float FlattenArea(float x0, float x1, float z0, float z1);
// mark a specific square of tiles as dirty - use this after modifying the heightmap
void MakeDirty(ssize_t i0, ssize_t j0, ssize_t i1, ssize_t j1, int dirtyFlags);
// mark the entire map as dirty
void MakeDirty(int dirtyFlags);
// get the base colour for the terrain (typically pure white - other colours
// will interact badly with LOS - but used by the Actor Viewer tool)
SColor4ub GetBaseColour() const { return m_BaseColour; }
// set the base colour for the terrain
void SetBaseColour(SColor4ub colour) { m_BaseColour = colour; }
private:
// delete any data allocated by this terrain
void ReleaseData();
// setup patch pointers etc
void InitialisePatches();
// size of this map in each direction, in vertices; ie. total tiles = sqr(m_MapSize-1)
ssize_t m_MapSize;
// size of this map in each direction, in patches; total patches = sqr(m_MapSizePatches)
ssize_t m_MapSizePatches;
// the patches comprising this terrain
CPatch* m_Patches;
// 16-bit heightmap data
u16* m_Heightmap;
// base colour (usually white)
SColor4ub m_BaseColour;
};
#endif