ioq3/code/renderervk/tr_Cull.c
Trung Lê 15ff484715
Add vulkan renderer
Copied from vkQuake3 which is in turn based on Quake III Kenny Edition
2025-03-14 00:31:15 +11:00

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
}