try to fix q2/q3bsp checkclient bug by rewriting everything to do with pvs!

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4668 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-05-23 02:02:51 +00:00
parent faae661e9e
commit 3bd6892353
17 changed files with 224 additions and 131 deletions

View file

@ -1387,6 +1387,7 @@ void Media_Send_MouseMove(cin_t *cin, float x, float y);
void Media_Send_Resize(cin_t *cin, int x, int y);
void Media_Send_GetSize(cin_t *cin, int *x, int *y);
void Media_Send_KeyEvent(cin_t *cin, int button, int unicode, int event);
void Media_Send_Reset(cin_t *cin);
void MVD_Interpolate(void);

View file

@ -2705,6 +2705,11 @@ void Media_Send_GetSize(cin_t *cin, int *x, int *y)
return;
cin->getsize(cin, x, y);
}
void Media_Send_Reset(cin_t *cin)
{
if (!cin || !cin->rewind)
cin->rewind(cin);
}

View file

@ -358,42 +358,54 @@ void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s
#ifndef NOMEDIA
// #487 float(string name) gecko_create( string name )
// #487 float(string name) gecko_create
void QCBUILTIN PF_cs_gecko_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *shadername = PR_GetStringOfs(prinst, OFS_PARM0);
cin_t *cin;
cin = R_ShaderGetCinematic(R_RegisterShader(shadername, SUF_2D,
"{\n"
"program default2d\n"
"{\n"
"videomap http:\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"blendfunc blend\n"
"nodepth\n"
"}\n"
"}\n"
));
if (!cin)
G_FLOAT(OFS_RETURN) = 0;
else
if (cin)
{
G_FLOAT(OFS_RETURN) = 1;
Media_Send_Reset(cin);
}
else
G_FLOAT(OFS_RETURN) = 0;
}
// #488 void(string name) gecko_destroy( string name )
// #488 void(string name) gecko_destroy
void QCBUILTIN PF_cs_gecko_destroy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
return;
Media_Send_Reset(cin); //FIXME
}
// #489 void(string name) gecko_navigate( string name, string URI )
// #489 void(string name, string URI) gecko_navigate
void QCBUILTIN PF_cs_gecko_navigate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
const char *command = PR_GetStringOfs(prinst, OFS_PARM1);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
return;
Media_Send_Command(cin, command);
}
// #490 float(string name) gecko_keyevent( string name, float key, float eventtype )
// #490 float(string name, float key, float eventtype) gecko_keyevent
void QCBUILTIN PF_cs_gecko_keyevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
@ -401,12 +413,11 @@ void QCBUILTIN PF_cs_gecko_keyevent (pubprogfuncs_t *prinst, struct globalvars_s
int eventtype = G_FLOAT(OFS_PARM2);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
return;
Media_Send_KeyEvent(cin, MP_TranslateQCtoFTECodes(key), (key>127)?0:key, eventtype);
}
// #491 void gecko_mousemove( string name, float x, float y )
// #491 void(string name, float x, float y) gecko_mousemove
void QCBUILTIN PF_cs_gecko_mousemove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
@ -414,12 +425,11 @@ void QCBUILTIN PF_cs_gecko_mousemove (pubprogfuncs_t *prinst, struct globalvars_
float posy = G_FLOAT(OFS_PARM2);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
return;
Media_Send_MouseMove(cin, posx, posy);
}
// #492 void gecko_resize( string name, float w, float h )
// #492 void(string name, float w, float h) gecko_resize
void QCBUILTIN PF_cs_gecko_resize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
@ -431,7 +441,7 @@ void QCBUILTIN PF_cs_gecko_resize (pubprogfuncs_t *prinst, struct globalvars_s *
return;
Media_Send_Resize(cin, sizex, sizey);
}
// #493 vector gecko_get_texture_extent( string name )
// #493 vector(string name) gecko_get_texture_extent
void QCBUILTIN PF_cs_gecko_get_texture_extent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
const char *shader = PR_GetStringOfs(prinst, OFS_PARM0);

View file

