mirror of
https://github.com/ioquake/ioq3.git
synced 2025-05-31 00:51:17 +00:00
121 lines
2.5 KiB
C
121 lines
2.5 KiB
C
#include "tr_local.h"
|
|
#include "tr_cvar.h"
|
|
#include "tr_globals.h"
|
|
/*
|
|
=================
|
|
|
|
Returns CULL_IN, CULL_CLIP, or CULL_OUT
|
|
=================
|
|
*/
|
|
int R_CullLocalBox (vec3_t bounds[2])
|
|
{
|
|
int i, j;
|
|
vec3_t transformed[8];
|
|
float dists[8];
|
|
vec3_t v;
|
|
cplane_t *frust;
|
|
int anyBack;
|
|
int front, back;
|
|
|
|
if ( r_nocull->integer ) {
|
|
return CULL_CLIP;
|
|
}
|
|
|
|
// transform into world space
|
|
for (i = 0 ; i < 8 ; i++) {
|
|
v[0] = bounds[i&1][0];
|
|
v[1] = bounds[(i>>1)&1][1];
|
|
v[2] = bounds[(i>>2)&1][2];
|
|
|
|
VectorCopy( tr.or.origin, transformed[i] );
|
|
VectorMA( transformed[i], v[0], tr.or.axis[0], transformed[i] );
|
|
VectorMA( transformed[i], v[1], tr.or.axis[1], transformed[i] );
|
|
VectorMA( transformed[i], v[2], tr.or.axis[2], transformed[i] );
|
|
}
|
|
|
|
// check against frustum planes
|
|
anyBack = 0;
|
|
for (i = 0 ; i < 4 ; i++) {
|
|
frust = &tr.viewParms.frustum[i];
|
|
|
|
front = back = 0;
|
|
for (j = 0 ; j < 8 ; j++) {
|
|
dists[j] = DotProduct(transformed[j], frust->normal);
|
|
if ( dists[j] > frust->dist ) {
|
|
front = 1;
|
|
if ( back ) {
|
|
break; // a point is in front
|
|
}
|
|
} else {
|
|
back = 1;
|
|
}
|
|
}
|
|
if ( !front ) {
|
|
// all points were behind one of the planes
|
|
return CULL_OUT;
|
|
}
|
|
anyBack |= back;
|
|
}
|
|
|
|
if ( !anyBack ) {
|
|
return CULL_IN; // completely inside frustum
|
|
}
|
|
|
|
return CULL_CLIP; // partially clipped
|
|
}
|
|
|
|
|
|
static void R_LocalPointToWorld (vec3_t local, const orientationr_t * const pRT, vec3_t world)
|
|
{
|
|
world[0] = local[0] * pRT->axis[0][0] + local[1] * pRT->axis[1][0] + local[2] * pRT->axis[2][0] + pRT->origin[0];
|
|
world[1] = local[0] * pRT->axis[0][1] + local[1] * pRT->axis[1][1] + local[2] * pRT->axis[2][1] + pRT->origin[1];
|
|
world[2] = local[0] * pRT->axis[0][2] + local[1] * pRT->axis[1][2] + local[2] * pRT->axis[2][2] + pRT->origin[2];
|
|
}
|
|
|
|
|
|
int R_CullLocalPointAndRadius( vec3_t pt, float radius )
|
|
{
|
|
vec3_t transformed;
|
|
|
|
R_LocalPointToWorld( pt, &tr.or, transformed );
|
|
|
|
return R_CullPointAndRadius( transformed, radius );
|
|
}
|
|
|
|
/*
|
|
** R_CullPointAndRadius
|
|
*/
|
|
int R_CullPointAndRadius( vec3_t pt, float radius )
|
|
{
|
|
int i;
|
|
float dist;
|
|
cplane_t *frust;
|
|
qboolean mightBeClipped = qfalse;
|
|
|
|
if ( r_nocull->integer ) {
|
|
return CULL_CLIP;
|
|
}
|
|
|
|
// check against frustum planes
|
|
for (i = 0 ; i < 4 ; i++)
|
|
{
|
|
frust = &tr.viewParms.frustum[i];
|
|
|
|
dist = DotProduct( pt, frust->normal) - frust->dist;
|
|
if ( dist < -radius )
|
|
{
|
|
return CULL_OUT;
|
|
}
|
|
else if ( dist <= radius )
|
|
{
|
|
mightBeClipped = qtrue;
|
|
}
|
|
}
|
|
|
|
if ( mightBeClipped )
|
|
{
|
|
return CULL_CLIP;
|
|
}
|
|
|
|
return CULL_IN; // completely inside frustum
|
|
}
|