jediacademy/code/qcommon/cm_landscape.h

272 lines
12 KiB
C++

#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