etqw-sdk/source/idlib/geometry/TraceModel.h

193 lines
6.7 KiB
C
Raw Permalink Normal View History

2008-05-29 00:00:00 +00:00
// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __TRACEMODEL_H__
#define __TRACEMODEL_H__
/*
===============================================================================
A trace model is an arbitrary polygonal model which is used by the
collision detection system to find collisions, contacts or the contents
of a volume. For collision detection speed reasons the number of vertices
and edges are limited. The trace model can have any shape. However convex
models are usually preferred.
===============================================================================
*/
class idVec3;
class idMat3;
class idBounds;
class idMaterial;
typedef const idMaterial* ( trmMaterialForName_t )( const char* name );
typedef const char* ( trmNameForMaterial_t )( const idMaterial* material );
// trace model type
enum traceModel_t {
TRM_INVALID, // invalid trm
TRM_BOX, // box
TRM_OCTAHEDRON, // octahedron
TRM_DODECAHEDRON, // dodecahedron
TRM_CYLINDER, // cylinder approximation
TRM_CONE, // cone approximation
TRM_BONE, // two tetrahedrons attached to each other
TRM_POLYGON, // arbitrary convex polygon
TRM_POLYGONVOLUME, // volume for arbitrary convex polygon
TRM_CUSTOM // loaded from map model or ASE/LWO
};
// these are bit cache limits
#define MAX_TRACEMODEL_VERTS 32
#define MAX_TRACEMODEL_EDGES 32
#define MAX_TRACEMODEL_POLYS 16
#define MAX_TRACEMODEL_POLYEDGES 16
typedef idVec3 traceModelVert_t;
struct traceModelEdge_t {
int v[2];
idVec3 normal;
};
struct traceModelPoly_t {
idVec3 normal;
float dist;
idBounds bounds;
int numEdges;
int edges[MAX_TRACEMODEL_POLYEDGES];
};
class idTraceModel {
public:
traceModel_t type;
int numVerts;
traceModelVert_t verts[MAX_TRACEMODEL_VERTS];
int numEdges;
traceModelEdge_t edges[MAX_TRACEMODEL_EDGES+1]; // edges[0] is unused because edge index signs are used for direction
int numPolys;
traceModelPoly_t polys[MAX_TRACEMODEL_POLYS];
const idMaterial* polyMaterials[MAX_TRACEMODEL_POLYS];
idVec3 offset; // offset to center of model
idBounds bounds; // bounds of model
bool isConvex; // true when model is convex
public:
idTraceModel( void );
// axial bounding box
idTraceModel( const idBounds &boxBounds );
// cylinder approximation
idTraceModel( const idBounds &cylBounds, const int numSides );
// bone
idTraceModel( const float length, const float width );
// axial box
void SetupBox( const idBounds &boxBounds );
void SetupBox( const float size );
// octahedron
void SetupOctahedron( const idBounds &octBounds );
void SetupOctahedron( const float size );
// dodecahedron
void SetupDodecahedron( const idBounds &dodBounds );
void SetupDodecahedron( const float size );
// cylinder approximation
void SetupCylinder( const idBounds &cylBounds, const int numSides, float offset = 0, int axis = 0 );
void SetupCylinder( const float height, const float width, const int numSides );
// cone approximation
void SetupCone( const idBounds &coneBounds, const int numSides );
void SetupCone( const float height, const float width, const int numSides );
// two tetrahedrons attached to each other
void SetupBone( const float length, const float width );
// arbitrary convex polygon
void SetupPolygon( const idVec3 *v, const int count );
void SetupPolygon( const idWinding &w );
// extruded polygonal prism
void SetupPolygonPrism( const idWinding &w, float thickness );
// basically a box, but with the top verts pushed out
void SetupFrustum( const idBounds& boxBounds, float topOffset );
void SetNullPolygonMaterials( void );
// generate edge normals
int GenerateEdgeNormals( void );
// test whether or not the model is convex and set isConvex accordingly
void TestConvexity( void );
// translate the trm
void Translate( const idVec3 &translation );
// rotate the trm
void Rotate( const idMat3 &rotation );
// shrink the model m units on all sides
void Shrink( const float m );
// clear unused spots in the arrays
void ClearUnused( void );
// make sure the trace model is well formed
bool Verify( void );
// compare
bool Compare( const idTraceModel &trm ) const;
bool operator==( const idTraceModel &trm ) const;
bool operator!=( const idTraceModel &trm ) const;
bool ContainsPoint( const idVec3& point ) const;
// returns true of the model is a closed surface
bool IsClosedSurface( void ) const;
// get the area of one of the polygons
float GetPolygonArea( int polyNum ) const;
// get the silhouette edges
int GetProjectionSilhouetteEdges( const idVec3 &projectionOrigin, int silEdges[MAX_TRACEMODEL_EDGES] ) const;
int GetParallelProjectionSilhouetteEdges( const idVec3 &projectionDir, int silEdges[MAX_TRACEMODEL_EDGES] ) const;
// calculate mass properties assuming an uniform density
void GetMassProperties( const float density, float &mass, idVec3 &centerOfMass, idMat3 &inertiaTensor ) const;
void Write( idFile* fp, trmNameForMaterial_t lookup ) const;
void Read( idFile* fp, trmMaterialForName_t lookup );
private:
void InitBox( void );
void InitOctahedron( void );
void InitDodecahedron( void );
void InitBone( void );
void ProjectionIntegrals( int polyNum, int a, int b, struct projectionIntegrals_t &integrals ) const;
void PolygonIntegrals( int polyNum, int a, int b, int c, struct polygonIntegrals_t &integrals ) const;
void VolumeIntegrals( struct volumeIntegrals_t &integrals ) const;
void VolumeFromPolygon( idTraceModel &trm, float thickness ) const;
int GetOrderedSilhouetteEdges( const int edgeIsSilEdge[MAX_TRACEMODEL_EDGES+1], int silEdges[MAX_TRACEMODEL_EDGES] ) const;
};
ID_INLINE idTraceModel::idTraceModel( void ) {
type = TRM_INVALID;
numVerts = numEdges = numPolys = 0;
bounds.Zero();
}
ID_INLINE idTraceModel::idTraceModel( const idBounds &boxBounds ) {
InitBox();
SetupBox( boxBounds );
}
ID_INLINE idTraceModel::idTraceModel( const idBounds &cylBounds, const int numSides ) {
SetupCylinder( cylBounds, numSides );
}
ID_INLINE idTraceModel::idTraceModel( const float length, const float width ) {
InitBone();
SetupBone( length, width );
}
ID_INLINE bool idTraceModel::operator==( const idTraceModel &trm ) const {
return Compare( trm );
}
ID_INLINE bool idTraceModel::operator!=( const idTraceModel &trm ) const {
return !Compare( trm );
}
#endif /* !__TRACEMODEL_H__ */