2013-04-19 02:52:48 +00:00
|
|
|
#if !defined(CM_LANDSCAPE_H_INC)
|
|
|
|
#define CM_LANDSCAPE_H_INC
|
|
|
|
|
|
|
|
#pragma warning (push, 3) //go back down to 3 for the stl include
|
|
|
|
#include <list>
|
|
|
|
#pragma warning (pop)
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
// These are the root classes using data shared in both the server and the renderer.
|
|
|
|
// This common data is also available to physics
|
|
|
|
|
|
|
|
#define HEIGHT_RESOLUTION 256
|
|
|
|
|
|
|
|
// Trying to make a guess at the optimal step through the patches
|
|
|
|
// This is the average of 1 side and the diagonal presuming a square patch
|
|
|
|
#define TERRAIN_STEP_MAGIC (1.0f / 1.2071f)
|
|
|
|
|
|
|
|
#define MIN_TERXELS 2
|
|
|
|
#define MAX_TERXELS 8
|
|
|
|
// Defined as 1 << (sqrt(MAX_TERXELS) + 1)
|
|
|
|
#define MAX_VARIANCE_SIZE 16
|
|
|
|
|
|
|
|
// Maximum number of instances to pick from an instance file
|
|
|
|
#define MAX_INSTANCE_TYPES 16
|
|
|
|
|
|
|
|
// Types of areas
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
AT_NONE,
|
|
|
|
AT_FLAT,
|
|
|
|
AT_BSP,
|
|
|
|
AT_NPC,
|
|
|
|
AT_GROUP,
|
|
|
|
AT_RIVER,
|
|
|
|
AT_OBJECTIVE,
|
|
|
|
AT_PLAYER,
|
|
|
|
|
|
|
|
} areaType_t;
|
|
|
|
|
|
|
|
class CArea
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
vec3_t mPosition;
|
|
|
|
float mRadius;
|
|
|
|
float mAngle;
|
|
|
|
float mAngleDiff;
|
|
|
|
int mType;
|
|
|
|
int mVillageID;
|
|
|
|
public:
|
|
|
|
CArea(void) {}
|
|
|
|
~CArea(void) {}
|
|
|
|
|
|
|
|
void Init(vec3_t pos, float radius, float angle = 0.0f, int type = AT_NONE, float angleDiff = 0.0f, int villageID = 0)
|
|
|
|
{
|
|
|
|
VectorCopy(pos, mPosition);
|
|
|
|
mRadius = radius;
|
|
|
|
mAngle = angle;
|
|
|
|
mAngleDiff = angleDiff;
|
|
|
|
mType = type;
|
|
|
|
mVillageID = villageID;
|
|
|
|
}
|
|
|
|
float GetRadius(void) const { return(mRadius); }
|
|
|
|
float GetAngle(void) const { return(mAngle); }
|
|
|
|
float GetAngleDiff(void) const { return(mAngleDiff); }
|
|
|
|
vec3_t &GetPosition(void) { return(mPosition); }
|
|
|
|
int GetType(void) const { return(mType); }
|
|
|
|
int GetVillageID(void) const { return(mVillageID); }
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef list<CArea*> areaList_t;
|
|
|
|
typedef list<CArea*>::iterator areaIter_t;
|
|
|
|
|
|
|
|
class CCMHeightDetails
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
int mContents;
|
|
|
|
int mSurfaceFlags;
|
|
|
|
public:
|
|
|
|
CCMHeightDetails(void) {}
|
|
|
|
~CCMHeightDetails(void) {}
|
|
|
|
|
|
|
|
// Accessors
|
|
|
|
const int GetSurfaceFlags(void) const { return(mSurfaceFlags); }
|
|
|
|
const int GetContents(void) const { return(mContents); }
|
|
|
|
void SetFlags(const int con, const int sf) { mContents = con; mSurfaceFlags = sf; }
|
|
|
|
};
|
|
|
|
|
|
|
|
class CCMPatch
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
class CCMLandScape *owner; // Owning landscape
|
|
|
|
int mHx, mHy; // Terxel coords of patch
|
|
|
|
byte *mHeightMap; // Pointer to height map to use
|
|
|
|
byte mCornerHeights[4]; // Heights at the corners of the patch
|
|
|
|
vec3_t mWorldCoords; // World coordinate offset of this patch.
|
|
|
|
vec3pair_t mBounds; // mins and maxs of the patch for culling
|
|
|
|
int mNumBrushes; // number of brushes to collide with in the patch
|
|
|
|
struct cbrush_s *mPatchBrushData; // List of brushes that make up the patch
|
|
|
|
int mSurfaceFlags; // surfaceflag of the heightshader
|
|
|
|
int mContentFlags; // contents of the heightshader
|
|
|
|
public:
|
|
|
|
// Constructors
|
|
|
|
CCMPatch(void) {}
|
|
|
|
~CCMPatch(void);
|
|
|
|
|
|
|
|
// Accessors
|
|
|
|
const vec3_t &GetWorld(void) const { return(mWorldCoords); }
|
|
|
|
const vec3_t &GetMins(void) const { return(mBounds[0]); }
|
|
|
|
const vec3_t &GetMaxs(void) const { return(mBounds[1]); }
|
|
|
|
const vec3pair_t &GetBounds(void) const { return(mBounds); }
|
|
|
|
const int GetHeightMapX(void) const { return(mHx); }
|
|
|
|
const int GetHeightMapY(void) const { return(mHy); }
|
|
|
|
const int GetHeight(int corner) const { return(mCornerHeights[corner]); }
|
|
|
|
const int GetNumBrushes(void) const { return(mNumBrushes); }
|
|
|
|
struct cbrush_s *GetCollisionData(void) const { return(mPatchBrushData); }
|
|
|
|
|
|
|
|
void SetSurfaceFlags(const int in) { mSurfaceFlags = in; }
|
|
|
|
const int GetSurfaceFlags(void) const { return(mSurfaceFlags); }
|
|
|
|
void SetContents(const int in) { mContentFlags = in; }
|
|
|
|
const int GetContents(void) const { return(mContentFlags); }
|
|
|
|
|
|
|
|
// Prototypes
|
|
|
|
void Init(CCMLandScape *ls, int heightX, int heightY, vec3_t world, byte *hMap, byte *patchBrushData);
|
|
|
|
void InitPlane(struct cbrushside_s *side, cplane_t *plane, vec3_t p0, vec3_t p1, vec3_t p2);
|
|
|
|
void CreatePatchPlaneData(void);
|
|
|
|
|
|
|
|
void* GetAdjacentBrushX ( int x, int y );
|
|
|
|
void* GetAdjacentBrushY ( int x, int y );
|
|
|
|
};
|
|
|
|
|
|
|
|
class CRandomTerrain;
|
|
|
|
|
|
|
|
class CCMLandScape
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
int mRefCount; // Number of times this class is referenced
|
|
|
|
thandle_t mTerrainHandle;
|
|
|
|
byte *mHeightMap; // Pointer to byte array of height samples
|
|
|
|
byte *mFlattenMap; // Pointer to byte array of flatten samples
|
|
|
|
int mWidth, mHeight; // Width and height of heightMap excluding the 1 pixel edge
|
|
|
|
int mTerxels; // Number of terxels per patch side
|
|
|
|
vec3_t mTerxelSize; // Vector to scale heightMap samples to real world coords
|
|
|
|
vec3pair_t mBounds; // Real world bounds of terrain brush
|
|
|
|
vec3_t mSize; // Size of terrain brush in real world coords excluding 1 patch edge
|
|
|
|
vec3_t mPatchSize; // Size of each patch in the x and y directions only
|
|
|
|
float mPatchScalarSize; // Horizontal size of the patch
|
|
|
|
int mBlockWidth, mBlockHeight; // Width and height of heightfield on blocks
|
|
|
|
CCMPatch *mPatches;
|
|
|
|
byte *mPatchBrushData; // Base memory from which the patch brush data is taken
|
|
|
|
bool mHasPhysics; // Set to true unless disabled
|
|
|
|
CRandomTerrain *mRandomTerrain;
|
|
|
|
|
|
|
|
int mBaseWaterHeight; // Base water height in terxels
|
|
|
|
float mWaterHeight; // Real world height of the water
|
|
|
|
int mWaterContents; // Contents of the water shader
|
|
|
|
int mWaterSurfaceFlags; // Surface flags of the water shader
|
|
|
|
|
|
|
|
unsigned long holdrand;
|
|
|
|
|
|
|
|
list<CArea *> mAreas; // List of flattened areas on this landscape
|
|
|
|
list<CArea *>::iterator mAreasIt;
|
|
|
|
|
|
|
|
CCMHeightDetails mHeightDetails[HEIGHT_RESOLUTION]; // Surfaceflags per height
|
|
|
|
vec3_t *mCoords; // Temp storage for real world coords
|
|
|
|
|
|
|
|
public:
|
|
|
|
CCMLandScape(const char *configstring, bool server);
|
|
|
|
~CCMLandScape(void);
|
|
|
|
|
|
|
|
CCMPatch *GetPatch(int x, int y);
|
|
|
|
|
|
|
|
// Prototypes
|
|
|
|
void PatchCollide(struct traceWork_s *tw, trace_t &trace, const vec3_t start, const vec3_t end, int checkcount);
|
|
|
|
void TerrainPatchIterate(void (*IterateFunc)( CCMPatch *, void * ), void *userdata) const;
|
|
|
|
float GetWorldHeight(vec3_t origin, const vec3pair_t bounds, bool aboveGround) const;
|
|
|
|
float WaterCollide(const vec3_t begin, const vec3_t end, float fraction) const;
|
|
|
|
void UpdatePatches(void);
|
|
|
|
void GetTerxelLocalCoords ( int x, int y, vec3_t coords[8] );
|
|
|
|
void LoadTerrainDef(const char *td);
|
|
|
|
void SetShaders(int height, class CCMShader *shader);
|
|
|
|
void FlattenArea(CArea *area, int height, bool save, bool forceHeight, bool smooth);
|
|
|
|
void CarveLine ( vec3_t start, vec3_t end, int depth, int width );
|
|
|
|
void CarveBezierCurve ( int numCtlPoints, vec3_t* ctlPoints, int steps, int depth, int size );
|
|
|
|
void SaveArea(CArea *area);
|
|
|
|
float FractionBelowLevel(CArea *area, int height);
|
|
|
|
bool AreaCollision(CArea *area, int *areaTypes, int areaTypeCount);
|
|
|
|
CArea *GetFirstArea(void);
|
|
|
|
CArea *GetFirstObjectiveArea(void);
|
|
|
|
CArea *GetPlayerArea(void);
|
|
|
|
CArea *GetNextArea(void);
|
|
|
|
CArea *GetNextObjectiveArea(void);
|
|
|
|
|
|
|
|
// Accessors
|
|
|
|
const int GetRefCount(void) const { return(mRefCount); }
|
|
|
|
void IncreaseRefCount(void) { mRefCount++; }
|
|
|
|
void DecreaseRefCount(void) { mRefCount--; }
|
|
|
|
const vec3pair_t &GetBounds(void) const { return(mBounds); }
|
|
|
|
const vec3_t &GetMins(void) const { return(mBounds[0]); }
|
|
|
|
const vec3_t &GetMaxs(void) const { return(mBounds[1]); }
|
|
|
|
const vec3_t &GetSize(void) const { return(mSize); }
|
|
|
|
const vec3_t &GetTerxelSize(void) const { return(mTerxelSize); }
|
|
|
|
const vec3_t &GetPatchSize(void) const { return(mPatchSize); }
|
|
|
|
const float GetPatchWidth(void) const { return(mPatchSize[0]); }
|
|
|
|
const float GetPatchHeight(void) const { return(mPatchSize[1]); }
|
|
|
|
const float GetPatchScalarSize(void) const { return(mPatchScalarSize); }
|
|
|
|
const int GetTerxels(void) const { return(mTerxels); }
|
|
|
|
const int GetRealWidth(void) const { return(mWidth + 1); }
|
|
|
|
const int GetRealHeight(void) const { return(mHeight + 1); }
|
|
|
|
const int GetRealArea(void) const { return((mWidth + 1) * (mHeight + 1)); }
|
|
|
|
const int GetWidth(void) const { return(mWidth); }
|
|
|
|
const int GetHeight(void) const { return(mHeight); }
|
|
|
|
const int GetArea(void) const { return(mWidth * mHeight); }
|
|
|
|
const int GetBlockWidth(void) const { return(mBlockWidth); }
|
|
|
|
const int GetBlockHeight(void) const { return(mBlockHeight); }
|
|
|
|
const int GetBlockCount(void) const { return(mBlockWidth * mBlockHeight); }
|
|
|
|
byte *GetHeightMap(void) const { return(mHeightMap); }
|
|
|
|
byte *GetFlattenMap(void) const { return(mFlattenMap); }
|
|
|
|
const thandle_t GetTerrainId(void) const { return(mTerrainHandle); }
|
|
|
|
void SetTerrainId(const thandle_t terrainId) { mTerrainHandle = terrainId; }
|
|
|
|
const float CalcWorldHeight(int height) const { return((height * mTerxelSize[2]) + mBounds[0][2]); }
|
|
|
|
const bool GetHasPhysics(void) const { return(mHasPhysics); }
|
|
|
|
const bool GetIsRandom(void) const { return(mRandomTerrain != 0); }
|
|
|
|
const int GetSurfaceFlags(int height) const { return(mHeightDetails[height].GetSurfaceFlags()); }
|
|
|
|
const int GetContentFlags(int height) const { return(mHeightDetails[height].GetContents()); }
|
|
|
|
void CalcRealCoords(void);
|
|
|
|
vec3_t *GetCoords(void) const { return(mCoords); }
|
|
|
|
|
|
|
|
int GetBaseWaterHeight(void) const { return(mBaseWaterHeight); }
|
|
|
|
void SetRealWaterHeight(int height) { mWaterHeight = height * mTerxelSize[2]; }
|
|
|
|
float GetWaterHeight(void) const { return(mWaterHeight); }
|
|
|
|
int GetWaterContents(void) const { return(mWaterContents); }
|
|
|
|
int GetWaterSurfaceFlags(void) const { return(mWaterSurfaceFlags); }
|
|
|
|
|
|
|
|
CRandomTerrain *GetRandomTerrain(void) { return mRandomTerrain; }
|
|
|
|
|
|
|
|
void rand_seed(int seed);
|
|
|
|
unsigned long get_rand_seed(void) { return holdrand; }
|
|
|
|
|
|
|
|
float flrand(float min, float max);
|
|
|
|
int irand(int min, int max);
|
|
|
|
};
|
|
|
|
|
|
|
|
void CM_TerrainPatchIterate(const class CCMLandScape *ls, void (*IterateFunc)( CCMPatch *, void * ), void *userdata);
|
|
|
|
class CCMLandScape *CM_InitTerrain(const char *configstring, thandle_t terrainId, bool server);
|
|
|
|
float CM_GetWorldHeight(const CCMLandScape *landscape, vec3_t origin, const vec3pair_t bounds, bool aboveGround);
|
|
|
|
void CM_FlattenArea(CCMLandScape *landscape, CArea *area, int height, bool save, bool forceHeight, bool smooth);
|
|
|
|
void CM_CarveBezierCurve (CCMLandScape *landscape, int numCtls, vec3_t* ctls, int steps, int depth, int size );
|
|
|
|
void CM_SaveArea(CCMLandScape *landscape, CArea *area);
|
|
|
|
float CM_FractionBelowLevel(CCMLandScape *landscape, CArea *area, int height);
|
|
|
|
bool CM_AreaCollision(class CCMLandScape *landscape, class CArea *area, int *areaTypes, int areaTypeCount);
|
|
|
|
CArea *CM_GetFirstArea(CCMLandScape *landscape);
|
|
|
|
CArea *CM_GetFirstObjectiveArea(CCMLandScape *landscape);
|
|
|
|
CArea *CM_GetPlayerArea(class CCMLandScape *common);
|
|
|
|
CArea *CM_GetNextArea(CCMLandScape *landscape);
|
|
|
|
CArea *CM_GetNextObjectiveArea(CCMLandScape *landscape);
|
|
|
|
void CM_CircularIterate(byte *data, int width, int height, int xo, int yo, int insideRadius, int outsideRadius, int *user, void (*callback)(byte *, float, int *));
|
|
|
|
|
|
|
|
CRandomTerrain *CreateRandomTerrain(const char *config, CCMLandScape *landscape, byte *heightmap, int width, int height);
|
|
|
|
|
|
|
|
void SV_LoadMissionDef(const char *configstring, class CCMLandScape *landscape);
|
|
|
|
void CL_CreateRandomTerrain(const char *config, class CCMLandScape *landscape, byte *image, int width, int height);
|
|
|
|
void CL_LoadInstanceDef(const char *configstring, class CCMLandScape *landscape);
|
|
|
|
void CL_LoadMissionDef(const char *configstring, class CCMLandScape *landscape);
|
|
|
|
|
|
|
|
extern cvar_t *com_terrainPhysics;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// end
|