@ -2030,7 +2030,7 @@ qbyte *R_CalcVis_Q1 (void)
int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, curframevis, sizeof(curframevis));
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL, sizeof(curframevis));
c = (cl.worldmodel->numvisleafs+31)/32;
c = (cl.worldmodel->numclusters+31)/32;
for (i=0 ; i<c ; i++)
((int *)curframevis)[i] |= ((int *)vis)[i];
vis = curframevis;
@ -2080,7 +2080,7 @@ qbyte *R_MarkLeaves_Q1 (void)
if (r_novis.ival)
{
vis = cvis[portal] = fatvis[portal];
memset (fatvis[portal], 0xff, (cl.worldmodel->numvisleafs+7)>>3);
memset (fatvis[portal], 0xff, (cl.worldmodel->numclusters+7)>>3);
r_oldviewleaf = NULL;
r_oldviewleaf2 = NULL;
@ -2090,7 +2090,7 @@ qbyte *R_MarkLeaves_Q1 (void)
int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis[portal], sizeof(fatvis[portal]));
vis = cvis[portal] = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL, 0);
c = (cl.worldmodel->numvisleafs+31)/32;
c = (cl.worldmodel->numclusters+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis[portal])[i] |= ((int *)vis)[i];
@ -2104,7 +2104,7 @@ qbyte *R_MarkLeaves_Q1 (void)
r_visframecount++;
for (i=0 ; i<cl.worldmodel->numvisleafs ; i++)
for (i=0 ; i<cl.worldmodel->numclusters ; i++)
{
if (vis[i>>3] & (1<<(i&7)))
{

View file

@ -57,6 +57,7 @@ void Mod_LoadLighting (lump_t *l);
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace);
static unsigned int CM_NativeContents(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
static unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p);
static int CM_PointCluster (model_t *mod, vec3_t p);
extern mplane_t *box_planes;
@ -3739,10 +3740,12 @@ void CMQ3_CalcPHS (void)
}
#endif
/*
static qbyte *CM_LeafnumPVS (model_t *model, int leafnum, qbyte *buffer, unsigned int buffersize)
{
return CM_ClusterPVS(model, CM_LeafCluster(model, leafnum), buffer, buffersize);
}
*/
#ifndef SERVERONLY
#define GLQ2BSP_LightPointValues GLQ1BSP_LightPointValues
@ -4079,8 +4082,8 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
loadmodel->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS;
loadmodel->funcs.FindTouchedLeafs = Q2BSP_FindTouchedLeafs;
#endif
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.ClusterPVS = CM_ClusterPVS;
loadmodel->funcs.ClusterForPoint = CM_PointCluster;
#ifndef SERVERONLY
loadmodel->funcs.LightPointValues = GLQ3_LightGrid;
@ -4170,8 +4173,8 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
loadmodel->funcs.LightPointValues = NULL;
loadmodel->funcs.StainNode = NULL;
loadmodel->funcs.MarkLights = NULL;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.ClusterPVS = CM_ClusterPVS;
loadmodel->funcs.ClusterForPoint = CM_PointCluster;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
loadmodel->funcs.NativeTrace = CM_NativeTrace;
loadmodel->funcs.NativeContents = CM_NativeContents;
@ -4220,8 +4223,8 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
loadmodel->funcs.LightPointValues = GLQ2BSP_LightPointValues;
loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode;
loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.ClusterPVS = CM_ClusterPVS;
loadmodel->funcs.ClusterForPoint = CM_PointCluster;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
loadmodel->funcs.NativeTrace = CM_NativeTrace;
loadmodel->funcs.NativeContents = CM_NativeContents;
@ -4416,8 +4419,8 @@ void CM_InitBoxHull (void)
#ifndef SERVERONLY
box_model.funcs.MarkLights = Q2BSP_MarkLights;
#endif
box_model.funcs.LeafPVS = CM_LeafnumPVS;
box_model.funcs.LeafnumForPoint = CM_PointLeafnum;
box_model.funcs.ClusterPVS = CM_ClusterPVS;
box_model.funcs.ClusterForPoint = CM_PointCluster;
box_model.funcs.NativeContents = CM_NativeContents;
box_model.funcs.NativeTrace = CM_NativeTrace;
@ -4516,7 +4519,7 @@ CM_PointLeafnum_r
==================
*/
int CM_PointLeafnum_r (model_t *mod, vec3_t p, int num)
static int CM_PointLeafnum_r (model_t *mod, vec3_t p, int num)
{
float d;
mnode_t *node;
@ -4547,6 +4550,13 @@ int CM_PointLeafnum (model_t *mod, vec3_t p)
return CM_PointLeafnum_r (mod, p, 0);
}
static int CM_PointCluster (model_t *mod, vec3_t p)
{
if (!mod || mod->needload)
return 0; // sound may call this without map loaded
return CM_LeafCluster(mod, CM_PointLeafnum_r (mod, p, 0));
}
/*
=============
CM_BoxLeafnums

View file

@ -1519,7 +1519,7 @@ Server only functions
#ifndef CLIENTONLY
//does the recursive work of Q1BSP_FatPVS
void SV_Q1BSP_AddToFatPVS (model_t *mod, vec3_t org, mnode_t *node, qbyte *buffer, unsigned int buffersize)
static void SV_Q1BSP_AddToFatPVS (model_t *mod, vec3_t org, mnode_t *node, qbyte *buffer, unsigned int buffersize)
{
int i;
qbyte *pvs;
@ -1562,7 +1562,7 @@ Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the
given point.
=============
*/
unsigned int Q1BSP_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean add)
static unsigned int Q1BSP_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean add)
{
unsigned int fatbytes = (mod->numleafs+31)>>3;
if (fatbytes > buffersize)
@ -1574,7 +1574,7 @@ unsigned int Q1BSP_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsigned
}
#endif
qboolean Q1BSP_EdictInFatPVS(model_t *mod, struct pvscache_s *ent, qbyte *pvs)
static qboolean Q1BSP_EdictInFatPVS(model_t *mod, struct pvscache_s *ent, qbyte *pvs)
{
int i;
@ -1595,7 +1595,7 @@ SV_FindTouchedLeafs
Links the edict to the right leafs so we can get it's potential visability.
===============
*/
void Q1BSP_RFindTouchedLeafs (model_t *wm, struct pvscache_s *ent, mnode_t *node, float *mins, float *maxs)
static void Q1BSP_RFindTouchedLeafs (model_t *wm, struct pvscache_s *ent, mnode_t *node, float *mins, float *maxs)
{
mplane_t *splitplane;
mleaf_t *leaf;
@ -1635,7 +1635,7 @@ void Q1BSP_RFindTouchedLeafs (model_t *wm, struct pvscache_s *ent, mnode_t *node
if (sides & 2)
Q1BSP_RFindTouchedLeafs (wm, ent, node->children[1], mins, maxs);
}
void Q1BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, float *mins, float *maxs)
static void Q1BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, float *mins, float *maxs)
{
ent->num_leafs = 0;
if (mins && maxs)
@ -1656,13 +1656,13 @@ PVS type stuff
Mod_DecompressVis
===================
*/
qbyte *Q1BSP_DecompressVis (qbyte *in, model_t *model, qbyte *decompressed, unsigned int buffersize)
static qbyte *Q1BSP_DecompressVis (qbyte *in, model_t *model, qbyte *decompressed, unsigned int buffersize)
{
int c;
qbyte *out;
int row;
row = (model->numvisleafs+7)>>3;
row = (model->numclusters+7)>>3;
out = decompressed;
if (buffersize < row)
@ -1720,13 +1720,26 @@ qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer, unsigned int
return Q1BSP_DecompressVis (leaf->compressed_vis, model, buffer, buffersize);
}
qbyte *Q1BSP_LeafnumPVS (model_t *model, int leafnum, qbyte *buffer, unsigned int buffersize)
//pvs is 1-based. clusters are 0-based. otherwise, q1bsp has a 1:1 mapping.
static qbyte *Q1BSP_ClusterPVS (model_t *model, int cluster, qbyte *buffer, unsigned int buffersize)
{
return Q1BSP_LeafPVS(model, model->leafs + leafnum, buffer, buffersize);
static qbyte decompressed[MAX_MAP_LEAFS/8];
if (cluster == -1)
return mod_novis;
cluster++;
if (!buffer)
{
buffer = decompressed;
buffersize = sizeof(decompressed);
}
return Q1BSP_DecompressVis (model->leafs[cluster+1].compressed_vis, model, buffer, buffersize);
}
//returns the leaf number, which is used as a bit index into the pvs.
int Q1BSP_LeafnumForPoint (model_t *model, vec3_t p)
static int Q1BSP_LeafnumForPoint (model_t *model, vec3_t p)
{
mnode_t *node;
float d;
@ -1760,6 +1773,36 @@ mleaf_t *Q1BSP_LeafForPoint (model_t *model, vec3_t p)
return model->leafs + Q1BSP_LeafnumForPoint(model, p);
}
//returns the leaf number, which is used as a direct bit index into the pvs.
//-1 for invalid
static int Q1BSP_ClusterForPoint (model_t *model, vec3_t p)
{
mnode_t *node;
float d;
mplane_t *plane;
if (!model)
{
Sys_Error ("Mod_PointInLeaf: bad model");
}
if (!model->nodes)
return -1;
node = model->nodes;
while (1)
{
if (node->contents < 0)
return ((mleaf_t *)node - model->leafs) - 1;
plane = node->plane;
d = DotProduct (p,plane->normal) - plane->dist;
if (d > 0)
node = node->children[0];
else
node = node->children[1];
}
return -1; // never reached
}
/*
@ -1858,8 +1901,8 @@ void Q1BSP_SetModelFuncs(model_t *mod)
mod->funcs.StainNode = NULL;
mod->funcs.MarkLights = NULL;
mod->funcs.LeafnumForPoint = Q1BSP_LeafnumForPoint;
mod->funcs.LeafPVS = Q1BSP_LeafnumPVS;
mod->funcs.ClusterForPoint = Q1BSP_ClusterForPoint;
mod->funcs.ClusterPVS = Q1BSP_ClusterPVS;
mod->funcs.NativeTrace = Q1BSP_Trace;
mod->funcs.PointContents = Q1BSP_PointContents;
}

View file

@ -3697,14 +3697,15 @@ void Heightmap_MarkLights (dlight_t *light, int bit, mnode_t *node)
{
}
qbyte *Heightmap_LeafnumPVS (model_t *model, int num, qbyte *buffer, unsigned int buffersize)
qbyte *Heightmap_ClusterPVS (model_t *model, int num, qbyte *buffer, unsigned int buffersize)
{
static qbyte heightmappvs = 255;
return &heightmappvs;
return NULL;
// static qbyte heightmappvs = 255;
// return &heightmappvs;
}
int Heightmap_LeafForPoint (model_t *model, vec3_t point)
int Heightmap_ClusterForPoint (model_t *model, vec3_t point)
{
return 0;
return -1;
}
#ifndef SERVERONLY
@ -4572,8 +4573,8 @@ qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize
mod->funcs.StainNode = Heightmap_StainNode;
mod->funcs.MarkLights = Heightmap_MarkLights;
mod->funcs.LeafnumForPoint = Heightmap_LeafForPoint;
mod->funcs.LeafPVS = Heightmap_LeafnumPVS;
mod->funcs.ClusterForPoint = Heightmap_ClusterForPoint;
mod->funcs.ClusterPVS = Heightmap_ClusterPVS;
#ifndef CLIENTONLY
mod->funcs.FindTouchedLeafs = Heightmap_FindTouchedLeafs;

View file

@ -3337,7 +3337,7 @@ qboolean Mod_LoadLeafs (lump_t *l, int lm)
loadmodel->leafs = out;
loadmodel->numleafs = count;
loadmodel->numvisleafs = count-1;
loadmodel->numclusters = count-1;
for ( i=0 ; i<count ; i++, in++, out++)
{
@ -3400,7 +3400,7 @@ qboolean Mod_LoadLeafs (lump_t *l, int lm)
loadmodel->leafs = out;
loadmodel->numleafs = count;
loadmodel->numvisleafs = count-1;
loadmodel->numclusters = count-1;
for ( i=0 ; i<count ; i++, in++, out++)
{
@ -3463,7 +3463,7 @@ qboolean Mod_LoadLeafs (lump_t *l, int lm)
loadmodel->leafs = out;
loadmodel->numleafs = count;
loadmodel->numvisleafs = count-1;
loadmodel->numclusters = count-1;
for ( i=0 ; i<count ; i++, in++, out++)
{
@ -4424,7 +4424,7 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
mod->numvisleafs = bm->visleafs;
mod->numclusters = bm->visleafs;
memset(&mod->batches, 0, sizeof(mod->batches));
mod->vbos = NULL;

View file

@ -216,8 +216,8 @@ typedef struct {
void (*StainNode) (struct mnode_s *node, float *parms);
void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node);
qbyte *(*LeafPVS) (struct model_s *model, int num, qbyte *buffer, unsigned int buffersize);
int (*LeafnumForPoint) (struct model_s *model, vec3_t point);
int (*ClusterForPoint) (struct model_s *model, vec3_t point); //pvs index. may be negative (ie: no pvs).
qbyte *(*ClusterPVS) (struct model_s *model, int cluster, qbyte *buffer, unsigned int buffersize);
} modelfuncs_t;
@ -501,9 +501,6 @@ void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
void GLQ1BSP_LightPointValues(struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, struct trace_s *trace);
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
unsigned int Q1BSP_FatPVS (struct model_s *mod, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct pvscache_s *ent, qbyte *pvs);
void Q1BSP_FindTouchedLeafs(struct model_s *mod, struct pvscache_s *ent, float *mins, float *maxs);
qbyte *Q1BSP_LeafPVS (struct model_s *model, mleaf_t *leaf, qbyte *buffer, unsigned int buffersize);
/*
@ -874,7 +871,7 @@ typedef struct model_s
int numplanes;
mplane_t *planes;
int numvisleafs;
int numclusters;
int numleafs; // number of visible leafs, not counting 0
mleaf_t *leafs;

View file

@ -876,12 +876,12 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
//use the player's origin for r_viewleaf, because there's not much we can do anyway*/
VectorCopy(r_origin, r_refdef.pvsorigin);
if (cl.worldmodel && cl.worldmodel->funcs.LeafPVS && !r_novis.ival)
if (cl.worldmodel && cl.worldmodel->funcs.ClusterPVS && !r_novis.ival)
{
int lnum, i, j;
int clust, i, j;
float d;
vec3_t point;
int pvsbytes = (cl.worldmodel->numvisleafs+7)>>3;
int pvsbytes = (cl.worldmodel->numclusters+7)>>3;
if (pvsbytes > sizeof(newvis))
pvsbytes = sizeof(newvis);
r_refdef.forcevis = true;
@ -897,16 +897,16 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
d += 0.1; //an epsilon on the far side
VectorMA(point, d, plane.normal, point);
lnum = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, point);
clust = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, point);
if (i == batch->firstmesh)
r_refdef.forcedvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, lnum, newvis, sizeof(newvis));
r_refdef.forcedvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clust, newvis, sizeof(newvis));
else
{
if (r_refdef.forcedvis != newvis)
{
memcpy(newvis, r_refdef.forcedvis, pvsbytes);
}
r_refdef.forcedvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, lnum, NULL, sizeof(newvis));
r_refdef.forcedvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clust, NULL, sizeof(newvis));
for (j = 0; j < pvsbytes; j+= 4)
{

View file

@ -449,7 +449,7 @@ static void SHM_BeginShadowMesh(dlight_t *dl, int type)
unsigned int lb;
sh_vertnum = 0;
lb = (cl.worldmodel->numvisleafs+7)/8;
lb = (cl.worldmodel->numclusters+7)/8;
if (!dl->die || !dl->key)
{
sh_shmesh = dl->worldshadowmesh;
@ -978,7 +978,7 @@ static void SHM_MarkLeavesQ2(dlight_t *dl, unsigned char *lvis, unsigned char *v
{
//static
//variation on mark leaves
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numvisleafs ; i++, leaf++)
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if (cluster == -1)
@ -1000,7 +1000,7 @@ static void SHM_MarkLeavesQ2(dlight_t *dl, unsigned char *lvis, unsigned char *v
{
//dynamic lights will be discarded after this frame anyway, so only include leafs that are visible
//variation on mark leaves
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numvisleafs ; i++, leaf++)
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if (cluster == -1)
@ -1027,8 +1027,11 @@ static void SHM_MarkLeavesQ1(dlight_t *dl, unsigned char *lvis)
int i;
sh_shadowframe++;
if (!lvis)
return;
//variation on mark leaves
for (i=0 ; i<cl.worldmodel->numvisleafs ; i++)
for (i=0 ; i<cl.worldmodel->numclusters ; i++)
{
if (lvis[i>>3] & (1<<(i&7)))
{
@ -1395,9 +1398,9 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
if (!lvis)
{
int leaf;
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
int clus;
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, lvisb, sizeof(lvisb));
}
firstedge=0;
@ -1512,9 +1515,9 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
static qboolean Sh_VisOverlaps(qbyte *v1, qbyte *v2)
{
int i, m;
if (!v2)
if (!v2 || !v1)
return false;
m = (cl.worldmodel->numvisleafs+7)>>3;
m = (cl.worldmodel->numclusters+7)>>3;
for (i=(m&~3) ; i<m ; i++)
{
@ -2502,9 +2505,11 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
}
else
{
int leaf;
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, l->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
int clus;
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, l->origin);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, lvisb, sizeof(lvisb));
//FIXME: surely we can use the phs for this?
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
{
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
@ -2816,7 +2821,7 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
{
int sref;
int leaf;
int clus;
qbyte *lvis;
srect_t rect;
@ -2849,8 +2854,8 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
}
else
{
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, lvisb, sizeof(lvisb));
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
{
@ -3073,11 +3078,11 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
}
else
{
int leaf;
int clus;
qbyte *lvis;
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, lvisb, sizeof(lvisb));
SHM_BuildShadowMesh(dl, lvis, vvis, SMT_SHADOWLESS);
@ -3255,8 +3260,8 @@ void Sh_PreGenerateLights(void)
else
shadowtype = SMT_STENCILVOLUME;
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
leaf = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
SHM_BuildShadowMesh(dl, lvis, NULL, shadowtype);
continue;

View file

@ -79,26 +79,32 @@ static void pp_flush(multicast_t to, vec3_t origin, void (*flushfunc)(client_t *
case MULTICAST_ALL_R:
reliable = true; // intentional fallthrough
case MULTICAST_ALL:
mask = sv.pvs; // leaf 0 is everything;
mask = NULL;
break;
case MULTICAST_PHS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PHS:
if (!sv.phs)
mask = sv.pvs;
mask = NULL;
else
{
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numvisleafs+31)>>5);
cluster = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
if (cluster >= 0)
mask = sv.phs + cluster * 4*((sv.world.worldmodel->numclusters+31)>>5);
else
mask = NULL;
}
break;
case MULTICAST_PVS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PVS:
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
mask = sv.pvs + leafnum * 4*((sv.world.worldmodel->numvisleafs+31)>>5);
cluster = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
if (cluster >= 0)
mask = sv.pvs + cluster * 4*((sv.world.worldmodel->numclusters+31)>>5);
else
mask = NULL;
break;
default:
@ -125,11 +131,10 @@ static void pp_flush(multicast_t to, vec3_t origin, void (*flushfunc)(client_t *
goto inrange;
}
// -1 is because pvs rows are 1 based, not 0 based like leafs
if (mask != sv.pvs)
if (mask)
{
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint (sv.world.worldmodel, client->edict->v->origin)-1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, client->edict->v->origin);
if (cluster >= 0 && !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
{
continue;
}

View file

@ -3250,13 +3250,14 @@ static void QCBUILTIN PF_TraceToss (pubprogfuncs_t *prinst, struct globalvars_s
qbyte checkpvsbuffer[MAX_MAP_LEAFS/8];
qbyte *checkpvs;
vec3_t checkorg;
extern cvar_t sv_nopvs;
int PF_newcheckclient (pubprogfuncs_t *prinst, int check)
{
int i;
// qbyte *pvs;
edict_t *ent;
int leaf;
int cluster;
// cycle to the next one
@ -3272,7 +3273,7 @@ int PF_newcheckclient (pubprogfuncs_t *prinst, int check)
for ( ; ; i++)
{
if (i == sv.allocated_client_slots+1)
if (i >= sv.allocated_client_slots+1)
i = 1;
ent = EDICT_NUM(prinst, i);
@ -3293,12 +3294,12 @@ int PF_newcheckclient (pubprogfuncs_t *prinst, int check)
// get the PVS for the entity
VectorAdd (ent->v->origin, ent->v->view_ofs, checkorg);
if (sv.world.worldmodel->type == mod_heightmap)
if (sv.world.worldmodel->type == mod_heightmap || sv_nopvs.ival)
checkpvs = NULL;
else
{
leaf = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, checkorg);
checkpvs = sv.world.worldmodel->funcs.LeafPVS (sv.world.worldmodel, leaf, checkpvsbuffer, sizeof(checkpvsbuffer));
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, checkorg);
checkpvs = sv.world.worldmodel->funcs.ClusterPVS (sv.world.worldmodel, cluster, checkpvsbuffer, sizeof(checkpvsbuffer));
}
return i;
@ -3324,7 +3325,7 @@ int c_invis, c_notvis;
int PF_checkclient_Internal (pubprogfuncs_t *prinst)
{
edict_t *ent, *self;
int l;
int clust;
vec3_t view;
vec3_t dist;
world_t *w = &sv.world;
@ -3353,8 +3354,8 @@ int PF_checkclient_Internal (pubprogfuncs_t *prinst)
if (checkpvs)
{
l = w->worldmodel->funcs.LeafnumForPoint(w->worldmodel, view)-1;
if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
clust = w->worldmodel->funcs.ClusterForPoint(w->worldmodel, view);
if ( (clust<0) || !(checkpvs[clust>>3] & (1<<(clust&7)) ) )
{
c_notvis++;
return 0;

View file

@ -2733,7 +2733,7 @@ unsigned int Q2BSP_FatPVS(model_t *mod, vec3_t org, qbyte *buffer, unsigned int
{//fixme: this doesn't add
int leafnum;
leafnum = CM_PointLeafnum (mod, org);
clientarea = CM_LeafArea (mod, leafnum);
/// clientarea = CM_LeafArea (mod, leafnum);
return SV_Q2BSP_FatPVS (mod, org, buffer, buffersize, add);
}
@ -3216,17 +3216,24 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t
}
else if ((pvsflags & PVSF_MODE_MASK) == PVSF_USEPHS && sv.world.worldmodel->fromgame == fg_quake)
{
int leafnum;
int cluster;
unsigned char *mask;
if (sv.phs)
{
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, host_client->edict->v->origin);
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numvisleafs+31)>>5);
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint (sv.world.worldmodel, ent->v->origin)-1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
//FIXME: this lookup should be cachable or something.
if (client->edict)
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, client->edict->v->origin);
else
cluster = -1; //mvd
if (cluster >= 0)
{
continue;
mask = sv.phs + cluster * 4*((sv.world.worldmodel->numclusters+31)>>5);
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, ent->v->origin);
if (cluster >= 0 && !(mask[cluster>>3] & (1<<(cluster&7)) ) )
{
continue;
}
}
}
tracecullent = NULL;
@ -3243,11 +3250,11 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t
//DP_SV_NODRAWONLYTOCLIENT
if (ent->xv->nodrawtoclient) //DP extension.
if (ent->xv->nodrawtoclient == EDICT_TO_PROG(svprogfuncs, client->edict))
if (client->edict && ent->xv->nodrawtoclient == EDICT_TO_PROG(svprogfuncs, client->edict))
continue;
//DP_SV_DRAWONLYTOCLIENT
if (ent->xv->drawonlytoclient)
if (ent->xv->drawonlytoclient != EDICT_TO_PROG(svprogfuncs, client->edict))
if (!client->edict || ent->xv->drawonlytoclient != EDICT_TO_PROG(svprogfuncs, client->edict))
{
client_t *split;
for (split = client->controlled; split; split=split->controlled)

View file

@ -407,7 +407,7 @@ void SV_CalcPHS (void)
return;
}
num = sv.world.worldmodel->numleafs;
num = sv.world.worldmodel->numclusters;
rowwords = (num+31)>>5;
rowbytes = rowwords*4;
@ -417,7 +417,7 @@ void SV_CalcPHS (void)
scan = sv.pvs;
for (i=0 ; i<num ; i++, scan+=rowbytes)
{
lf = sv.world.worldmodel->funcs.LeafPVS(sv.world.worldmodel, i, scan, rowbytes);
lf = sv.world.worldmodel->funcs.ClusterPVS(sv.world.worldmodel, i, scan, rowbytes);
if (lf != scan)
memcpy (scan, lf, rowbytes);
}
@ -432,7 +432,7 @@ void SV_CalcPHS (void)
vcount = 0;
for (i=0 ; i<num ; i++, scan+=rowbytes)
{
lf = sv.world.worldmodel->funcs.LeafPVS(sv.world.worldmodel, i, scan, rowbytes);
lf = sv.world.worldmodel->funcs.ClusterPVS(sv.world.worldmodel, i, scan, rowbytes);
if (lf != scan)
memcpy (scan, lf, rowbytes);
if (i == 0)
@ -488,7 +488,8 @@ void SV_CalcPHS (void)
continue;
// or this pvs row into the phs
// +1 because pvs is 1 based
index = ((j<<3)+k+1);
//except we now use clusters internally, which are 0-based (ie: leaf 0 is invalid and maps to cluster -1)
index = ((j<<3)+k);
if (index >= num)
continue;
src = (unsigned *)sv.pvs + index*rowwords;

View file

@ -545,10 +545,10 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
{
client_t *client;
qbyte *mask;
int leafnum;
int cluster;
int j;
qboolean reliable;
int pnum = 0;
int pnum = -1;
if (to == MULTICAST_INIT)
{
@ -580,7 +580,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
#ifdef Q2BSPS
if (sv.world.worldmodel->fromgame == fg_quake2 || sv.world.worldmodel->fromgame == fg_quake3)
{
int area1, area2, cluster;
int area1, area2, leafnum;
reliable = false;
@ -656,12 +656,12 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
}
}
if (!mask)
if (pnum >= 0)
{
if (pnum != j)
continue;
}
else
else if (mask)
{
#ifdef Q2SERVER
if (ge)
@ -743,26 +743,32 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
case MULTICAST_ALL_R:
reliable = true; // intentional fallthrough
case MULTICAST_ALL:
mask = sv.pvs; // leaf 0 is everything;
mask = NULL;
break;
case MULTICAST_PHS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PHS:
if (!sv.phs) /*broadcast if no pvs*/
mask = sv.pvs;
mask = NULL;
else
{
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin);
if (cluster >= 0)
mask = sv.phs + cluster * 4*((sv.world.worldmodel->numclusters+31)>>5);
else
mask = NULL;
}
break;
case MULTICAST_PVS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PVS:
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
mask = sv.pvs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin);
if (cluster >= 0)
mask = sv.pvs + cluster * 4*((sv.world.worldmodel->numclusters+31)>>5);
else
mask = NULL;
break;
case MULTICAST_ONE_R:
@ -804,7 +810,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
}
}
if (!mask)
if (pnum >= 0)
{
if (pnum != j)
continue;
@ -814,6 +820,9 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
if (!((int)client->edict->xv->dimension_see & dimension_mask))
continue;
if (!mask) //no pvs? broadcast.
goto inrange;
if (to == MULTICAST_PHS_R || to == MULTICAST_PHS)
{
vec3_t delta;
@ -822,13 +831,11 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
goto inrange;
}
if (mask != sv.pvs) //leaf 0 is the solid see-all region, so no point figuring out where the players are
{
vec3_t pos;
VectorAdd(client->edict->v->origin, client->edict->v->view_ofs, pos);
// -1 is because pvs rows are 1 based, not 0 based like leafs
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint (sv.world.worldmodel, pos)-1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, pos);
if (cluster>= 0 && !(mask[cluster>>3] & (1<<(cluster&7)) ) )
{
// Con_Printf ("PVS supressed multicast\n");
continue;

View file

@ -2317,7 +2317,7 @@ void SVQ3_BuildClientSnapshot( client_t *client )
org[2] += ps->viewheight;
clientarea = CM_PointLeafnum(sv.world.worldmodel, org);
bitvector = sv.world.worldmodel->funcs.LeafPVS(sv.world.worldmodel, sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, org), NULL, 0);
bitvector = sv.world.worldmodel->funcs.ClusterPVS(sv.world.worldmodel, sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, org), NULL, 0);
clientarea = CM_LeafArea(sv.world.worldmodel, clientarea);
/*
if (client->areanum != clientarea)