1 /* 2 =========================================================================== 3 4 Doom 3 GPL Source Code 5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). 8 9 Doom 3 Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 /* 30 =============================================================================== 31 32 Trace model vs. polygonal model collision detection. 33 34 =============================================================================== 35 */ 36 37 #include "idlib/math/Pluecker.h" 38 #include "cm/CollisionModel.h" 39 40 #define MIN_NODE_SIZE 64.0f 41 #define MAX_NODE_POLYGONS 128 42 #define CM_MAX_POLYGON_EDGES 64 43 #define CIRCLE_APPROXIMATION_LENGTH 64.0f 44 45 #define MAX_SUBMODELS 2048 46 #define TRACE_MODEL_HANDLE MAX_SUBMODELS 47 48 #define VERTEX_HASH_BOXSIZE (1<<6) // must be power of 2 49 #define VERTEX_HASH_SIZE (VERTEX_HASH_BOXSIZE*VERTEX_HASH_BOXSIZE) 50 #define EDGE_HASH_SIZE (1<<14) 51 52 #define NODE_BLOCK_SIZE_SMALL 8 53 #define NODE_BLOCK_SIZE_LARGE 256 54 #define REFERENCE_BLOCK_SIZE_SMALL 8 55 #define REFERENCE_BLOCK_SIZE_LARGE 256 56 57 #define MAX_WINDING_LIST 128 // quite a few are generated at times 58 #define INTEGRAL_EPSILON 0.01f 59 #define VERTEX_EPSILON 0.1f 60 #define CHOP_EPSILON 0.1f 61 62 63 typedef struct cm_windingList_s { 64 int numWindings; // number of windings 65 idFixedWinding w[MAX_WINDING_LIST]; // windings 66 idVec3 normal; // normal for all windings 67 idBounds bounds; // bounds of all windings in list 68 idVec3 origin; // origin for radius 69 float radius; // radius relative to origin for all windings 70 int contents; // winding surface contents 71 int primitiveNum; // number of primitive the windings came from 72 } cm_windingList_t; 73 74 /* 75 =============================================================================== 76 77 Collision model 78 79 =============================================================================== 80 */ 81 82 typedef struct cm_vertex_s { 83 idVec3 p; // vertex point 84 int checkcount; // for multi-check avoidance 85 unsigned int side; // each bit tells at which side this vertex passes one of the trace model edges 86 unsigned int sideSet; // each bit tells if sidedness for the trace model edge has been calculated yet 87 } cm_vertex_t; 88 89 typedef struct cm_edge_s { 90 int checkcount; // for multi-check avoidance 91 unsigned short internal; // a trace model can never collide with internal edges 92 unsigned short numUsers; // number of polygons using this edge 93 unsigned int side; // each bit tells at which side of this edge one of the trace model vertices passes 94 unsigned int sideSet; // each bit tells if sidedness for the trace model vertex has been calculated yet 95 int vertexNum[2]; // start and end point of edge 96 idVec3 normal; // edge normal 97 } cm_edge_t; 98 99 typedef struct cm_polygonBlock_s { 100 int bytesRemaining; 101 byte * next; 102 } cm_polygonBlock_t; 103 104 typedef struct cm_polygon_s { 105 idBounds bounds; // polygon bounds 106 int checkcount; // for multi-check avoidance 107 int contents; // contents behind polygon 108 const idMaterial * material; // material 109 idPlane plane; // polygon plane 110 int numEdges; // number of edges 111 int edges[1]; // variable sized, indexes into cm_edge_t list 112 } cm_polygon_t; 113 114 typedef struct cm_polygonRef_s { 115 cm_polygon_t * p; // pointer to polygon 116 struct cm_polygonRef_s *next; // next polygon in chain 117 } cm_polygonRef_t; 118 119 typedef struct cm_polygonRefBlock_s { 120 cm_polygonRef_t * nextRef; // next polygon reference in block 121 struct cm_polygonRefBlock_s *next; // next block with polygon references 122 } cm_polygonRefBlock_t; 123 124 typedef struct cm_brushBlock_s { 125 int bytesRemaining; 126 byte * next; 127 } cm_brushBlock_t; 128 129 typedef struct cm_brush_s { 130 int checkcount; // for multi-check avoidance 131 idBounds bounds; // brush bounds 132 int contents; // contents of brush 133 const idMaterial * material; // material 134 int primitiveNum; // number of brush primitive 135 int numPlanes; // number of bounding planes 136 idPlane planes[1]; // variable sized 137 } cm_brush_t; 138 139 typedef struct cm_brushRef_s { 140 cm_brush_t * b; // pointer to brush 141 struct cm_brushRef_s * next; // next brush in chain 142 } cm_brushRef_t; 143 144 typedef struct cm_brushRefBlock_s { 145 cm_brushRef_t * nextRef; // next brush reference in block 146 struct cm_brushRefBlock_s *next; // next block with brush references 147 } cm_brushRefBlock_t; 148 149 typedef struct cm_node_s { 150 int planeType; // node axial plane type 151 float planeDist; // node plane distance 152 cm_polygonRef_t * polygons; // polygons in node 153 cm_brushRef_t * brushes; // brushes in node 154 struct cm_node_s * parent; // parent of this node 155 struct cm_node_s * children[2]; // node children 156 } cm_node_t; 157 158 typedef struct cm_nodeBlock_s { 159 cm_node_t * nextNode; // next node in block 160 struct cm_nodeBlock_s *next; // next block with nodes 161 } cm_nodeBlock_t; 162 163 typedef struct cm_model_s { 164 idStr name; // model name 165 idBounds bounds; // model bounds 166 int contents; // all contents of the model ored together 167 bool isConvex; // set if model is convex 168 // model geometry 169 int maxVertices; // size of vertex array 170 int numVertices; // number of vertices 171 cm_vertex_t * vertices; // array with all vertices used by the model 172 int maxEdges; // size of edge array 173 int numEdges; // number of edges 174 cm_edge_t * edges; // array with all edges used by the model 175 cm_node_t * node; // first node of spatial subdivision 176 // blocks with allocated memory 177 cm_nodeBlock_t * nodeBlocks; // list with blocks of nodes 178 cm_polygonRefBlock_t * polygonRefBlocks; // list with blocks of polygon references 179 cm_brushRefBlock_t * brushRefBlocks; // list with blocks of brush references 180 cm_polygonBlock_t * polygonBlock; // memory block with all polygons 181 cm_brushBlock_t * brushBlock; // memory block with all brushes 182 // statistics 183 int numPolygons; 184 int polygonMemory; 185 int numBrushes; 186 int brushMemory; 187 int numNodes; 188 int numBrushRefs; 189 int numPolygonRefs; 190 int numInternalEdges; 191 int numSharpEdges; 192 int numRemovedPolys; 193 int numMergedPolys; 194 int usedMemory; 195 } cm_model_t; 196 197 /* 198 =============================================================================== 199 200 Data used during collision detection calculations 201 202 =============================================================================== 203 */ 204 205 typedef struct cm_trmVertex_s { 206 int used; // true if this vertex is used for collision detection 207 idVec3 p; // vertex position 208 idVec3 endp; // end point of vertex after movement 209 int polygonSide; // side of polygon this vertex is on (rotational collision) 210 idPluecker pl; // pluecker coordinate for vertex movement 211 idVec3 rotationOrigin; // rotation origin for this vertex 212 idBounds rotationBounds; // rotation bounds for this vertex 213 } cm_trmVertex_t; 214 215 typedef struct cm_trmEdge_s { 216 int used; // true when vertex is used for collision detection 217 idVec3 start; // start of edge 218 idVec3 end; // end of edge 219 int vertexNum[2]; // indexes into cm_traceWork_t->vertices 220 idPluecker pl; // pluecker coordinate for edge 221 idVec3 cross; // (z,-y,x) of cross product between edge dir and movement dir 222 idBounds rotationBounds; // rotation bounds for this edge 223 idPluecker plzaxis; // pluecker coordinate for rotation about the z-axis 224 unsigned short bitNum; // vertex bit number 225 } cm_trmEdge_t; 226 227 typedef struct cm_trmPolygon_s { 228 int used; 229 idPlane plane; // polygon plane 230 int numEdges; // number of edges 231 int edges[MAX_TRACEMODEL_POLYEDGES]; // index into cm_traceWork_t->edges 232 idBounds rotationBounds; // rotation bounds for this polygon 233 } cm_trmPolygon_t; 234 235 typedef struct cm_traceWork_s { 236 int numVerts; 237 cm_trmVertex_t vertices[MAX_TRACEMODEL_VERTS]; // trm vertices 238 int numEdges; 239 cm_trmEdge_t edges[MAX_TRACEMODEL_EDGES+1]; // trm edges 240 int numPolys; 241 cm_trmPolygon_t polys[MAX_TRACEMODEL_POLYS]; // trm polygons 242 cm_model_t *model; // model colliding with 243 idVec3 start; // start of trace 244 idVec3 end; // end of trace 245 idVec3 dir; // trace direction 246 idBounds bounds; // bounds of full trace 247 idBounds size; // bounds of transformed trm relative to start 248 idVec3 extents; // largest of abs(size[0]) and abs(size[1]) for BSP trace 249 int contents; // ignore polygons that do not have any of these contents flags 250 trace_t trace; // collision detection result 251 252 bool rotation; // true if calculating rotational collision 253 bool pointTrace; // true if only tracing a point 254 bool positionTest; // true if not tracing but doing a position test 255 bool isConvex; // true if the trace model is convex 256 bool axisIntersectsTrm; // true if the rotation axis intersects the trace model 257 bool getContacts; // true if retrieving contacts 258 bool quickExit; // set to quickly stop the collision detection calculations 259 260 idVec3 origin; // origin of rotation in model space 261 idVec3 axis; // rotation axis in model space 262 idMat3 matrix; // rotates axis of rotation to the z-axis 263 float angle; // angle for rotational collision 264 float maxTan; // max tangent of half the positive angle used instead of fraction 265 float radius; // rotation radius of trm start 266 idRotation modelVertexRotation; // inverse rotation for model vertices 267 268 contactInfo_t *contacts; // array with contacts 269 int maxContacts; // max size of contact array 270 int numContacts; // number of contacts found 271 272 idPlane heartPlane1; // polygons should be near anough the trace heart planes 273 float maxDistFromHeartPlane1; 274 idPlane heartPlane2; 275 float maxDistFromHeartPlane2; 276 idPluecker polygonEdgePlueckerCache[CM_MAX_POLYGON_EDGES]; 277 idPluecker polygonVertexPlueckerCache[CM_MAX_POLYGON_EDGES]; 278 idVec3 polygonRotationOriginCache[CM_MAX_POLYGON_EDGES]; 279 } cm_traceWork_t; 280 281 /* 282 =============================================================================== 283 284 Collision Map 285 286 =============================================================================== 287 */ 288 289 typedef struct cm_procNode_s { 290 idPlane plane; 291 int children[2]; // negative numbers are (-1 - areaNumber), 0 = solid 292 } cm_procNode_t; 293 294 class idCollisionModelManagerLocal : public idCollisionModelManager { 295 public: 296 // load collision models from a map file 297 void LoadMap( const idMapFile *mapFile ); 298 // frees all the collision models 299 void FreeMap( void ); 300 301 // get clip handle for model 302 cmHandle_t LoadModel( const char *modelName, const bool precache ); 303 // sets up a trace model for collision with other trace models 304 cmHandle_t SetupTrmModel( const idTraceModel &trm, const idMaterial *material ); 305 // create trace model from a collision model, returns true if succesfull 306 bool TrmFromModel( const char *modelName, idTraceModel &trm ); 307 308 // name of the model 309 const char * GetModelName( cmHandle_t model ) const; 310 // bounds of the model 311 bool GetModelBounds( cmHandle_t model, idBounds &bounds ) const; 312 // all contents flags of brushes and polygons ored together 313 bool GetModelContents( cmHandle_t model, int &contents ) const; 314 // get the vertex of a model 315 bool GetModelVertex( cmHandle_t model, int vertexNum, idVec3 &vertex ) const; 316 // get the edge of a model 317 bool GetModelEdge( cmHandle_t model, int edgeNum, idVec3 &start, idVec3 &end ) const; 318 // get the polygon of a model 319 bool GetModelPolygon( cmHandle_t model, int polygonNum, idFixedWinding &winding ) const; 320 321 // translates a trm and reports the first collision if any 322 void Translation( trace_t *results, const idVec3 &start, const idVec3 &end, 323 const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, 324 cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); 325 // rotates a trm and reports the first collision if any 326 void Rotation( trace_t *results, const idVec3 &start, const idRotation &rotation, 327 const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, 328 cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); 329 // returns the contents the trm is stuck in or 0 if the trm is in free space 330 int Contents( const idVec3 &start, 331 const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, 332 cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); 333 // stores all contact points of the trm with the model, returns the number of contacts 334 int Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, 335 const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, 336 cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); 337 // test collision detection 338 void DebugOutput( const idVec3 &origin ); 339 // draw a model 340 void DrawModel( cmHandle_t model, const idVec3 &origin, const idMat3 &axis, 341 const idVec3 &viewOrigin, const float radius ); 342 // print model information, use -1 handle for accumulated model info 343 void ModelInfo( cmHandle_t model ); 344 // list all loaded models 345 void ListModels( void ); 346 // write a collision model file for the map entity 347 bool WriteCollisionModelForMapEntity( const idMapEntity *mapEnt, const char *filename, const bool testTraceModel = true ); 348 349 private: // CollisionMap_translate.cpp 350 int TranslateEdgeThroughEdge( idVec3 &cross, idPluecker &l1, idPluecker &l2, float *fraction ); 351 void TranslateTrmEdgeThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmEdge_t *trmEdge ); 352 void TranslateTrmVertexThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v, int bitNum ); 353 void TranslatePointThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v ); 354 void TranslateVertexThroughTrmPolygon( cm_traceWork_t *tw, cm_trmPolygon_t *trmpoly, cm_polygon_t *poly, cm_vertex_t *v, idVec3 &endp, idPluecker &pl ); 355 bool TranslateTrmThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *p ); 356 void SetupTranslationHeartPlanes( cm_traceWork_t *tw ); 357 void SetupTrm( cm_traceWork_t *tw, const idTraceModel *trm ); 358 359 private: // CollisionMap_rotate.cpp 360 int CollisionBetweenEdgeBounds( cm_traceWork_t *tw, const idVec3 &va, const idVec3 &vb, 361 const idVec3 &vc, const idVec3 &vd, float tanHalfAngle, 362 idVec3 &collisionPoint, idVec3 &collisionNormal ); 363 int RotateEdgeThroughEdge( cm_traceWork_t *tw, const idPluecker &pl1, 364 const idVec3 &vc, const idVec3 &vd, 365 const float minTan, float &tanHalfAngle ); 366 int EdgeFurthestFromEdge( cm_traceWork_t *tw, const idPluecker &pl1, 367 const idVec3 &vc, const idVec3 &vd, 368 float &tanHalfAngle, float &dir ); 369 void RotateTrmEdgeThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmEdge_t *trmEdge ); 370 int RotatePointThroughPlane( const cm_traceWork_t *tw, const idVec3 &point, const idPlane &plane, 371 const float angle, const float minTan, float &tanHalfAngle ); 372 int PointFurthestFromPlane( const cm_traceWork_t *tw, const idVec3 &point, const idPlane &plane, 373 const float angle, float &tanHalfAngle, float &dir ); 374 int RotatePointThroughEpsilonPlane( const cm_traceWork_t *tw, const idVec3 &point, const idVec3 &endPoint, 375 const idPlane &plane, const float angle, const idVec3 &origin, 376 float &tanHalfAngle, idVec3 &collisionPoint, idVec3 &endDir ); 377 void RotateTrmVertexThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *poly, cm_trmVertex_t *v, int vertexNum); 378 void RotateVertexThroughTrmPolygon( cm_traceWork_t *tw, cm_trmPolygon_t *trmpoly, cm_polygon_t *poly, 379 cm_vertex_t *v, idVec3 &rotationOrigin ); 380 bool RotateTrmThroughPolygon( cm_traceWork_t *tw, cm_polygon_t *p ); 381 void BoundsForRotation( const idVec3 &origin, const idVec3 &axis, const idVec3 &start, const idVec3 &end, idBounds &bounds ); 382 void Rotation180( trace_t *results, const idVec3 &rorg, const idVec3 &axis, 383 const float startAngle, const float endAngle, const idVec3 &start, 384 const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, 385 cmHandle_t model, const idVec3 &origin, const idMat3 &modelAxis ); 386 387 private: // CollisionMap_contents.cpp 388 bool TestTrmVertsInBrush( cm_traceWork_t *tw, cm_brush_t *b ); 389 bool TestTrmInPolygon( cm_traceWork_t *tw, cm_polygon_t *p ); 390 cm_node_t * PointNode( const idVec3 &p, cm_model_t *model ); 391 int PointContents( const idVec3 p, cmHandle_t model ); 392 int TransformedPointContents( const idVec3 &p, cmHandle_t model, const idVec3 &origin, const idMat3 &modelAxis ); 393 int ContentsTrm( trace_t *results, const idVec3 &start, 394 const idTraceModel *trm, const idMat3 &trmAxis, int contentMask, 395 cmHandle_t model, const idVec3 &modelOrigin, const idMat3 &modelAxis ); 396 397 private: // CollisionMap_trace.cpp 398 void TraceTrmThroughNode( cm_traceWork_t *tw, cm_node_t *node ); 399 void TraceThroughAxialBSPTree_r( cm_traceWork_t *tw, cm_node_t *node, float p1f, float p2f, idVec3 &p1, idVec3 &p2); 400 void TraceThroughModel( cm_traceWork_t *tw ); 401 void RecurseProcBSP_r( trace_t *results, int parentNodeNum, int nodeNum, float p1f, float p2f, const idVec3 &p1, const idVec3 &p2 ); 402 403 private: // CollisionMap_load.cpp 404 void Clear( void ); 405 void FreeTrmModelStructure( void ); 406 // model deallocation 407 void RemovePolygonReferences_r( cm_node_t *node, cm_polygon_t *p ); 408 void RemoveBrushReferences_r( cm_node_t *node, cm_brush_t *b ); 409 void FreeNode( cm_node_t *node ); 410 void FreePolygonReference( cm_polygonRef_t *pref ); 411 void FreeBrushReference( cm_brushRef_t *bref ); 412 void FreePolygon( cm_model_t *model, cm_polygon_t *poly ); 413 void FreeBrush( cm_model_t *model, cm_brush_t *brush ); 414 void FreeTree_r( cm_model_t *model, cm_node_t *headNode, cm_node_t *node ); 415 void FreeModel( cm_model_t *model ); 416 // merging polygons 417 void ReplacePolygons( cm_model_t *model, cm_node_t *node, cm_polygon_t *p1, cm_polygon_t *p2, cm_polygon_t *newp ); 418 cm_polygon_t * TryMergePolygons( cm_model_t *model, cm_polygon_t *p1, cm_polygon_t *p2 ); 419 bool MergePolygonWithTreePolygons( cm_model_t *model, cm_node_t *node, cm_polygon_t *polygon ); 420 void MergeTreePolygons( cm_model_t *model, cm_node_t *node ); 421 // finding internal edges 422 bool PointInsidePolygon( cm_model_t *model, cm_polygon_t *p, idVec3 &v ); 423 void FindInternalEdgesOnPolygon( cm_model_t *model, cm_polygon_t *p1, cm_polygon_t *p2 ); 424 void FindInternalPolygonEdges( cm_model_t *model, cm_node_t *node, cm_polygon_t *polygon ); 425 void FindInternalEdges( cm_model_t *model, cm_node_t *node ); 426 void FindContainedEdges( cm_model_t *model, cm_polygon_t *p ); 427 // loading of proc BSP tree 428 void ParseProcNodes( idLexer *src ); 429 void LoadProcBSP( const char *name ); 430 // removal of contained polygons 431 int R_ChoppedAwayByProcBSP( int nodeNum, idFixedWinding *w, const idVec3 &normal, const idVec3 &origin, const float radius ); 432 int ChoppedAwayByProcBSP( const idFixedWinding &w, const idPlane &plane, int contents ); 433 void ChopWindingListWithBrush( cm_windingList_t *list, cm_brush_t *b ); 434 void R_ChopWindingListWithTreeBrushes( cm_windingList_t *list, cm_node_t *node ); 435 idFixedWinding *WindingOutsideBrushes( idFixedWinding *w, const idPlane &plane, int contents, int patch, cm_node_t *headNode ); 436 // creation of axial BSP tree 437 cm_model_t * AllocModel( void ); 438 cm_node_t * AllocNode( cm_model_t *model, int blockSize ); 439 cm_polygonRef_t*AllocPolygonReference( cm_model_t *model, int blockSize ); 440 cm_brushRef_t * AllocBrushReference( cm_model_t *model, int blockSize ); 441 cm_polygon_t * AllocPolygon( cm_model_t *model, int numEdges ); 442 cm_brush_t * AllocBrush( cm_model_t *model, int numPlanes ); 443 void AddPolygonToNode( cm_model_t *model, cm_node_t *node, cm_polygon_t *p ); 444 void AddBrushToNode( cm_model_t *model, cm_node_t *node, cm_brush_t *b ); 445 void SetupTrmModelStructure( void ); 446 void R_FilterPolygonIntoTree( cm_model_t *model, cm_node_t *node, cm_polygonRef_t *pref, cm_polygon_t *p ); 447 void R_FilterBrushIntoTree( cm_model_t *model, cm_node_t *node, cm_brushRef_t *pref, cm_brush_t *b ); 448 cm_node_t * R_CreateAxialBSPTree( cm_model_t *model, cm_node_t *node, const idBounds &bounds ); 449 cm_node_t * CreateAxialBSPTree( cm_model_t *model, cm_node_t *node ); 450 // creation of raw polygons 451 void SetupHash(void); 452 void ShutdownHash(void); 453 void ClearHash( idBounds &bounds ); 454 int HashVec(const idVec3 &vec); 455 int GetVertex( cm_model_t *model, const idVec3 &v, int *vertexNum ); 456 int GetEdge( cm_model_t *model, const idVec3 &v1, const idVec3 &v2, int *edgeNum, int v1num ); 457 void CreatePolygon( cm_model_t *model, idFixedWinding *w, const idPlane &plane, const idMaterial *material, int primitiveNum ); 458 void PolygonFromWinding( cm_model_t *model, idFixedWinding *w, const idPlane &plane, const idMaterial *material, int primitiveNum ); 459 void CalculateEdgeNormals( cm_model_t *model, cm_node_t *node ); 460 void CreatePatchPolygons( cm_model_t *model, idSurface_Patch &mesh, const idMaterial *material, int primitiveNum ); 461 void ConvertPatch( cm_model_t *model, const idMapPatch *patch, int primitiveNum ); 462 void ConvertBrushSides( cm_model_t *model, const idMapBrush *mapBrush, int primitiveNum ); 463 void ConvertBrush( cm_model_t *model, const idMapBrush *mapBrush, int primitiveNum ); 464 void PrintModelInfo( const cm_model_t *model ); 465 void AccumulateModelInfo( cm_model_t *model ); 466 void RemapEdges( cm_node_t *node, int *edgeRemap ); 467 void OptimizeArrays( cm_model_t *model ); 468 void FinishModel( cm_model_t *model ); 469 void BuildModels( const idMapFile *mapFile ); 470 cmHandle_t FindModel( const char *name ); 471 cm_model_t * CollisionModelForMapEntity( const idMapEntity *mapEnt ); // brush/patch model from .map 472 cm_model_t * LoadRenderModel( const char *fileName ); // ASE/LWO models 473 bool TrmFromModel_r( idTraceModel &trm, cm_node_t *node ); 474 bool TrmFromModel( const cm_model_t *model, idTraceModel &trm ); 475 476 private: // CollisionMap_files.cpp 477 // writing 478 void WriteNodes( idFile *fp, cm_node_t *node ); 479 int CountPolygonMemory( cm_node_t *node ) const; 480 void WritePolygons( idFile *fp, cm_node_t *node ); 481 int CountBrushMemory( cm_node_t *node ) const; 482 void WriteBrushes( idFile *fp, cm_node_t *node ); 483 void WriteCollisionModel( idFile *fp, cm_model_t *model ); 484 void WriteCollisionModelsToFile( const char *filename, int firstModel, int lastModel, unsigned int mapFileCRC ); 485 // loading 486 cm_node_t * ParseNodes( idLexer *src, cm_model_t *model, cm_node_t *parent ); 487 void ParseVertices( idLexer *src, cm_model_t *model ); 488 void ParseEdges( idLexer *src, cm_model_t *model ); 489 void ParsePolygons( idLexer *src, cm_model_t *model ); 490 void ParseBrushes( idLexer *src, cm_model_t *model ); 491 bool ParseCollisionModel( idLexer *src ); 492 bool LoadCollisionModelFile( const char *name, unsigned int mapFileCRC ); 493 494 private: // CollisionMap_debug 495 int ContentsFromString( const char *string ) const; 496 const char * StringFromContents( const int contents ) const; 497 void DrawEdge( cm_model_t *model, int edgeNum, const idVec3 &origin, const idMat3 &axis ); 498 void DrawPolygon( cm_model_t *model, cm_polygon_t *p, const idVec3 &origin, const idMat3 &axis, 499 const idVec3 &viewOrigin ); 500 void DrawNodePolygons( cm_model_t *model, cm_node_t *node, const idVec3 &origin, const idMat3 &axis, 501 const idVec3 &viewOrigin, const float radius ); 502 503 private: // collision map data 504 idStr mapName; 505 ID_TIME_T mapFileTime; 506 int loaded; 507 // for multi-check avoidance 508 int checkCount; 509 // models 510 int maxModels; 511 int numModels; 512 cm_model_t ** models; 513 // polygons and brush for trm model 514 cm_polygonRef_t*trmPolygons[MAX_TRACEMODEL_POLYS]; 515 cm_brushRef_t * trmBrushes[1]; 516 const idMaterial *trmMaterial; 517 // for data pruning 518 int numProcNodes; 519 cm_procNode_t * procNodes; 520 // for retrieving contact points 521 bool getContacts; 522 contactInfo_t * contacts; 523 int maxContacts; 524 int numContacts; 525 }; 526 527 // for debugging 528 extern idCVar cm_debugCollision; 529