void R_PVSUpdate (entity_render_t *ent, mleaf_t *viewleaf)
{
- int i, j, l, c, bits, *surfacepvsframes, *mark;
+ int j, c, *surfacepvsframes, *mark;
mleaf_t *leaf;
- qbyte *vis;
+ qbyte *pvs;
model_t *model;
model = ent->model;
model->brushq1.pvssurflistlength = 0;
if (viewleaf)
{
+ pvs = viewleaf->pvsdata;
surfacepvsframes = model->brushq1.surfacepvsframes;
- vis = model->brushq1.LeafPVS(model, viewleaf);
- for (j = 0;j < model->brushq1.numleafs;j += 8)
+ for (j = 0;j < model->brushq1.numleafs-1;j++)
{
- bits = *vis++;
- if (bits)
+ if (pvs[j >> 3] & (1 << (j & 7)))
{
- l = model->brushq1.numleafs - j;
- if (l > 8)
- l = 8;
- for (i = 0;i < l;i++)
- {
- if (bits & (1 << i))
- {
- leaf = &model->brushq1.leafs[j + i + 1];
- leaf->pvschain = model->brushq1.pvsleafchain;
- model->brushq1.pvsleafchain = leaf;
- leaf->pvsframe = model->brushq1.pvsframecount;
- // mark surfaces bounding this leaf as visible
- for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--, mark++)
- surfacepvsframes[*mark] = model->brushq1.pvsframecount;
- }
- }
+ leaf = model->brushq1.leafs + j + 1;
+ leaf->pvsframe = model->brushq1.pvsframecount;
+ leaf->pvschain = model->brushq1.pvsleafchain;
+ model->brushq1.pvsleafchain = leaf;
+ // mark surfaces bounding this leaf as visible
+ for (c = leaf->nummarksurfaces, mark = leaf->firstmarksurface;c;c--, mark++)
+ surfacepvsframes[*mark] = model->brushq1.pvsframecount;
}
}
model->brushq1.BuildPVSTextureChains(model);
Mod_Q1BSP_LightPoint_RecursiveBSPNode(ambientcolor, diffusecolor, diffusenormal, cl.worldmodel->brushq1.nodes + cl.worldmodel->brushq1.hulls[0].firstclipnode, p[0], p[1], p[2], p[2] - 65536);
}
-static qbyte *Mod_Q1BSP_DecompressVis(model_t *model, qbyte *in)
+static void Mod_Q1BSP_DecompressVis(const qbyte *in, const qbyte *inend, qbyte *out, qbyte *outend)
{
- static qbyte decompressed[MAX_MAP_LEAFS/8];
int c;
- qbyte *out;
- int row;
-
- row = (model->brushq1.numleafs+7)>>3;
- out = decompressed;
-
- do
+ while (out < outend)
{
- if (*in)
+ if (in == inend)
{
- *out++ = *in++;
- continue;
+ Con_Printf("Mod_Q1BSP_DecompressVis: input underrun\n");
+ return;
}
-
- c = in[1];
- in += 2;
- while (c)
+ c = *in++;
+ if (c)
+ *out++ = c;
+ else
{
- *out++ = 0;
- c--;
+ for (c = *in++;c > 0;c--)
+ {
+ if (out == outend)
+ {
+ Con_Printf("Mod_Q1BSP_DecompressVis: output overrun\n");
+ return;
+ }
+ *out++ = 0;
+ }
}
- } while (out - decompressed < row);
-
- return decompressed;
-}
-
-static qbyte *Mod_Q1BSP_LeafPVS(model_t *model, mleaf_t *leaf)
-{
- if (r_novis.integer || leaf == model->brushq1.leafs || leaf->compressed_vis == NULL)
- return mod_q1bsp_novis;
- return Mod_Q1BSP_DecompressVis(model, leaf->compressed_vis);
+ }
}
static void Mod_Q1BSP_LoadTextures(lump_t *l)
static void Mod_Q1BSP_LoadVisibility(lump_t *l)
{
- loadmodel->brushq1.visdata = NULL;
+ loadmodel->brushq1.num_compressedpvs = 0;
+ loadmodel->brushq1.data_compressedpvs = NULL;
if (!l->filelen)
return;
- loadmodel->brushq1.visdata = Mem_Alloc(loadmodel->mempool, l->filelen);
- memcpy(loadmodel->brushq1.visdata, mod_base + l->fileofs, l->filelen);
+ loadmodel->brushq1.num_compressedpvs = l->filelen;
+ loadmodel->brushq1.data_compressedpvs = Mem_Alloc(loadmodel->mempool, l->filelen);
+ memcpy(loadmodel->brushq1.data_compressedpvs, mod_base + l->fileofs, l->filelen);
}
// used only for HalfLife maps
static void Mod_Q1BSP_LoadLeafs(lump_t *l)
{
- dleaf_t *in;
- mleaf_t *out;
- int i, j, count, p;
+ dleaf_t *in;
+ mleaf_t *out;
+ int i, j, count, p, pvschainbytes;
+ qbyte *pvs;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
loadmodel->brushq1.leafs = out;
loadmodel->brushq1.numleafs = count;
+ pvschainbytes = ((loadmodel->brushq1.num_leafs - 1)+7)>>3;
+ loadmodel->brushq1.data_decompressedpvs = pvs = Mem_Alloc(loadmodel->mempool, loadmodel->brushq1.numleafs * pvschainbytes);
for ( i=0 ; i<count ; i++, in++, out++)
{
out->maxs[j] = LittleShort(in->maxs[j]);
}
- p = LittleLong(in->contents);
- out->contents = p;
+ // FIXME: this function could really benefit from some error checking
+
+ out->contents = LittleLong(in->contents);
- out->firstmarksurface = loadmodel->brushq1.marksurfaces +
- LittleShort(in->firstmarksurface);
+ out->firstmarksurface = loadmodel->brushq1.marksurfaces + LittleShort(in->firstmarksurface);
out->nummarksurfaces = LittleShort(in->nummarksurfaces);
+ out->pvsdata = pvs;
+ pvs += pvschainbytes;
+
p = LittleLong(in->visofs);
- if (p == -1)
- out->compressed_vis = NULL;
+ if (p >= 0)
+ Mod_Q1BSP_DecompressVis(loadmodel->brushq1.data_compressedpvs + p, loadmodel->brushq1.data_compressedpvs + loadmodel->brushq1.num_compressedpvs, out->pvsdata, out->pvsdata + pvschainbytes);
else
- out->compressed_vis = loadmodel->brushq1.visdata + p;
+ memset(out->pvsdata, 0xFF, pvschainbytes);
- for (j=0 ; j<4 ; j++)
+ for (j = 0;j < 4;j++)
out->ambient_sound_level[j] = in->ambient_level[j];
// FIXME: Insert caustics here
void Mod_Q1BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbytes, mnode_t *node)
{
int i;
- qbyte *pvs;
mplane_t *plane;
float d;
// if this is a leaf, accumulate the pvs bits
if (node->contents < 0)
{
- if (node->contents != CONTENTS_SOLID)
- {
- pvs = model->brushq1.LeafPVS(model, (mleaf_t *)node);
+ if (node->contents != CONTENTS_SOLID && ((mleaf_t *)node)->pvsdata)
for (i = 0;i < pvsbytes;i++)
- pvsbuffer[i] |= pvs[i];
- }
+ pvsbuffer[i] |= ((mleaf_t *)node)->pvsdata[i];
return;
}
//of the given point.
int Mod_Q1BSP_FatPVS(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbufferlength)
{
- int bytes = (sv.worldmodel->brushq1.numleafs+31)>>3;
- if (bytes > pvsbufferlength)
- bytes = pvsbufferlength;
+ int bytes = ((model->brushq1.num_leafs - 1) + 7) >> 3;
+ bytes = min(bytes, pvsbufferlength);
memset(pvsbuffer, 0, bytes);
Mod_Q1BSP_FatPVS_RecursiveBSPNode(model, org, radius, pvsbuffer, bytes, sv.worldmodel->brushq1.nodes);
return bytes;
mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation;
mod->brush.TraceBox = Mod_Q1BSP_TraceBox;
mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf;
- mod->brushq1.LeafPVS = Mod_Q1BSP_LeafPVS;
mod->brushq1.BuildPVSTextureChains = Mod_Q1BSP_BuildPVSTextureChains;
if (loadmodel->isworldmodel)
Mod_Q1BSP_LoadClipnodes(&header->lumps[LUMP_CLIPNODES]);
Mod_Q1BSP_LoadSubmodels(&header->lumps[LUMP_MODELS]);
+ if (mod->brushq1.data_compressedpvs)
+ Mem_Free(mod->brushq1.data_compressedpvs);
+ mod->brushq1.data_compressedpvs = NULL;
+ mod->brushq1.num_compressedpvs = 0;
+
Mod_Q1BSP_MakeHull0();
Mod_Q1BSP_MakePortals();
+ if (developer.integer)
+ Con_Printf("Some stats for q1bsp model \"%s\": %i faces, %i nodes, %i leafs, %i visleafs, %i visleafportals\n", loadmodel->name, loadmodel->brushq1.numsurfaces, loadmodel->brushq1.numnodes, loadmodel->brushq1.numleafs, loadmodel->brushq1.num_leafs - 1, loadmodel->brushq1.numportals);
+
mod->numframes = 2; // regular and alternate animation
mainmempool = mod->mempool;
mod->brush.FindNonSolidLocation = Mod_Q3BSP_FindNonSolidLocation;
mod->brush.TraceBox = Mod_Q3BSP_TraceBox;
//mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf;
- //mod->brushq1.LeafPVS = Mod_Q1BSP_LeafPVS;
//mod->brushq1.BuildPVSTextureChains = Mod_Q1BSP_BuildPVSTextureChains;
mod_base = (qbyte *)header;
// used by polygon-through-portals visibility checker
int portalmarkid;
- qbyte *compressed_vis;
+ // decompressed pvs bits (potentially visible set)
+ // note: never NULL, always present, may be full of 0xFF though
+ qbyte *pvsdata;
int *firstmarksurface;
int nummarksurfaces;
int numtextures;
texture_t *textures;
- qbyte *visdata;
+ int num_compressedpvs;
+ qbyte *data_compressedpvs;
+ qbyte *data_decompressedpvs;
+
+ int num_lightdata;
qbyte *lightdata;
int numportals;
float light_ambient;
mleaf_t *(*PointInLeaf)(struct model_s *model, const float *p);
- qbyte *(*LeafPVS)(struct model_s *model, mleaf_t *leaf);
void (*BuildPVSTextureChains)(struct model_s *model);
}
model_brushq1_t;
//============================================================================
+int checkpvsbytes;
qbyte checkpvs[MAX_MAP_LEAFS/8];
int PF_newcheckclient (int check)
}
// get the PVS for the entity
- VectorAdd (ent->v->origin, ent->v->view_ofs, org);
- memcpy (checkpvs, sv.worldmodel->brushq1.LeafPVS(sv.worldmodel, sv.worldmodel->brushq1.PointInLeaf(sv.worldmodel, org)), (sv.worldmodel->brushq1.numleafs+7)>>3 );
+ VectorAdd(ent->v->origin, ent->v->view_ofs, org);
+ checkpvsbytes = 0;
+ if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
+ checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
return i;
}
void PF_checkclient (void)
{
edict_t *ent, *self;
- mleaf_t *leaf;
- int l;
vec3_t view;
// find a new check if on a new frame
// if current entity can't possibly see the check entity, return 0
self = PROG_TO_EDICT(pr_global_struct->self);
- VectorAdd (self->v->origin, self->v->view_ofs, view);
- leaf = sv.worldmodel->brushq1.PointInLeaf(sv.worldmodel, view);
- if (leaf)
+ VectorAdd(self->v->origin, self->v->view_ofs, view);
+ if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
{
- l = (leaf - sv.worldmodel->brushq1.leafs) - 1;
- if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
- {
- c_notvis++;
- RETURN_EDICT(sv.edicts);
- return;
- }
+ c_notvis++;
+ RETURN_EDICT(sv.edicts);
+ return;
}
// might be able to see it
=============================================================================
*/
+static int lightpvsbytes;
+static qbyte lightpvs[(MAX_MAP_LEAFS+7)>>3];
+
/*
=============
R_MarkLights
=============
*/
-static void R_OldMarkLights (entity_render_t *ent, vec3_t lightorigin, rdlight_t *rd, int bit, int bitindex, mnode_t *node)
+static void R_RecursiveMarkLights(entity_render_t *ent, vec3_t lightorigin, rdlight_t *rd, int bit, int bitindex, mnode_t *node, qbyte *pvs, int pvsbits)
{
- float ndist, maxdist;
- msurface_t *surf;
- int i, *surfacepvsframes;
- int d, impacts, impactt;
- float dist, dist2, impact[3];
-
- if (!r_dynamic.integer)
- return;
+ int i;
+ mleaf_t *leaf;
+ float dist;
// for comparisons to minimum acceptable light
- maxdist = rd->cullradius2;
-
- surfacepvsframes = ent->model->brushq1.surfacepvsframes;
-loc0:
- if (node->contents < 0)
- return;
-
- ndist = PlaneDiff(lightorigin, node->plane);
-
- if (ndist > rd->cullradius)
+ while(node->contents >= 0)
{
- node = node->children[0];
- goto loc0;
- }
- if (ndist < -rd->cullradius)
- {
- node = node->children[1];
- goto loc0;
- }
-
-// mark the polygons
- surf = ent->model->brushq1.surfaces + node->firstsurface;
- for (i = 0;i < node->numsurfaces;i++, surf++)
- {
- if (surfacepvsframes[surf->number] != ent->model->brushq1.pvsframecount)
- continue;
- dist = ndist;
- if (surf->flags & SURF_PLANEBACK)
- dist = -dist;
-
- if (dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES))
- continue;
-
- dist2 = dist * dist;
- if (dist2 >= maxdist)
- continue;
-
- if (node->plane->type < 3)
- {
- VectorCopy(lightorigin, impact);
- impact[node->plane->type] -= dist;
- }
+ dist = PlaneDiff(lightorigin, node->plane);
+ if (dist > rd->cullradius)
+ node = node->children[0];
else
{
- impact[0] = lightorigin[0] - surf->plane->normal[0] * dist;
- impact[1] = lightorigin[1] - surf->plane->normal[1] * dist;
- impact[2] = lightorigin[2] - surf->plane->normal[2] * dist;
- }
-
- impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
-
- d = bound(0, impacts, surf->extents[0] + 16) - impacts;
- dist2 += d * d;
- if (dist2 > maxdist)
- continue;
-
- impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
-
- d = bound(0, impactt, surf->extents[1] + 16) - impactt;
- dist2 += d * d;
- if (dist2 > maxdist)
- continue;
-
- if (surf->dlightframe != r_framecount) // not dynamic until now
- {
- surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
- surf->dlightframe = r_framecount;
- if (r_dlightmap.integer)
- surf->cached_dlight = true;
+ if (dist >= -rd->cullradius)
+ R_RecursiveMarkLights(ent, lightorigin, rd, bit, bitindex, node->children[0], pvs, pvsbits);
+ node = node->children[1];
}
- surf->dlightbits[bitindex] |= bit;
}
- if (node->children[0]->contents >= 0)
+ // check if leaf is visible according to pvs
+ leaf = (mleaf_t *)node;
+ i = (leaf - ent->model->brushq1.leafs) - 1;
+ if (leaf->nummarksurfaces && (i >= pvsbits || pvs[i >> 3] & (1 << (i & 7))))
{
- if (node->children[1]->contents >= 0)
- {
- R_OldMarkLights (ent, lightorigin, rd, bit, bitindex, node->children[0]);
- node = node->children[1];
- goto loc0;
- }
- else
+ int *surfacepvsframes, d, impacts, impactt;
+ float sdist, maxdist, dist2, impact[3];
+ msurface_t *surf;
+ // mark the polygons
+ maxdist = rd->cullradius2;
+ surfacepvsframes = ent->model->brushq1.surfacepvsframes;
+ for (i = 0;i < leaf->nummarksurfaces;i++)
{
- node = node->children[0];
- goto loc0;
- }
- }
- else if (node->children[1]->contents >= 0)
- {
- node = node->children[1];
- goto loc0;
- }
-}
+ if (surfacepvsframes[leaf->firstmarksurface[i]] != ent->model->brushq1.pvsframecount)
+ continue;
+ surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[i];
+ dist = sdist = PlaneDiff(lightorigin, surf->plane);
+ if (surf->flags & SURF_PLANEBACK)
+ dist = -dist;
+ if (dist < -0.25f && !(surf->flags & SURF_LIGHTBOTHSIDES))
+ continue;
-static void R_VisMarkLights (entity_render_t *ent, rdlight_t *rd, int bit, int bitindex)
-{
- static int lightframe = 0;
- mleaf_t *pvsleaf;
- vec3_t lightorigin;
- model_t *model;
- int i, k, m, c, leafnum, *surfacepvsframes, *mark;
- msurface_t *surf;
- mleaf_t *leaf;
- qbyte *in;
- int row;
- float low[3], high[3], dist, maxdist;
+ dist2 = dist * dist;
+ if (dist2 >= maxdist)
+ continue;
- if (!r_dynamic.integer || !ent->model)
- return;
-
- Matrix4x4_Transform(&ent->inversematrix, rd->origin, lightorigin);
-
- model = ent->model;
- pvsleaf = model->brushq1.PointInLeaf(model, lightorigin);
- if (pvsleaf == NULL)
- return;
-
- in = pvsleaf->compressed_vis;
- if (!r_vismarklights.integer || !in)
- {
- // told not to use pvs, or there's no pvs to use
- R_OldMarkLights(ent, lightorigin, rd, bit, bitindex, model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode);
- return;
- }
+ VectorCopy(lightorigin, impact);
+ if (surf->plane->type >= 3)
+ VectorMA(impact, -sdist, surf->plane->normal, impact);
+ else
+ impact[surf->plane->type] -= sdist;
- lightframe++;
+ impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
- low[0] = lightorigin[0] - rd->cullradius;low[1] = lightorigin[1] - rd->cullradius;low[2] = lightorigin[2] - rd->cullradius;
- high[0] = lightorigin[0] + rd->cullradius;high[1] = lightorigin[1] + rd->cullradius;high[2] = lightorigin[2] + rd->cullradius;
+ d = bound(0, impacts, surf->extents[0] + 16) - impacts;
+ dist2 += d * d;
+ if (dist2 > maxdist)
+ continue;
- // for comparisons to minimum acceptable light
- maxdist = rd->cullradius2;
+ impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
- row = (model->brushq1.numleafs+7)>>3;
- surfacepvsframes = model->brushq1.surfacepvsframes;
+ d = bound(0, impactt, surf->extents[1] + 16) - impactt;
+ dist2 += d * d;
+ if (dist2 > maxdist)
+ continue;
- k = 0;
- while (k < row)
- {
- c = *in++;
- if (c)
- {
- for (i = 0;i < 8;i++)
+ if (surf->dlightframe != r_framecount) // not dynamic until now
{
- if (c & (1<<i))
- {
- // warning to the clumsy: numleafs is one less than it should be, it only counts leafs with vis bits (skips leaf 0)
- leafnum = (k << 3)+i+1;
- if (leafnum > model->brushq1.numleafs)
- return;
- leaf = &model->brushq1.leafs[leafnum];
- if (leaf->mins[0] > high[0] || leaf->maxs[0] < low[0]
- || leaf->mins[1] > high[1] || leaf->maxs[1] < low[1]
- || leaf->mins[2] > high[2] || leaf->maxs[2] < low[2])
- continue;
- if ((m = leaf->nummarksurfaces))
- {
- mark = leaf->firstmarksurface;
- do
- {
- surf = model->brushq1.surfaces + *mark++;
- // if not visible in current frame, or already marked because it was in another leaf we passed, skip
- if (surf->lightframe == lightframe)
- continue;
- surf->lightframe = lightframe;
- if (surfacepvsframes[surf->number] != model->brushq1.pvsframecount)
- continue;
- dist = PlaneDiff(lightorigin, surf->plane);
- if (surf->flags & SURF_PLANEBACK)
- dist = -dist;
- // LordHavoc: make sure it is infront of the surface and not too far away
- if (dist < rd->cullradius && (dist > -0.25f || ((surf->flags & SURF_LIGHTBOTHSIDES) && dist > -rd->cullradius)))
- {
- int d;
- int impacts, impactt;
- float dist2, impact[3];
-
- dist2 = dist * dist;
-
- if (surf->plane->type < 3)
- {
- VectorCopy(lightorigin, impact);
- impact[surf->plane->type] -= dist;
- }
- else
- {
- impact[0] = lightorigin[0] - surf->plane->normal[0] * dist;
- impact[1] = lightorigin[1] - surf->plane->normal[1] * dist;
- impact[2] = lightorigin[2] - surf->plane->normal[2] * dist;
- }
-
- impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
- d = bound(0, impacts, surf->extents[0] + 16) - impacts;
- dist2 += d * d;
- if (dist2 > maxdist)
- continue;
-
- impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
- d = bound(0, impactt, surf->extents[1] + 16) - impactt;
- dist2 += d * d;
- if (dist2 > maxdist)
- continue;
-
- if (surf->dlightframe != r_framecount) // not dynamic until now
- {
- surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
- surf->dlightframe = r_framecount;
- if (r_dlightmap.integer)
- surf->cached_dlight = true;
- }
- surf->dlightbits[bitindex] |= bit;
- }
- }
- while (--m);
- }
- }
+ surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0;
+ surf->dlightframe = r_framecount;
+ if (r_dlightmap.integer)
+ surf->cached_dlight = true;
}
- k++;
- continue;
+ surf->dlightbits[bitindex] |= bit;
}
-
- k += *in++;
}
}
void R_MarkLights(entity_render_t *ent)
{
- int i;
- if (!gl_flashblend.integer)
- for (i = 0;i < r_numdlights;i++)
- R_VisMarkLights (ent, r_dlight + i, 1 << (i & 31), i >> 5);
+ int i, bit, bitindex;
+ rdlight_t *rd;
+ vec3_t lightorigin;
+ if (!gl_flashblend.integer && r_dynamic.integer && ent->model)
+ {
+ for (i = 0, rd = r_dlight;i < r_numdlights;i++, rd++)
+ {
+ bit = 1 << (i & 31);
+ bitindex = i >> 5;
+ Matrix4x4_Transform(&ent->inversematrix, rd->origin, lightorigin);
+ lightpvsbytes = 0;
+ if (r_vismarklights.integer && ent->model->brush.FatPVS)
+ lightpvsbytes = ent->model->brush.FatPVS(ent->model, lightorigin, 0, lightpvs, sizeof(lightpvs));
+ R_RecursiveMarkLights(ent, lightorigin, rd, bit, bitindex, ent->model->brushq1.nodes + ent->model->brushq1.hulls[0].firstclipnode, lightpvs, min(lightpvsbytes * 8, ent->model->brushq1.num_leafs - 1));
+ }
+ }
}
/*
worldlight_t *r_shadow_selectedlight;
vec3_t r_editlights_cursorlocation;
+static int lightpvsbytes;
+static qbyte lightpvs[(MAX_MAP_LEAFS + 7)/ 8];
+
static int castshadowcount = 1;
void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style, const char *cubemapname, int castshadow)
{
shadowmesh_t *mesh, *castmesh;
mleaf_t *leaf;
msurface_t *surf;
- qbyte *pvs;
surfmesh_t *surfmesh;
if (radius < 15 || DotProduct(color, color) < 0.03)
qbyte *byteleafpvs;
qbyte *bytesurfacepvs;
- byteleafpvs = Mem_Alloc(tempmempool, cl.worldmodel->brushq1.numleafs + 1);
+ byteleafpvs = Mem_Alloc(tempmempool, cl.worldmodel->brushq1.numleafs);
bytesurfacepvs = Mem_Alloc(tempmempool, cl.worldmodel->brushq1.numsurfaces);
Portal_Visibility(cl.worldmodel, e->origin, byteleafpvs, bytesurfacepvs, NULL, 0, true, RadiusFromBoundsAndOrigin(e->mins, e->maxs, e->origin));
- for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
- if (byteleafpvs[i+1] && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
+ for (i = 0, leaf = cl.worldmodel->brushq1.leafs;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
+ if (byteleafpvs[i] && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
leaf->worldnodeframe = castshadowcount;
for (i = 0, surf = cl.worldmodel->brushq1.surfaces;i < cl.worldmodel->brushq1.numsurfaces;i++, surf++)
}
else
{
- leaf = cl.worldmodel->brushq1.PointInLeaf(cl.worldmodel, origin);
- pvs = cl.worldmodel->brushq1.LeafPVS(cl.worldmodel, leaf);
- for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
+ lightpvsbytes = cl.worldmodel->brush.FatPVS(cl.worldmodel, origin, 0, lightpvs, sizeof(lightpvs));
+ for (i = 0, leaf = cl.worldmodel->brushq1.leafs + 1;i < cl.worldmodel->brushq1.numleafs - 1;i++, leaf++)
{
- if (pvs[i >> 3] & (1 << (i & 7)) && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
+ if (lightpvs[i >> 3] & (1 << (i & 7)) && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
{
leaf->worldnodeframe = castshadowcount;
for (j = 0, mark = leaf->firstmarksurface;j < leaf->nummarksurfaces;j++, mark++)