engine: hack mnode_t struct so we can have 24-bit face and children indices to support BSP2 format in runtime
This commit is contained in:
parent
ced8744ac9
commit
47aff9e30b
19 changed files with 388 additions and 181 deletions
|
@ -159,13 +159,31 @@ typedef struct mnode_s
|
|||
|
||||
// node specific
|
||||
mplane_t *plane;
|
||||
struct mnode_s *children[2];
|
||||
#ifdef SUPPORT_BSP2_FORMAT
|
||||
int firstsurface;
|
||||
int numsurfaces;
|
||||
|
||||
#if !XASH_64BIT
|
||||
union
|
||||
{
|
||||
struct mnode_s *children_[2];
|
||||
struct
|
||||
{
|
||||
// the ordering is important
|
||||
int child_0_leaf : 1;
|
||||
int child_0_off : 23;
|
||||
int firstsurface_1 : 8;
|
||||
int child_1_leaf : 1;
|
||||
int child_1_off : 23;
|
||||
int numsurfaces_1 : 8;
|
||||
};
|
||||
};
|
||||
unsigned short firstsurface_0;
|
||||
unsigned short numsurfaces_0;
|
||||
#else
|
||||
unsigned short firstsurface;
|
||||
unsigned short numsurfaces;
|
||||
// in 64-bit ABI this struct has 4 more bytes of padding, let's use it!
|
||||
struct mnode_s *children_[2];
|
||||
unsigned short firstsurface_0;
|
||||
unsigned short numsurfaces_0;
|
||||
unsigned short firstsurface_1;
|
||||
unsigned short numsurfaces_1;
|
||||
#endif
|
||||
} mnode_t;
|
||||
|
||||
|
@ -206,7 +224,6 @@ typedef struct mleaf_s
|
|||
int nummarksurfaces;
|
||||
int cluster; // helper to acess to uncompressed visdata
|
||||
byte ambient_sound_level[NUM_AMBIENTS];
|
||||
|
||||
} mleaf_t;
|
||||
|
||||
// surface extradata
|
||||
|
@ -566,16 +583,68 @@ typedef struct
|
|||
#define ANIM_CYCLE 2
|
||||
#define MOD_FRAMES 20
|
||||
|
||||
|
||||
|
||||
#define MAX_DEMOS 32
|
||||
#define MAX_MOVIES 8
|
||||
#define MAX_CDTRACKS 32
|
||||
#define MAX_CLIENT_SPRITES 512 // SpriteTextures (0-256 hud, 256-512 client)
|
||||
#define MAX_REQUESTS 64
|
||||
|
||||
STATIC_CHECK_SIZEOF( mnode_t, 52, 72 );
|
||||
STATIC_CHECK_SIZEOF( mextrasurf_t, 324, 496 );
|
||||
STATIC_CHECK_SIZEOF( decal_t, 60, 88 );
|
||||
STATIC_CHECK_SIZEOF( mfaceinfo_t, 176, 304 );
|
||||
|
||||
// model flags (stored in model_t->flags)
|
||||
#define MODEL_QBSP2 BIT( 28 ) // uses 32-bit types
|
||||
|
||||
// access functions
|
||||
static inline mnode_t *node_child( const mnode_t *n, int side, const model_t *mod )
|
||||
{
|
||||
#if !XASH_64BIT
|
||||
if( unlikely( mod->flags & MODEL_QBSP2 )) // MODEL_QBSP2
|
||||
{
|
||||
if( side == 0 )
|
||||
{
|
||||
if( n->child_0_leaf )
|
||||
return (mnode_t *)(mod->leafs + n->child_0_off);
|
||||
else
|
||||
return (mnode_t *)(mod->nodes + n->child_0_off);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( n->child_1_leaf )
|
||||
return (mnode_t *)(mod->leafs + n->child_1_off);
|
||||
else
|
||||
return (mnode_t *)(mod->nodes + n->child_1_off);
|
||||
}
|
||||
}
|
||||
|
||||
return n->children_[side];
|
||||
#else
|
||||
return n->children_[side];
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void node_children( mnode_t *children[2], const mnode_t *n, const model_t *mod )
|
||||
{
|
||||
children[0] = node_child( n, 0, mod );
|
||||
children[1] = node_child( n, 1, mod );
|
||||
}
|
||||
|
||||
static inline int node_firstsurface( const mnode_t *n, const model_t *mod )
|
||||
{
|
||||
if( mod->flags & MODEL_QBSP2 )
|
||||
return n->firstsurface_0 + ( n->firstsurface_1 << 16 );
|
||||
else
|
||||
return n->firstsurface_0;
|
||||
}
|
||||
|
||||
static inline int node_numsurfaces( const mnode_t *n, const model_t *mod )
|
||||
{
|
||||
if( mod->flags & MODEL_QBSP2 )
|
||||
return n->numsurfaces_0 + ( n->numsurfaces_1 << 16 );
|
||||
else
|
||||
return n->numsurfaces_0;
|
||||
}
|
||||
|
||||
#endif//COM_MODEL_H
|
||||
|
|
|
@ -127,8 +127,10 @@ static void R_SplitEntityOnNode( mnode_t *node )
|
|||
}
|
||||
|
||||
// recurse down the contacted sides
|
||||
if( sides & 1 ) R_SplitEntityOnNode( node->children[0] );
|
||||
if( sides & 2 ) R_SplitEntityOnNode( node->children[1] );
|
||||
if( sides & 1 )
|
||||
R_SplitEntityOnNode( node_child( node, 0, cl.worldmodel ));
|
||||
if( sides & 2 )
|
||||
R_SplitEntityOnNode( node_child( node, 1, cl.worldmodel ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -466,8 +466,8 @@ static void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int show
|
|||
R_DrawNodeConnection( x, y, x + scale, y + scale );
|
||||
}
|
||||
|
||||
R_ShowTree_r( node->children[1], x - scale, y + scale, downScale, shownodes, viewleaf );
|
||||
R_ShowTree_r( node->children[0], x + scale, y + scale, downScale, shownodes, viewleaf );
|
||||
R_ShowTree_r( node_child( node, 1, cl.worldmodel ), x - scale, y + scale, downScale, shownodes, viewleaf );
|
||||
R_ShowTree_r( node_child( node, 0, cl.worldmodel ), x + scale, y + scale, downScale, shownodes, viewleaf );
|
||||
|
||||
world.recursion_level--;
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ static void R_ShowTree( void )
|
|||
return;
|
||||
|
||||
world.recursion_level = 0;
|
||||
viewleaf = Mod_PointInLeaf( refState.vieworg, cl.worldmodel->nodes );
|
||||
viewleaf = Mod_PointInLeaf( refState.vieworg, cl.worldmodel->nodes, cl.worldmodel );
|
||||
|
||||
ref.dllFuncs.TriRenderMode( kRenderTransTexture );
|
||||
|
||||
|
|
|
@ -300,6 +300,12 @@ static qboolean R_Init_Video_( const int type )
|
|||
return R_Init_Video( type );
|
||||
}
|
||||
|
||||
static mleaf_t *pfnMod_PointInLeaf( const vec3_t p, mnode_t *node )
|
||||
{
|
||||
// FIXME: get rid of this on next RefAPI update
|
||||
return Mod_PointInLeaf( p, node, cl.models[1] );
|
||||
}
|
||||
|
||||
static const ref_api_t gEngfuncs =
|
||||
{
|
||||
pfnEngineGetParm,
|
||||
|
@ -340,7 +346,7 @@ static const ref_api_t gEngfuncs =
|
|||
|
||||
Mod_SampleSizeForFace,
|
||||
Mod_BoxVisible,
|
||||
Mod_PointInLeaf,
|
||||
pfnMod_PointInLeaf,
|
||||
R_DrawWorldHull,
|
||||
R_DrawModelHull,
|
||||
|
||||
|
|
|
@ -996,7 +996,7 @@ static void S_UpdateAmbientSounds( void )
|
|||
// calc ambient sound levels
|
||||
if( !cl.worldmodel ) return;
|
||||
|
||||
leaf = Mod_PointInLeaf( s_listener.origin, cl.worldmodel->nodes );
|
||||
leaf = Mod_PointInLeaf( s_listener.origin, cl.worldmodel->nodes, cl.worldmodel );
|
||||
|
||||
if( !leaf || !s_ambient_level.value )
|
||||
{
|
||||
|
|
|
@ -856,7 +856,7 @@ Mod_PointInLeaf
|
|||
|
||||
==================
|
||||
*/
|
||||
mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node )
|
||||
mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node, model_t *mod )
|
||||
{
|
||||
Assert( node != NULL );
|
||||
|
||||
|
@ -864,7 +864,7 @@ mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node )
|
|||
{
|
||||
if( node->contents < 0 )
|
||||
return (mleaf_t *)node;
|
||||
node = node->children[PlaneDiff( p, node->plane ) <= 0];
|
||||
node = node_child( node, PlaneDiff( p, node->plane ) <= 0, mod );
|
||||
}
|
||||
|
||||
// never reached
|
||||
|
@ -885,7 +885,7 @@ byte *Mod_GetPVSForPoint( const vec3_t p )
|
|||
|
||||
ASSERT( worldmodel != NULL );
|
||||
|
||||
leaf = Mod_PointInLeaf( p, worldmodel->nodes );
|
||||
leaf = Mod_PointInLeaf( p, worldmodel->nodes, worldmodel );
|
||||
|
||||
if( leaf && leaf->cluster >= 0 )
|
||||
return Mod_DecompressPVS( leaf->compressed_vis, world.visbytes );
|
||||
|
@ -905,14 +905,14 @@ static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *v
|
|||
float d = PlaneDiff( org, node->plane );
|
||||
|
||||
if( d > radius )
|
||||
node = node->children[0];
|
||||
node = node_child( node, 0, worldmodel );
|
||||
else if( d < -radius )
|
||||
node = node->children[1];
|
||||
node = node_child( node, 1, worldmodel );
|
||||
else
|
||||
{
|
||||
// go down both sides
|
||||
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, visbytes, node->children[0], phs );
|
||||
node = node->children[1];
|
||||
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, visbytes, node_child( node, 0, worldmodel ), phs );
|
||||
node = node_child( node, 1, worldmodel );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -950,7 +950,7 @@ int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, q
|
|||
|
||||
ASSERT( worldmodel != NULL );
|
||||
|
||||
leaf = Mod_PointInLeaf( org, worldmodel->nodes );
|
||||
leaf = Mod_PointInLeaf( org, worldmodel->nodes, worldmodel );
|
||||
bytes = Q_min( bytes, visbytes );
|
||||
|
||||
// enable full visibility for some reasons
|
||||
|
@ -1009,20 +1009,16 @@ static void Mod_BoxLeafnums_r( leaflist_t *ll, mnode_t *node )
|
|||
sides = BOX_ON_PLANE_SIDE( ll->mins, ll->maxs, node->plane );
|
||||
|
||||
if( sides == 1 )
|
||||
{
|
||||
node = node->children[0];
|
||||
}
|
||||
node = node_child( node, 0, worldmodel );
|
||||
else if( sides == 2 )
|
||||
{
|
||||
node = node->children[1];
|
||||
}
|
||||
node = node_child( node, 1, worldmodel );
|
||||
else
|
||||
{
|
||||
// go down both
|
||||
if( ll->topnode == -1 )
|
||||
ll->topnode = node - worldmodel->nodes;
|
||||
Mod_BoxLeafnums_r( ll, node->children[0] );
|
||||
node = node->children[1];
|
||||
Mod_BoxLeafnums_r( ll, node_child( node, 0, worldmodel ));
|
||||
node = node_child( node, 1, worldmodel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1079,35 +1075,6 @@ qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbi
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Mod_HeadnodeVisible
|
||||
=============
|
||||
*/
|
||||
qboolean Mod_HeadnodeVisible( mnode_t *node, const byte *visbits, int *lastleaf )
|
||||
{
|
||||
if( !node || node->contents == CONTENTS_SOLID )
|
||||
return false;
|
||||
|
||||
if( node->contents < 0 )
|
||||
{
|
||||
if( !CHECKVISBIT( visbits, ((mleaf_t *)node)->cluster ))
|
||||
return false;
|
||||
|
||||
if( lastleaf )
|
||||
*lastleaf = ((mleaf_t *)node)->cluster;
|
||||
return true;
|
||||
}
|
||||
|
||||
if( Mod_HeadnodeVisible( node->children[0], visbits, lastleaf ))
|
||||
return true;
|
||||
|
||||
if( Mod_HeadnodeVisible( node->children[1], visbits, lastleaf ))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_FindModelOrigin
|
||||
|
@ -1562,13 +1529,15 @@ static void Mod_CreateFaceBevels( model_t *mod, msurface_t *surf, const dbspmode
|
|||
Mod_SetParent
|
||||
=================
|
||||
*/
|
||||
static void Mod_SetParent( mnode_t *node, mnode_t *parent )
|
||||
static void Mod_SetParent( model_t *mod, mnode_t *node, mnode_t *parent )
|
||||
{
|
||||
node->parent = parent;
|
||||
|
||||
if( node->contents < 0 ) return; // it's leaf
|
||||
Mod_SetParent( node->children[0], node );
|
||||
Mod_SetParent( node->children[1], node );
|
||||
if( node->contents < 0 )
|
||||
return; // it's leaf
|
||||
|
||||
Mod_SetParent( mod, node_child( node, 0, mod ), node );
|
||||
Mod_SetParent( mod, node_child( node, 1, mod ), node );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1686,11 +1655,12 @@ static void Mod_MakeHull0( model_t *mod, const dbspmodel_t *bmod )
|
|||
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
mnode_t *child = in->children[j];
|
||||
mnode_t *child = node_child( in, j, mod );
|
||||
|
||||
if( child->contents < 0 )
|
||||
out->children[j] = child->contents;
|
||||
else out->children[j] = child - mod->nodes;
|
||||
else
|
||||
out->children[j] = child - mod->nodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1709,11 +1679,12 @@ static void Mod_MakeHull0( model_t *mod, const dbspmodel_t *bmod )
|
|||
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
mnode_t *child = in->children[j];
|
||||
mnode_t *child = node_child( in, j, mod );
|
||||
|
||||
if( child->contents < 0 )
|
||||
out->children[j] = child->contents;
|
||||
else out->children[j] = child - mod->nodes;
|
||||
else
|
||||
out->children[j] = child - mod->nodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1848,6 +1819,7 @@ for embedded submodels
|
|||
static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
|
||||
{
|
||||
qboolean colored = false;
|
||||
qboolean qbsp2 = false;
|
||||
poolhandle_t mempool;
|
||||
char *ents;
|
||||
dmodel_t *bm;
|
||||
|
@ -1859,6 +1831,9 @@ static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
|
|||
if( FBitSet( mod->flags, MODEL_COLORED_LIGHTING ))
|
||||
colored = true;
|
||||
|
||||
if( FBitSet( mod->flags, MODEL_QBSP2 ))
|
||||
qbsp2 = true;
|
||||
|
||||
mod->numframes = 2; // regular and alternate animation
|
||||
|
||||
// set up the submodels
|
||||
|
@ -1892,6 +1867,7 @@ static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
|
|||
|
||||
// this bit will be shared between all the submodels include worldmodel
|
||||
if( colored ) SetBits( mod->flags, MODEL_COLORED_LIGHTING );
|
||||
if( qbsp2 ) SetBits( mod->flags, MODEL_QBSP2 );
|
||||
|
||||
if( i != 0 )
|
||||
{
|
||||
|
@ -3075,16 +3051,62 @@ static void Mod_LoadNodes( model_t *mod, dbspmodel_t *bmod )
|
|||
out->minmaxs[j+3] = in->maxs[j];
|
||||
}
|
||||
|
||||
#if !XASH_64BIT
|
||||
if( in->firstface >= BIT( 24 ))
|
||||
{
|
||||
Host_Error( "%s: face index limit exceeded on node %i\n", __func__, i );
|
||||
return;
|
||||
}
|
||||
|
||||
if( in->numfaces >= BIT( 24 ))
|
||||
{
|
||||
Host_Error( "%s: face count limit exceeded on node %i\n", __func__, i );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
p = in->planenum;
|
||||
out->plane = mod->planes + p;
|
||||
out->firstsurface = in->firstface;
|
||||
out->numsurfaces = in->numfaces;
|
||||
out->firstsurface_0 = in->firstface & 0xFFFF;
|
||||
out->numsurfaces_0 = in->numfaces & 0xFFFF;
|
||||
|
||||
out->firstsurface_1 = in->firstface >> 16;
|
||||
out->numsurfaces_1 = in->numfaces >> 16;
|
||||
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
p = in->children[j];
|
||||
if( p >= 0 ) out->children[j] = mod->nodes + p;
|
||||
else out->children[j] = (mnode_t *)(mod->leafs + ( -1 - p ));
|
||||
#if XASH_64BIT
|
||||
if( p >= 0 ) out->children_[j] = mod->nodes + p;
|
||||
else out->children_[j] = (mnode_t *)(mod->leafs + ( -1 - p ));
|
||||
#else
|
||||
if( j == 0 )
|
||||
{
|
||||
if( p >= 0 )
|
||||
{
|
||||
out->child_0_leaf = 0;
|
||||
out->child_0_off = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->child_0_leaf = 1;
|
||||
out->child_0_off = -1 - p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p >= 0 )
|
||||
{
|
||||
out->child_1_leaf = 0;
|
||||
out->child_1_off = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
out->child_1_leaf = 1;
|
||||
out->child_1_off = -1 - p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3099,20 +3121,20 @@ static void Mod_LoadNodes( model_t *mod, dbspmodel_t *bmod )
|
|||
|
||||
p = in->planenum;
|
||||
out->plane = mod->planes + p;
|
||||
out->firstsurface = in->firstface;
|
||||
out->numsurfaces = in->numfaces;
|
||||
out->firstsurface_0 = in->firstface;
|
||||
out->numsurfaces_0 = in->numfaces;
|
||||
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
p = in->children[j];
|
||||
if( p >= 0 ) out->children[j] = mod->nodes + p;
|
||||
else out->children[j] = (mnode_t *)(mod->leafs + ( -1 - p ));
|
||||
if( p >= 0 ) out->children_[j] = mod->nodes + p;
|
||||
else out->children_[j] = (mnode_t *)(mod->leafs + ( -1 - p ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets nodes and leafs
|
||||
Mod_SetParent( mod->nodes, NULL );
|
||||
Mod_SetParent( mod, mod->nodes, NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3601,6 +3623,9 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, const byte *mod_base, qboolea
|
|||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
|
||||
if( header->version == QBSP2_VERSION )
|
||||
SetBits( mod->flags, MODEL_QBSP2 );
|
||||
break;
|
||||
default:
|
||||
Con_Printf( S_ERROR "%s has wrong version number (%i should be %i)\n", mod->name, header->version, HLBSP_VERSION );
|
||||
|
|
|
@ -167,13 +167,12 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded );
|
|||
//
|
||||
void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded );
|
||||
qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities );
|
||||
qboolean Mod_HeadnodeVisible( mnode_t *node, const byte *visbits, int *lastleaf );
|
||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean false );
|
||||
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
|
||||
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
|
||||
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );
|
||||
int Mod_SaveLump( const char *filename, const int lump, void *lumpdata, int lumpsize );
|
||||
mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node );
|
||||
mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node, model_t *mod );
|
||||
int Mod_SampleSizeForFace( const msurface_t *surf );
|
||||
byte *Mod_GetPVSForPoint( const vec3_t p );
|
||||
void Mod_UnloadBrushModel( model_t *mod );
|
||||
|
|
|
@ -112,6 +112,9 @@ msurface_t *PM_RecursiveSurfCheck( model_t *mod, mnode_t *node, vec3_t p1, vec3_
|
|||
int i, side;
|
||||
msurface_t *surf;
|
||||
vec3_t mid;
|
||||
mnode_t *children[2];
|
||||
int numsurfaces, firstsurface;
|
||||
|
||||
loc0:
|
||||
if( node->contents < 0 )
|
||||
return NULL;
|
||||
|
@ -119,15 +122,17 @@ loc0:
|
|||
t1 = PlaneDiff( p1, node->plane );
|
||||
t2 = PlaneDiff( p2, node->plane );
|
||||
|
||||
node_children( children, node, mod );
|
||||
|
||||
if( t1 >= -FRAC_EPSILON && t2 >= -FRAC_EPSILON )
|
||||
{
|
||||
node = node->children[0];
|
||||
node = children[0];
|
||||
goto loc0;
|
||||
}
|
||||
|
||||
if( t1 < FRAC_EPSILON && t2 < FRAC_EPSILON )
|
||||
{
|
||||
node = node->children[1];
|
||||
node = children[1];
|
||||
goto loc0;
|
||||
}
|
||||
|
||||
|
@ -137,13 +142,15 @@ loc0:
|
|||
|
||||
VectorLerp( p1, frac, p2, mid );
|
||||
|
||||
if(( surf = PM_RecursiveSurfCheck( mod, node->children[side], p1, mid )) != NULL )
|
||||
if(( surf = PM_RecursiveSurfCheck( mod, children[side], p1, mid )) != NULL )
|
||||
return surf;
|
||||
|
||||
// walk through real faces
|
||||
for( i = 0; i < node->numsurfaces; i++ )
|
||||
numsurfaces = node_numsurfaces( node, mod );
|
||||
firstsurface = node_firstsurface( node, mod );
|
||||
for( i = 0; i < numsurfaces; i++ )
|
||||
{
|
||||
msurface_t *surf = &mod->surfaces[node->firstsurface + i];
|
||||
msurface_t *surf = &mod->surfaces[firstsurface + i];
|
||||
mextrasurf_t *info = surf->info;
|
||||
mfacebevel_t *fb = info->bevel;
|
||||
int j, contents;
|
||||
|
@ -172,7 +179,7 @@ loc0:
|
|||
return NULL; // through the fence
|
||||
}
|
||||
|
||||
return PM_RecursiveSurfCheck( mod, node->children[side^1], mid, p2 );
|
||||
return PM_RecursiveSurfCheck( mod, children[side^1], mid, p2 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -227,6 +234,9 @@ static int PM_TestLine_r( model_t *mod, mnode_t *node, vec_t p1f, vec_t p2f, con
|
|||
float frac, midf;
|
||||
int i, r, side;
|
||||
vec3_t mid;
|
||||
mnode_t *children[2];
|
||||
int numsurfaces, firstsurface;
|
||||
|
||||
loc0:
|
||||
if( node->contents < 0 )
|
||||
{
|
||||
|
@ -242,15 +252,17 @@ loc0:
|
|||
front = PlaneDiff( start, node->plane );
|
||||
back = PlaneDiff( stop, node->plane );
|
||||
|
||||
node_children( children, node, mod );
|
||||
|
||||
if( front >= -FRAC_EPSILON && back >= -FRAC_EPSILON )
|
||||
{
|
||||
node = node->children[0];
|
||||
node = children[0];
|
||||
goto loc0;
|
||||
}
|
||||
|
||||
if( front < FRAC_EPSILON && back < FRAC_EPSILON )
|
||||
{
|
||||
node = node->children[1];
|
||||
node = children[1];
|
||||
goto loc0;
|
||||
}
|
||||
|
||||
|
@ -261,7 +273,7 @@ loc0:
|
|||
VectorLerp( start, frac, stop, mid );
|
||||
midf = p1f + ( p2f - p1f ) * frac;
|
||||
|
||||
r = PM_TestLine_r( mod, node->children[side], p1f, midf, start, mid, trace );
|
||||
r = PM_TestLine_r( mod, children[side], p1f, midf, start, mid, trace );
|
||||
|
||||
if( r != CONTENTS_EMPTY )
|
||||
{
|
||||
|
@ -272,9 +284,11 @@ loc0:
|
|||
}
|
||||
|
||||
// walk through real faces
|
||||
for( i = 0; i < node->numsurfaces; i++ )
|
||||
numsurfaces = node_numsurfaces( node, mod );
|
||||
firstsurface = node_firstsurface( node, mod );
|
||||
for( i = 0; i < numsurfaces; i++ )
|
||||
{
|
||||
msurface_t *surf = &mod->surfaces[node->firstsurface + i];
|
||||
msurface_t *surf = &mod->surfaces[firstsurface + i];
|
||||
mextrasurf_t *info = surf->info;
|
||||
mfacebevel_t *fb = info->bevel;
|
||||
int j, contents;
|
||||
|
@ -308,7 +322,7 @@ loc0:
|
|||
return contents;
|
||||
}
|
||||
|
||||
return PM_TestLine_r( mod, node->children[!side], midf, p2f, mid, stop, trace );
|
||||
return PM_TestLine_r( mod, children[!side], midf, p2f, mid, stop, trace );
|
||||
}
|
||||
|
||||
int PM_TestLineExt( playermove_t *pmove, physent_t *ents, int numents, const vec3_t start, const vec3_t end, int flags )
|
||||
|
|
|
@ -80,6 +80,7 @@ GNU General Public License for more details.
|
|||
#define MODEL_LIQUID BIT( 2 ) // model has only point hull
|
||||
#define MODEL_TRANSPARENT BIT( 3 ) // have transparent surfaces
|
||||
#define MODEL_COLORED_LIGHTING BIT( 4 ) // lightmaps stored as RGB
|
||||
|
||||
#define MODEL_WORLD BIT( 29 ) // it's a worldmodel
|
||||
#define MODEL_CLIENT BIT( 30 ) // client sprite
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ static qboolean SV_CheckClientVisiblity( sv_client_t *cl, const byte *mask )
|
|||
else
|
||||
VectorCopy( cl->edict->v.origin, vieworg );
|
||||
|
||||
leaf = Mod_PointInLeaf( vieworg, sv.worldmodel->nodes );
|
||||
leaf = Mod_PointInLeaf( vieworg, sv.worldmodel->nodes, sv.worldmodel );
|
||||
|
||||
if( CHECKVISBIT( mask, leaf->cluster ))
|
||||
return true; // visible from player view or camera view
|
||||
|
@ -342,7 +342,7 @@ static qboolean SV_CheckClientVisiblity( sv_client_t *cl, const byte *mask )
|
|||
continue;
|
||||
|
||||
VectorAdd( view->v.origin, view->v.view_ofs, vieworg );
|
||||
leaf = Mod_PointInLeaf( vieworg, sv.worldmodel->nodes );
|
||||
leaf = Mod_PointInLeaf( vieworg, sv.worldmodel->nodes, sv.worldmodel );
|
||||
|
||||
if( CHECKVISBIT( mask, leaf->cluster ))
|
||||
return true; // visible from portal camera view
|
||||
|
@ -1732,7 +1732,7 @@ static edict_t* GAME_EXPORT pfnFindClientInPVS( edict_t *pEdict )
|
|||
VectorAdd( pEdict->v.origin, pEdict->v.view_ofs, view );
|
||||
}
|
||||
|
||||
leaf = Mod_PointInLeaf( view, sv.worldmodel->nodes );
|
||||
leaf = Mod_PointInLeaf( view, sv.worldmodel->nodes, sv.worldmodel );
|
||||
|
||||
if( CHECKVISBIT( clientpvs, leaf->cluster ))
|
||||
return pClient; // client which currently in PVS
|
||||
|
@ -4291,6 +4291,35 @@ static byte *GAME_EXPORT pfnSetFatPAS( const float *org )
|
|||
return fatphs;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Mod_HeadnodeVisible
|
||||
=============
|
||||
*/
|
||||
static qboolean Mod_HeadnodeVisible( model_t *mod, mnode_t *node, const byte *visbits, int *lastleaf )
|
||||
{
|
||||
if( !node || node->contents == CONTENTS_SOLID )
|
||||
return false;
|
||||
|
||||
if( node->contents < 0 )
|
||||
{
|
||||
if( !CHECKVISBIT( visbits, ((mleaf_t *)node)->cluster ))
|
||||
return false;
|
||||
|
||||
if( lastleaf )
|
||||
*lastleaf = ((mleaf_t *)node)->cluster;
|
||||
return true;
|
||||
}
|
||||
|
||||
if( Mod_HeadnodeVisible( mod, node_child( node, 0, mod ), visbits, lastleaf ))
|
||||
return true;
|
||||
|
||||
if( Mod_HeadnodeVisible( mod, node_child( node, 1, mod ), visbits, lastleaf ))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnCheckVisibility
|
||||
|
@ -4333,7 +4362,7 @@ static int GAME_EXPORT pfnCheckVisibility( const edict_t *ent, byte *pset )
|
|||
}
|
||||
|
||||
// too many leafs for individual check, go by headnode
|
||||
if( !Mod_HeadnodeVisible( &sv.worldmodel->nodes[ent->headnode], pset, &leafnum ))
|
||||
if( !Mod_HeadnodeVisible( sv.worldmodel, &sv.worldmodel->nodes[ent->headnode], pset, &leafnum ))
|
||||
return 0;
|
||||
|
||||
((edict_t *)ent)->leafnums[ent->num_leafs] = leafnum;
|
||||
|
|
|
@ -644,8 +644,10 @@ static void SV_FindTouchedLeafs( edict_t *ent, mnode_t *node, int *headnode )
|
|||
*headnode = node - sv.worldmodel->nodes;
|
||||
|
||||
// recurse down the contacted sides
|
||||
if( sides & 1 ) SV_FindTouchedLeafs( ent, node->children[0], headnode );
|
||||
if( sides & 2 ) SV_FindTouchedLeafs( ent, node->children[1], headnode );
|
||||
if( sides & 1 )
|
||||
SV_FindTouchedLeafs( ent, node_child( node, 0, sv.worldmodel ), headnode );
|
||||
if( sides & 2 )
|
||||
SV_FindTouchedLeafs( ent, node_child( node, 1, sv.worldmodel ), headnode );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1535,6 +1537,8 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec
|
|||
float front, back, frac;
|
||||
int i, side;
|
||||
vec3_t mid;
|
||||
mnode_t *children[2];
|
||||
int numsurfaces, firstsurface;
|
||||
|
||||
// didn't hit anything
|
||||
if( !node || node->contents < 0 )
|
||||
|
@ -1544,25 +1548,29 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec
|
|||
front = PlaneDiff( start, node->plane );
|
||||
back = PlaneDiff( end, node->plane );
|
||||
|
||||
node_children( children, node, model );
|
||||
|
||||
side = front < 0.0f;
|
||||
if(( back < 0.0f ) == side )
|
||||
return SV_RecursiveLightPoint( model, node->children[side], start, end, point_color );
|
||||
return SV_RecursiveLightPoint( model, children[side], start, end, point_color );
|
||||
|
||||
frac = front / ( front - back );
|
||||
|
||||
VectorLerp( start, frac, end, mid );
|
||||
|
||||
// co down front side
|
||||
if( SV_RecursiveLightPoint( model, node->children[side], start, mid, point_color ))
|
||||
if( SV_RecursiveLightPoint( model, children[side], start, mid, point_color ))
|
||||
return true; // hit something
|
||||
|
||||
if(( back < 0.0f ) == side )
|
||||
return false; // didn't hit anything
|
||||
|
||||
// check for impact on this node
|
||||
for( i = 0; i < node->numsurfaces; i++ )
|
||||
numsurfaces = node_numsurfaces( node, model );
|
||||
firstsurface = node_firstsurface( node, model );
|
||||
for( i = 0; i < numsurfaces; i++ )
|
||||
{
|
||||
const msurface_t *surf = &model->surfaces[node->firstsurface + i];
|
||||
const msurface_t *surf = &model->surfaces[firstsurface + i];
|
||||
const mextrasurf_t *info = surf->info;
|
||||
int smax, tmax, map, size;
|
||||
int sample_size;
|
||||
|
@ -1613,7 +1621,7 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec
|
|||
}
|
||||
|
||||
// go down back side
|
||||
return SV_RecursiveLightPoint( model, node->children[!side], mid, end, point_color );
|
||||
return SV_RecursiveLightPoint( model, children[!side], mid, end, point_color );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -670,10 +670,14 @@ static void R_DecalNodeSurfaces( model_t *model, mnode_t *node, decalinfo_t *dec
|
|||
// iterate over all surfaces in the node
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
int firstsurface, numsurfaces;
|
||||
|
||||
surf = model->surfaces + node->firstsurface;
|
||||
firstsurface = node_firstsurface( node, model );
|
||||
numsurfaces = node_numsurfaces( node, model );
|
||||
|
||||
for( i = 0; i < node->numsurfaces; i++, surf++ )
|
||||
surf = model->surfaces + firstsurface;
|
||||
|
||||
for( i = 0; i < numsurfaces; i++, surf++ )
|
||||
{
|
||||
// never apply decals on the water or sky surfaces
|
||||
if( surf->flags & (SURF_DRAWTURB|SURF_DRAWSKY|SURF_CONVEYOR))
|
||||
|
@ -695,6 +699,7 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
|
|||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
mnode_t *children[2];
|
||||
|
||||
Assert( node != NULL );
|
||||
|
||||
|
@ -706,6 +711,7 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
|
|||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct( decalinfo->m_Position, splitplane->normal ) - splitplane->dist;
|
||||
node_children( children, node, model );
|
||||
|
||||
// This is arbitrarily set to 10 right now. In an ideal world we'd have the
|
||||
// exact surface but we don't so, this tells me which planes are "sort of
|
||||
|
@ -717,19 +723,19 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
|
|||
// have a surface normal
|
||||
if( dist > decalinfo->m_Size )
|
||||
{
|
||||
R_DecalNode( model, node->children[0], decalinfo );
|
||||
R_DecalNode( model, children[0], decalinfo );
|
||||
}
|
||||
else if( dist < -decalinfo->m_Size )
|
||||
{
|
||||
R_DecalNode( model, node->children[1], decalinfo );
|
||||
R_DecalNode( model, children[1], decalinfo );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dist < DECAL_DISTANCE && dist > -DECAL_DISTANCE )
|
||||
R_DecalNodeSurfaces( model, node, decalinfo );
|
||||
|
||||
R_DecalNode( model, node->children[0], decalinfo );
|
||||
R_DecalNode( model, node->children[1], decalinfo );
|
||||
R_DecalNode( model, children[0], decalinfo );
|
||||
R_DecalNode( model, children[1], decalinfo );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -104,27 +104,33 @@ void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
|
|||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
mnode_t *children[2];
|
||||
int firstsurface, numsurfaces;
|
||||
|
||||
if( !node || node->contents < 0 )
|
||||
return;
|
||||
|
||||
dist = PlaneDiff( light->origin, node->plane );
|
||||
|
||||
node_children( children, node, RI.currentmodel );
|
||||
firstsurface = node_firstsurface( node, RI.currentmodel );
|
||||
numsurfaces = node_numsurfaces( node, RI.currentmodel );
|
||||
|
||||
if( dist > light->radius )
|
||||
{
|
||||
R_MarkLights( light, bit, node->children[0] );
|
||||
R_MarkLights( light, bit, children[0] );
|
||||
return;
|
||||
}
|
||||
if( dist < -light->radius )
|
||||
{
|
||||
R_MarkLights( light, bit, node->children[1] );
|
||||
R_MarkLights( light, bit, children[1] );
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = RI.currentmodel->surfaces + node->firstsurface;
|
||||
surf = RI.currentmodel->surfaces + firstsurface;
|
||||
|
||||
for( i = 0; i < node->numsurfaces; i++, surf++ )
|
||||
for( i = 0; i < numsurfaces; i++, surf++ )
|
||||
{
|
||||
if( !BoundsAndSphereIntersect( surf->info->mins, surf->info->maxs, light->origin, light->radius ))
|
||||
continue; // no intersection
|
||||
|
@ -137,8 +143,8 @@ void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
|
|||
surf->dlightbits |= bit;
|
||||
}
|
||||
|
||||
R_MarkLights( light, bit, node->children[0] );
|
||||
R_MarkLights( light, bit, node->children[1] );
|
||||
R_MarkLights( light, bit, children[0] );
|
||||
R_MarkLights( light, bit, children[1] );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -202,6 +208,8 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
mtexinfo_t *tex;
|
||||
matrix3x4 tbn;
|
||||
vec3_t mid;
|
||||
mnode_t *children[2];
|
||||
int firstsurface, numsurfaces;
|
||||
|
||||
// didn't hit anything
|
||||
if( !node || node->contents < 0 )
|
||||
|
@ -210,13 +218,17 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
return false;
|
||||
}
|
||||
|
||||
node_children( children, node, model );
|
||||
firstsurface = node_firstsurface( node, model );
|
||||
numsurfaces = node_numsurfaces( node, model );
|
||||
|
||||
// calculate mid point
|
||||
front = PlaneDiff( start, node->plane );
|
||||
back = PlaneDiff( end, node->plane );
|
||||
|
||||
side = front < 0;
|
||||
if(( back < 0 ) == side )
|
||||
return R_RecursiveLightPoint( model, node->children[side], p1f, p2f, cv, start, end );
|
||||
return R_RecursiveLightPoint( model, children[side], p1f, p2f, cv, start, end );
|
||||
|
||||
frac = front / ( front - back );
|
||||
|
||||
|
@ -224,7 +236,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
midf = p1f + ( p2f - p1f ) * frac;
|
||||
|
||||
// co down front side
|
||||
if( R_RecursiveLightPoint( model, node->children[side], p1f, midf, cv, start, mid ))
|
||||
if( R_RecursiveLightPoint( model, children[side], p1f, midf, cv, start, mid ))
|
||||
return true; // hit something
|
||||
|
||||
if(( back < 0 ) == side )
|
||||
|
@ -234,10 +246,10 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
}
|
||||
|
||||
// check for impact on this node
|
||||
surf = model->surfaces + node->firstsurface;
|
||||
surf = model->surfaces + firstsurface;
|
||||
VectorCopy( mid, g_trace_lightspot );
|
||||
|
||||
for( i = 0; i < node->numsurfaces; i++, surf++ )
|
||||
for( i = 0; i < numsurfaces; i++, surf++ )
|
||||
{
|
||||
int smax, tmax;
|
||||
|
||||
|
@ -326,7 +338,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
}
|
||||
|
||||
// go down back side
|
||||
return R_RecursiveLightPoint( model, node->children[!side], midf, p2f, cv, mid, end );
|
||||
return R_RecursiveLightPoint( model, children[!side], midf, p2f, cv, mid, end );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -600,6 +600,7 @@ watertexture to grab fog values from it
|
|||
static gl_texture_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mnode_t *ignore, qboolean down )
|
||||
{
|
||||
gl_texture_t *tex = NULL;
|
||||
mnode_t *children[2];
|
||||
|
||||
// assure the initial node is not null
|
||||
// we could check it here, but we would rather check it
|
||||
|
@ -637,15 +638,17 @@ static gl_texture_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mno
|
|||
|
||||
// this is a regular node
|
||||
// traverse children
|
||||
if( node->children[0] && ( node->children[0] != ignore ))
|
||||
node_children( children, node, WORLDMODEL );
|
||||
|
||||
if( children[0] && ( children[0] != ignore ))
|
||||
{
|
||||
tex = R_RecursiveFindWaterTexture( node->children[0], node, true );
|
||||
tex = R_RecursiveFindWaterTexture( children[0], node, true );
|
||||
if( tex ) return tex;
|
||||
}
|
||||
|
||||
if( node->children[1] && ( node->children[1] != ignore ))
|
||||
if( children[1] && ( children[1] != ignore ))
|
||||
{
|
||||
tex = R_RecursiveFindWaterTexture( node->children[1], node, true );
|
||||
tex = R_RecursiveFindWaterTexture( children[1], node, true );
|
||||
if( tex ) return tex;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ static void R_GetEdgePosition( const model_t *mod, const msurface_t *fa, int i,
|
|||
{
|
||||
const int lindex = mod->surfedges[fa->firstedge + i];
|
||||
|
||||
if( tr.world->version == QBSP2_VERSION )
|
||||
if( FBitSet( mod->flags, MODEL_QBSP2 ))
|
||||
{
|
||||
const medge32_t *pedges = mod->edges32;
|
||||
|
||||
|
@ -3319,6 +3319,9 @@ static void R_RecursiveWorldNode( mnode_t *node, uint clipflags )
|
|||
mleaf_t *pleaf;
|
||||
int c, side;
|
||||
float dot;
|
||||
mnode_t *children[2];
|
||||
int numsurfaces, firstsurface;
|
||||
|
||||
loc0:
|
||||
if( node->contents == CONTENTS_SOLID )
|
||||
return; // hit a solid leaf
|
||||
|
@ -3373,10 +3376,14 @@ loc0:
|
|||
side = (dot >= 0.0f) ? 0 : 1;
|
||||
|
||||
// recurse down the children, front side first
|
||||
R_RecursiveWorldNode( node->children[side], clipflags );
|
||||
node_children( children, node, WORLDMODEL );
|
||||
R_RecursiveWorldNode( children[side], clipflags );
|
||||
|
||||
firstsurface = node_firstsurface( node, WORLDMODEL );
|
||||
numsurfaces = node_numsurfaces( node, WORLDMODEL );
|
||||
|
||||
// draw stuff
|
||||
for( c = node->numsurfaces, surf = WORLDMODEL->surfaces + node->firstsurface; c; c--, surf++ )
|
||||
for( c = numsurfaces, surf = WORLDMODEL->surfaces + firstsurface; c; c--, surf++ )
|
||||
{
|
||||
if( R_CullSurface( surf, &RI.frustum, clipflags ))
|
||||
continue;
|
||||
|
@ -3395,7 +3402,7 @@ loc0:
|
|||
}
|
||||
|
||||
// recurse down the back side
|
||||
node = node->children[!side];
|
||||
node = children[!side];
|
||||
goto loc0;
|
||||
}
|
||||
|
||||
|
@ -3471,6 +3478,9 @@ static void R_DrawWorldTopView( mnode_t *node, uint clipflags )
|
|||
|
||||
do
|
||||
{
|
||||
mnode_t *children[2];
|
||||
int numsurfaces, firstsurface;
|
||||
|
||||
if( node->contents == CONTENTS_SOLID )
|
||||
return; // hit a solid leaf
|
||||
|
||||
|
@ -3504,7 +3514,10 @@ static void R_DrawWorldTopView( mnode_t *node, uint clipflags )
|
|||
}
|
||||
|
||||
// draw stuff
|
||||
for( c = node->numsurfaces, surf = WORLDMODEL->surfaces + node->firstsurface; c; c--, surf++ )
|
||||
numsurfaces = node_numsurfaces( node, WORLDMODEL );
|
||||
firstsurface = node_firstsurface( node, WORLDMODEL );
|
||||
|
||||
for( c = numsurfaces, surf = WORLDMODEL->surfaces + firstsurface; c; c--, surf++ )
|
||||
{
|
||||
// don't process the same surface twice
|
||||
if( surf->visframe == tr.framecount )
|
||||
|
@ -3523,9 +3536,9 @@ static void R_DrawWorldTopView( mnode_t *node, uint clipflags )
|
|||
}
|
||||
|
||||
// recurse down both children, we don't care the order...
|
||||
R_DrawWorldTopView( node->children[0], clipflags );
|
||||
node = node->children[1];
|
||||
|
||||
node_children( children, node, WORLDMODEL );
|
||||
R_DrawWorldTopView( children[0], clipflags );
|
||||
node = children[1];
|
||||
} while( node );
|
||||
}
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ void R_RotateBmodel( void )
|
|||
R_RecursiveClipBPoly
|
||||
================
|
||||
*/
|
||||
static void R_RecursiveClipBPoly( bedge_t *pedges, mnode_t *pnode, msurface_t *psurf )
|
||||
static void R_RecursiveClipBPoly( model_t *mod, bedge_t *pedges, mnode_t *pnode, msurface_t *psurf )
|
||||
{
|
||||
bedge_t *psideedges[2], *pnextedge, *ptedge;
|
||||
int i, side, lastside;
|
||||
|
@ -316,7 +316,7 @@ static void R_RecursiveClipBPoly( bedge_t *pedges, mnode_t *pnode, msurface_t *p
|
|||
{
|
||||
// draw if we've reached a non-solid leaf, done if all that's left is a
|
||||
// solid leaf, and continue down the tree if it's not a leaf
|
||||
pn = pnode->children[i];
|
||||
pn = node_child( pnode, i, mod );
|
||||
|
||||
// we're done with this branch if the node or leaf isn't in the PVS
|
||||
if( pn->visframe == tr.visframecount )
|
||||
|
@ -332,8 +332,7 @@ static void R_RecursiveClipBPoly( bedge_t *pedges, mnode_t *pnode, msurface_t *p
|
|||
}
|
||||
else
|
||||
{
|
||||
R_RecursiveClipBPoly( psideedges[i], pnode->children[i],
|
||||
psurf );
|
||||
R_RecursiveClipBPoly( mod, psideedges[i], pn, psurf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +418,7 @@ void R_DrawSolidClippedSubmodelPolygons( model_t *pmodel, mnode_t *topnode )
|
|||
pbedge[j - 1].pnext = NULL; // mark end of edges
|
||||
|
||||
// if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ) )
|
||||
R_RecursiveClipBPoly( pbedge, topnode, psurf );
|
||||
R_RecursiveClipBPoly( pmodel, pbedge, topnode, psurf );
|
||||
// else
|
||||
// R_RenderBmodelFace( pbedge, psurf );
|
||||
}
|
||||
|
@ -566,6 +565,9 @@ static void R_RecursiveWorldNode( mnode_t *node, int clipflags )
|
|||
}
|
||||
else
|
||||
{
|
||||
mnode_t *children[2];
|
||||
int firstsurface;
|
||||
|
||||
// node is just a decision point, so go down the apropriate sides
|
||||
|
||||
// find which side of the node we are on
|
||||
|
@ -593,14 +595,16 @@ static void R_RecursiveWorldNode( mnode_t *node, int clipflags )
|
|||
side = 1;
|
||||
|
||||
// recurse down the children, front side first
|
||||
R_RecursiveWorldNode( node->children[side], clipflags );
|
||||
node_children( children, node, WORLDMODEL );
|
||||
R_RecursiveWorldNode( children[side], clipflags );
|
||||
|
||||
// draw stuff
|
||||
c = node->numsurfaces;
|
||||
c = node_numsurfaces( node, WORLDMODEL );
|
||||
firstsurface = node_firstsurface( node, WORLDMODEL );
|
||||
|
||||
if( c )
|
||||
{
|
||||
surf = WORLDMODEL->surfaces + node->firstsurface;
|
||||
surf = WORLDMODEL->surfaces + firstsurface;
|
||||
|
||||
if( dot < -BACKFACE_EPSILON )
|
||||
{
|
||||
|
@ -636,7 +640,7 @@ static void R_RecursiveWorldNode( mnode_t *node, int clipflags )
|
|||
}
|
||||
|
||||
// recurse down the back side
|
||||
R_RecursiveWorldNode( node->children[!side], clipflags );
|
||||
R_RecursiveWorldNode( children[!side], clipflags );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -681,21 +681,22 @@ static void R_DecalNodeSurfaces( model_t *model, mnode_t *node, decalinfo_t *dec
|
|||
// iterate over all surfaces in the node
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
int firstsurface, numsurfaces;
|
||||
|
||||
surf = model->surfaces + node->firstsurface;
|
||||
firstsurface = node_firstsurface( node, model );
|
||||
numsurfaces = node_numsurfaces( node, model );
|
||||
|
||||
for( i = 0; i < node->numsurfaces; i++, surf++ )
|
||||
surf = model->surfaces + firstsurface;
|
||||
|
||||
for( i = 0; i < numsurfaces; i++, surf++ )
|
||||
{
|
||||
// never apply decals on the water or sky surfaces
|
||||
if( surf->flags & (SURF_DRAWTURB|SURF_DRAWSKY|SURF_CONVEYOR))
|
||||
continue;
|
||||
|
||||
// we can implement alpha testing without stencil
|
||||
// if( surf->flags & SURF_TRANSPARENT && !glState.stencilEnabled )
|
||||
// continue;
|
||||
|
||||
R_DecalSurface( surf, decalinfo );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -707,6 +708,7 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
|
|||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
mnode_t *children[2];
|
||||
|
||||
Assert( node != NULL );
|
||||
|
||||
|
@ -718,6 +720,7 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
|
|||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct( decalinfo->m_Position, splitplane->normal ) - splitplane->dist;
|
||||
node_children( children, node, model );
|
||||
|
||||
// This is arbitrarily set to 10 right now. In an ideal world we'd have the
|
||||
// exact surface but we don't so, this tells me which planes are "sort of
|
||||
|
@ -729,19 +732,19 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
|
|||
// have a surface normal
|
||||
if( dist > decalinfo->m_Size )
|
||||
{
|
||||
R_DecalNode( model, node->children[0], decalinfo );
|
||||
R_DecalNode( model, children[0], decalinfo );
|
||||
}
|
||||
else if( dist < -decalinfo->m_Size )
|
||||
{
|
||||
R_DecalNode( model, node->children[1], decalinfo );
|
||||
R_DecalNode( model, children[1], decalinfo );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dist < DECAL_DISTANCE && dist > -DECAL_DISTANCE )
|
||||
R_DecalNodeSurfaces( model, node, decalinfo );
|
||||
|
||||
R_DecalNode( model, node->children[0], decalinfo );
|
||||
R_DecalNode( model, node->children[1], decalinfo );
|
||||
R_DecalNode( model, children[0], decalinfo );
|
||||
R_DecalNode( model, children[1], decalinfo );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,41 +107,47 @@ void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
|
|||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
mnode_t *children[2];
|
||||
int firstsurface, numsurfaces;
|
||||
|
||||
if( !node || node->contents < 0 )
|
||||
return;
|
||||
|
||||
dist = PlaneDiff( light->origin, node->plane );
|
||||
|
||||
node_children( children, node, RI.currentmodel );
|
||||
firstsurface = node_firstsurface( node, RI.currentmodel );
|
||||
numsurfaces = node_numsurfaces( node, RI.currentmodel );
|
||||
|
||||
if( dist > light->radius )
|
||||
{
|
||||
R_MarkLights( light, bit, node->children[0] );
|
||||
R_MarkLights( light, bit, children[0] );
|
||||
return;
|
||||
}
|
||||
if( dist < -light->radius )
|
||||
{
|
||||
R_MarkLights( light, bit, node->children[1] );
|
||||
R_MarkLights( light, bit, children[1] );
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = RI.currentmodel->surfaces + node->firstsurface;
|
||||
surf = RI.currentmodel->surfaces + firstsurface;
|
||||
|
||||
for( i = 0; i < node->numsurfaces; i++, surf++ )
|
||||
for( i = 0; i < numsurfaces; i++, surf++ )
|
||||
{
|
||||
if( !BoundsAndSphereIntersect( surf->info->mins, surf->info->maxs, light->origin, light->radius ))
|
||||
continue; // no intersection
|
||||
|
||||
if( surf->dlightframe != tr.framecount ) // tr.dlightframecount )
|
||||
if( surf->dlightframe != tr.dlightframecount )
|
||||
{
|
||||
surf->dlightbits = 0;
|
||||
surf->dlightframe = tr.framecount; // tr.dlightframecount;
|
||||
surf->dlightframe = tr.dlightframecount;
|
||||
}
|
||||
surf->dlightbits |= bit;
|
||||
}
|
||||
|
||||
R_MarkLights( light, bit, node->children[0] );
|
||||
R_MarkLights( light, bit, node->children[1] );
|
||||
R_MarkLights( light, bit, children[0] );
|
||||
R_MarkLights( light, bit, children[1] );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -205,6 +211,8 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
mtexinfo_t *tex;
|
||||
matrix3x4 tbn;
|
||||
vec3_t mid;
|
||||
mnode_t *children[2];
|
||||
int firstsurface, numsurfaces;
|
||||
|
||||
// didn't hit anything
|
||||
if( !node || node->contents < 0 )
|
||||
|
@ -213,13 +221,17 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
return false;
|
||||
}
|
||||
|
||||
node_children( children, node, model );
|
||||
firstsurface = node_firstsurface( node, model );
|
||||
numsurfaces = node_numsurfaces( node, model );
|
||||
|
||||
// calculate mid point
|
||||
front = PlaneDiff( start, node->plane );
|
||||
back = PlaneDiff( end, node->plane );
|
||||
|
||||
side = front < 0;
|
||||
if(( back < 0 ) == side )
|
||||
return R_RecursiveLightPoint( model, node->children[side], p1f, p2f, cv, start, end );
|
||||
return R_RecursiveLightPoint( model, children[side], p1f, p2f, cv, start, end );
|
||||
|
||||
frac = front / ( front - back );
|
||||
|
||||
|
@ -227,7 +239,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
midf = p1f + ( p2f - p1f ) * frac;
|
||||
|
||||
// co down front side
|
||||
if( R_RecursiveLightPoint( model, node->children[side], p1f, midf, cv, start, mid ))
|
||||
if( R_RecursiveLightPoint( model, children[side], p1f, midf, cv, start, mid ))
|
||||
return true; // hit something
|
||||
|
||||
if(( back < 0 ) == side )
|
||||
|
@ -237,10 +249,10 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
}
|
||||
|
||||
// check for impact on this node
|
||||
surf = model->surfaces + node->firstsurface;
|
||||
surf = model->surfaces + firstsurface;
|
||||
VectorCopy( mid, g_trace_lightspot );
|
||||
|
||||
for( i = 0; i < node->numsurfaces; i++, surf++ )
|
||||
for( i = 0; i < numsurfaces; i++, surf++ )
|
||||
{
|
||||
int smax, tmax;
|
||||
|
||||
|
@ -330,7 +342,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
|
|||
}
|
||||
|
||||
// go down back side
|
||||
return R_RecursiveLightPoint( model, node->children[!side], midf, p2f, cv, mid, end );
|
||||
return R_RecursiveLightPoint( model, children[!side], midf, p2f, cv, mid, end );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -524,6 +524,7 @@ watertexture to grab fog values from it
|
|||
static image_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mnode_t *ignore, qboolean down )
|
||||
{
|
||||
image_t *tex = NULL;
|
||||
mnode_t *children[2];
|
||||
|
||||
// assure the initial node is not null
|
||||
// we could check it here, but we would rather check it
|
||||
|
@ -561,18 +562,18 @@ static image_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mnode_t
|
|||
|
||||
// this is a regular node
|
||||
// traverse children
|
||||
if( node->children[0] && ( node->children[0] != ignore ))
|
||||
node_children( children, node, WORLDMODEL );
|
||||
|
||||
if( children[0] && ( children[0] != ignore ))
|
||||
{
|
||||
tex = R_RecursiveFindWaterTexture( node->children[0], node, true );
|
||||
if( tex )
|
||||
return tex;
|
||||
tex = R_RecursiveFindWaterTexture( children[0], node, true );
|
||||
if( tex ) return tex;
|
||||
}
|
||||
|
||||
if( node->children[1] && ( node->children[1] != ignore ))
|
||||
if( children[1] && ( children[1] != ignore ))
|
||||
{
|
||||
tex = R_RecursiveFindWaterTexture( node->children[1], node, true );
|
||||
if( tex )
|
||||
return tex;
|
||||
tex = R_RecursiveFindWaterTexture( children[1], node, true );
|
||||
if( tex ) return tex;
|
||||
}
|
||||
|
||||
// for down recursion, return immediately
|
||||
|
@ -796,9 +797,9 @@ static mnode_t *R_FindTopnode( vec3_t mins, vec3_t maxs )
|
|||
|
||||
// not split yet; recurse down the contacted side
|
||||
if( sides & 1 )
|
||||
node = node->children[0];
|
||||
node = node_child( node, 0, WORLDMODEL );
|
||||
else
|
||||
node = node->children[1];
|
||||
node = node_child( node, 1, WORLDMODEL );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue