48 #include "../idlib/precompiled.h"
88 src->
Error(
"ParseProcNodes: bad numProcNodes" );
122 common->
Warning(
"idCollisionModelManagerLocal::LoadProcBSP: couldn't load %s", filename.
c_str() );
139 if ( token ==
"model" ) {
144 if ( token ==
"shadowModel" ) {
149 if ( token ==
"interAreaPortals" ) {
154 if ( token ==
"nodes" ) {
159 src->
Error(
"idCollisionModelManagerLocal::LoadProcBSP: bad token \"%s\"", token.
c_str() );
206 for ( pref = node->
polygons; pref; pref = pref->
next ) {
207 if ( pref->
p == p ) {
239 for ( bref = node->
brushes; bref; bref = bref->
next ) {
240 if ( bref->
b == b ) {
376 for ( polygonRefBlock = model->
polygonRefBlocks; polygonRefBlock; polygonRefBlock = nextPolygonRefBlock ) {
377 nextPolygonRefBlock = polygonRefBlock->
next;
381 for ( brushRefBlock = model->
brushRefBlocks; brushRefBlock; brushRefBlock = nextBrushRefBlock ) {
382 nextBrushRefBlock = brushRefBlock->
next;
386 for ( nodeBlock = model->
nodeBlocks; nodeBlock; nodeBlock = nextNodeBlock ) {
387 nextNodeBlock = nodeBlock->
next;
468 #define SHARP_EDGE_DOT -0.7f
479 for ( pref = node->
polygons; pref; pref = pref->
next ) {
487 for ( i = 0; i < p->
numEdges; i++ ) {
489 edge = model->
edges + abs( edgeNum );
490 if ( edge->
normal[0] == 0.0f && edge->
normal[1] == 0.0f && edge->
normal[2] == 0.0f ) {
510 s = 0.5f / ( 0.5f + 0.5f *
dot );
582 for ( i = 0; i < blockSize - 1; i++ ) {
612 for ( i = 0; i < blockSize - 1; i++ ) {
613 pref->
next = pref + 1;
641 for ( i = 0; i < blockSize - 1; i++ ) {
642 bref->
next = bref + 1;
685 size =
sizeof(
cm_brush_t ) + ( numPlanes - 1 ) *
sizeof( brush->
planes[0] );
801 if ( material ==
NULL ) {
816 for ( i = 0; i < trm.
numVerts; i++, vertex++, trmVert++ ) {
817 vertex->p = *trmVert;
822 edge = model->
edges + 1;
823 trmEdge = trm.
edges + 1;
824 for ( i = 0; i < trm.
numEdges; i++, edge++, trmEdge++ ) {
825 edge->vertexNum[0] = trmEdge->
v[0];
826 edge->vertexNum[1] = trmEdge->
v[1];
827 edge->normal = trmEdge->
normal;
828 edge->internal =
false;
834 for ( i = 0; i < trm.
numPolys; i++, trmPoly++ ) {
837 for ( j = 0; j < trmPoly->
numEdges; j++ ) {
852 for ( i = 0; i < trm.
numPolys; i++ ) {
890 if ( dist > radius ) {
893 else if ( dist < -radius ) {
927 }
while ( nodeNum > 0 );
956 origin = (bounds[1] - bounds[0]) * 0.5
f;
958 origin = bounds[0] + origin;
971 int i, k,
res, startPlane, planeNum, bestNumWindings;
987 if ( dist > list->
radius ) {
990 else if ( dist < -list->radius ) {
1016 for ( planeNum = startPlane, i = 0; i < b->
numPlanes; i++, planeNum++ ) {
1022 res = sidedness[planeNum];
1025 plane = -b->
planes[planeNum];
1062 if ( cm_tmpList->
numWindings >= bestNumWindings ) {
1068 if ( cm_tmpList->
numWindings < bestNumWindings ) {
1079 if ( bestNumWindings == 1 ) {
1087 }
while ( chopped && startPlane < b->numPlanes );
1094 list->
w[k] = cm_outList->
w[k];
1110 for ( bref = node->
brushes; bref; bref = bref->
next ) {
1126 for ( i = 0; i < 3; i++ ) {
1182 cm_windingList->
origin = (cm_windingList->
bounds[1] - cm_windingList->
bounds[0]) * 0.5;
1188 cm_windingList->
w[0] = *
w;
1191 cm_windingList->
contents = contents;
1201 return &cm_windingList->
w[0];
1209 for ( i = 0; i < cm_windingList->
numWindings; i++ ) {
1211 if ( windingLeft >= 0 ) {
1217 if ( windingLeft >= 0 ) {
1218 return &cm_windingList->
w[windingLeft];
1246 for ( pref = node->
polygons; pref; pref = nextpref ) {
1247 nextpref = pref->
next;
1251 if ( p == p1 || p == p2 ) {
1255 lastpref->
next = nextpref;
1295 #define CONTINUOUS_EPSILON 0.005f
1296 #define NORMAL_EPSILON 0.01f
1299 int i,
j, nexti, prevj;
1300 int p1BeforeShare, p1AfterShare, p2BeforeShare, p2AfterShare;
1302 int edgeNum, edgeNum1, edgeNum2, newEdgeNum1, newEdgeNum2;
1315 for ( i = 0; i < 3; i++ ) {
1328 p1BeforeShare = p1AfterShare = p2BeforeShare = p2AfterShare = -1;
1329 for ( i = 0; i < p1->
numEdges; i++ ) {
1331 for ( j = 0; j < p2->
numEdges; j++ ) {
1336 if ( abs(p1->
edges[nexti]) == abs(p2->
edges[prevj]) ) {
1338 if ( p1->
edges[nexti] != p2->
edges[prevj] ) {
1348 if ( abs(p1->
edges[nexti]) != abs(p2->
edges[prevj]) ) {
1349 p1AfterShare = nexti;
1350 p2BeforeShare = prevj;
1356 if ( p1BeforeShare < 0 || p1AfterShare < 0 || p2BeforeShare < 0 || p2AfterShare < 0 ) {
1361 edgeNum = p1->
edges[p1BeforeShare];
1362 edge = model->
edges + abs(edgeNum);
1368 edgeNum = p2->
edges[p2AfterShare];
1369 edge = model->
edges + abs(edgeNum);
1373 dot = delta * normal;
1378 edgeNum = p2->
edges[p2BeforeShare];
1379 edge = model->
edges + abs(edgeNum);
1385 edgeNum = p1->
edges[p1AfterShare];
1386 edge = model->
edges + abs(edgeNum);
1390 dot = delta * normal;
1395 newEdgeNum1 = newEdgeNum2 = 0;
1398 edgeNum1 = p1->
edges[p1BeforeShare];
1399 edgeNum2 = p2->
edges[p2AfterShare];
1403 if ( newEdgeNum1 == 0 ) {
1408 edgeNum1 = p2->
edges[p2BeforeShare];
1409 edgeNum2 = p1->
edges[p1AfterShare];
1413 if ( newEdgeNum2 == 0 ) {
1420 newEdges[newNumEdges++] = newEdgeNum2;
1422 if ( p1AfterShare < p1BeforeShare ) {
1423 for ( i = p1AfterShare + (!keep2); i <= p1BeforeShare - (!keep1); i++ ) {
1424 newEdges[newNumEdges++] = p1->
edges[
i];
1428 for ( i = p1AfterShare + (!keep2); i < p1->
numEdges; i++ ) {
1429 newEdges[newNumEdges++] = p1->
edges[
i];
1431 for ( i = 0; i <= p1BeforeShare - (!keep1); i++ ) {
1432 newEdges[newNumEdges++] = p1->
edges[
i];
1436 newEdges[newNumEdges++] = newEdgeNum1;
1438 if ( p2AfterShare < p2BeforeShare ) {
1439 for ( i = p2AfterShare + (!keep1); i <= p2BeforeShare - (!keep2); i++ ) {
1440 newEdges[newNumEdges++] = p2->
edges[
i];
1444 for ( i = p2AfterShare + (!keep1); i < p2->
numEdges; i++ ) {
1445 newEdges[newNumEdges++] = p2->
edges[
i];
1447 for ( i = 0; i <= p2BeforeShare - (!keep2); i++ ) {
1448 newEdges[newNumEdges++] = p2->
edges[
i];
1454 memcpy( newp->
edges, newEdges, newNumEdges *
sizeof(
int) );
1458 for ( i = 0; i < newp->
numEdges; i++ ) {
1459 if ( !keep1 && newp->
edges[i] == newEdgeNum1 ) {
1462 if ( !keep2 && newp->
edges[i] == newEdgeNum2 ) {
1484 for ( pref = node->
polygons; pref; pref = pref->
next ) {
1487 if ( p == polygon ) {
1498 for ( i = 0; i < polygon->
numEdges; i++ ) {
1501 for ( i = 0; i < p->
numEdges; i++ ) {
1546 for ( pref = node->
polygons; pref; pref = pref->
next ) {
1601 for ( i = 0; i < p->
numEdges; i++ ) {
1603 edge = model->
edges + abs(edgeNum);
1607 dir1 = (*v2) - (*v1);
1623 int i,
j, k, edgeNum;
1629 for ( i = 0; i < 3; i++ ) {
1640 for ( i = 0; i < p1->
numEdges; i++ ) {
1642 edge = model->
edges + abs(edgeNum);
1651 for ( k = 0; k < 3; k++ ) {
1653 if ( (*v1)[k] > d || (*v2)[k] > d ) {
1657 if ( (*v1)[k] < d || (*v2)[k] < d ) {
1666 for ( j = 0; j < p2->
numEdges; j++ ) {
1667 if ( k == abs(p2->
edges[j]) ) {
1672 if ( j < p2->numEdges ) {
1679 if ( edgeNum == p2->
edges[j] ) {
1697 dir1 = (*v2) - (*v1);
1733 for ( pref = node->
polygons; pref; pref = pref->
next ) {
1743 if ( p == polygon ) {
1775 for ( i = 0; i < p->
numEdges; i++ ) {
1777 edge = model->
edges + abs(edgeNum);
1800 for ( pref = node->
polygons; pref; pref = pref->
next ) {
1834 static int CM_FindSplitter(
const cm_node_t *node,
const idBounds &bounds,
int *planeType,
float *planeDist ) {
1835 int i,
j,
type, axis[3], polyCount;
1836 float dist,
t, bestt,
size[3];
1840 bool forceSplit =
false;
1842 for ( i = 0; i < 3; i++ ) {
1843 size[
i] = bounds[1][
i] - bounds[0][
i];
1847 for ( i = 0; i < 2; i++ ) {
1848 if ( size[i] < size[i+1] ) {
1850 size[
i] = size[i+1];
1853 axis[
i] = axis[i+1];
1861 for ( pref = node->
polygons; pref; pref = pref->
next) {
1869 for ( i = 0; i < 3; i++ ) {
1879 for ( n = node;
n; n = n->
parent ) {
1880 for ( bref = n->
brushes; bref; bref = bref->
next) {
1881 for ( j = 0; j < 2; j++ ) {
1884 if ( dist >= bounds[1][type] || dist <= bounds[0][type] ) {
1888 t = abs((bounds[1][type] - dist) - (dist - bounds[0][type]));
1899 for ( n = node;
n; n = n->
parent ) {
1901 for ( j = 0; j < 2; j++ ) {
1904 if ( dist >= bounds[1][type] || dist <= bounds[0][type] ) {
1908 t = abs((bounds[1][type] - dist) - (dist - bounds[0][type]));
1918 if ( bestt < size[i] ) {
1947 if ( !CM_R_InsideAllChildren( node->
children[0], bounds ) ) {
1950 if ( !CM_R_InsideAllChildren( node->
children[1], bounds ) ) {
1965 if ( CM_R_InsideAllChildren( node, p->
bounds ) ) {
1996 if ( CM_R_InsideAllChildren( node, b->
bounds ) ) {
2035 if ( !CM_FindSplitter( node, bounds, &planeType, &planeDist ) ) {
2041 memset( frontNode, 0,
sizeof(
cm_node_t) );
2042 frontNode->
parent = node;
2046 memset( backNode, 0,
sizeof(
cm_node_t) );
2052 frontBounds = bounds;
2053 frontBounds[0][planeType] = planeDist;
2055 backBounds = bounds;
2056 backBounds[1][planeType] = planeDist;
2063 for ( n = node;
n; n = n->
parent ) {
2065 for ( pref = n->
polygons; pref; pref = nextpref) {
2066 nextpref = pref->
next;
2068 if ( !CM_R_InsideAllChildren( n, pref->
p->
bounds ) ) {
2072 prevpref->
next = nextpref;
2083 for ( bref = n->
brushes; bref; bref = nextbref) {
2084 nextbref = bref->
next;
2086 if ( !CM_R_InsideAllChildren( n, bref->
b->
bounds ) ) {
2090 prevbref->
next = nextbref;
2155 for ( pref = node->
polygons; pref; pref = pref->
next) {
2158 for ( bref = node->
brushes; bref; bref = bref->
next) {
2182 if ( !cm_vertexHash ) {
2185 if ( !cm_edgeHash ) {
2189 if ( !cm_windingList ) {
2192 if ( !cm_outList ) {
2195 if ( !cm_tmpList ) {
2207 cm_vertexHash =
NULL;
2215 cm_windingList =
NULL;
2227 cm_vertexHash->
Clear();
2228 cm_edgeHash->
Clear();
2230 cm_modelBounds = bounds;
2231 max = bounds[1].x - bounds[0].x;
2232 f = bounds[1].y - bounds[0].y;
2265 x = (((
int) (vec[0] - cm_modelBounds[0].x + 0.5)) + 2) >> 2;
2266 y = (((
int) (vec[1] - cm_modelBounds[0].y + 0.5)) + 2) >> 2;
2267 z = (((
int) (vec[2] - cm_modelBounds[0].z + 0.5)) + 2) >> 2;
2280 for (i = 0; i < 3; i++) {
2289 for (vn = cm_vertexHash->
First( hashKey ); vn >= 0; vn = cm_vertexHash->
Next( vn ) ) {
2329 int v2num, hashKey, e;
2330 int found, *vertexNum;
2337 if ( v1num != -1 ) {
2343 found &=
GetVertex( model, v2, &v2num );
2345 if ( v1num == v2num ) {
2349 hashKey = cm_edgeHash->
GenerateKey( v1num, v2num );
2352 for (e = cm_edgeHash->
First( hashKey ); e >= 0; e = cm_edgeHash->
Next( e ) )
2360 if ( vertexNum[0] == v2num ) {
2361 if ( vertexNum[1] == v1num ) {
2387 oldEdges = model->
edges;
2417 int i,
j, edgeNum, v1num;
2425 for ( i = 0, j = 1; i < w->
GetNumPoints(); i++, j++ ) {
2429 GetEdge( model, (*w)[i].ToVec3(), (*w)[j].ToVec3(), &polyEdges[numPolyEdges], v1num );
2430 if ( polyEdges[numPolyEdges] ) {
2438 if ( numPolyEdges < 3 ) {
2442 for ( i = 0; i < numPolyEdges; i++ ) {
2443 for ( j = i+1; j < numPolyEdges; j++ ) {
2444 if ( abs(polyEdges[i]) == abs(polyEdges[j]) ) {
2451 common->
Warning(
"idCollisionModelManagerLocal::CreatePolygon: polygon has more than %d edges", numPolyEdges );
2464 for ( i = 0; i < numPolyEdges; i++ ) {
2465 edgeNum = polyEdges[
i];
2502 common->
Warning(
"idCollisionModelManagerLocal::PolygonFromWinding: model %s primitive %d is degenerate", model->
name.
c_str(), abs(primitiveNum) );
2527 for ( i = 0; i < mesh.
GetWidth() - 1; i++ ) {
2528 for ( j = 0; j < mesh.
GetHeight() - 1; j++ ) {
2535 d1 = mesh[
v2].xyz - mesh[
v1].xyz;
2536 d2 = mesh[
v3].xyz - mesh[
v1].xyz;
2540 dot = plane.
Distance( mesh[v4].xyz );
2563 d1 = mesh[
v3].xyz - mesh[
v1].xyz;
2564 d2 = mesh[v4].xyz - mesh[
v1].xyz;
2585 static void CM_EstimateVertsAndEdges(
const idMapEntity *mapEnt,
int *numVerts,
int *numEdges ) {
2588 *numVerts = *numEdges = 0;
2594 width =
static_cast<const idMapPatch*
>(mapPrim)->GetWidth();
2595 height =
static_cast<const idMapPatch*
>(mapPrim)->GetHeight();
2596 *numVerts += width *
height;
2597 *numEdges += (width-1) * height + width * (height-1) + (width-1) * (height-1);
2602 *numVerts += (
static_cast<const idMapBrush*
>(mapPrim)->GetNumSides() - 2) * 2;
2603 *numEdges += (
static_cast<const idMapBrush*
>(mapPrim)->GetNumSides() - 2) * 3;
2660 mapSide = mapBrush->
GetSide(i);
2705 for ( i = 0; i < mapBrush->
GetNumSides() - 1; i++ ) {
2706 mapSide = mapBrush->
GetSide(i);
2743 static int CM_CountNodeBrushes(
const cm_node_t *node ) {
2748 for ( bref = node->
brushes; bref; bref = bref->
next ) {
2764 for ( pref = node->
polygons; pref; pref = pref->
next ) {
2768 for ( bref = node->
brushes; bref; bref = bref->
next ) {
2775 CM_R_GetNodeBounds( bounds, node->
children[1] );
2787 CM_R_GetNodeBounds( bounds, node );
2805 for ( pref = node->
polygons; pref; pref = pref->
next ) {
2808 for ( bref = node->
brushes; bref; bref = bref->
next ) {
2831 for ( pref = node->
polygons; pref; pref = pref->
next ) {
2838 for ( i = 0; i < p->
numEdges; i++ ) {
2839 if ( p->
edges[i] < 0 ) {
2865 int i, newNumVertices, newNumEdges, *
v;
2872 for ( i = 0; i < model->
numEdges; i++ ) {
2880 remap[
i ] = newNumVertices;
2887 for ( i = 1; i < model->
numEdges; i++ ) {
2889 v[0] = remap[ v[0] ];
2890 v[1] = remap[ v[1] ];
2895 for ( i = 1; i < model->
numEdges; i++ ) {
2898 remap[
i ] = newNumEdges;
2912 if ( oldVertices ) {
2919 oldEdges = model->
edges;
2976 bool collisionSurface;
2981 if ( ( extension.
Icmp(
"ase" ) != 0 ) && ( extension.
Icmp(
"lwo" ) != 0 ) && ( extension.
Icmp(
"ma" ) != 0 ) ) {
2992 model->
name = fileName;
3004 collisionSurface =
false;
3005 for ( i = 0; i < renderModel->
NumSurfaces(); i++ ) {
3006 surf = renderModel->
Surface( i );
3008 collisionSurface =
true;
3012 for ( i = 0; i < renderModel->
NumSurfaces(); i++ ) {
3013 surf = renderModel->
Surface( i );
3038 for ( i = 0; i < renderModel->
NumSurfaces(); i++ ) {
3039 surf = renderModel->
Surface( i );
3101 name =
"unnamed inline model";
3127 ConvertBrush( model, static_cast<idMapBrush*>(mapPrim), i );
3133 brushCount = CM_CountNodeBrushes( model->
node );
3134 if ( brushCount > 4 ) {
3144 bounds[0].Set( -256, -256, -256 );
3145 bounds[1].Set( 256, 256, 256 );
3157 ConvertPatch( model, static_cast<idMapPatch*>(mapPrim), i );
3181 if ( !
models[i]->name.Icmp( name ) ) {
3186 if ( i < numModels ) {
3220 memset( model, 0,
sizeof( *model ) );
3248 if ( model == -1 ) {
3254 common->
Printf(
"idCollisionModelManagerLocal::ModelInfo: invalid model handle\n" );
3258 common->
Printf(
"idCollisionModelManagerLocal::ModelInfo: invalid model\n" );
3278 common->
Printf(
"%4d KB in %d models\n", (totalMemory>>10), numModels );
3343 if ( mapFile ==
NULL ) {
3344 common->
Error(
"idCollisionModelManagerLocal::LoadMap: NULL mapFile" );
3392 common->
Printf(
"idCollisionModelManagerLocal::GetModelBounds: invalid model handle\n" );
3406 common->
Printf(
"idCollisionModelManagerLocal::GetModelBounds: invalid model handle\n" );
3421 common->
Printf(
"idCollisionModelManagerLocal::GetModelContents: invalid model handle\n" );
3437 common->
Printf(
"idCollisionModelManagerLocal::GetModelVertex: invalid model handle\n" );
3441 if ( vertexNum < 0 || vertexNum >=
models[model]->numVertices ) {
3442 common->
Printf(
"idCollisionModelManagerLocal::GetModelVertex: invalid vertex number\n" );
3458 common->
Printf(
"idCollisionModelManagerLocal::GetModelEdge: invalid model handle\n" );
3462 edgeNum = abs( edgeNum );
3463 if ( edgeNum >=
models[model]->numEdges ) {
3464 common->
Printf(
"idCollisionModelManagerLocal::GetModelEdge: invalid edge number\n" );
3484 common->
Printf(
"idCollisionModelManagerLocal::GetModelPolygon: invalid model handle\n" );
3488 poly = *
reinterpret_cast<cm_polygon_t **
>(&polygonNum);
3490 for ( i = 0; i < poly->
numEdges; i++ ) {
3491 edgeNum = poly->
edges[
i];
3507 if ( handle >= 0 ) {
3512 common->
Error(
"idCollisionModelManagerLocal::LoadModel: no free slots\n" );
3519 if ( handle >= 0 ) {
3522 common->
Warning(
"idCollisionModelManagerLocal::LoadModel: collision file for '%s' contains different model", modelName );
3552 for ( pref = node->
polygons; pref; pref = pref->
next ) {
3570 for ( i = 0; i < p->
numEdges; i++ ) {
3598 common->
Printf(
"idCollisionModelManagerLocal::TrmFromModel: model %s has too many vertices.\n", model->
name.
c_str() );
3605 common->
Printf(
"idCollisionModelManagerLocal::TrmFromModel: model %s has too many edges.\n", model->
name.
c_str() );
3619 common->
Printf(
"idCollisionModelManagerLocal::TrmFromModel: model %s has too many polygons.\n", model->
name.
c_str() );
3632 for ( i = 0; i < model->
numEdges; i++ ) {
3640 memset( numEdgeUsers, 0,
sizeof(numEdgeUsers) );
3641 for ( i = 0; i < trm.
numPolys; i++ ) {
3643 numEdgeUsers[ abs( trm.
polys[i].
edges[j] ) ]++;
3646 for ( i = 1; i <= trm.
numEdges; i++ ) {
3647 if ( numEdgeUsers[i] != 2 ) {
3648 common->
Printf(
"idCollisionModelManagerLocal::TrmFromModel: model %s has dangling edges, the model has to be an enclosed hull.\n", model->
name.
c_str() );
3657 for ( i = 0; i < trm.
numPolys; i++ ) {
3659 for ( j = 0; j < trm.
numVerts; j++ ) {
3688 common->
Printf(
"idCollisionModelManagerLocal::TrmFromModel: model %s not found.\n", modelName );
int GetNumSides(void) const
void WriteCollisionModelsToFile(const char *filename, int firstModel, int lastModel, unsigned int mapFileCRC)
int HashVec(const idVec3 &vec)
const idPlane & GetPlane(void) const
void GetBounds(idBounds &bounds) const
void ResizeIndex(const int newIndexSize)
struct cm_vertex_s cm_vertex_t
struct cm_node_s * children[2]
const float DEFAULT_CURVE_MAX_ERROR_CD
idMapEntity * GetEntity(int i) const
void MergeTreePolygons(cm_model_t *model, cm_node_t *node)
cmHandle_t LoadModel(const char *modelName, const bool precache)
idHashIndex * cm_edgeHash
idStr & SetFileExtension(const char *extension)
cm_nodeBlock_t * nodeBlocks
unsigned int GetGeometryCRC(void) const
assert(prefInfo.fullscreenBtn)
bool MergePolygonWithTreePolygons(cm_model_t *model, cm_node_t *node, cm_polygon_t *polygon)
const idVec3 & Normal(void) const
idMapBrushSide * GetSide(int i) const
idVec3 GetCenter(void) const
int GetVertSubdivisions(void) const
void FreeBrushReference(cm_brushRef_t *bref)
int Next(const int index) const
void FreePolygonReference(cm_polygonRef_t *pref)
#define CONTINUOUS_EPSILON
GLdouble GLdouble GLint vn
cmHandle_t SetupTrmModel(const idTraceModel &trm, const idMaterial *material)
void FindInternalEdges(cm_model_t *model, cm_node_t *node)
traceModelVert_t verts[MAX_TRACEMODEL_VERTS]
void FreePolygon(cm_model_t *model, cm_polygon_t *poly)
ID_INLINE T Max(T x, T y)
float Distance(const idVec3 &v) const
int CM_GetNodeContents(cm_node_t *node)
int Parse1DMatrix(int x, float *m)
void RemoveBrushReferences_r(cm_node_t *node, cm_brush_t *b)
void ConvertBrushSides(cm_model_t *model, const idMapBrush *mapBrush, int primitiveNum)
cm_polygon_t * AllocPolygon(cm_model_t *model, int numEdges)
const char * GetModelName(cmHandle_t model) const
const idMaterial * shader
int SkipBracedSection(bool parseFirstBrace=true)
struct cm_nodeBlock_s * next
struct cm_polygonRef_s * next
void ModelInfo(cmHandle_t model)
int GetHorzSubdivisions(void) const
void RemovePolygonReferences_r(cm_node_t *node, cm_polygon_t *p)
const float * ToFloatPtr(void) const
const idMaterial * trmMaterial
const idMaterial * material
const char * GetMaterial(void) const
void FreeBrush(cm_model_t *model, cm_brush_t *brush)
GLuint GLuint GLsizei GLenum type
traceModelEdge_t edges[MAX_TRACEMODEL_EDGES+1]
cm_brushRefBlock_t * brushRefBlocks
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
cm_procNode_t * procNodes
void SetNormal(const idVec3 &normal)
double Milliseconds(void) const
idVec3 Cross(const idVec3 &a) const
cm_polygonRef_t * trmPolygons[MAX_TRACEMODEL_POLYS]
static float Rint(float f)
void PrintModelInfo(const cm_model_t *model)
void R_FilterPolygonIntoTree(cm_model_t *model, cm_node_t *node, cm_polygonRef_t *pref, cm_polygon_t *p)
#define REFERENCE_BLOCK_SIZE_LARGE
cm_polygonRef_t * nextRef
int Split(idFixedWinding *back, const idPlane &plane, const float epsilon=ON_EPSILON)
int Icmp(const char *text) const
void SubdivideExplicit(int horzSubdivisions, int vertSubdivisions, bool genNormals, bool removeLinear=false)
#define DEGENERATE_DIST_EPSILON
bool PointInsidePolygon(cm_model_t *model, cm_polygon_t *p, idVec3 &v)
void LoadProcBSP(const char *name)
int First(const int key) const
void ReplacePolygons(cm_model_t *model, cm_node_t *node, cm_polygon_t *p1, cm_polygon_t *p2, cm_polygon_t *newp)
int GetVertex(cm_model_t *model, const idVec3 &v, int *vertexNum)
#define VERTEX_HASH_BOXSIZE
int GetHeight(void) const
#define MAX_TRACEMODEL_POLYS
int R_ChoppedAwayByProcBSP(int nodeNum, idFixedWinding *w, const idVec3 &normal, const idVec3 &origin, const float radius)
void AccumulateModelInfo(cm_model_t *model)
bool AddPoint(const idVec3 &v)
GLfloat GLfloat GLfloat v2
struct cm_model_s cm_model_t
void Error(const char *str,...) id_attribute((format(printf
void CM_GetNodeBounds(idBounds *bounds, cm_node_t *node)
bool LoadCollisionModelFile(const char *name, unsigned int mapFileCRC)
GLuint GLuint GLsizei count
void Subdivide(float maxHorizontalError, float maxVerticalError, float maxLength, bool genNormals=false)
cm_model_t * AllocModel(void)
void FreeTree_r(cm_model_t *model, cm_node_t *headNode, cm_node_t *node)
#define NODE_BLOCK_SIZE_LARGE
int GetNumPoints(void) const
#define MAX_POINTS_ON_WINDING
void FinishModel(cm_model_t *model)
const char * GetString(const char *key, const char *defaultString="") const
GLubyte GLubyte GLubyte GLubyte w
struct cm_polygonRef_s cm_polygonRef_t
const cullType_t GetCullType(void) const
void SetDist(const float dist)
void ConvertPatch(cm_model_t *model, const idMapPatch *patch, int primitiveNum)
const idMaterial * material
bool GetModelPolygon(cmHandle_t model, int polygonNum, idFixedWinding &winding) const
cm_polygon_t * TryMergePolygons(cm_model_t *model, cm_polygon_t *p1, cm_polygon_t *p2)
int GetNumEntities(void) const
const float DEFAULT_CURVE_MAX_LENGTH_CD
cm_brushBlock_t * brushBlock
idFixedWinding * WindingOutsideBrushes(idFixedWinding *w, const idPlane &plane, int contents, int patch, cm_node_t *headNode)
int ChoppedAwayByProcBSP(const idFixedWinding &w, const idPlane &plane, int contents)
static float Fabs(float f)
#define INTSIGNBITNOTSET(i)
srfTriangles_t * geometry
ID_TIME_T GetFileTime(void) const
int edges[MAX_TRACEMODEL_POLYEDGES]
virtual idRenderModel * FindModel(const char *modelName)=0
void R_FilterBrushIntoTree(cm_model_t *model, cm_node_t *node, cm_brushRef_t *pref, cm_brush_t *b)
const int GetContentFlags(void) const
cm_polygonRef_t * AllocPolygonReference(cm_model_t *model, int blockSize)
void FreeModel(cm_model_t *model)
cm_node_t * R_CreateAxialBSPTree(cm_model_t *model, cm_node_t *node, const idBounds &bounds)
virtual const modelSurface_t * Surface(int surfaceNum) const =0
struct cm_polygonRefBlock_s * next
void GetPlane(idVec3 &normal, float &dist) const
virtual void virtual void FatalError(const char *fmt,...) id_attribute((format(printf
idCollisionModelManager * collisionModelManager
cm_polygonBlock_t * polygonBlock
const int GetSurfaceFlags(void) const
bool GetExplicitlySubdivided(void) const
struct cm_brush_s cm_brush_t
void AddBrushToNode(cm_model_t *model, cm_node_t *node, cm_brush_t *b)
int GetEdge(cm_model_t *model, const idVec3 &v1, const idVec3 &v2, int *edgeNum, int v1num)
void CalculateEdgeNormals(cm_model_t *model, cm_node_t *node)
void FindInternalEdgesOnPolygon(cm_model_t *model, cm_polygon_t *p1, cm_polygon_t *p2)
#define CM_MAX_POLYGON_EDGES
void RemapEdges(cm_node_t *node, int *edgeRemap)
void FindInternalPolygonEdges(cm_model_t *model, cm_node_t *node, cm_polygon_t *polygon)
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void FreeNode(cm_node_t *node)
float Normalize(bool fixDegenerate=true)
#define NODE_BLOCK_SIZE_SMALL
virtual idBounds Bounds(const struct renderEntity_s *ent=NULL) const =0
cm_node_t * AllocNode(cm_model_t *model, int blockSize)
void CreatePolygon(cm_model_t *model, idFixedWinding *w, const idPlane &plane, const idMaterial *material, int primitiveNum)
void SetupTrmModelStructure(void)
cm_windingList_t * cm_windingList
GLenum GLsizei GLsizei height
idDeclManager * declManager
int GenerateKey(const char *string, bool caseSensitive=true) const
bool GetModelBounds(cmHandle_t model, idBounds &bounds) const
struct cm_polygon_s cm_polygon_t
void AddPolygonToNode(cm_model_t *model, cm_node_t *node, cm_polygon_t *p)
int ExpectTokenString(const char *string)
#define MAX_TRACEMODEL_EDGES
idFixedWinding w[MAX_WINDING_LIST]
GLfloat GLfloat GLfloat GLfloat v3
cmHandle_t FindModel(const char *name)
bool GetModelEdge(cmHandle_t model, int edgeNum, idVec3 &start, idVec3 &end) const
idRenderModelManager * renderModelManager
cm_model_t * CollisionModelForMapEntity(const idMapEntity *mapEnt)
idMapPrimitive * GetPrimitive(int i) const
#define REFERENCE_BLOCK_SIZE_SMALL
void R_ChopWindingListWithTreeBrushes(cm_windingList_t *list, cm_node_t *node)
void FreeTrmModelStructure(void)
struct cm_brushRefBlock_s * next
cm_brushRef_t * AllocBrushReference(cm_model_t *model, int blockSize)
bool IsCleared(void) const
void PolygonFromWinding(cm_model_t *model, idFixedWinding *w, const idPlane &plane, const idMaterial *material, int primitiveNum)
bool TrmFromModel_r(idTraceModel &trm, cm_node_t *node)
void FindContainedEdges(cm_model_t *model, cm_polygon_t *p)
struct cm_node_s cm_node_t
bool ShouldCreateBackSides(void) const
struct cm_node_s * parent
void BaseForPlane(const idVec3 &normal, const float dist)
bool GetModelVertex(cmHandle_t model, int vertexNum, idVec3 &vertex) const
struct cm_brushRef_s * next
void OptimizeArrays(cm_model_t *model)
void * Mem_ClearedAlloc(const int size)
const char * GetMaterial(void) const
const char * c_str(void) const
traceModelPoly_t polys[MAX_TRACEMODEL_POLYS]
int GenerateEdgeNormals(void)
idHashIndex * cm_vertexHash
#define MAX_TRACEMODEL_VERTS
void Add(const int key, const int index)
void * Mem_Alloc(const int size)
idCollisionModelManagerLocal collisionModelManagerLocal
float dot(float a[], float b[])
virtual idRenderModel * CheckModel(const char *modelName)=0
cm_windingList_t * cm_outList
void ChopWindingListWithBrush(cm_windingList_t *list, cm_brush_t *b)
struct cm_brushRef_s cm_brushRef_t
if(!ValidDisplayID(prefInfo.prefDisplayID)) prefInfo.prefDisplayID
void CreatePatchPolygons(cm_model_t *model, idSurface_Patch &mesh, const idMaterial *material, int primitiveNum)
#define MAX_TRACEMODEL_POLYEDGES
bool FixDegeneracies(float distEpsilon)
bool TrmFromModel(const char *modelName, idTraceModel &trm)
#define MAX_NODE_POLYGONS
void ConvertBrush(cm_model_t *model, const idMapBrush *mapBrush, int primitiveNum)
void ExtractFileExtension(idStr &dest) const
int PlaneSide(const idPlane &plane, const float epsilon=ON_EPSILON) const
cm_windingList_t * cm_tmpList
cm_polygonRef_t * polygons
cm_polygonRefBlock_t * polygonRefBlocks
virtual void DPrintf(const char *fmt,...) id_attribute((format(printf
virtual void Error(const char *fmt,...) id_attribute((format(printf
void LoadMap(const idMapFile *mapFile)
int GetNumPrimitives(void) const
cm_node_t * CreateAxialBSPTree(cm_model_t *model, cm_node_t *node)
void ClearHash(idBounds &bounds)
bool ClipInPlace(const idPlane &plane, const float epsilon=ON_EPSILON, const bool keepOn=false)
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
const char * GetName(void) const
cm_model_t * LoadRenderModel(const char *fileName)
bool GetModelContents(cmHandle_t model, int &contents) const
int ReadToken(idToken *token)
#define TRACE_MODEL_HANDLE
void BuildModels(const idMapFile *mapFile)
struct cm_windingList_s cm_windingList_t
void ParseProcNodes(idLexer *src)
void FitThroughPoint(const idVec3 &p)
cm_brushRef_t * trmBrushes[1]
cm_brush_t * AllocBrush(cm_model_t *model, int numPlanes)
virtual int NumSurfaces() const =0