This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/engine/common/cm_test.c

194 lines
4.1 KiB
C

//=======================================================================
// Copyright XashXT Group 2007 ©
// cm_trace.c - combined tracing
//=======================================================================
#include "cm_local.h"
#include "mathlib.h"
#include "world.h"
/*
==================
CM_PointInLeaf
==================
*/
mleaf_t *CM_PointInLeaf( const vec3_t p, mnode_t *node )
{
mleaf_t *leaf;
// find which leaf the point is in
while( node->plane )
node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct(p, node->plane->normal)) < node->plane->dist];
leaf = (mleaf_t *)node;
return leaf;
}
int CM_PointLeafnum( const vec3_t p )
{
// map not loaded
if ( !worldmodel ) return 0;
return CM_PointInLeaf( p, worldmodel->nodes ) - worldmodel->leafs - 1;
}
/*
======================================================================
LEAF LISTING
======================================================================
*/
void CM_BoxLeafnums_r( leaflist_t *ll, mnode_t *node )
{
mplane_t *plane;
int s;
while( 1 )
{
if( node->contents == CONTENTS_SOLID )
return;
if( node->contents < 0 )
{
mleaf_t *leaf = (mleaf_t *)node;
// it's a leaf!
if( ll->count >= ll->maxcount )
{
ll->overflowed = true;
return;
}
ll->list[ll->count++] = leaf - worldmodel->leafs - 1;
return;
}
plane = node->plane;
s = BOX_ON_PLANE_SIDE( ll->mins, ll->maxs, plane );
if( s == 1 )
{
node = node->children[0];
}
else if( s == 2 )
{
node = node->children[1];
}
else
{
// go down both
if( ll->topnode == -1 )
ll->topnode = node - worldmodel->nodes;
CM_BoxLeafnums_r( ll, node->children[0] );
node = node->children[1];
}
}
}
/*
==================
CM_BoxLeafnums
==================
*/
int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, short *list, int listsize, int *topnode )
{
leaflist_t ll;
if( !worldmodel ) return 0;
cm.checkcount++;
VectorCopy( mins, ll.mins );
VectorCopy( maxs, ll.maxs );
ll.count = 0;
ll.maxcount = listsize;
ll.list = list;
ll.topnode = -1;
ll.overflowed = false;
CM_BoxLeafnums_r( &ll, worldmodel->nodes );
if( topnode ) *topnode = ll.topnode;
return ll.count;
}
/*
=============
CM_BoxVisible
Returns true if any leaf in boxspace
is potentially visible
=============
*/
qboolean CM_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits )
{
short leafList[MAX_BOX_LEAFS];
int i, count;
if( !visbits || !mins || !maxs )
return true;
// FIXME: Could save a loop here by traversing the tree in this routine like the code above
count = CM_BoxLeafnums( mins, maxs, leafList, MAX_BOX_LEAFS, NULL );
for( i = 0; i < count; i++ )
{
int leafnum = leafList[i];
if( visbits[leafnum>>3] & (1<<( leafnum & 7 )))
return true;
}
return false;
}
/*
===============================================================================
POINT TESTING IN HULLS
===============================================================================
*/
/*
==================
CM_HullPointContents
==================
*/
int CM_HullPointContents( hull_t *hull, int num, const vec3_t p )
{
while( num >= 0 )
num = hull->clipnodes[num].children[(hull->planes[hull->clipnodes[num].planenum].type < 3 ? p[hull->planes[hull->clipnodes[num].planenum].type] : DotProduct (hull->planes[hull->clipnodes[num].planenum].normal, p)) < hull->planes[hull->clipnodes[num].planenum].dist];
return num;
}
/*
==================
CM_PointContents
==================
*/
int CM_PointContents( const vec3_t p )
{
if( !worldmodel ) return 0;
return CM_HullPointContents( &worldmodel->hulls[0], 0, p );
}
/*
==================
CM_AmbientLevels
grab the ambient sound levels for current point
==================
*/
void CM_AmbientLevels( const vec3_t p, byte *pvolumes )
{
mleaf_t *leaf;
if( !worldmodel || !p || !pvolumes )
return;
leaf = CM_PointInLeaf( p, worldmodel->nodes );
*(int *)pvolumes = *(int *)leaf->ambient_sound_level;
}