//#define CULL_BBOX /* This file does not reference any globals, and has these entry points: void CM_ClearLevelPatches( void ); struct patchCollide_s *CM_GeneratePatchCollide( int width, int height, const vec3_t *points ); void CM_TraceThroughPatchCollide( traceWork_t *tw, const struct patchCollide_s *pc ); qboolean CM_PositionTestInPatchCollide( traceWork_t *tw, const struct patchCollide_s *pc ); void CM_DrawDebugSurface( void (*drawPoly)(int color, int numPoints, flaot *points) ); Issues for collision against curved surfaces: Surface edges need to be handled differently than surface planes Plane expansion causes raw surfaces to expand past expanded bounding box Position test of a volume against a surface is tricky. Position test of a point against a surface is not well defined, because the surface has no volume. Tracing leading edge points instead of volumes? Position test by tracing corner to corner? (8*7 traces -- ouch) coplanar edges triangulated patches degenerate patches endcaps degenerate WARNING: this may misbehave with meshes that have rows or columns that only degenerate a few triangles. Completely degenerate rows and columns are handled properly. */ #define MAX_FACETS 1024 #define MAX_PATCH_PLANES 2048 typedef struct { float plane[4]; int signbits; // signx + (signy<<1) + (signz<<2), used as lookup during collision } patchPlane_t; #ifdef _XBOX //Facets are now two structures - a maximum sized version that's used //temporarily during load time, and smaller version that only allocates //as much memory as needed. The load version is copied into the small //version after it's been assembled. #pragma pack(push, 1) typedef struct { int surfacePlane; int numBorders; // 3 or four + 6 axial bevels + 4 or 3 * 4 edge bevels short borderPlanes[4+6+16]; unsigned char borderInward[4+6+16]; unsigned char borderNoAdjust[4+6+16]; } facetLoad_t; typedef struct { int surfacePlane; int numBorders; // 3 or four + 6 axial bevels + 4 or 3 * 4 edge bevels char *data; short *GetBorderPlanes(void) { return (short*)data; } char *GetBorderInward(void) { return data + (numBorders * 2); } char *GetBorderNoAdjust(void) { return data + (numBorders * 2) + numBorders; } const short *GetBorderPlanes(void) const { return (short*)data; } const char *GetBorderInward(void) const { return data + (numBorders * 2); } const char *GetBorderNoAdjust(void) const { return data + (numBorders * 2) + numBorders; } } facet_t; #pragma pack(pop) #else // _XBOX typedef struct { int surfacePlane; int numBorders; // 3 or four + 6 axial bevels + 4 or 3 * 4 edge bevels int borderPlanes[4+6+16]; int borderInward[4+6+16]; qboolean borderNoAdjust[4+6+16]; } facet_t; #endif // _XBOX typedef struct patchCollide_s { vec3_t bounds[2]; int numPlanes; // surface planes plus edge planes patchPlane_t *planes; int numFacets; facet_t *facets; } patchCollide_t; #ifdef _XBOX #define CM_MAX_GRID_SIZE 129 #else #define MAX_GRID_SIZE 129 #endif typedef struct { int width; int height; qboolean wrapWidth; qboolean wrapHeight; #ifdef _XBOX vec3_t points[CM_MAX_GRID_SIZE][CM_MAX_GRID_SIZE]; // [width][height] #else vec3_t points[MAX_GRID_SIZE][MAX_GRID_SIZE]; // [width][height] #endif } cGrid_t; #define SUBDIVIDE_DISTANCE 16 //4 // never more than this units away from curve #define PLANE_TRI_EPSILON 0.1 #define WRAP_POINT_EPSILON 0.1 #ifdef _XBOX struct patchCollide_s *CM_GeneratePatchCollide( int width, int height, vec3_t *points, facetLoad_t *facetbuf, int *gridbuf ); #else struct patchCollide_s *CM_GeneratePatchCollide( int width, int height, vec3_t *points ); #endif