mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 12:31:10 +00:00
[model] Move plane info into mnode_t, and visframe out
The main goal was to get visframe out of mnode_t to make it thread-safe (each thread can have its own visframe array), but moving the plane info into mnode_t made for better data access patters when traversing the bsp tree as the plane is right there with the child indices. Nicely, the size of mnode_t is the same as before (64 bytes due to alignment), with 4 bytes wasted. Performance-wise, there seems to be very little difference. Maybe slightly slower. The unfortunate thing about the change is the plane distance is negated, possibly leading to some confusion, particularly since the box and sphere culling functions were affected. However, this is so point-plane distance calculations can be done with a single 4d dot product.
This commit is contained in:
parent
8633ffe9d2
commit
7240d2dc80
36 changed files with 397 additions and 350 deletions
|
@ -136,6 +136,7 @@ void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right,
|
||||||
vec3_t up);
|
vec3_t up);
|
||||||
void AngleQuat (const vec3_t angles, quat_t q);
|
void AngleQuat (const vec3_t angles, quat_t q);
|
||||||
void VectorVectors (const vec3_t forward, vec3_t right, vec3_t up);
|
void VectorVectors (const vec3_t forward, vec3_t right, vec3_t up);
|
||||||
|
// NOTE expects plane distance is -p.n
|
||||||
int BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs,
|
int BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs,
|
||||||
const plane_t *plane) __attribute__((pure));
|
const plane_t *plane) __attribute__((pure));
|
||||||
float anglemod (float a) __attribute__((const));
|
float anglemod (float a) __attribute__((const));
|
||||||
|
@ -143,14 +144,15 @@ float anglemod (float a) __attribute__((const));
|
||||||
void RotatePointAroundVector (vec3_t dst, const vec3_t axis,
|
void RotatePointAroundVector (vec3_t dst, const vec3_t axis,
|
||||||
const vec3_t point, float degrees);
|
const vec3_t point, float degrees);
|
||||||
|
|
||||||
|
// NOTE expects plane distance is -p.n
|
||||||
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
|
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
|
||||||
(((p)->type < 3)? \
|
(((p)->type < 3)? \
|
||||||
( \
|
( \
|
||||||
((p)->dist <= (emins)[(p)->type])? \
|
(-(p)->dist <= (emins)[(p)->type])? \
|
||||||
1 \
|
1 \
|
||||||
: \
|
: \
|
||||||
( \
|
( \
|
||||||
((p)->dist >= (emaxs)[(p)->type])? \
|
(-(p)->dist >= (emaxs)[(p)->type])? \
|
||||||
2 \
|
2 \
|
||||||
: \
|
: \
|
||||||
3 \
|
3 \
|
||||||
|
@ -185,6 +187,7 @@ R_CullBox (const plane_t *frustum, const vec3_t mins, const vec3_t maxs)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i < 4 ; i++) {
|
for (i=0 ; i < 4 ; i++) {
|
||||||
|
// NOTE frustum distance is -p.n
|
||||||
if (BOX_ON_PLANE_SIDE (mins, maxs, &frustum[i]) == 2) {
|
if (BOX_ON_PLANE_SIDE (mins, maxs, &frustum[i]) == 2) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -205,7 +208,8 @@ R_CullSphere (const plane_t *frustum, const vec3_t origin, const float radius)
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
r = DotProduct (origin, frustum[i].normal) - frustum[i].dist;
|
// NOTE frustum distance is -p.n
|
||||||
|
r = DotProduct (origin, frustum[i].normal) + frustum[i].dist;
|
||||||
if (r <= -radius)
|
if (r <= -radius)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "QF/modelgen.h"
|
#include "QF/modelgen.h"
|
||||||
#include "QF/zone.h"
|
#include "QF/zone.h"
|
||||||
|
|
||||||
|
#include "QF/simd/types.h"
|
||||||
|
|
||||||
extern struct vid_model_funcs_s *mod_funcs;
|
extern struct vid_model_funcs_s *mod_funcs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -174,18 +176,18 @@ typedef struct msurface_s {
|
||||||
} msurface_t;
|
} msurface_t;
|
||||||
|
|
||||||
typedef struct mnode_s {
|
typedef struct mnode_s {
|
||||||
// common with leaf
|
/// Vector representation of the plane.
|
||||||
int contents; // 0, to differentiate from leafs
|
/// \note the 4th component is the negative of the plane distance. This
|
||||||
int visframe; // node needs to be traversed if current
|
/// makes it so a 4d dot product with a point vector (4th component = 1)
|
||||||
|
/// gives the distance of the point from the plane.
|
||||||
float minmaxs[6]; // for bounding box culling
|
vec4f_t plane;
|
||||||
|
byte type;
|
||||||
// node specific
|
byte signbits;
|
||||||
plane_t *plane;
|
byte pad[2];
|
||||||
struct mnode_s *children[2];
|
int32_t children[2]; ///< Negative values = ~(leaf number)
|
||||||
|
float minmaxs[6];
|
||||||
unsigned int firstsurface;
|
uint32_t firstsurface;
|
||||||
unsigned int numsurfaces;
|
uint32_t numsurfaces;
|
||||||
} mnode_t;
|
} mnode_t;
|
||||||
|
|
||||||
typedef struct mleaf_s {
|
typedef struct mleaf_s {
|
||||||
|
@ -267,8 +269,8 @@ typedef struct mod_brush_s {
|
||||||
byte *lightdata;
|
byte *lightdata;
|
||||||
char *entities; //FIXME should not be here
|
char *entities; //FIXME should not be here
|
||||||
|
|
||||||
mnode_t **node_parents;
|
int32_t *node_parents;
|
||||||
mnode_t **leaf_parents;
|
int32_t *leaf_parents;
|
||||||
int *leaf_flags; // union of surf flags for surfs in leaf
|
int *leaf_flags; // union of surf flags for surfs in leaf
|
||||||
|
|
||||||
unsigned int checksum;
|
unsigned int checksum;
|
||||||
|
@ -437,7 +439,7 @@ model_t *Mod_ForName (const char *name, qboolean crash);
|
||||||
void Mod_TouchModel (const char *name);
|
void Mod_TouchModel (const char *name);
|
||||||
void Mod_UnloadModel (model_t *model);
|
void Mod_UnloadModel (model_t *model);
|
||||||
// brush specific
|
// brush specific
|
||||||
mleaf_t *Mod_PointInLeaf (const vec3_t p, model_t *model) __attribute__((pure));
|
mleaf_t *Mod_PointInLeaf (vec4f_t p, model_t *model) __attribute__((pure));
|
||||||
struct set_s *Mod_LeafPVS (const mleaf_t *leaf, const model_t *model);
|
struct set_s *Mod_LeafPVS (const mleaf_t *leaf, const model_t *model);
|
||||||
|
|
||||||
void Mod_LeafPVS_set (const mleaf_t *leaf, const model_t *model, byte defvis,
|
void Mod_LeafPVS_set (const mleaf_t *leaf, const model_t *model, byte defvis,
|
||||||
|
|
|
@ -59,7 +59,7 @@ typedef struct animation_s {
|
||||||
typedef struct visibility_s {
|
typedef struct visibility_s {
|
||||||
struct entity_s *entity; // owning entity
|
struct entity_s *entity; // owning entity
|
||||||
struct efrag_s *efrag; // linked list of efrags
|
struct efrag_s *efrag; // linked list of efrags
|
||||||
struct mnode_s *topnode; // bmodels, first world node that
|
int topnode_id; // bmodels, first world node that
|
||||||
// splits bmodel, or NULL if not split
|
// splits bmodel, or NULL if not split
|
||||||
// applies to other models, too
|
// applies to other models, too
|
||||||
// found in an active leaf
|
// found in an active leaf
|
||||||
|
|
|
@ -74,7 +74,8 @@ struct entity_s;
|
||||||
struct animation_s;
|
struct animation_s;
|
||||||
void R_DrawAliasModel (struct entity_s *e);
|
void R_DrawAliasModel (struct entity_s *e);
|
||||||
|
|
||||||
void R_MarkLeaves (struct mleaf_s *viewleaf);
|
void R_MarkLeaves (struct mleaf_s *viewleaf, int *node_visframes);
|
||||||
|
extern int *r_node_visframes;
|
||||||
|
|
||||||
void GL_SetPalette (void *data, const byte *palette);
|
void GL_SetPalette (void *data, const byte *palette);
|
||||||
void GLSL_SetPalette (void *data, const byte *palette);
|
void GLSL_SetPalette (void *data, const byte *palette);
|
||||||
|
|
|
@ -159,7 +159,7 @@ texture_t *R_TextureAnimation (const struct entity_s *entity, msurface_t *surf)
|
||||||
|
|
||||||
void R_GenSkyTile (void *pdest);
|
void R_GenSkyTile (void *pdest);
|
||||||
void R_SurfPatch (void);
|
void R_SurfPatch (void);
|
||||||
void R_DrawSubmodelPolygons (struct entity_s *ent, model_t *pmodel, int clipflags, struct mnode_s *topnode);
|
void R_DrawSubmodelPolygons (struct entity_s *ent, model_t *pmodel, int clipflags, struct mleaf_s *topleaf);
|
||||||
void R_DrawSolidClippedSubmodelPolygons (struct entity_s *ent, model_t *pmodel, struct mnode_s *topnode);
|
void R_DrawSolidClippedSubmodelPolygons (struct entity_s *ent, model_t *pmodel, struct mnode_s *topnode);
|
||||||
|
|
||||||
void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel);
|
void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel);
|
||||||
|
@ -308,8 +308,8 @@ void R_SetupFrame (void);
|
||||||
void R_cshift_f (void);
|
void R_cshift_f (void);
|
||||||
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1);
|
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1);
|
||||||
void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
|
void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
|
||||||
void R_RecursiveMarkLights (mod_brush_t *brush, const vec3_t lightorigin,
|
void R_RecursiveMarkLights (mod_brush_t *brush, vec4f_t lightorigin,
|
||||||
struct dlight_s *light, int bit, mnode_t *node);
|
struct dlight_s *light, int bit, int node_id);
|
||||||
|
|
||||||
void R_LoadSkys (const char *);
|
void R_LoadSkys (const char *);
|
||||||
//void Vulkan_R_LoadSkys (const char *, struct vulkan_ctx_s *ctx);
|
//void Vulkan_R_LoadSkys (const char *, struct vulkan_ctx_s *ctx);
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "QF/va.h"
|
#include "QF/va.h"
|
||||||
|
|
||||||
#include "QF/plugin/vid_render.h"
|
#include "QF/plugin/vid_render.h"
|
||||||
|
#include "QF/simd/vec4f.h"
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "mod_internal.h"
|
#include "mod_internal.h"
|
||||||
|
@ -60,25 +61,20 @@ VISIBLE int mod_sky_divide; //FIXME visibility?
|
||||||
VISIBLE int mod_lightmap_bytes = 1; //FIXME should this be visible?
|
VISIBLE int mod_lightmap_bytes = 1; //FIXME should this be visible?
|
||||||
|
|
||||||
VISIBLE mleaf_t *
|
VISIBLE mleaf_t *
|
||||||
Mod_PointInLeaf (const vec3_t p, model_t *model)
|
Mod_PointInLeaf (vec4f_t p, model_t *model)
|
||||||
{
|
{
|
||||||
float d;
|
float d;
|
||||||
mnode_t *node;
|
|
||||||
plane_t *plane;
|
|
||||||
|
|
||||||
if (!model || !model->brush.nodes)
|
if (!model || !model->brush.nodes)
|
||||||
Sys_Error ("Mod_PointInLeaf: bad model");
|
Sys_Error ("Mod_PointInLeaf: bad model");
|
||||||
|
|
||||||
node = model->brush.nodes;
|
int node_id = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (node->contents < 0)
|
if (node_id < 0)
|
||||||
return (mleaf_t *) node;
|
return model->brush.leafs + ~node_id;
|
||||||
plane = node->plane;
|
mnode_t *node = model->brush.nodes + node_id;
|
||||||
d = DotProduct (p, plane->normal) - plane->dist;
|
d = dotf (p, node->plane)[0];
|
||||||
if (d >= 0)
|
node_id = node->children[d < 0];
|
||||||
node = node->children[0];
|
|
||||||
else
|
|
||||||
node = node->children[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL; // never reached
|
return NULL; // never reached
|
||||||
|
@ -668,15 +664,16 @@ Mod_LoadFaces (model_t *mod, bsp_t *bsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Mod_SetParent (mod_brush_t *brush, mnode_t *node, mnode_t *parent)
|
Mod_SetParent (mod_brush_t *brush, int node_id, int parent_id)
|
||||||
{
|
{
|
||||||
if (node->contents < 0) {
|
if (node_id < 0) {
|
||||||
brush->leaf_parents[(mleaf_t *)node - brush->leafs] = parent;
|
brush->leaf_parents[~node_id] = parent_id;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
brush->node_parents[node - brush->nodes] = parent;
|
brush->node_parents[node_id] = parent_id;
|
||||||
Mod_SetParent (brush, node->children[0], node);
|
mnode_t *node = brush->nodes + node_id;
|
||||||
Mod_SetParent (brush, node->children[1], node);
|
Mod_SetParent (brush, node->children[0], node_id);
|
||||||
|
Mod_SetParent (brush, node->children[1], node_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -720,8 +717,11 @@ Mod_LoadNodes (model_t *mod, bsp_t *bsp)
|
||||||
out->minmaxs[3 + j] = in->maxs[j];
|
out->minmaxs[3 + j] = in->maxs[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
p = in->planenum;
|
plane_t *plane = brush->planes + in->planenum;
|
||||||
out->plane = brush->planes + p;
|
out->plane = loadvec3f (plane->normal);
|
||||||
|
out->plane[3] = -plane->dist;
|
||||||
|
out->type = plane->type;
|
||||||
|
out->signbits = plane->signbits;
|
||||||
|
|
||||||
out->firstsurface = in->firstface;
|
out->firstsurface = in->firstface;
|
||||||
out->numsurfaces = in->numfaces;
|
out->numsurfaces = in->numfaces;
|
||||||
|
@ -730,28 +730,27 @@ Mod_LoadNodes (model_t *mod, bsp_t *bsp)
|
||||||
p = in->children[j];
|
p = in->children[j];
|
||||||
// this check is for extended bsp 29 files
|
// this check is for extended bsp 29 files
|
||||||
if (p >= 0) {
|
if (p >= 0) {
|
||||||
out->children[j] = brush->nodes + p;
|
out->children[j] = p;
|
||||||
} else {
|
} else {
|
||||||
p = ~p;
|
if ((unsigned) ~p < brush->modleafs) {
|
||||||
if ((unsigned) p < brush->modleafs) {
|
out->children[j] = p;
|
||||||
out->children[j] = (mnode_t *) (brush->leafs + p);
|
|
||||||
} else {
|
} else {
|
||||||
Sys_Printf ("Mod_LoadNodes: invalid leaf index %i "
|
Sys_Printf ("Mod_LoadNodes: invalid leaf index %i "
|
||||||
"(file has only %i leafs)\n", p,
|
"(file has only %i leafs)\n", ~p,
|
||||||
brush->modleafs);
|
brush->modleafs);
|
||||||
//map it to the solid leaf
|
//map it to the solid leaf
|
||||||
out->children[j] = (mnode_t *)(brush->leafs);
|
out->children[j] = ~0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = (brush->modleafs + brush->numnodes) * sizeof (mnode_t *);
|
size_t size = (brush->modleafs + brush->numnodes) * sizeof (int32_t);
|
||||||
size += brush->modleafs * sizeof (int);
|
size += brush->modleafs * sizeof (int);
|
||||||
brush->node_parents = Hunk_AllocName (0, size, mod->name);
|
brush->node_parents = Hunk_AllocName (0, size, mod->name);
|
||||||
brush->leaf_parents = brush->node_parents + brush->numnodes;
|
brush->leaf_parents = brush->node_parents + brush->numnodes;
|
||||||
brush->leaf_flags = (int *) (brush->leaf_parents + brush->modleafs);
|
brush->leaf_flags = (int *) (brush->leaf_parents + brush->modleafs);
|
||||||
Mod_SetParent (brush, brush->nodes, NULL); // sets nodes and leafs
|
Mod_SetParent (brush, 0, -1); // sets nodes and leafs
|
||||||
Mod_SetLeafFlags (brush);
|
Mod_SetLeafFlags (brush);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -889,12 +888,12 @@ Mod_LoadClipnodes (model_t *mod, bsp_t *bsp)
|
||||||
Replicate the drawing hull structure as a clipping hull
|
Replicate the drawing hull structure as a clipping hull
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
Mod_MakeHull0 (model_t *mod)
|
Mod_MakeHull0 (model_t *mod, bsp_t *bsp)
|
||||||
{
|
{
|
||||||
dclipnode_t *out;
|
dclipnode_t *out;
|
||||||
hull_t *hull;
|
hull_t *hull;
|
||||||
int count, i, j;
|
int count, i, j;
|
||||||
mnode_t *in, *child;
|
mnode_t *in;
|
||||||
mod_brush_t *brush = &mod->brush;
|
mod_brush_t *brush = &mod->brush;
|
||||||
|
|
||||||
hull = &brush->hulls[0];
|
hull = &brush->hulls[0];
|
||||||
|
@ -910,13 +909,14 @@ Mod_MakeHull0 (model_t *mod)
|
||||||
hull->planes = brush->planes;
|
hull->planes = brush->planes;
|
||||||
|
|
||||||
for (i = 0; i < count; i++, out++, in++) {
|
for (i = 0; i < count; i++, out++, in++) {
|
||||||
out->planenum = in->plane - brush->planes;
|
out->planenum = bsp->nodes[i].planenum;
|
||||||
for (j = 0; j < 2; j++) {
|
for (j = 0; j < 2; j++) {
|
||||||
child = in->children[j];
|
int child_id = in->children[j];
|
||||||
if (child->contents < 0)
|
if (child_id < 0) {
|
||||||
out->children[j] = child->contents;
|
out->children[j] = bsp->leafs[~child_id].contents;
|
||||||
else
|
} else {
|
||||||
out->children[j] = child - brush->nodes;
|
out->children[j] = child_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1026,13 +1026,14 @@ do_checksums (const bsp_t *bsp, void *_mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recurse_draw_tree (mod_brush_t *brush, mnode_t *node, int depth)
|
recurse_draw_tree (mod_brush_t *brush, int node_id, int depth)
|
||||||
{
|
{
|
||||||
if (!node || node->contents < 0) {
|
if (node_id < 0) {
|
||||||
if (depth > brush->depth)
|
if (depth > brush->depth)
|
||||||
brush->depth = depth;
|
brush->depth = depth;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mnode_t *node = &brush->nodes[node_id];
|
||||||
recurse_draw_tree (brush, node->children[0], depth + 1);
|
recurse_draw_tree (brush, node->children[0], depth + 1);
|
||||||
recurse_draw_tree (brush, node->children[1], depth + 1);
|
recurse_draw_tree (brush, node->children[1], depth + 1);
|
||||||
}
|
}
|
||||||
|
@ -1041,7 +1042,7 @@ static void
|
||||||
Mod_FindDrawDepth (mod_brush_t *brush)
|
Mod_FindDrawDepth (mod_brush_t *brush)
|
||||||
{
|
{
|
||||||
brush->depth = 0;
|
brush->depth = 0;
|
||||||
recurse_draw_tree (brush, brush->nodes, 1);
|
recurse_draw_tree (brush, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1074,9 +1075,9 @@ Mod_LoadBrushModel (model_t *mod, void *buffer)
|
||||||
Mod_LoadEntities (mod, bsp);
|
Mod_LoadEntities (mod, bsp);
|
||||||
Mod_LoadSubmodels (mod, bsp);
|
Mod_LoadSubmodels (mod, bsp);
|
||||||
|
|
||||||
BSP_Free(bsp);
|
Mod_MakeHull0 (mod, bsp);
|
||||||
|
|
||||||
Mod_MakeHull0 (mod);
|
BSP_Free(bsp);
|
||||||
|
|
||||||
Mod_FindDrawDepth (&mod->brush);
|
Mod_FindDrawDepth (&mod->brush);
|
||||||
for (i = 0; i < MAX_MAP_HULLS; i++)
|
for (i = 0; i < MAX_MAP_HULLS; i++)
|
||||||
|
|
|
@ -78,7 +78,7 @@ Light_AddLight (lightingdata_t *ldata, const light_t *light, int style)
|
||||||
int visleaf = -1; // directional light
|
int visleaf = -1; // directional light
|
||||||
if (light->position[3]) {
|
if (light->position[3]) {
|
||||||
// positional light
|
// positional light
|
||||||
mleaf_t *leaf = Mod_PointInLeaf (&light->position[0], model);
|
mleaf_t *leaf = Mod_PointInLeaf (light->position, model);
|
||||||
visleaf = leaf - model->brush.leafs - 1;
|
visleaf = leaf - model->brush.leafs - 1;
|
||||||
} else if (!DotProduct (light->direction, light->direction)) {
|
} else if (!DotProduct (light->direction, light->direction)) {
|
||||||
// ambient light
|
// ambient light
|
||||||
|
|
|
@ -57,8 +57,8 @@ static mleaf_t empty_leafs[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static mnode_t *empty_leaf_parents[] = {
|
static int empty_leaf_parents[] = {
|
||||||
[1] = 0,
|
[1] = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int empty_leaf_flags[] = {
|
static int empty_leaf_flags[] = {
|
||||||
|
|
|
@ -486,9 +486,9 @@ BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, const plane_t *p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sides = 0;
|
sides = 0;
|
||||||
if (dist1 >= p->dist)
|
if (dist1 >= -p->dist)
|
||||||
sides = 1;
|
sides = 1;
|
||||||
if (dist2 < p->dist)
|
if (dist2 < -p->dist)
|
||||||
sides |= 2;
|
sides |= 2;
|
||||||
|
|
||||||
#ifdef PARANOID
|
#ifdef PARANOID
|
||||||
|
|
|
@ -122,8 +122,8 @@ gl_R_RenderEntities (entqueue_t *queue)
|
||||||
qfglEnable (GL_NORMALIZE);
|
qfglEnable (GL_NORMALIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < queue->ent_queues[mod_alias].size; i++) { \
|
for (size_t i = 0; i < queue->ent_queues[mod_alias].size; i++) {
|
||||||
entity_t *ent = queue->ent_queues[mod_alias].a[i]; \
|
entity_t *ent = queue->ent_queues[mod_alias].a[i];
|
||||||
gl_R_DrawAliasModel (ent);
|
gl_R_DrawAliasModel (ent);
|
||||||
}
|
}
|
||||||
qfglColor3ubv (color_white);
|
qfglColor3ubv (color_white);
|
||||||
|
|
|
@ -173,7 +173,7 @@ gl_R_NewScene (scene_t *scene)
|
||||||
brush->leafs[i].efrags = NULL;
|
brush->leafs[i].efrags = NULL;
|
||||||
|
|
||||||
// Force a vis update
|
// Force a vis update
|
||||||
R_MarkLeaves (0);
|
R_MarkLeaves (0, 0);
|
||||||
|
|
||||||
R_ClearParticles ();
|
R_ClearParticles ();
|
||||||
|
|
||||||
|
|
|
@ -548,16 +548,16 @@ gl_R_DrawBrushModel (entity_t *e)
|
||||||
|
|
||||||
// calculate dynamic lighting for bmodel if it's not an instanced model
|
// calculate dynamic lighting for bmodel if it's not an instanced model
|
||||||
if (brush->firstmodelsurface != 0 && r_dlight_lightmap) {
|
if (brush->firstmodelsurface != 0 && r_dlight_lightmap) {
|
||||||
vec3_t lightorigin;
|
|
||||||
|
|
||||||
for (unsigned k = 0; k < r_maxdlights; k++) {
|
for (unsigned k = 0; k < r_maxdlights; k++) {
|
||||||
if ((r_dlights[k].die < vr_data.realtime)
|
if ((r_dlights[k].die < vr_data.realtime)
|
||||||
|| (!r_dlights[k].radius))
|
|| (!r_dlights[k].radius))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
vec4f_t lightorigin;
|
||||||
VectorSubtract (r_dlights[k].origin, worldMatrix[3], lightorigin);
|
VectorSubtract (r_dlights[k].origin, worldMatrix[3], lightorigin);
|
||||||
|
lightorigin[3] = 1;
|
||||||
R_RecursiveMarkLights (brush, lightorigin, &r_dlights[k], k,
|
R_RecursiveMarkLights (brush, lightorigin, &r_dlights[k], k,
|
||||||
brush->nodes + brush->hulls[0].firstclipnode);
|
brush->hulls[0].firstclipnode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,12 +597,9 @@ static inline int
|
||||||
get_side (mnode_t *node)
|
get_side (mnode_t *node)
|
||||||
{
|
{
|
||||||
// find which side of the node we are on
|
// find which side of the node we are on
|
||||||
plane_t *plane = node->plane;
|
|
||||||
vec4f_t org = r_refdef.frame.position;
|
vec4f_t org = r_refdef.frame.position;
|
||||||
|
|
||||||
if (plane->type < 3)
|
return dotf (org, node->plane)[0] < 0;
|
||||||
return (org[plane->type] - plane->dist) < 0;
|
|
||||||
return (DotProduct (org, plane->normal) - plane->dist) < 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -630,12 +627,13 @@ visit_node (glbspctx_t *bctx, mnode_t *node, int side)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
test_node (mnode_t *node)
|
test_node (glbspctx_t *bctx, int node_id)
|
||||||
{
|
{
|
||||||
if (node->contents < 0)
|
if (node_id < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (node->visframe != r_visframecount)
|
if (r_node_visframes[node_id] != r_visframecount)
|
||||||
return 0;
|
return 0;
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
if (R_CullBox (r_refdef.frustum, node->minmaxs, node->minmaxs + 3))
|
if (R_CullBox (r_refdef.frustum, node->minmaxs, node->minmaxs + 3))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -645,45 +643,55 @@ static void
|
||||||
R_VisitWorldNodes (glbspctx_t *bctx)
|
R_VisitWorldNodes (glbspctx_t *bctx)
|
||||||
{
|
{
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mnode_t *node;
|
int node_id;
|
||||||
int side;
|
int side;
|
||||||
} rstack_t;
|
} rstack_t;
|
||||||
mod_brush_t *brush = bctx->brush;
|
mod_brush_t *brush = bctx->brush;
|
||||||
rstack_t *node_ptr;
|
rstack_t *node_ptr;
|
||||||
rstack_t *node_stack;
|
rstack_t *node_stack;
|
||||||
mnode_t *node;
|
int node_id;
|
||||||
mnode_t *front;
|
int front;
|
||||||
int side;
|
int side;
|
||||||
|
|
||||||
node = brush->nodes;
|
node_id = 0;
|
||||||
// +2 for paranoia
|
// +2 for paranoia
|
||||||
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
||||||
node_ptr = node_stack;
|
node_ptr = node_stack;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while (test_node (node)) {
|
while (test_node (bctx, node_id)) {
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
side = get_side (node);
|
side = get_side (node);
|
||||||
front = node->children[side];
|
front = node->children[side];
|
||||||
if (test_node (front)) {
|
if (test_node (bctx, front)) {
|
||||||
node_ptr->node = node;
|
node_ptr->node_id = node_id;
|
||||||
node_ptr->side = side;
|
node_ptr->side = side;
|
||||||
node_ptr++;
|
node_ptr++;
|
||||||
node = front;
|
node_id = front;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (front->contents < 0 && front->contents != CONTENTS_SOLID)
|
if (front < 0) {
|
||||||
visit_leaf ((mleaf_t *) front);
|
mleaf_t *leaf = bctx->brush->leafs + ~front;
|
||||||
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
|
visit_leaf (leaf);
|
||||||
|
}
|
||||||
|
}
|
||||||
visit_node (bctx, node, side);
|
visit_node (bctx, node, side);
|
||||||
node = node->children[!side];
|
node_id = node->children[side ^ 1];
|
||||||
|
}
|
||||||
|
if (node_id < 0) {
|
||||||
|
mleaf_t *leaf = bctx->brush->leafs + ~node_id;
|
||||||
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
|
visit_leaf (leaf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (node->contents < 0 && node->contents != CONTENTS_SOLID)
|
|
||||||
visit_leaf ((mleaf_t *) node);
|
|
||||||
if (node_ptr != node_stack) {
|
if (node_ptr != node_stack) {
|
||||||
node_ptr--;
|
node_ptr--;
|
||||||
node = node_ptr->node;
|
node_id = node_ptr->node_id;
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
side = node_ptr->side;
|
side = node_ptr->side;
|
||||||
visit_node (bctx, node, side);
|
visit_node (bctx, node, side);
|
||||||
node = node->children[!side];
|
node_id = node->children[side ^ 1];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -694,16 +694,16 @@ R_DrawBrushModel (entity_t *e)
|
||||||
|
|
||||||
// calculate dynamic lighting for bmodel if it's not an instanced model
|
// calculate dynamic lighting for bmodel if it's not an instanced model
|
||||||
if (brush->firstmodelsurface != 0 && r_dlight_lightmap) {
|
if (brush->firstmodelsurface != 0 && r_dlight_lightmap) {
|
||||||
vec3_t lightorigin;
|
|
||||||
|
|
||||||
for (k = 0; k < r_maxdlights; k++) {
|
for (k = 0; k < r_maxdlights; k++) {
|
||||||
if ((r_dlights[k].die < vr_data.realtime)
|
if ((r_dlights[k].die < vr_data.realtime)
|
||||||
|| (!r_dlights[k].radius))
|
|| (!r_dlights[k].radius))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
vec4f_t lightorigin;
|
||||||
VectorSubtract (r_dlights[k].origin, mat[3], lightorigin);
|
VectorSubtract (r_dlights[k].origin, mat[3], lightorigin);
|
||||||
|
lightorigin[3] = 1;
|
||||||
R_RecursiveMarkLights (brush, lightorigin, &r_dlights[k], k,
|
R_RecursiveMarkLights (brush, lightorigin, &r_dlights[k], k,
|
||||||
brush->nodes + brush->hulls[0].firstclipnode);
|
brush->hulls[0].firstclipnode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,12 +736,9 @@ static inline int
|
||||||
get_side (mnode_t *node)
|
get_side (mnode_t *node)
|
||||||
{
|
{
|
||||||
// find the node side on which we are
|
// find the node side on which we are
|
||||||
plane_t *plane = node->plane;
|
|
||||||
vec4f_t org = r_refdef.frame.position;
|
vec4f_t org = r_refdef.frame.position;
|
||||||
|
|
||||||
if (plane->type < 3)
|
return dotf (org, node->plane)[0] < 0;
|
||||||
return (org[plane->type] - plane->dist) < 0;
|
|
||||||
return (DotProduct (org, plane->normal) - plane->dist) < 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -773,12 +770,13 @@ visit_node (glslbspctx_t *bctx, mnode_t *node, int side)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
test_node (mnode_t *node)
|
test_node (glslbspctx_t *bctx, int node_id)
|
||||||
{
|
{
|
||||||
if (node->contents < 0)
|
if (node_id < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (node->visframe != r_visframecount)
|
if (r_node_visframes[node_id] != r_visframecount)
|
||||||
return 0;
|
return 0;
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
if (R_CullBox (r_refdef.frustum, node->minmaxs, node->minmaxs + 3))
|
if (R_CullBox (r_refdef.frustum, node->minmaxs, node->minmaxs + 3))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -788,45 +786,55 @@ static void
|
||||||
R_VisitWorldNodes (glslbspctx_t *bctx)
|
R_VisitWorldNodes (glslbspctx_t *bctx)
|
||||||
{
|
{
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mnode_t *node;
|
int node_id;
|
||||||
int side;
|
int side;
|
||||||
} rstack_t;
|
} rstack_t;
|
||||||
mod_brush_t *brush = bctx->brush;
|
mod_brush_t *brush = bctx->brush;
|
||||||
rstack_t *node_ptr;
|
rstack_t *node_ptr;
|
||||||
rstack_t *node_stack;
|
rstack_t *node_stack;
|
||||||
mnode_t *node;
|
int node_id;
|
||||||
mnode_t *front;
|
int front;
|
||||||
int side;
|
int side;
|
||||||
|
|
||||||
node = brush->nodes;
|
node_id = 0;
|
||||||
// +2 for paranoia
|
// +2 for paranoia
|
||||||
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
||||||
node_ptr = node_stack;
|
node_ptr = node_stack;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while (test_node (node)) {
|
while (test_node (bctx, node_id)) {
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
side = get_side (node);
|
side = get_side (node);
|
||||||
front = node->children[side];
|
front = node->children[side];
|
||||||
if (test_node (front)) {
|
if (test_node (bctx, front)) {
|
||||||
node_ptr->node = node;
|
node_ptr->node_id = node_id;
|
||||||
node_ptr->side = side;
|
node_ptr->side = side;
|
||||||
node_ptr++;
|
node_ptr++;
|
||||||
node = front;
|
node_id = front;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (front->contents < 0 && front->contents != CONTENTS_SOLID)
|
if (front < 0) {
|
||||||
visit_leaf ((mleaf_t *) front);
|
mleaf_t *leaf = bctx->brush->leafs + ~front;
|
||||||
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
|
visit_leaf (leaf);
|
||||||
|
}
|
||||||
|
}
|
||||||
visit_node (bctx, node, side);
|
visit_node (bctx, node, side);
|
||||||
node = node->children[!side];
|
node_id = node->children[side ^ 1];
|
||||||
|
}
|
||||||
|
if (node_id < 0) {
|
||||||
|
mleaf_t *leaf = bctx->brush->leafs + ~node_id;
|
||||||
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
|
visit_leaf (leaf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (node->contents < 0 && node->contents != CONTENTS_SOLID)
|
|
||||||
visit_leaf ((mleaf_t *) node);
|
|
||||||
if (node_ptr != node_stack) {
|
if (node_ptr != node_stack) {
|
||||||
node_ptr--;
|
node_ptr--;
|
||||||
node = node_ptr->node;
|
node_id = node_ptr->node_id;
|
||||||
side = node_ptr->side;
|
side = node_ptr->side;
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
visit_node (bctx, node, side);
|
visit_node (bctx, node, side);
|
||||||
node = node->children[!side];
|
node_id = node->children[side ^ 1];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -199,7 +199,7 @@ glsl_R_NewScene (scene_t *scene)
|
||||||
r_refdef.worldmodel = scene->worldmodel;
|
r_refdef.worldmodel = scene->worldmodel;
|
||||||
|
|
||||||
// Force a vis update
|
// Force a vis update
|
||||||
R_MarkLeaves (0);
|
R_MarkLeaves (0, 0);
|
||||||
|
|
||||||
R_ClearParticles ();
|
R_ClearParticles ();
|
||||||
glsl_R_RegisterTextures (scene->models, scene->num_models);
|
glsl_R_RegisterTextures (scene->models, scene->num_models);
|
||||||
|
|
|
@ -47,12 +47,11 @@ static mleaf_t *r_oldviewleaf;
|
||||||
static set_t *solid;
|
static set_t *solid;
|
||||||
|
|
||||||
void
|
void
|
||||||
R_MarkLeaves (mleaf_t *viewleaf)
|
R_MarkLeaves (mleaf_t *viewleaf, int *node_visframes)
|
||||||
{
|
{
|
||||||
set_t *vis;
|
set_t *vis;
|
||||||
int c;
|
int c;
|
||||||
mleaf_t *leaf;
|
mleaf_t *leaf;
|
||||||
mnode_t *node;
|
|
||||||
msurface_t **mark;
|
msurface_t **mark;
|
||||||
mod_brush_t *brush = &r_refdef.worldmodel->brush;
|
mod_brush_t *brush = &r_refdef.worldmodel->brush;
|
||||||
|
|
||||||
|
@ -86,12 +85,12 @@ R_MarkLeaves (mleaf_t *viewleaf)
|
||||||
} while (--c);
|
} while (--c);
|
||||||
}
|
}
|
||||||
leaf->visframe = r_visframecount;
|
leaf->visframe = r_visframecount;
|
||||||
node = brush->leaf_parents[leaf - brush->leafs];
|
int node_id = brush->leaf_parents[leaf - brush->leafs];
|
||||||
while (node) {
|
while (node_id >= 0) {
|
||||||
if (node->visframe == r_visframecount)
|
if (node_visframes[node_id] == r_visframecount)
|
||||||
break;
|
break;
|
||||||
node->visframe = r_visframecount;
|
node_visframes[node_id] = r_visframecount;
|
||||||
node = brush->node_parents[node - brush->nodes];
|
node_id = brush->node_parents[node_id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,25 +140,25 @@ R_SplitEntityOnNode (mod_brush_t *brush, entity_t *ent,
|
||||||
mleaf_t *leaf;
|
mleaf_t *leaf;
|
||||||
int sides;
|
int sides;
|
||||||
efrag_t **lastlink;
|
efrag_t **lastlink;
|
||||||
mnode_t **node_stack;
|
int *node_stack;
|
||||||
mnode_t **node_ptr;
|
int *node_ptr;
|
||||||
mnode_t *node = brush->nodes;
|
|
||||||
|
|
||||||
node_stack = alloca ((brush->depth + 2) * sizeof (mnode_t *));
|
node_stack = alloca ((brush->depth + 2) * sizeof (mnode_t *));
|
||||||
node_ptr = node_stack;
|
node_ptr = node_stack;
|
||||||
|
|
||||||
lastlink = &ent->visibility.efrag;
|
lastlink = &ent->visibility.efrag;
|
||||||
|
|
||||||
*node_ptr++ = 0;
|
*node_ptr++ = brush->numnodes;
|
||||||
|
|
||||||
while (node) {
|
int node_id = 0;
|
||||||
|
while (node_id != (int) brush->numnodes) {
|
||||||
// add an efrag if the node is a leaf
|
// add an efrag if the node is a leaf
|
||||||
if (__builtin_expect (node->contents < 0, 0)) {
|
if (__builtin_expect (node_id < 0, 0)) {
|
||||||
if (!ent->visibility.topnode) {
|
if (ent->visibility.topnode_id == -1) {
|
||||||
ent->visibility.topnode = node;
|
ent->visibility.topnode_id = node_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
leaf = (mleaf_t *) node;
|
leaf = brush->leafs + ~node_id;
|
||||||
|
|
||||||
ef = new_efrag (); // ensures ef->entnext is 0
|
ef = new_efrag (); // ensures ef->entnext is 0
|
||||||
|
|
||||||
|
@ -172,29 +172,30 @@ R_SplitEntityOnNode (mod_brush_t *brush, entity_t *ent,
|
||||||
ef->leafnext = leaf->efrags;
|
ef->leafnext = leaf->efrags;
|
||||||
leaf->efrags = ef;
|
leaf->efrags = ef;
|
||||||
|
|
||||||
node = *--node_ptr;
|
node_id = *--node_ptr;
|
||||||
} else {
|
} else {
|
||||||
|
mnode_t *node = brush->nodes + node_id;
|
||||||
// NODE_MIXED
|
// NODE_MIXED
|
||||||
splitplane = node->plane;
|
splitplane = (plane_t *) &node->plane;
|
||||||
sides = BOX_ON_PLANE_SIDE (emins, emaxs, splitplane);
|
sides = BOX_ON_PLANE_SIDE (emins, emaxs, splitplane);
|
||||||
|
|
||||||
if (sides == 3) {
|
if (sides == 3) {
|
||||||
// split on this plane
|
// split on this plane
|
||||||
// if this is the first splitter of this bmodel, remember it
|
// if this is the first splitter of this bmodel, remember it
|
||||||
if (!ent->visibility.topnode) {
|
if (ent->visibility.topnode_id == -1) {
|
||||||
ent->visibility.topnode = node;
|
ent->visibility.topnode_id = node_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// recurse down the contacted sides
|
// recurse down the contacted sides
|
||||||
if (sides & 1 && node->children[0]->contents != CONTENTS_SOLID) {
|
if (sides & 1) {
|
||||||
if (sides & 2 && node->children[1]->contents != CONTENTS_SOLID)
|
if (sides & 2)
|
||||||
*node_ptr++ = node->children[1];
|
*node_ptr++ = node->children[1];
|
||||||
node = node->children[0];
|
node_id = node->children[0];
|
||||||
} else {
|
} else {
|
||||||
if (sides & 2 && node->children[1]->contents != CONTENTS_SOLID)
|
if (sides & 2)
|
||||||
node = node->children[1];
|
node_id = node->children[1];
|
||||||
else
|
else
|
||||||
node = *--node_ptr;
|
node_id = *--node_ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +217,7 @@ R_AddEfrags (mod_brush_t *brush, entity_t *ent)
|
||||||
VectorAdd (org, entmodel->mins, emins);
|
VectorAdd (org, entmodel->mins, emins);
|
||||||
VectorAdd (org, entmodel->maxs, emaxs);
|
VectorAdd (org, entmodel->maxs, emaxs);
|
||||||
|
|
||||||
ent->visibility.topnode = 0;
|
ent->visibility.topnode_id = -1; // leaf 0 (solid space)
|
||||||
R_SplitEntityOnNode (brush, ent, emins, emaxs);
|
R_SplitEntityOnNode (brush, ent, emins, emaxs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ R_AnimateLight (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
real_mark_surfaces (float dist, msurface_t *surf, const vec3_t lightorigin,
|
real_mark_surfaces (float dist, msurface_t *surf, vec4f_t lightorigin,
|
||||||
dlight_t *light, unsigned lightnum)
|
dlight_t *light, unsigned lightnum)
|
||||||
{
|
{
|
||||||
float dist2, is, it;
|
float dist2, is, it;
|
||||||
|
@ -190,7 +190,7 @@ real_mark_surfaces (float dist, msurface_t *surf, const vec3_t lightorigin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
mark_surfaces (msurface_t *surf, const vec3_t lightorigin, dlight_t *light,
|
mark_surfaces (msurface_t *surf, vec4f_t lightorigin, dlight_t *light,
|
||||||
int lightnum)
|
int lightnum)
|
||||||
{
|
{
|
||||||
float dist;
|
float dist;
|
||||||
|
@ -208,35 +208,33 @@ mark_surfaces (msurface_t *surf, const vec3_t lightorigin, dlight_t *light,
|
||||||
// LordHavoc: heavily modified, to eliminate unnecessary texture uploads,
|
// LordHavoc: heavily modified, to eliminate unnecessary texture uploads,
|
||||||
// and support bmodel lighting better
|
// and support bmodel lighting better
|
||||||
void
|
void
|
||||||
R_RecursiveMarkLights (mod_brush_t *brush, const vec3_t lightorigin,
|
R_RecursiveMarkLights (mod_brush_t *brush, vec4f_t lightorigin,
|
||||||
dlight_t *light, int lightnum, mnode_t *node)
|
dlight_t *light, int lightnum, int node_id)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
float ndist, maxdist;
|
float ndist, maxdist;
|
||||||
plane_t *splitplane;
|
|
||||||
msurface_t *surf;
|
msurface_t *surf;
|
||||||
|
|
||||||
maxdist = light->radius;
|
maxdist = light->radius;
|
||||||
|
|
||||||
loc0:
|
loc0:
|
||||||
if (node->contents < 0)
|
if (node_id < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
splitplane = node->plane;
|
mnode_t *node = brush->nodes + node_id;
|
||||||
ndist = DotProduct (lightorigin, splitplane->normal) - splitplane->dist;
|
ndist = dotf (lightorigin, node->plane)[0];
|
||||||
|
|
||||||
if (ndist > maxdist * maxdist) {
|
if (ndist > maxdist * maxdist) {
|
||||||
// Save time by not pushing another stack frame.
|
// Save time by not pushing another stack frame.
|
||||||
if (node->children[0]->contents >= 0) {
|
if (node->children[0] >= 0) {
|
||||||
node = node->children[0];
|
node_id = node->children[0];
|
||||||
goto loc0;
|
goto loc0;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ndist < -maxdist * maxdist) {
|
if (ndist < -maxdist * maxdist) {
|
||||||
// Save time by not pushing another stack frame.
|
if (node->children[1] >= 0) {
|
||||||
if (node->children[1]->contents >= 0) {
|
node_id = node->children[1];
|
||||||
node = node->children[1];
|
|
||||||
goto loc0;
|
goto loc0;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -248,29 +246,29 @@ loc0:
|
||||||
mark_surfaces (surf, lightorigin, light, lightnum);
|
mark_surfaces (surf, lightorigin, light, lightnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->children[0]->contents >= 0) {
|
if (node->children[0] >= 0) {
|
||||||
if (node->children[1]->contents >= 0)
|
if (node->children[1] >= 0)
|
||||||
R_RecursiveMarkLights (brush, lightorigin, light, lightnum,
|
R_RecursiveMarkLights (brush, lightorigin, light, lightnum,
|
||||||
node->children[1]);
|
node->children[1]);
|
||||||
node = node->children[0];
|
node_id = node->children[0];
|
||||||
goto loc0;
|
goto loc0;
|
||||||
} else if (node->children[1]->contents >= 0) {
|
} else if (node->children[1] >= 0) {
|
||||||
node = node->children[1];
|
node_id = node->children[1];
|
||||||
goto loc0;
|
goto loc0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
R_MarkLights (const vec3_t lightorigin, dlight_t *light, int lightnum,
|
R_MarkLights (vec4f_t lightorigin, dlight_t *light, int lightnum,
|
||||||
model_t *model)
|
model_t *model)
|
||||||
{
|
{
|
||||||
mod_brush_t *brush = &model->brush;
|
mod_brush_t *brush = &model->brush;
|
||||||
mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model);
|
mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model);
|
||||||
|
|
||||||
if (!pvsleaf->compressed_vis) {
|
if (!pvsleaf->compressed_vis) {
|
||||||
mnode_t *node = brush->nodes + brush->hulls[0].firstclipnode;
|
int node_id = brush->hulls[0].firstclipnode;
|
||||||
R_RecursiveMarkLights (brush, lightorigin, light, lightnum, node);
|
R_RecursiveMarkLights (brush, lightorigin, light, lightnum, node_id);
|
||||||
} else {
|
} else {
|
||||||
float radius = light->radius;
|
float radius = light->radius;
|
||||||
vec3_t mins, maxs;
|
vec3_t mins, maxs;
|
||||||
|
@ -321,7 +319,6 @@ R_PushDlights (const vec3_t entorigin)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
dlight_t *l;
|
dlight_t *l;
|
||||||
vec3_t lightorigin;
|
|
||||||
|
|
||||||
// because the count hasn't advanced yet for this frame
|
// because the count hasn't advanced yet for this frame
|
||||||
r_dlightframecount = r_framecount + 1;
|
r_dlightframecount = r_framecount + 1;
|
||||||
|
@ -334,14 +331,15 @@ R_PushDlights (const vec3_t entorigin)
|
||||||
for (i = 0; i < r_maxdlights; i++, l++) {
|
for (i = 0; i < r_maxdlights; i++, l++) {
|
||||||
if (l->die < r_data->realtime || !l->radius)
|
if (l->die < r_data->realtime || !l->radius)
|
||||||
continue;
|
continue;
|
||||||
|
vec4f_t lightorigin;
|
||||||
VectorSubtract (l->origin, entorigin, lightorigin);
|
VectorSubtract (l->origin, entorigin, lightorigin);
|
||||||
|
lightorigin[3] = 1;
|
||||||
R_MarkLights (lightorigin, l, i, r_refdef.worldmodel);
|
R_MarkLights (lightorigin, l, i, r_refdef.worldmodel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LIGHT SAMPLING */
|
/* LIGHT SAMPLING */
|
||||||
|
|
||||||
plane_t *lightplane;
|
|
||||||
vec3_t lightspot;
|
vec3_t lightspot;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -408,27 +406,26 @@ calc_lighting_3 (msurface_t *surf, int ds, int dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
RecursiveLightPoint (mod_brush_t *brush, mnode_t *node, vec4f_t start,
|
RecursiveLightPoint (mod_brush_t *brush, int node_id, vec4f_t start,
|
||||||
vec4f_t end)
|
vec4f_t end)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int r, s, t, ds, dt, side;
|
int r, s, t, ds, dt, side;
|
||||||
float front, back, frac;
|
float front, back, frac;
|
||||||
plane_t *plane;
|
|
||||||
msurface_t *surf;
|
msurface_t *surf;
|
||||||
mtexinfo_t *tex;
|
mtexinfo_t *tex;
|
||||||
loop:
|
loop:
|
||||||
if (node->contents < 0)
|
if (node_id < 0)
|
||||||
return -1; // didn't hit anything
|
return -1; // didn't hit anything
|
||||||
|
|
||||||
// calculate mid point
|
// calculate mid point
|
||||||
plane = node->plane;
|
mnode_t *node = brush->nodes + node_id;
|
||||||
front = DotProduct (start, plane->normal) - plane->dist;
|
front = dotf (start, node->plane)[0];
|
||||||
back = DotProduct (end, plane->normal) - plane->dist;
|
back = dotf (end, node->plane)[0];
|
||||||
side = front < 0;
|
side = front < 0;
|
||||||
|
|
||||||
if ((back < 0) == side) {
|
if ((back < 0) == side) {
|
||||||
node = node->children[side];
|
node_id = node->children[side];
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +442,6 @@ loop:
|
||||||
|
|
||||||
// check for impact on this node
|
// check for impact on this node
|
||||||
VectorCopy (mid, lightspot);
|
VectorCopy (mid, lightspot);
|
||||||
lightplane = plane;
|
|
||||||
|
|
||||||
surf = brush->surfaces + node->firstsurface;
|
surf = brush->surfaces + node->firstsurface;
|
||||||
for (i = 0; i < node->numsurfaces; i++, surf++) {
|
for (i = 0; i < node->numsurfaces; i++, surf++) {
|
||||||
|
@ -478,7 +474,7 @@ loop:
|
||||||
}
|
}
|
||||||
|
|
||||||
// go down back side
|
// go down back side
|
||||||
return RecursiveLightPoint (brush, node->children[!side], mid, end);
|
return RecursiveLightPoint (brush, node->children[side ^ 1], mid, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -491,7 +487,7 @@ R_LightPoint (mod_brush_t *brush, vec4f_t p)
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4f_t end = p - (vec4f_t) { 0, 0, 2048, 0 };
|
vec4f_t end = p - (vec4f_t) { 0, 0, 2048, 0 };
|
||||||
int r = RecursiveLightPoint (brush, brush->nodes, p, end);
|
int r = RecursiveLightPoint (brush, 0, p, end);
|
||||||
|
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
|
@ -111,7 +111,7 @@ R_SetFrustum (plane_t *frustum, const refframe_t *frame,
|
||||||
vec4f_t origin = frame->position;
|
vec4f_t origin = frame->position;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
frustum[i].type = PLANE_ANYZ;
|
frustum[i].type = PLANE_ANYZ;
|
||||||
frustum[i].dist = DotProduct (origin, frustum[i].normal);
|
frustum[i].dist = -DotProduct (origin, frustum[i].normal);
|
||||||
frustum[i].signbits = SignbitsForPlane (&frustum[i]);
|
frustum[i].signbits = SignbitsForPlane (&frustum[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
int scr_copytop;
|
int scr_copytop;
|
||||||
byte *draw_chars; // 8*8 graphic characters FIXME location
|
byte *draw_chars; // 8*8 graphic characters FIXME location
|
||||||
qboolean r_cache_thrash; // set if surface cache is thrashing
|
qboolean r_cache_thrash; // set if surface cache is thrashing
|
||||||
|
int *r_node_visframes; //FIXME per renderer
|
||||||
|
|
||||||
qboolean scr_skipupdate;
|
qboolean scr_skipupdate;
|
||||||
static qboolean scr_initialized;// ready to draw
|
static qboolean scr_initialized;// ready to draw
|
||||||
|
@ -273,8 +274,7 @@ SCR_UpdateScreen (transform_t *camera, double realtime, SCR_Func *scr_funcs)
|
||||||
if (scr_scene && scr_scene->worldmodel) {
|
if (scr_scene && scr_scene->worldmodel) {
|
||||||
scr_scene->viewleaf = 0;
|
scr_scene->viewleaf = 0;
|
||||||
vec4f_t position = refdef->frame.position;
|
vec4f_t position = refdef->frame.position;
|
||||||
scr_scene->viewleaf = Mod_PointInLeaf ((vec_t*)&position,
|
scr_scene->viewleaf = Mod_PointInLeaf (position, scr_scene->worldmodel);
|
||||||
scr_scene->worldmodel);//FIXME
|
|
||||||
r_dowarpold = r_dowarp;
|
r_dowarpold = r_dowarp;
|
||||||
if (r_waterwarp) {
|
if (r_waterwarp) {
|
||||||
r_dowarp = scr_scene->viewleaf->contents <= CONTENTS_WATER;
|
r_dowarp = scr_scene->viewleaf->contents <= CONTENTS_WATER;
|
||||||
|
@ -283,7 +283,7 @@ SCR_UpdateScreen (transform_t *camera, double realtime, SCR_Func *scr_funcs)
|
||||||
warp_buffer = r_funcs->create_frame_buffer (r_data->vid->width,
|
warp_buffer = r_funcs->create_frame_buffer (r_data->vid->width,
|
||||||
r_data->vid->height);
|
r_data->vid->height);
|
||||||
}
|
}
|
||||||
R_MarkLeaves (scr_scene->viewleaf);
|
R_MarkLeaves (scr_scene->viewleaf, r_node_visframes);
|
||||||
}
|
}
|
||||||
R_PushDlights (vec3_origin);
|
R_PushDlights (vec3_origin);
|
||||||
|
|
||||||
|
@ -514,6 +514,9 @@ SCR_NewScene (scene_t *scene)
|
||||||
{
|
{
|
||||||
scr_scene = scene;
|
scr_scene = scene;
|
||||||
if (scene) {
|
if (scene) {
|
||||||
|
mod_brush_t *brush = &scr_scene->worldmodel->brush;
|
||||||
|
int size = brush->numnodes * sizeof (int);
|
||||||
|
r_node_visframes = Hunk_AllocName (0, size, "visframes");
|
||||||
r_funcs->set_fov (tan_fov_x, tan_fov_y);
|
r_funcs->set_fov (tan_fov_x, tan_fov_y);
|
||||||
r_funcs->R_NewScene (scene);
|
r_funcs->R_NewScene (scene);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -118,8 +118,8 @@ R_RecursiveClipBPoly (entity_t *ent, bedge_t *pedges, mnode_t *pnode,
|
||||||
|
|
||||||
// transform the BSP plane into model space
|
// transform the BSP plane into model space
|
||||||
// FIXME: cache these?
|
// FIXME: cache these?
|
||||||
splitplane = pnode->plane;
|
splitplane = (plane_t *) &pnode->plane;
|
||||||
tplane.dist = splitplane->dist -
|
tplane.dist = splitplane->dist +
|
||||||
DotProduct (r_entorigin, splitplane->normal);
|
DotProduct (r_entorigin, splitplane->normal);
|
||||||
tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal);
|
tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal);
|
||||||
tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal);
|
tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal);
|
||||||
|
@ -132,7 +132,7 @@ R_RecursiveClipBPoly (entity_t *ent, bedge_t *pedges, mnode_t *pnode,
|
||||||
// set the status for the last point as the previous point
|
// set the status for the last point as the previous point
|
||||||
// FIXME: cache this stuff somehow?
|
// FIXME: cache this stuff somehow?
|
||||||
plastvert = pedges->v[0];
|
plastvert = pedges->v[0];
|
||||||
lastdist = DotProduct (plastvert->position, tplane.normal) -
|
lastdist = DotProduct (plastvert->position, tplane.normal) +
|
||||||
tplane.dist;
|
tplane.dist;
|
||||||
|
|
||||||
if (lastdist > 0)
|
if (lastdist > 0)
|
||||||
|
@ -142,7 +142,7 @@ R_RecursiveClipBPoly (entity_t *ent, bedge_t *pedges, mnode_t *pnode,
|
||||||
|
|
||||||
pvert = pedges->v[1];
|
pvert = pedges->v[1];
|
||||||
|
|
||||||
dist = DotProduct (pvert->position, tplane.normal) - tplane.dist;
|
dist = DotProduct (pvert->position, tplane.normal) + tplane.dist;
|
||||||
|
|
||||||
if (dist > 0)
|
if (dist > 0)
|
||||||
side = 0;
|
side = 0;
|
||||||
|
@ -228,18 +228,20 @@ R_RecursiveClipBPoly (entity_t *ent, bedge_t *pedges, mnode_t *pnode,
|
||||||
if (psideedges[i]) {
|
if (psideedges[i]) {
|
||||||
// draw if we've reached a non-solid leaf, done if all that's left
|
// 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
|
// is a solid leaf, and continue down the tree if it's not a leaf
|
||||||
pn = pnode->children[i];
|
int child_id = pnode->children[i];
|
||||||
|
pn = r_refdef.worldmodel->brush.nodes + child_id;
|
||||||
|
|
||||||
// we're done with this branch if the node or leaf isn't in the PVS
|
// we're done with this branch if the node or leaf isn't in the PVS
|
||||||
if (pn->visframe == r_visframecount) {
|
if (child_id < 0) {
|
||||||
if (pn->contents < 0) {
|
mleaf_t *leaf = r_refdef.worldmodel->brush.leafs + ~child_id;
|
||||||
if (pn->contents != CONTENTS_SOLID) {
|
if (leaf->visframe == r_visframecount
|
||||||
r_currentbkey = ((mleaf_t *) pn)->key;
|
&& leaf->contents != CONTENTS_SOLID) {
|
||||||
R_RenderBmodelFace (ent, psideedges[i], psurf);
|
r_currentbkey = leaf->key;
|
||||||
}
|
R_RenderBmodelFace (ent, psideedges[i], psurf);
|
||||||
} else {
|
}
|
||||||
R_RecursiveClipBPoly (ent, psideedges[i],
|
} else {
|
||||||
pnode->children[i], psurf);
|
if (r_node_visframes[child_id] == r_visframecount) {
|
||||||
|
R_RecursiveClipBPoly (ent, psideedges[i], pn, psurf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,7 +322,7 @@ R_DrawSolidClippedSubmodelPolygons (entity_t *ent, model_t *model,
|
||||||
|
|
||||||
void
|
void
|
||||||
R_DrawSubmodelPolygons (entity_t *ent, model_t *model, int clipflags,
|
R_DrawSubmodelPolygons (entity_t *ent, model_t *model, int clipflags,
|
||||||
mnode_t *topnode)
|
mleaf_t *topleaf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
vec_t dot;
|
vec_t dot;
|
||||||
|
@ -343,7 +345,7 @@ R_DrawSubmodelPolygons (entity_t *ent, model_t *model, int clipflags,
|
||||||
// draw the polygon
|
// draw the polygon
|
||||||
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
|
||||||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
|
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
|
||||||
r_currentkey = ((mleaf_t *) topnode)->key;
|
r_currentkey = topleaf->key;
|
||||||
|
|
||||||
// FIXME: use bounding-box-based frustum clipping info?
|
// FIXME: use bounding-box-based frustum clipping info?
|
||||||
R_RenderFace (ent, psurf, clipflags);
|
R_RenderFace (ent, psurf, clipflags);
|
||||||
|
@ -365,12 +367,9 @@ static inline int
|
||||||
get_side (mnode_t *node)
|
get_side (mnode_t *node)
|
||||||
{
|
{
|
||||||
// find which side of the node we are on
|
// find which side of the node we are on
|
||||||
plane_t *plane = node->plane;
|
|
||||||
vec4f_t org = r_refdef.frame.position;
|
vec4f_t org = r_refdef.frame.position;
|
||||||
|
|
||||||
if (plane->type < 3)
|
return dotf (org, node->plane)[0] < 0;
|
||||||
return (org[plane->type] - plane->dist) < 0;
|
|
||||||
return (DotProduct (org, plane->normal) - plane->dist) < 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -414,20 +413,21 @@ visit_node (swbspctx_t *bctx, mnode_t *node, int side, int clipflags)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
test_node (mnode_t *node, int *clipflags)
|
test_node (swbspctx_t *bctx, int node_id, int *clipflags)
|
||||||
{
|
{
|
||||||
int i, *pindex;
|
int i, *pindex;
|
||||||
vec3_t acceptpt, rejectpt;
|
vec3_t acceptpt, rejectpt;
|
||||||
double d;
|
double d;
|
||||||
|
|
||||||
if (node->contents < 0)
|
if (node_id < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (node->visframe != r_visframecount)
|
if (r_node_visframes[node_id] != r_visframecount)
|
||||||
return 0;
|
return 0;
|
||||||
// cull the clipping planes if not trivial accept
|
// cull the clipping planes if not trivial accept
|
||||||
// FIXME: the compiler is doing a lousy job of optimizing here; it could be
|
// FIXME: the compiler is doing a lousy job of optimizing here; it could be
|
||||||
// twice as fast in ASM
|
// twice as fast in ASM
|
||||||
if (*clipflags) {
|
if (*clipflags) {
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (!(*clipflags & (1 << i)))
|
if (!(*clipflags & (1 << i)))
|
||||||
continue; // don't need to clip against it
|
continue; // don't need to clip against it
|
||||||
|
@ -465,50 +465,60 @@ static void
|
||||||
R_VisitWorldNodes (swbspctx_t *bctx, int clipflags)
|
R_VisitWorldNodes (swbspctx_t *bctx, int clipflags)
|
||||||
{
|
{
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mnode_t *node;
|
int node_id;
|
||||||
int side, clipflags;
|
int side, clipflags;
|
||||||
} rstack_t;
|
} rstack_t;
|
||||||
rstack_t *node_ptr;
|
rstack_t *node_ptr;
|
||||||
rstack_t *node_stack;
|
rstack_t *node_stack;
|
||||||
mnode_t *node;
|
int front;
|
||||||
mnode_t *front;
|
|
||||||
int side, cf;
|
int side, cf;
|
||||||
|
int node_id;
|
||||||
mod_brush_t *brush = &bctx->entity->renderer.model->brush;
|
mod_brush_t *brush = &bctx->entity->renderer.model->brush;
|
||||||
|
|
||||||
node = brush->nodes;
|
|
||||||
// +2 for paranoia
|
// +2 for paranoia
|
||||||
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
||||||
node_ptr = node_stack;
|
node_ptr = node_stack;
|
||||||
|
|
||||||
|
node_id = 0;
|
||||||
cf = clipflags;
|
cf = clipflags;
|
||||||
while (1) {
|
while (1) {
|
||||||
while (test_node (node, &cf)) {
|
while (test_node (bctx, node_id, &cf)) {
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
cf = clipflags;
|
cf = clipflags;
|
||||||
side = get_side (node);
|
side = get_side (node);
|
||||||
front = node->children[side];
|
front = node->children[side];
|
||||||
if (test_node (front, &cf)) {
|
if (test_node (bctx, front, &cf)) {
|
||||||
node_ptr->node = node;
|
node_ptr->node_id = node_id;
|
||||||
node_ptr->side = side;
|
node_ptr->side = side;
|
||||||
node_ptr->clipflags = clipflags;
|
node_ptr->clipflags = clipflags;
|
||||||
node_ptr++;
|
node_ptr++;
|
||||||
clipflags = cf;
|
clipflags = cf;
|
||||||
node = front;
|
node_id = front;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (front->contents < 0 && front->contents != CONTENTS_SOLID)
|
if (front < 0) {
|
||||||
visit_leaf ((mleaf_t *) front);
|
mleaf_t *leaf = bctx->brush->leafs + ~front;
|
||||||
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
|
visit_leaf (leaf);
|
||||||
|
}
|
||||||
|
}
|
||||||
visit_node (bctx, node, side, clipflags);
|
visit_node (bctx, node, side, clipflags);
|
||||||
node = node->children[!side];
|
node_id = node->children[side ^ 1];
|
||||||
|
}
|
||||||
|
if (node_id < 0) {
|
||||||
|
mleaf_t *leaf = bctx->brush->leafs + ~node_id;
|
||||||
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
|
visit_leaf (leaf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (node->contents < 0 && node->contents != CONTENTS_SOLID)
|
|
||||||
visit_leaf ((mleaf_t *) node);
|
|
||||||
if (node_ptr != node_stack) {
|
if (node_ptr != node_stack) {
|
||||||
node_ptr--;
|
node_ptr--;
|
||||||
node = node_ptr->node;
|
node_id = node_ptr->node_id;
|
||||||
|
mnode_t *node = bctx->brush->nodes + node_id;
|
||||||
side = node_ptr->side;
|
side = node_ptr->side;
|
||||||
clipflags = node_ptr->clipflags;
|
clipflags = node_ptr->clipflags;
|
||||||
visit_node (bctx, node, side, clipflags);
|
visit_node (bctx, node, side, clipflags);
|
||||||
node = node->children[!side];
|
node_id = node->children[side ^ 1];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -167,7 +167,7 @@ R_NewScene (scene_t *scene)
|
||||||
R_InitSky (brush->skytexture);
|
R_InitSky (brush->skytexture);
|
||||||
|
|
||||||
// Force a vis update
|
// Force a vis update
|
||||||
R_MarkLeaves (0);
|
R_MarkLeaves (0, 0);
|
||||||
|
|
||||||
R_ClearParticles ();
|
R_ClearParticles ();
|
||||||
|
|
||||||
|
@ -303,8 +303,7 @@ R_DrawEntitiesOnList (entqueue_t *queue)
|
||||||
for (size_t i = 0; i < queue->ent_queues[mod_##type_name].size; \
|
for (size_t i = 0; i < queue->ent_queues[mod_##type_name].size; \
|
||||||
i++) { \
|
i++) { \
|
||||||
entity_t *ent = queue->ent_queues[mod_##type_name].a[i]; \
|
entity_t *ent = queue->ent_queues[mod_##type_name].a[i]; \
|
||||||
VectorCopy (Transform_GetWorldPosition (ent->transform), \
|
r_entorigin = Transform_GetWorldPosition (ent->transform); \
|
||||||
r_entorigin); \
|
|
||||||
draw_##type_name##_entity (ent); \
|
draw_##type_name##_entity (ent); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -473,19 +472,18 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue)
|
||||||
// calculate dynamic lighting for bmodel if it's not an
|
// calculate dynamic lighting for bmodel if it's not an
|
||||||
// instanced model
|
// instanced model
|
||||||
if (brush->firstmodelsurface != 0) {
|
if (brush->firstmodelsurface != 0) {
|
||||||
vec3_t lightorigin;
|
|
||||||
|
|
||||||
for (k = 0; k < r_maxdlights; k++) {
|
for (k = 0; k < r_maxdlights; k++) {
|
||||||
if ((r_dlights[k].die < vr_data.realtime) ||
|
if ((r_dlights[k].die < vr_data.realtime) ||
|
||||||
(!r_dlights[k].radius)) {
|
(!r_dlights[k].radius)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4f_t lightorigin;
|
||||||
VectorSubtract (r_dlights[k].origin, origin, lightorigin);
|
VectorSubtract (r_dlights[k].origin, origin, lightorigin);
|
||||||
|
lightorigin[3] = 1;
|
||||||
R_RecursiveMarkLights (brush, lightorigin,
|
R_RecursiveMarkLights (brush, lightorigin,
|
||||||
&r_dlights[k], k,
|
&r_dlights[k], k,
|
||||||
brush->nodes
|
brush->hulls[0].firstclipnode);
|
||||||
+ brush->hulls[0].firstclipnode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if the driver wants polygons, deliver those.
|
// if the driver wants polygons, deliver those.
|
||||||
|
@ -494,20 +492,21 @@ R_DrawBrushEntitiesOnList (entqueue_t *queue)
|
||||||
if (r_drawpolys | r_drawculledpolys) {
|
if (r_drawpolys | r_drawculledpolys) {
|
||||||
R_ZDrawSubmodelPolys (ent, clmodel);
|
R_ZDrawSubmodelPolys (ent, clmodel);
|
||||||
} else {
|
} else {
|
||||||
if (ent->visibility.topnode) {
|
int topnode_id = ent->visibility.topnode_id;
|
||||||
mnode_t *topnode = ent->visibility.topnode;
|
mod_brush_t *brush = &r_refdef.worldmodel->brush;
|
||||||
|
|
||||||
if (topnode->contents >= 0) {
|
if (topnode_id >= 0) {
|
||||||
// not a leaf; has to be clipped to the world
|
// not a leaf; has to be clipped to the world
|
||||||
// BSP
|
// BSP
|
||||||
r_clipflags = clipflags;
|
mnode_t *node = brush->nodes + topnode_id;
|
||||||
R_DrawSolidClippedSubmodelPolygons (ent, clmodel, topnode);
|
r_clipflags = clipflags;
|
||||||
} else {
|
R_DrawSolidClippedSubmodelPolygons (ent, clmodel, node);
|
||||||
// falls entirely in one leaf, so we just put
|
} else {
|
||||||
// all the edges in the edge list and let 1/z
|
// falls entirely in one leaf, so we just put
|
||||||
// sorting handle drawing order
|
// all the edges in the edge list and let 1/z
|
||||||
R_DrawSubmodelPolygons (ent, clmodel, clipflags, topnode);
|
// sorting handle drawing order
|
||||||
}
|
mleaf_t *leaf = brush->leafs + ~topnode_id;
|
||||||
|
R_DrawSubmodelPolygons (ent, clmodel, clipflags, leaf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -648,12 +648,9 @@ static inline int
|
||||||
get_side (mnode_t *node)
|
get_side (mnode_t *node)
|
||||||
{
|
{
|
||||||
// find the node side on which we are
|
// find the node side on which we are
|
||||||
plane_t *plane = node->plane;
|
|
||||||
vec4f_t org = r_refdef.frame.position;
|
vec4f_t org = r_refdef.frame.position;
|
||||||
|
|
||||||
if (plane->type < 3)
|
return dotf (org, node->plane)[0] < 0;
|
||||||
return (org[plane->type] - plane->dist) < 0;
|
|
||||||
return (DotProduct (org, plane->normal) - plane->dist) < 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -685,12 +682,13 @@ visit_node (mod_brush_t *brush, mnode_t *node, int side, vulkan_ctx_t *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
test_node (mnode_t *node)
|
test_node (mod_brush_t *brush, int node_id)
|
||||||
{
|
{
|
||||||
if (node->contents < 0)
|
if (node_id < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (node->visframe != r_visframecount)
|
if (r_node_visframes[node_id] != r_visframecount)
|
||||||
return 0;
|
return 0;
|
||||||
|
mnode_t *node = brush->nodes + node_id;
|
||||||
if (R_CullBox (r_refdef.frustum, node->minmaxs, node->minmaxs + 3))
|
if (R_CullBox (r_refdef.frustum, node->minmaxs, node->minmaxs + 3))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -700,48 +698,58 @@ static void
|
||||||
R_VisitWorldNodes (mod_brush_t *brush, vulkan_ctx_t *ctx)
|
R_VisitWorldNodes (mod_brush_t *brush, vulkan_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mnode_t *node;
|
int node_id;
|
||||||
int side;
|
int side;
|
||||||
} rstack_t;
|
} rstack_t;
|
||||||
rstack_t *node_ptr;
|
rstack_t *node_ptr;
|
||||||
rstack_t *node_stack;
|
rstack_t *node_stack;
|
||||||
mnode_t *node;
|
int node_id;
|
||||||
mnode_t *front;
|
int front;
|
||||||
int side;
|
int side;
|
||||||
|
|
||||||
node = brush->nodes;
|
node_id = 0;
|
||||||
// +2 for paranoia
|
// +2 for paranoia
|
||||||
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
node_stack = alloca ((brush->depth + 2) * sizeof (rstack_t));
|
||||||
node_ptr = node_stack;
|
node_ptr = node_stack;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
while (test_node (node)) {
|
while (test_node (brush, node_id)) {
|
||||||
|
mnode_t *node = brush->nodes + node_id;
|
||||||
side = get_side (node);
|
side = get_side (node);
|
||||||
front = node->children[side];
|
front = node->children[side];
|
||||||
if (test_node (front)) {
|
if (test_node (brush, front)) {
|
||||||
node_ptr->node = node;
|
node_ptr->node_id = node_id;
|
||||||
node_ptr->side = side;
|
node_ptr->side = side;
|
||||||
node_ptr++;
|
node_ptr++;
|
||||||
node = front;
|
node_id = front;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// front is either not a node (ie, is a leaf) or is not visible
|
// front is either not a node (ie, is a leaf) or is not visible
|
||||||
// if node is visible, then at least one of its child nodes
|
// if node is visible, then at least one of its child nodes
|
||||||
// must also be visible, and a leaf child in front of the node
|
// must also be visible, and a leaf child in front of the node
|
||||||
// will be visible, so no need for vis checks on a leaf
|
// will be visible, so no need for vis checks on a leaf
|
||||||
if (front->contents < 0 && front->contents != CONTENTS_SOLID)
|
if (front < 0) {
|
||||||
visit_leaf ((mleaf_t *) front);
|
mleaf_t *leaf = brush->leafs + ~front;
|
||||||
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
|
visit_leaf (leaf);
|
||||||
|
}
|
||||||
|
}
|
||||||
visit_node (brush, node, side, ctx);
|
visit_node (brush, node, side, ctx);
|
||||||
node = node->children[!side];
|
node_id = node->children[side ^ 1];
|
||||||
|
}
|
||||||
|
if (node_id < 0) {
|
||||||
|
mleaf_t *leaf = brush->leafs + ~node_id;
|
||||||
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
|
visit_leaf (leaf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (node->contents < 0 && node->contents != CONTENTS_SOLID)
|
|
||||||
visit_leaf ((mleaf_t *) node);
|
|
||||||
if (node_ptr != node_stack) {
|
if (node_ptr != node_stack) {
|
||||||
node_ptr--;
|
node_ptr--;
|
||||||
node = node_ptr->node;
|
node_id = node_ptr->node_id;
|
||||||
side = node_ptr->side;
|
side = node_ptr->side;
|
||||||
|
mnode_t *node = brush->nodes + node_id;
|
||||||
visit_node (brush, node, side, ctx);
|
visit_node (brush, node, side, ctx);
|
||||||
node = node->children[!side];
|
node_id = node->children[side ^ 1];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -142,7 +142,7 @@ Vulkan_NewScene (scene_t *scene, vulkan_ctx_t *ctx)
|
||||||
r_refdef.worldmodel = scene->worldmodel;
|
r_refdef.worldmodel = scene->worldmodel;
|
||||||
|
|
||||||
// Force a vis update
|
// Force a vis update
|
||||||
R_MarkLeaves (0);
|
R_MarkLeaves (0, 0);
|
||||||
|
|
||||||
R_ClearParticles ();
|
R_ClearParticles ();
|
||||||
Vulkan_RegisterTextures (scene->models, scene->num_models, ctx);
|
Vulkan_RegisterTextures (scene->models, scene->num_models, ctx);
|
||||||
|
|
|
@ -83,7 +83,7 @@ SCR_CShift (void)
|
||||||
if (cls.state == ca_active && cl_world.scene->worldmodel) {
|
if (cls.state == ca_active && cl_world.scene->worldmodel) {
|
||||||
vec4f_t origin;
|
vec4f_t origin;
|
||||||
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
||||||
leaf = Mod_PointInLeaf ((vec_t*)&origin, cl_world.scene->worldmodel);//FIXME
|
leaf = Mod_PointInLeaf (origin, cl_world.scene->worldmodel);
|
||||||
contents = leaf->contents;
|
contents = leaf->contents;
|
||||||
}
|
}
|
||||||
V_SetContentsColor (&cl.viewstate, contents);
|
V_SetContentsColor (&cl.viewstate, contents);
|
||||||
|
|
|
@ -757,7 +757,7 @@ Host_ClientFrame (void)
|
||||||
vec4f_t origin;
|
vec4f_t origin;
|
||||||
|
|
||||||
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
||||||
l = Mod_PointInLeaf ((vec_t*)&origin, cl_world.scene->worldmodel);//FIXME
|
l = Mod_PointInLeaf (origin, cl_world.scene->worldmodel);
|
||||||
if (l)
|
if (l)
|
||||||
asl = l->ambient_sound_level;
|
asl = l->ambient_sound_level;
|
||||||
S_Update (cl.viewstate.camera_transform, asl);
|
S_Update (cl.viewstate.camera_transform, asl);
|
||||||
|
|
|
@ -372,30 +372,29 @@ SV_ClearDatagram (void)
|
||||||
static set_t *fatpvs;
|
static set_t *fatpvs;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_AddToFatPVS (vec3_t org, mnode_t *node)
|
SV_AddToFatPVS (vec4f_t org, int node_id)
|
||||||
{
|
{
|
||||||
float d;
|
float d;
|
||||||
plane_t *plane;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// if this is a leaf, accumulate the pvs bits
|
// if this is a leaf, accumulate the pvs bits
|
||||||
if (node->contents < 0) {
|
if (node_id < 0) {
|
||||||
if (node->contents != CONTENTS_SOLID) {
|
mleaf_t *leaf = sv.worldmodel->brush.leafs + ~node_id;
|
||||||
set_union (fatpvs, Mod_LeafPVS ((mleaf_t *) node,
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
sv.worldmodel));
|
set_union (fatpvs, Mod_LeafPVS (leaf, sv.worldmodel));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mnode_t *node = sv.worldmodel->brush.nodes + node_id;
|
||||||
|
|
||||||
plane = node->plane;
|
d = dotf (node->plane, org)[0];
|
||||||
d = DotProduct (org, plane->normal) - plane->dist;
|
|
||||||
if (d > 8)
|
if (d > 8)
|
||||||
node = node->children[0];
|
node_id = node->children[0];
|
||||||
else if (d < -8)
|
else if (d < -8)
|
||||||
node = node->children[1];
|
node_id = node->children[1];
|
||||||
else { // go down both
|
else { // go down both
|
||||||
SV_AddToFatPVS (org, node->children[0]);
|
SV_AddToFatPVS (org, node->children[0]);
|
||||||
node = node->children[1];
|
node_id = node->children[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,14 +406,14 @@ SV_AddToFatPVS (vec3_t org, mnode_t *node)
|
||||||
given point.
|
given point.
|
||||||
*/
|
*/
|
||||||
static set_t *
|
static set_t *
|
||||||
SV_FatPVS (vec3_t org)
|
SV_FatPVS (vec4f_t org)
|
||||||
{
|
{
|
||||||
if (!fatpvs) {
|
if (!fatpvs) {
|
||||||
fatpvs = set_new_size (sv.worldmodel->brush.visleafs);
|
fatpvs = set_new_size (sv.worldmodel->brush.visleafs);
|
||||||
}
|
}
|
||||||
set_expand (fatpvs, sv.worldmodel->brush.visleafs);
|
set_expand (fatpvs, sv.worldmodel->brush.visleafs);
|
||||||
set_empty (fatpvs);
|
set_empty (fatpvs);
|
||||||
SV_AddToFatPVS (org, sv.worldmodel->brush.nodes);
|
SV_AddToFatPVS (org, 0);
|
||||||
return fatpvs;
|
return fatpvs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,13 +425,14 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
|
||||||
pr_uint_t bits, e;
|
pr_uint_t bits, e;
|
||||||
set_t *pvs;
|
set_t *pvs;
|
||||||
float miss;
|
float miss;
|
||||||
vec3_t org;
|
vec4f_t org;
|
||||||
edict_t *ent;
|
edict_t *ent;
|
||||||
entity_state_t *baseline;
|
entity_state_t *baseline;
|
||||||
edict_leaf_t *el;
|
edict_leaf_t *el;
|
||||||
|
|
||||||
// find the client's PVS
|
// find the client's PVS
|
||||||
VectorAdd (SVvector (clent, origin), SVvector (clent, view_ofs), org);
|
VectorAdd (SVvector (clent, origin), SVvector (clent, view_ofs), org);
|
||||||
|
org[3] = 1;
|
||||||
pvs = SV_FatPVS (org);
|
pvs = SV_FatPVS (org);
|
||||||
|
|
||||||
// send over all entities (excpet the client) that touch the pvs
|
// send over all entities (excpet the client) that touch the pvs
|
||||||
|
|
|
@ -548,7 +548,6 @@ PF_newcheckclient (progs_t *pr, unsigned check)
|
||||||
edict_t *ent;
|
edict_t *ent;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
mleaf_t *leaf;
|
mleaf_t *leaf;
|
||||||
vec3_t org;
|
|
||||||
|
|
||||||
// cycle to the next one
|
// cycle to the next one
|
||||||
if (check < 1)
|
if (check < 1)
|
||||||
|
@ -582,7 +581,9 @@ PF_newcheckclient (progs_t *pr, unsigned check)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the PVS for the entity
|
// get the PVS for the entity
|
||||||
|
vec4f_t org;
|
||||||
VectorAdd (SVvector (ent, origin), SVvector (ent, view_ofs), org);
|
VectorAdd (SVvector (ent, origin), SVvector (ent, view_ofs), org);
|
||||||
|
org[3] = 1;
|
||||||
leaf = Mod_PointInLeaf (org, sv.worldmodel);
|
leaf = Mod_PointInLeaf (org, sv.worldmodel);
|
||||||
if (!checkpvs) {
|
if (!checkpvs) {
|
||||||
checkpvs = set_new_size (sv.worldmodel->brush.visleafs);
|
checkpvs = set_new_size (sv.worldmodel->brush.visleafs);
|
||||||
|
@ -615,7 +616,6 @@ PF_checkclient (progs_t *pr, void *data)
|
||||||
edict_t *ent, *self;
|
edict_t *ent, *self;
|
||||||
int l;
|
int l;
|
||||||
mleaf_t *leaf;
|
mleaf_t *leaf;
|
||||||
vec3_t view;
|
|
||||||
|
|
||||||
// find a new check if on a new frame
|
// find a new check if on a new frame
|
||||||
if (sv.time - sv.lastchecktime >= 0.1) {
|
if (sv.time - sv.lastchecktime >= 0.1) {
|
||||||
|
@ -630,7 +630,9 @@ PF_checkclient (progs_t *pr, void *data)
|
||||||
}
|
}
|
||||||
// if current entity can't possibly see the check entity, return 0
|
// if current entity can't possibly see the check entity, return 0
|
||||||
self = PROG_TO_EDICT (pr, *sv_globals.self);
|
self = PROG_TO_EDICT (pr, *sv_globals.self);
|
||||||
|
vec4f_t view;
|
||||||
VectorAdd (SVvector (self, origin), SVvector (self, view_ofs), view);
|
VectorAdd (SVvector (self, origin), SVvector (self, view_ofs), view);
|
||||||
|
view[3] = 1;
|
||||||
leaf = Mod_PointInLeaf (view, sv.worldmodel);
|
leaf = Mod_PointInLeaf (view, sv.worldmodel);
|
||||||
l = (leaf - sv.worldmodel->brush.leafs) - 1;
|
l = (leaf - sv.worldmodel->brush.leafs) - 1;
|
||||||
if (!set_is_member (checkpvs, l)) {
|
if (!set_is_member (checkpvs, l)) {
|
||||||
|
|
|
@ -410,19 +410,17 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
|
SV_FindTouchedLeafs (edict_t *ent, int node_id)
|
||||||
{
|
{
|
||||||
int sides;
|
int sides;
|
||||||
mleaf_t *leaf;
|
|
||||||
plane_t *splitplane;
|
plane_t *splitplane;
|
||||||
edict_leaf_t *edict_leaf;
|
edict_leaf_t *edict_leaf;
|
||||||
|
|
||||||
if (node->contents == CONTENTS_SOLID)
|
// add an efrag if the node is a non-solid leaf
|
||||||
return;
|
if (node_id < 0) {
|
||||||
|
mleaf_t *leaf = sv.worldmodel->brush.leafs + ~node_id;
|
||||||
// add an efrag if the node is a leaf
|
if (leaf->contents == CONTENTS_SOLID)
|
||||||
if (node->contents < 0) {
|
return;
|
||||||
leaf = (mleaf_t *) node;
|
|
||||||
|
|
||||||
edict_leaf = alloc_edict_leaf ();
|
edict_leaf = alloc_edict_leaf ();
|
||||||
edict_leaf->leafnum = leaf - sv.worldmodel->brush.leafs - 1;
|
edict_leaf->leafnum = leaf - sv.worldmodel->brush.leafs - 1;
|
||||||
|
@ -431,8 +429,9 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnode_t *node = sv.worldmodel->brush.nodes + node_id;
|
||||||
// NODE_MIXED
|
// NODE_MIXED
|
||||||
splitplane = node->plane;
|
splitplane = (plane_t *) &node->plane;
|
||||||
sides = BOX_ON_PLANE_SIDE (SVvector (ent, absmin),
|
sides = BOX_ON_PLANE_SIDE (SVvector (ent, absmin),
|
||||||
SVvector (ent, absmax), splitplane);
|
SVvector (ent, absmax), splitplane);
|
||||||
|
|
||||||
|
@ -497,7 +496,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
|
||||||
// link to PVS leafs
|
// link to PVS leafs
|
||||||
free_edict_leafs (&SVdata (ent)->leafs);
|
free_edict_leafs (&SVdata (ent)->leafs);
|
||||||
if (SVfloat (ent, modelindex))
|
if (SVfloat (ent, modelindex))
|
||||||
SV_FindTouchedLeafs (ent, sv.worldmodel->brush.nodes);
|
SV_FindTouchedLeafs (ent, 0);
|
||||||
|
|
||||||
if (SVfloat (ent, solid) == SOLID_NOT)
|
if (SVfloat (ent, solid) == SOLID_NOT)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
#include "QF/va.h"
|
#include "QF/va.h"
|
||||||
|
|
||||||
|
#include "QF/simd/vec4f.h"
|
||||||
|
|
||||||
#include "qw/bothdefs.h"
|
#include "qw/bothdefs.h"
|
||||||
#include "qw/msg_ucmd.h"
|
#include "qw/msg_ucmd.h"
|
||||||
#include "qw/protocol.h"
|
#include "qw/protocol.h"
|
||||||
|
@ -978,30 +980,27 @@ emit_entities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_to_fat_pvs (vec4f_t org, mnode_t *node, server_t *sv)
|
add_to_fat_pvs (vec4f_t org, int node_id, server_t *sv)
|
||||||
{
|
{
|
||||||
float d;
|
|
||||||
plane_t *plane;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// if this is a leaf, accumulate the pvs bits
|
// if this is a leaf, accumulate the pvs bits
|
||||||
if (node->contents < 0) {
|
if (node_id < 0) {
|
||||||
if (node->contents != CONTENTS_SOLID) {
|
mleaf_t *leaf = sv->worldmodel->brush.leafs + ~node_id;
|
||||||
set_union (sv->fatpvs, Mod_LeafPVS ((mleaf_t *) node,
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
sv->worldmodel));
|
set_union (sv->fatpvs, Mod_LeafPVS (leaf, sv->worldmodel));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
plane = node->plane;
|
mnode_t *node = sv->worldmodel->brush.nodes + node_id;
|
||||||
d = DotProduct (org, plane->normal) - plane->dist;
|
float d = dotf (node->plane, org)[0];
|
||||||
if (d > 8)
|
if (d > 8)
|
||||||
node = node->children[0];
|
node_id = node->children[0];
|
||||||
else if (d < -8)
|
else if (d < -8)
|
||||||
node = node->children[1];
|
node_id = node->children[1];
|
||||||
else { // go down both
|
else { // go down both
|
||||||
add_to_fat_pvs (org, node->children[0], sv);
|
add_to_fat_pvs (org, node->children[0], sv);
|
||||||
node = node->children[1];
|
node_id = node->children[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1014,7 @@ fat_pvs (vec4f_t org, server_t *sv)
|
||||||
set_expand (sv->fatpvs, sv->worldmodel->brush.visleafs);
|
set_expand (sv->fatpvs, sv->worldmodel->brush.visleafs);
|
||||||
set_empty (sv->fatpvs);
|
set_empty (sv->fatpvs);
|
||||||
|
|
||||||
add_to_fat_pvs (org, sv->worldmodel->brush.nodes, sv);
|
add_to_fat_pvs (org, 0, sv);
|
||||||
return sv->fatpvs;
|
return sv->fatpvs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,15 +116,16 @@ sv_unlink_entity (server_t *sv, qtv_entity_t *ent)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sv_find_touched_leafs (server_t *sv, qtv_entity_t *ent, mnode_t *node)
|
sv_find_touched_leafs (server_t *sv, qtv_entity_t *ent, int node_id)
|
||||||
{
|
{
|
||||||
if (node->contents == CONTENTS_SOLID) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// add an efrag if the node is a leaf
|
// add an efrag if the node is a leaf
|
||||||
if (node->contents < 0) {
|
if (node_id < 0) {
|
||||||
|
mleaf_t *leaf = sv->worldmodel->brush.leafs + ~node_id;
|
||||||
|
if (leaf->contents == CONTENTS_SOLID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
qtv_leaf_t *ent_leaf = alloc_qtv_leaf ();
|
qtv_leaf_t *ent_leaf = alloc_qtv_leaf ();
|
||||||
ent_leaf->num = (mleaf_t *) node - sv->worldmodel->brush.leafs - 1;
|
ent_leaf->num = ~node_id - 1;
|
||||||
ent_leaf->next = ent->leafs;
|
ent_leaf->next = ent->leafs;
|
||||||
ent->leafs = ent_leaf;
|
ent->leafs = ent_leaf;
|
||||||
return;
|
return;
|
||||||
|
@ -134,7 +135,8 @@ sv_find_touched_leafs (server_t *sv, qtv_entity_t *ent, mnode_t *node)
|
||||||
VectorAdd (ent->e.origin, ent->model->mins, emins);
|
VectorAdd (ent->e.origin, ent->model->mins, emins);
|
||||||
VectorAdd (ent->e.origin, ent->model->maxs, emaxs);
|
VectorAdd (ent->e.origin, ent->model->maxs, emaxs);
|
||||||
|
|
||||||
plane_t *splitplane = node->plane;
|
mnode_t *node = sv->worldmodel->brush.nodes + node_id;
|
||||||
|
plane_t *splitplane = (plane_t *) &node->plane;
|
||||||
int sides = BOX_ON_PLANE_SIDE (emins, emaxs, splitplane);
|
int sides = BOX_ON_PLANE_SIDE (emins, emaxs, splitplane);
|
||||||
if (sides & 1) {
|
if (sides & 1) {
|
||||||
sv_find_touched_leafs (sv, ent, node->children[0]);
|
sv_find_touched_leafs (sv, ent, node->children[0]);
|
||||||
|
@ -153,7 +155,7 @@ sv_link_entity (server_t *sv, qtv_entity_t *ent)
|
||||||
ent->model = Mod_ForName (sv->modellist[ent->model_index - 1], false);
|
ent->model = Mod_ForName (sv->modellist[ent->model_index - 1], false);
|
||||||
}
|
}
|
||||||
if (ent->model) {
|
if (ent->model) {
|
||||||
sv_find_touched_leafs (sv, ent, sv->worldmodel->brush.nodes);
|
sv_find_touched_leafs (sv, ent, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1995,7 +1995,7 @@ Host_Frame (float time)
|
||||||
vec4f_t origin;
|
vec4f_t origin;
|
||||||
|
|
||||||
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
||||||
l = Mod_PointInLeaf ((vec_t*)&origin, cl_world.scene->worldmodel);//FIXME
|
l = Mod_PointInLeaf (origin, cl_world.scene->worldmodel);
|
||||||
if (l)
|
if (l)
|
||||||
asl = l->ambient_sound_level;
|
asl = l->ambient_sound_level;
|
||||||
S_Update (cl.viewstate.camera_transform, asl);
|
S_Update (cl.viewstate.camera_transform, asl);
|
||||||
|
|
|
@ -82,7 +82,7 @@ SCR_CShift (void)
|
||||||
if (cls.state == ca_active && cl_world.scene->worldmodel) {
|
if (cls.state == ca_active && cl_world.scene->worldmodel) {
|
||||||
vec4f_t origin;
|
vec4f_t origin;
|
||||||
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
origin = Transform_GetWorldPosition (cl.viewstate.camera_transform);
|
||||||
leaf = Mod_PointInLeaf ((vec_t*)&origin, cl_world.scene->worldmodel);//FIXME
|
leaf = Mod_PointInLeaf (origin, cl_world.scene->worldmodel);
|
||||||
contents = leaf->contents;
|
contents = leaf->contents;
|
||||||
}
|
}
|
||||||
V_SetContentsColor (&cl.viewstate, contents);
|
V_SetContentsColor (&cl.viewstate, contents);
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include "QF/set.h"
|
#include "QF/set.h"
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
|
|
||||||
|
#include "QF/simd/vec4f.h"
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|
||||||
#include "qw/msg_ucmd.h"
|
#include "qw/msg_ucmd.h"
|
||||||
|
@ -59,30 +61,29 @@ static set_t *fatpvs;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_AddToFatPVS (vec3_t org, mnode_t *node)
|
SV_AddToFatPVS (vec4f_t org, int node_id)
|
||||||
{
|
{
|
||||||
float d;
|
float d;
|
||||||
plane_t *plane;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// if this is a leaf, accumulate the pvs bits
|
// if this is a leaf, accumulate the pvs bits
|
||||||
if (node->contents < 0) {
|
if (node_id < 0) {
|
||||||
if (node->contents != CONTENTS_SOLID) {
|
mleaf_t *leaf = sv.worldmodel->brush.leafs + ~node_id;
|
||||||
set_union (fatpvs, Mod_LeafPVS ((mleaf_t *) node,
|
if (leaf->contents != CONTENTS_SOLID) {
|
||||||
sv.worldmodel));
|
set_union (fatpvs, Mod_LeafPVS (leaf, sv.worldmodel));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
plane = node->plane;
|
mnode_t *node = sv.worldmodel->brush.nodes + node_id;
|
||||||
d = DotProduct (org, plane->normal) - plane->dist;
|
d = dotf (org, node->plane)[0];
|
||||||
if (d > 8)
|
if (d > 8)
|
||||||
node = node->children[0];
|
node_id = node->children[0];
|
||||||
else if (d < -8)
|
else if (d < -8)
|
||||||
node = node->children[1];
|
node_id = node->children[1];
|
||||||
else { // go down both
|
else { // go down both
|
||||||
SV_AddToFatPVS (org, node->children[0]);
|
SV_AddToFatPVS (org, node->children[0]);
|
||||||
node = node->children[1];
|
node_id = node->children[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,14 +95,14 @@ SV_AddToFatPVS (vec3_t org, mnode_t *node)
|
||||||
of the given point.
|
of the given point.
|
||||||
*/
|
*/
|
||||||
static set_t *
|
static set_t *
|
||||||
SV_FatPVS (vec3_t org)
|
SV_FatPVS (vec4f_t org)
|
||||||
{
|
{
|
||||||
if (!fatpvs) {
|
if (!fatpvs) {
|
||||||
fatpvs = set_new_size (sv.worldmodel->brush.visleafs);
|
fatpvs = set_new_size (sv.worldmodel->brush.visleafs);
|
||||||
}
|
}
|
||||||
set_expand (fatpvs, sv.worldmodel->brush.visleafs);
|
set_expand (fatpvs, sv.worldmodel->brush.visleafs);
|
||||||
set_empty (fatpvs);
|
set_empty (fatpvs);
|
||||||
SV_AddToFatPVS (org, sv.worldmodel->brush.nodes);
|
SV_AddToFatPVS (org, 0);
|
||||||
return fatpvs;
|
return fatpvs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,12 +711,13 @@ static inline set_t *
|
||||||
calc_pvs (delta_t *delta)
|
calc_pvs (delta_t *delta)
|
||||||
{
|
{
|
||||||
set_t *pvs = 0;
|
set_t *pvs = 0;
|
||||||
vec3_t org;
|
vec4f_t org = {};
|
||||||
|
|
||||||
// find the client's PVS
|
// find the client's PVS
|
||||||
if (delta->pvs == dt_pvs_normal) {
|
if (delta->pvs == dt_pvs_normal) {
|
||||||
edict_t *clent = delta->client->edict;
|
edict_t *clent = delta->client->edict;
|
||||||
VectorAdd (SVvector (clent, origin), SVvector (clent, view_ofs), org);
|
VectorAdd (SVvector (clent, origin), SVvector (clent, view_ofs), org);
|
||||||
|
org[3] = 1;
|
||||||
pvs = SV_FatPVS (org);
|
pvs = SV_FatPVS (org);
|
||||||
} else if (delta->pvs == dt_pvs_fat) {
|
} else if (delta->pvs == dt_pvs_fat) {
|
||||||
// when recording a demo, send only entities that can be seen. Can help
|
// when recording a demo, send only entities that can be seen. Can help
|
||||||
|
@ -735,10 +737,11 @@ calc_pvs (delta_t *delta)
|
||||||
|
|
||||||
VectorAdd (SVvector (cl->edict, origin),
|
VectorAdd (SVvector (cl->edict, origin),
|
||||||
SVvector (cl->edict, view_ofs), org);
|
SVvector (cl->edict, view_ofs), org);
|
||||||
|
org[3] = 1;
|
||||||
if (pvs == NULL) {
|
if (pvs == NULL) {
|
||||||
pvs = SV_FatPVS (org);
|
pvs = SV_FatPVS (org);
|
||||||
} else {
|
} else {
|
||||||
SV_AddToFatPVS (org, sv.worldmodel->brush.nodes);
|
SV_AddToFatPVS (org, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,7 +469,6 @@ PF_newcheckclient (progs_t *pr, int check)
|
||||||
edict_t *ent;
|
edict_t *ent;
|
||||||
int i;
|
int i;
|
||||||
mleaf_t *leaf;
|
mleaf_t *leaf;
|
||||||
vec3_t org;
|
|
||||||
|
|
||||||
// cycle to the next one
|
// cycle to the next one
|
||||||
if (check < 1)
|
if (check < 1)
|
||||||
|
@ -503,7 +502,9 @@ PF_newcheckclient (progs_t *pr, int check)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the PVS for the entity
|
// get the PVS for the entity
|
||||||
|
vec4f_t org;
|
||||||
VectorAdd (SVvector (ent, origin), SVvector (ent, view_ofs), org);
|
VectorAdd (SVvector (ent, origin), SVvector (ent, view_ofs), org);
|
||||||
|
org[3] = 1;
|
||||||
leaf = Mod_PointInLeaf (org, sv.worldmodel);
|
leaf = Mod_PointInLeaf (org, sv.worldmodel);
|
||||||
if (!checkpvs) {
|
if (!checkpvs) {
|
||||||
checkpvs = set_new_size (sv.worldmodel->brush.visleafs);
|
checkpvs = set_new_size (sv.worldmodel->brush.visleafs);
|
||||||
|
@ -536,7 +537,6 @@ PF_checkclient (progs_t *pr, void *data)
|
||||||
edict_t *ent, *self;
|
edict_t *ent, *self;
|
||||||
int l;
|
int l;
|
||||||
mleaf_t *leaf;
|
mleaf_t *leaf;
|
||||||
vec3_t view;
|
|
||||||
|
|
||||||
// find a new check if on a new frame
|
// find a new check if on a new frame
|
||||||
if (sv.time - sv.lastchecktime >= 0.1) {
|
if (sv.time - sv.lastchecktime >= 0.1) {
|
||||||
|
@ -551,7 +551,9 @@ PF_checkclient (progs_t *pr, void *data)
|
||||||
}
|
}
|
||||||
// if current entity can't possibly see the check entity, return 0
|
// if current entity can't possibly see the check entity, return 0
|
||||||
self = PROG_TO_EDICT (pr, *sv_globals.self);
|
self = PROG_TO_EDICT (pr, *sv_globals.self);
|
||||||
|
vec4f_t view;
|
||||||
VectorAdd (SVvector (self, origin), SVvector (self, view_ofs), view);
|
VectorAdd (SVvector (self, origin), SVvector (self, view_ofs), view);
|
||||||
|
view[3] = 1;
|
||||||
leaf = Mod_PointInLeaf (view, sv.worldmodel);
|
leaf = Mod_PointInLeaf (view, sv.worldmodel);
|
||||||
l = (leaf - sv.worldmodel->brush.leafs) - 1;
|
l = (leaf - sv.worldmodel->brush.leafs) - 1;
|
||||||
if (!set_is_member (checkpvs, l)) {
|
if (!set_is_member (checkpvs, l)) {
|
||||||
|
|
|
@ -302,7 +302,8 @@ SV_Multicast (const vec3_t origin, int to)
|
||||||
qboolean reliable;
|
qboolean reliable;
|
||||||
mod_brush_t *brush = &sv.worldmodel->brush;
|
mod_brush_t *brush = &sv.worldmodel->brush;
|
||||||
|
|
||||||
leaf = Mod_PointInLeaf (origin, sv.worldmodel);
|
vec4f_t org = { VectorExpand (origin), 1 };
|
||||||
|
leaf = Mod_PointInLeaf (org, sv.worldmodel);
|
||||||
if (!leaf)
|
if (!leaf)
|
||||||
leafnum = 0;
|
leafnum = 0;
|
||||||
else
|
else
|
||||||
|
@ -346,8 +347,8 @@ SV_Multicast (const vec3_t origin, int to)
|
||||||
goto inrange;
|
goto inrange;
|
||||||
}
|
}
|
||||||
|
|
||||||
leaf = Mod_PointInLeaf (SVvector (client->edict, origin),
|
org = (vec4f_t) {VectorExpand (SVvector (client->edict, origin)), 1};
|
||||||
sv.worldmodel);
|
leaf = Mod_PointInLeaf (org, sv.worldmodel);
|
||||||
if (leaf) {
|
if (leaf) {
|
||||||
// -1 is because pvs rows are 1 based, not 0 based like leafs
|
// -1 is because pvs rows are 1 based, not 0 based like leafs
|
||||||
leafnum = leaf - brush->leafs - 1;
|
leafnum = leaf - brush->leafs - 1;
|
||||||
|
|
|
@ -410,29 +410,28 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
|
SV_FindTouchedLeafs (edict_t *ent, int node_id)
|
||||||
{
|
{
|
||||||
int sides;
|
int sides;
|
||||||
mleaf_t *leaf;
|
|
||||||
plane_t *splitplane;
|
plane_t *splitplane;
|
||||||
edict_leaf_t *edict_leaf;
|
edict_leaf_t *edict_leaf;
|
||||||
|
|
||||||
if (node->contents == CONTENTS_SOLID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// add an efrag if the node is a leaf
|
// add an efrag if the node is a leaf
|
||||||
if (node->contents < 0) {
|
if (node_id < 0) {
|
||||||
leaf = (mleaf_t *) node;
|
mleaf_t *leaf = sv.worldmodel->brush.leafs + ~node_id;
|
||||||
|
if (leaf->contents == CONTENTS_SOLID)
|
||||||
|
return;
|
||||||
|
|
||||||
edict_leaf = alloc_edict_leaf ();
|
edict_leaf = alloc_edict_leaf ();
|
||||||
edict_leaf->leafnum = leaf - sv.worldmodel->brush.leafs - 1;
|
edict_leaf->leafnum = ~node_id - 1;
|
||||||
edict_leaf->next = SVdata (ent)->leafs;
|
edict_leaf->next = SVdata (ent)->leafs;
|
||||||
SVdata (ent)->leafs = edict_leaf;
|
SVdata (ent)->leafs = edict_leaf;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnode_t *node = sv.worldmodel->brush.nodes + node_id;
|
||||||
// NODE_MIXED
|
// NODE_MIXED
|
||||||
splitplane = node->plane;
|
splitplane = (plane_t *) &node->plane;
|
||||||
sides = BOX_ON_PLANE_SIDE (SVvector (ent, absmin),
|
sides = BOX_ON_PLANE_SIDE (SVvector (ent, absmin),
|
||||||
SVvector (ent, absmax), splitplane);
|
SVvector (ent, absmax), splitplane);
|
||||||
|
|
||||||
|
@ -497,7 +496,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
|
||||||
// link to PVS leafs
|
// link to PVS leafs
|
||||||
free_edict_leafs (&SVdata (ent)->leafs);
|
free_edict_leafs (&SVdata (ent)->leafs);
|
||||||
if (SVfloat (ent, modelindex))
|
if (SVfloat (ent, modelindex))
|
||||||
SV_FindTouchedLeafs (ent, sv.worldmodel->brush.nodes);
|
SV_FindTouchedLeafs (ent, 0);
|
||||||
|
|
||||||
if (SVfloat (ent, solid) == SOLID_NOT)
|
if (SVfloat (ent, solid) == SOLID_NOT)
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue