CollisionModel_local.h 26 KB

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