393 lines
16 KiB
C
393 lines
16 KiB
C
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
|
||
|
#ifndef __AASFILE_H__
|
||
|
#define __AASFILE_H__
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
AAS File
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
#define AAS_FILE_ID "ETQWAAS"
|
||
|
#define AAS_FILE_ID_BINARY "ETQWAASB"
|
||
|
#define AAS_FILE_VERSION "2.2"
|
||
|
|
||
|
// travel flags
|
||
|
#define TFL_INVALID BIT(0) // invalid
|
||
|
#define TFL_INVALID_GDF BIT(1) // not valid for GDF
|
||
|
#define TFL_INVALID_STROGG BIT(2) // not valid for STROGG
|
||
|
#define TFL_AIR BIT(3) // travel through air
|
||
|
#define TFL_WATER BIT(4) // travel through water
|
||
|
#define TFL_WALK BIT(5) // walking
|
||
|
#define TFL_WALKOFFLEDGE BIT(6) // walking off a ledge
|
||
|
#define TFL_WALKOFFBARRIER BIT(7) // walking off a barrier
|
||
|
#define TFL_BARRIERJUMP BIT(8) // jumping onto a barrier
|
||
|
#define TFL_JUMP BIT(9) // jumping
|
||
|
#define TFL_LADDER BIT(10) // climbing a ladder
|
||
|
#define TFL_SWIM BIT(11) // swimming
|
||
|
#define TFL_WATERJUMP BIT(12) // jump out of the water
|
||
|
#define TFL_TELEPORT BIT(13) // teleportation
|
||
|
#define TFL_ELEVATOR BIT(14) // travel by elevator
|
||
|
|
||
|
#define TFL_VALID_GDF ( ~( TFL_INVALID | TFL_INVALID_GDF ) )
|
||
|
#define TFL_VALID_STROGG ( ~( TFL_INVALID | TFL_INVALID_STROGG ) )
|
||
|
#define TFL_VALID_GDF_AND_STROGG ( ~( TFL_INVALID ) )
|
||
|
|
||
|
#define TFL_VALID_WALK_GDF ( TFL_WALK | TFL_AIR | TFL_WATER | TFL_INVALID_STROGG )
|
||
|
#define TFL_VALID_WALK_STROGG ( TFL_WALK | TFL_AIR | TFL_WATER | TFL_INVALID_GDF )
|
||
|
#define TFL_VALID_WALK_GDF_AND_STROGG ( TFL_WALK | TFL_AIR | TFL_WATER | TFL_INVALID_GDF | TFL_INVALID_STROGG )
|
||
|
|
||
|
// edge flags
|
||
|
#define AAS_EDGE_WALL BIT(0) // wall
|
||
|
#define AAS_EDGE_LEDGE BIT(1) // ledge
|
||
|
#define AAS_EDGE_WALL_CORNER BIT(2) // edge extending from a wall corner
|
||
|
#define AAS_EDGE_LEDGE_CORNER BIT(3) // edge extending from a ledge corner
|
||
|
#define AAS_EDGE_STEP_TOP BIT(4) // step top edge
|
||
|
#define AAS_EDGE_STEP_BOTTOM BIT(5) // step bottom edge
|
||
|
#define AAS_EDGE_VERTICAL BIT(6) // mostly vertical edge
|
||
|
#define AAS_EDGE_WATER BIT(7) // water edge
|
||
|
#define AAS_EDGE_LADDER BIT(8) // ladder edge
|
||
|
|
||
|
// area flags
|
||
|
#define AAS_AREA_LEDGE BIT(0) // if entered the AI bbox partly floats above a ledge
|
||
|
#define AAS_AREA_REACHABLE_WALK BIT(1) // area is reachable by walking or swimming
|
||
|
#define AAS_AREA_OUTSIDE BIT(2) // area is outside
|
||
|
#define AAS_AREA_HIGH_CEILING BIT(3) // area has a ceiling that is high enough to perform certain movements
|
||
|
#define AAS_AREA_NOPUSH BIT(4) // push into area failed because the area winding is malformed
|
||
|
#define AAS_AREA_CONTENTS_SOLID BIT(8) // solid, not a valid area
|
||
|
#define AAS_AREA_CONTENTS_WATER BIT(9) // area contains water
|
||
|
#define AAS_AREA_CONTENTS_CLUSTERPORTAL BIT(10) // area is a cluster portal
|
||
|
#define AAS_AREA_CONTENTS_OBSTACLE BIT(11) // area contains (part of) a binary obstacle
|
||
|
#define AAS_AREA_CONTENTS_TELEPORTER BIT(12) // area contains (part of) a teleporter trigger
|
||
|
#define AAS_AREA_FLOOD_VISITED BIT(15) // area visited during a flood routine. this is a temporary flag that should be removed before the routine exits
|
||
|
|
||
|
// node flags
|
||
|
#define AAS_NODE_FLAG_NONE 0
|
||
|
#define AAS_NODE_FLAG_FLOOR_PLANE BIT(0) // this node stores a floor plane
|
||
|
#define AAS_NODE_FLAG_COLUMN_HEIGHT BIT(1) // the top most bits of the flags are used to store a height
|
||
|
#define AAS_NODE_FLAG_COLUMN_HEIGHT_BITS ( sizeof( ((aasNode_t*)0)->flags ) * 8 - 2 )
|
||
|
#define AAS_NODE_FLAG_COLUMN_HEIGHT_SHIFT ( sizeof( ((aasNode_t*)0)->flags ) * 8 - AAS_NODE_FLAG_COLUMN_HEIGHT_BITS )
|
||
|
#define AAS_NODE_FLAG_COLUMN_HEIGHT_MAX ( ( 1 << AAS_NODE_FLAG_COLUMN_HEIGHT_BITS ) - 1 )
|
||
|
#define AAS_NODE_FLAG_COLUMN_HEIGHT_OFFSET ( ( 1 << ( AAS_NODE_FLAG_COLUMN_HEIGHT_BITS - 1 ) ) )
|
||
|
|
||
|
// obstacle PVS run-length encoding
|
||
|
#define AAS_PVS_RLE_IMMEDIATE_BITS 7
|
||
|
#define AAS_PVS_RLE_1ST_COUNT_BITS 6
|
||
|
#define AAS_PVS_RLE_2ND_COUNT_BITS 8
|
||
|
#define AAS_PVS_RLE_RUN_GRANULARITY 1
|
||
|
#define AAS_PVS_RLE_RUN_BIT (1 << 7)
|
||
|
#define AAS_PVS_RLE_RUN_LONG_BIT (1 << 6)
|
||
|
|
||
|
// area travel time offset and reachability number encoding
|
||
|
#define AAS_REACH_MAX_NUMBER_BITS 8
|
||
|
#define AAS_REACH_MAX_PER_AREA ( 1 << AAS_REACH_MAX_NUMBER_BITS )
|
||
|
#define AAS_REACH_NUMBER_SHIFT ( sizeof( ((aasReachability_t*)0)->areaTTOfsAndNumber ) * 8 - AAS_REACH_MAX_NUMBER_BITS )
|
||
|
#define AAS_REACH_NUMBER_MASK ( ( 1 << AAS_REACH_MAX_NUMBER_BITS ) - 1 )
|
||
|
#define AAS_AREA_TRAVEL_TIME_OFFSET_MASK ( ( 1 << AAS_REACH_NUMBER_SHIFT ) - 1 )
|
||
|
|
||
|
#define AAS_MAX_NAME_LENGTH 128
|
||
|
#define AAS_MAX_TREE_DEPTH 128
|
||
|
|
||
|
// index
|
||
|
typedef int aasIndex_t;
|
||
|
|
||
|
// plane
|
||
|
typedef idPlane aasPlane_t;
|
||
|
|
||
|
// vertex
|
||
|
typedef idVec3 aasVertex_t;
|
||
|
|
||
|
// edge
|
||
|
struct aasEdge_t {
|
||
|
int vertexNum[2]; // numbers of the vertexes of this edge
|
||
|
int flags;
|
||
|
};
|
||
|
|
||
|
// reachability to another area
|
||
|
struct aasReachability_t {
|
||
|
unsigned short travelFlags; // type of travel required to get to the area
|
||
|
unsigned short travelTime; // travel time of the inter area movement
|
||
|
unsigned short fromAreaNum; // number of area the reachability starts
|
||
|
unsigned short toAreaNum; // number of area the reachability leads to
|
||
|
short start[3]; // start point of inter area movement
|
||
|
short end[3]; // end point of inter area movement
|
||
|
unsigned int areaTTOfsAndNumber; // travel times in fromAreaNum from reachabilities that lead towards this area to this reachability, and the reachability number
|
||
|
aasReachability_t * next; // next reachability in list
|
||
|
aasReachability_t * rev_next; // next reachability in reversed list
|
||
|
|
||
|
// v is the vector, d is the direction to snap towards
|
||
|
void SetStart( const idVec3 &v, const idVec3 &d ) { for ( int i = 0; i < 3; i++ ) start[i] = idMath::Ftoi( v[i] + idMath::Rint( d[i] ) ); }
|
||
|
void SetEnd( const idVec3 &v, const idVec3 &d ) { for ( int i = 0; i < 3; i++ ) end[i] = idMath::Ftoi( v[i] + idMath::Rint( d[i] ) ); }
|
||
|
|
||
|
const idVec3 GetStart() const { return idVec3( start[0], start[1], start[2] ); }
|
||
|
const idVec3 GetEnd() const { return idVec3( end[0], end[1], end[2] ); }
|
||
|
};
|
||
|
|
||
|
assert_sizeof( aasReachability_t, 32 );
|
||
|
|
||
|
// area for navigation
|
||
|
struct aasArea_t {
|
||
|
unsigned short travelFlags; // travel flags for traveling through this area
|
||
|
unsigned short flags; // several area flags
|
||
|
int numEdges; // number of edges in the boundary of the face
|
||
|
int firstEdge; // first edge in the edge index
|
||
|
short cluster; // cluster the area belongs to, if negative it's a portal
|
||
|
unsigned short clusterAreaNum; // number of the area in the cluster
|
||
|
unsigned int obstaclePVSOffset; // offset into obstacle PVS
|
||
|
aasReachability_t * reach; // reachabilities that start from this area
|
||
|
aasReachability_t * rev_reach; // reachabilities that lead to this area
|
||
|
};
|
||
|
|
||
|
assert_sizeof( aasArea_t, 28 );
|
||
|
|
||
|
// nodes of the bsp tree
|
||
|
struct aasNode_t {
|
||
|
unsigned short planeNum; // number of the plane that splits the subspace at this node
|
||
|
unsigned short flags; // node flags
|
||
|
int children[2]; // child nodes, zero is solid, negative is -(area number)
|
||
|
};
|
||
|
|
||
|
assert_sizeof( aasNode_t, 12 );
|
||
|
|
||
|
// cluster portal
|
||
|
struct aasPortal_t {
|
||
|
unsigned short areaNum; // number of the area that is the actual portal
|
||
|
short clusters[2]; // number of cluster at the front and back of the portal
|
||
|
unsigned short clusterAreaNum[2]; // number of this portal area in the front and back cluster
|
||
|
unsigned short maxAreaTravelTime; // maximum travel time through the portal area
|
||
|
};
|
||
|
|
||
|
// cluster
|
||
|
struct aasCluster_t {
|
||
|
int numAreas; // number of areas in the cluster
|
||
|
int numReachableAreas; // number of areas with reachabilities
|
||
|
int numPortals; // number of cluster portals
|
||
|
int firstPortal; // first cluster portal in the index
|
||
|
};
|
||
|
|
||
|
// obstacle PVS
|
||
|
typedef byte aasObstaclePVS_t;
|
||
|
|
||
|
// names
|
||
|
struct aasName_t {
|
||
|
char name[AAS_MAX_NAME_LENGTH];
|
||
|
int index;
|
||
|
};
|
||
|
|
||
|
// trace through the world
|
||
|
struct aasTrace_t {
|
||
|
aasTrace_t() { areas = NULL; points = NULL; getOutOfSolid = false; flags = travelFlags = maxAreas = 0; }
|
||
|
|
||
|
// parameters
|
||
|
int flags; // areas with these flags block the trace
|
||
|
int travelFlags; // areas with these travel flags block the trace
|
||
|
int maxAreas; // size of the 'areas' array
|
||
|
int getOutOfSolid; // trace out of solid if the trace starts in solid
|
||
|
// output
|
||
|
float fraction; // fraction of trace completed
|
||
|
idVec3 endpos; // end position of trace
|
||
|
int planeNum; // plane hit
|
||
|
int lastAreaNum; // number of last area the trace went through
|
||
|
int blockingAreaNum; // area that could not be entered
|
||
|
int numAreas; // number of areas the trace went through
|
||
|
int * areas; // array to store areas the trace went through
|
||
|
idVec3 * points; // points where the trace entered each new area
|
||
|
};
|
||
|
|
||
|
struct aasTraceHeight_t {
|
||
|
int maxPoints;
|
||
|
int numPoints; // number of areas the trace went through
|
||
|
idVec3 * points; // points where the trace entered each new area
|
||
|
};
|
||
|
|
||
|
struct aasTraceFloor_t {
|
||
|
float fraction; // fraction of trace completed
|
||
|
idVec3 endpos; // end position of trace
|
||
|
int lastAreaNum; // number of last area the trace went through
|
||
|
int lastEdgeNum; // number of last edge the trace went through or edge that stopped the trace
|
||
|
};
|
||
|
|
||
|
// settings
|
||
|
class idAASSettings {
|
||
|
public:
|
||
|
|
||
|
enum type_t {
|
||
|
AAS_PLAYER,
|
||
|
AAS_VEHICLE
|
||
|
};
|
||
|
|
||
|
enum aasPrimitiveMode_t {
|
||
|
AAS_PRIMITIVE_MODE_DEFAULT = 0, // compile if marked or part of the world
|
||
|
AAS_PRIMITIVE_MODE_NEVER = 1, // never compile
|
||
|
AAS_PRIMITIVE_MODE_ALWAYS = 2, // always compile
|
||
|
AAS_PRIMITIVE_MODE_EXPLICIT = 3 // compile only if the primitive is marked
|
||
|
};
|
||
|
|
||
|
int type;
|
||
|
idStr fileExtensionAAS;
|
||
|
|
||
|
// collision settings
|
||
|
idBounds boundingBox;
|
||
|
int primitiveModeBrush;
|
||
|
int primitiveModePatch;
|
||
|
int primitiveModeModel;
|
||
|
int primitiveModeTerrain;
|
||
|
|
||
|
// physics settings
|
||
|
idVec3 gravity;
|
||
|
idVec3 gravityDir;
|
||
|
idVec3 invGravityDir;
|
||
|
float gravityValue;
|
||
|
float maxStepHeight;
|
||
|
float maxBarrierHeight;
|
||
|
float maxWaterJumpHeight;
|
||
|
float maxFallHeight;
|
||
|
float minFloorCos;
|
||
|
float minHighCeiling;
|
||
|
float groundSpeed; // in units per second
|
||
|
float waterSpeed; // in units per second
|
||
|
float ladderSpeed; // in units per second
|
||
|
|
||
|
// navigation settings
|
||
|
float wallCornerEdgeRadius;
|
||
|
float ledgeCornerEdgeRadius;
|
||
|
float obstaclePVSRadius;
|
||
|
|
||
|
// fixed travel times
|
||
|
int tt_barrierJump;
|
||
|
int tt_waterJump;
|
||
|
int tt_startWalkOffLedge;
|
||
|
int tt_startLadderClimb;
|
||
|
|
||
|
public:
|
||
|
idAASSettings();
|
||
|
|
||
|
bool ReadFromDict( const char *name, const idDict *dict );
|
||
|
|
||
|
bool WriteToFile( idFile *fp ) const;
|
||
|
bool ReadFromFile( idLexer &src );
|
||
|
|
||
|
bool WriteToFile( const char *fileName ) const;
|
||
|
bool ReadFromFile( const char *fileName );
|
||
|
|
||
|
bool WriteToFileBinary( idFile *fp ) const;
|
||
|
bool ReadFromFileBinary( idFile *fp );
|
||
|
|
||
|
bool ValidForBounds( const idBounds &bounds ) const;
|
||
|
bool ValidEntity( const idMapFile *mapFile, const char *classname ) const;
|
||
|
|
||
|
private:
|
||
|
bool ParseBool( idLexer &src, bool &b );
|
||
|
bool ParseInt( idLexer &src, int &i );
|
||
|
bool ParseFloat( idLexer &src, float &f );
|
||
|
bool ParseVector( idLexer &src, idVec3 &vec );
|
||
|
bool ParseBounds( idLexer &src, idBounds &bounds );
|
||
|
|
||
|
bool ParseAASTypeKey( const idDict *dict, const char *keyName, int &aasType );
|
||
|
bool ParseBoundsKey( const idDict *dict, const char *keyName, idBounds &bounds );
|
||
|
bool ParsePrimitiveModeKey( const idDict *dict, const char *keyName, int &primitiveMode );
|
||
|
};
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
- when a node child is a solid leaf the node child number is zero
|
||
|
- the edges are stored counter clockwise using the edgeindex
|
||
|
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
|
||
|
the cluster number set to the negative portal number
|
||
|
- edge zero is a dummy
|
||
|
- area zero is a dummy
|
||
|
- node zero is a dummy
|
||
|
- portal zero is a dummy
|
||
|
- cluster zero is a dummy
|
||
|
|
||
|
*/
|
||
|
|
||
|
class idAASFile {
|
||
|
public:
|
||
|
virtual ~idAASFile() {}
|
||
|
|
||
|
const char * GetName() const { return name.c_str(); }
|
||
|
unsigned int GetCRC() const { return crc; }
|
||
|
|
||
|
int GetNumPlanes() const { return planes.Num(); }
|
||
|
const aasPlane_t & GetPlane( int index ) const { return planes[index]; }
|
||
|
int GetNumVertices() const { return vertices.Num(); }
|
||
|
const aasVertex_t & GetVertex( int index ) const { return vertices[index]; }
|
||
|
int GetNumEdges() const { return edges.Num(); }
|
||
|
const aasEdge_t & GetEdge( int index ) const { return edges[index]; }
|
||
|
int GetNumEdgeIndexes() const { return edgeIndex.Num(); }
|
||
|
const aasIndex_t & GetEdgeIndex( int index ) const { return edgeIndex[index]; }
|
||
|
int GetNumReachabilities() const { return reachabilities.Num(); }
|
||
|
const aasReachability_t & GetReachability( int index ) const { return reachabilities[index]; }
|
||
|
int GetNumAreas() const { return areas.Num(); }
|
||
|
const aasArea_t & GetArea( int index ) { return areas[index]; }
|
||
|
int GetNumNodes() const { return nodes.Num(); }
|
||
|
const aasNode_t & GetNode( int index ) const { return nodes[index]; }
|
||
|
int GetNumPortals() const { return portals.Num(); }
|
||
|
const aasPortal_t & GetPortal( int index ) { return portals[index]; }
|
||
|
int GetNumPortalIndexes() const { return portalIndex.Num(); }
|
||
|
const aasIndex_t & GetPortalIndex( int index ) const { return portalIndex[index]; }
|
||
|
int GetNumClusters() const { return clusters.Num(); }
|
||
|
const aasCluster_t & GetCluster( int index ) const { return clusters[index]; }
|
||
|
int GetNumObstaclePVS() const { return obstaclePVS.Num(); }
|
||
|
const aasObstaclePVS_t & GetObstaclePVS( int index ) const { return obstaclePVS[index]; }
|
||
|
int GetNumReachabilityNames() const { return reachabilityNames.Num(); }
|
||
|
const aasName_t & GetReachabilityName( int index ) const { return reachabilityNames[index]; }
|
||
|
|
||
|
const idAASSettings & GetSettings() const { return settings; }
|
||
|
|
||
|
void SetPortalMaxTravelTime( int index, int time ) { portals[index].maxAreaTravelTime = time; }
|
||
|
void SetAreaTravelFlag( int index, int flag ) { areas[index].travelFlags |= flag; }
|
||
|
void RemoveAreaTravelFlag( int index, int flag ) { areas[index].travelFlags &= ~flag; }
|
||
|
|
||
|
virtual int FindReachabilityByName( const char *name ) const = 0;
|
||
|
void SetReachabilityTravelFlag( int index, int flag ) { reachabilities[index].travelFlags |= flag; }
|
||
|
void RemoveReachabilityTravelFlag( int index, int flag ) { reachabilities[index].travelFlags &= ~flag; }
|
||
|
|
||
|
virtual size_t MemorySize() const = 0;
|
||
|
virtual size_t MemoryUsed() const = 0;
|
||
|
virtual size_t MaxRoutingCacheSize() const = 0;
|
||
|
virtual size_t AreaTravelTimeCacheSize() const = 0;
|
||
|
|
||
|
virtual idVec3 EdgeCenter( int edgeNum ) const = 0;
|
||
|
virtual idVec3 AreaCenter( int areaNum ) const = 0;
|
||
|
virtual idBounds EdgeBounds( int edgeNum ) const = 0;
|
||
|
virtual idBounds AreaBounds( int areaNum ) const = 0;
|
||
|
|
||
|
virtual int PointAreaNum( const idVec3 &origin ) const = 0;
|
||
|
virtual int PointReachableAreaNum( const idVec3 &origin, const idBounds &searchBounds, const int areaFlags, const int excludeTravelFlags ) const = 0;
|
||
|
virtual int BoundsReachableAreaNum( const idBounds &bounds, const int areaFlags, const int excludeTravelFlags ) const = 0;
|
||
|
virtual bool PushPointIntoArea( int areaNum, idVec3 &point ) const = 0;
|
||
|
|
||
|
virtual bool Trace( aasTrace_t &trace, const idVec3 &start, const idVec3 &end ) const = 0;
|
||
|
virtual bool TraceHeight( aasTraceHeight_t &trace, const idVec3 &start, const idVec3 &end ) const = 0;
|
||
|
virtual bool TraceFloor( aasTraceFloor_t &trace, const idVec3 &start, int startAreaNum, const idVec3 &end, int endAreaNum, int travelFlags ) const = 0;
|
||
|
|
||
|
protected:
|
||
|
idStr name;
|
||
|
unsigned int crc;
|
||
|
|
||
|
idAASSettings settings;
|
||
|
|
||
|
idList<aasPlane_t> planes;
|
||
|
idList<aasVertex_t> vertices;
|
||
|
idList<aasEdge_t> edges;
|
||
|
idList<aasIndex_t> edgeIndex;
|
||
|
idList<aasReachability_t> reachabilities;
|
||
|
idList<aasArea_t> areas;
|
||
|
idList<aasNode_t> nodes;
|
||
|
idList<aasPortal_t> portals;
|
||
|
idList<aasIndex_t> portalIndex;
|
||
|
idList<aasCluster_t> clusters;
|
||
|
idList<aasObstaclePVS_t> obstaclePVS;
|
||
|
idList<aasName_t> reachabilityNames;
|
||
|
};
|
||
|
|
||
|
#endif /* !__AASFILE_H__ */
|