/* ============= CM_BoxLeafnums Fills in a list of all the leafs touched ============= */ void CM_BoxLeafnums_r( leafList_t *ll, int nodenum ) { cplane_t *plane; cNode_t *node; int s; while ( 1 ) { if ( nodenum < 0 ) { ll->storeLeafs( ll, nodenum ); return; } node = &cm.nodes[nodenum]; plane = node->plane; s = BoxOnPlaneSide( ll->bounds[0], ll->bounds[1], plane ); if ( s == 1 ) { nodenum = node->children[0]; } else if ( s == 2 ) { nodenum = node->children[1]; } else { // go down both CM_BoxLeafnums_r( ll, node->children[0] ); nodenum = node->children[1]; } } }
/* ================== CM_BoxBrushes ================== */ int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **list, int listsize ) { leafList_t ll; cm.checkcount++; VectorCopy( mins, ll.bounds[0] ); VectorCopy( maxs, ll.bounds[1] ); ll.count = 0; ll.maxcount = listsize; ll.list = (void *)list; ll.storeLeafs = CM_StoreBrushes; ll.lastLeaf = 0; ll.overflowed = qfalse; CM_BoxLeafnums_r( &ll, 0 ); return ll.count; }
/* ================== CM_BoxLeafnums ================== */ int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsize, int *lastLeaf ) { leafList_t ll; cm.checkcount++; VectorCopy( mins, ll.bounds[ 0 ] ); VectorCopy( maxs, ll.bounds[ 1 ] ); ll.count = 0; ll.maxcount = listsize; ll.list = list; ll.storeLeafs = CM_StoreLeafs; ll.lastLeaf = 0; ll.overflowed = false; CM_BoxLeafnums_r( &ll, 0 ); *lastLeaf = ll.lastLeaf; return ll.count; }
void CM_PositionTest(traceWork_t *tw) { int leafs[MAX_POSITION_LEAFS]; int i; leafList_t ll; // identify the leafs we are touching VectorAdd(tw->start, tw->size[0], ll.bounds[0]); VectorAdd(tw->start, tw->size[1], ll.bounds[1]); for (i = 0 ; i < 3 ; i++) { ll.bounds[0][i] -= 1; ll.bounds[1][i] += 1; } ll.count = 0; ll.maxcount = MAX_POSITION_LEAFS; ll.list = leafs; ll.storeLeafs = CM_StoreLeafs; ll.lastLeaf = 0; ll.overflowed = qfalse; cm.checkcount++; CM_BoxLeafnums_r(&ll, 0); cm.checkcount++; // test the contents of the leafs for (i = 0 ; i < ll.count ; i++) { CM_TestInLeaf(tw, &cm.leafs[leafs[i]]); if (tw->trace.allsolid) { break; } } }
/* ================ CM_TestInLeaf ================ */ void CM_TestInLeaf( traceWork_t *tw, cLeaf_t *leaf, clipMap_t *local ) { int k; int brushnum; cbrush_t *b; cPatch_t *patch; // test box position against all brushes in the leaf for (k=0 ; k<leaf->numLeafBrushes ; k++) { brushnum = local->leafbrushes[leaf->firstLeafBrush+k]; b = &local->brushes[brushnum]; if (b->checkcount == local->checkcount) { continue; // already checked this brush in another leaf } b->checkcount = local->checkcount; if ( !(b->contents & tw->contents)) { continue; } #ifndef BSPC #ifndef _XBOX // Removing terrain from Xbox if (com_terrainPhysics->integer && cmg.landScape && (b->contents & CONTENTS_TERRAIN) ) { // Invalidate the checkcount for terrain as the terrain brush has to be processed // many times. b->checkcount--; CM_TraceThroughTerrain( tw, tw->trace, b ); // If inside a terrain brush don't bother with regular brush collision continue; } #endif #endif CM_TestBoxInBrush( tw, b ); if ( tw->trace.allsolid ) { return; } } // test against all patches #ifdef BSPC if (1) { #else if ( !cm_noCurves->integer ) { #endif //BSPC for ( k = 0 ; k < leaf->numLeafSurfaces ; k++ ) { #ifdef _XBOX int index = CM_GetSurfaceIndex(leaf->firstLeafSurface + k); patch = cmg.surfaces[ index ]; #else patch = local->surfaces[ local->leafsurfaces[ leaf->firstLeafSurface + k ] ]; #endif if ( !patch ) { continue; } if ( patch->checkcount == local->checkcount ) { continue; // already checked this brush in another leaf } patch->checkcount = local->checkcount; if ( !(patch->contents & tw->contents)) { continue; } if ( CM_PositionTestInPatchCollide( tw, patch->pc ) ) { tw->trace.startsolid = tw->trace.allsolid = qtrue; tw->trace.fraction = 0; tw->trace.contents = patch->contents; return; } } } } /* ================== CM_PositionTest ================== */ #define MAX_POSITION_LEAFS 1024 void CM_PositionTest( traceWork_t *tw ) { int leafs[MAX_POSITION_LEAFS]; int i; leafList_t ll; // identify the leafs we are touching VectorAdd( tw->start, tw->size[0], ll.bounds[0] ); VectorAdd( tw->start, tw->size[1], ll.bounds[1] ); for (i=0 ; i<3 ; i++) { ll.bounds[0][i] -= 1; ll.bounds[1][i] += 1; } ll.count = 0; ll.maxcount = MAX_POSITION_LEAFS; ll.list = leafs; ll.storeLeafs = CM_StoreLeafs; ll.lastLeaf = 0; ll.overflowed = qfalse; cmg.checkcount++; CM_BoxLeafnums_r( &ll, 0 ); cmg.checkcount++; // test the contents of the leafs for (i=0 ; i < ll.count ; i++) { CM_TestInLeaf( tw, &cmg.leafs[leafs[i]], &cmg ); if ( tw->trace.allsolid ) { break; } } }