cvar_t r_shadow_realtime_dlight = {0, "r_shadow_realtime_dlight", "0"};
cvar_t r_shadow_visiblevolumes = {0, "r_shadow_visiblevolumes", "0"};
cvar_t r_shadow_gloss = {0, "r_shadow_gloss", "1"};
+cvar_t r_shadow_glossintensity = {0, "r_shadow_glossintensity", "1"};
+cvar_t r_shadow_gloss2intensity = {0, "r_shadow_gloss2intensity", "0.25"};
cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1"};
cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1"};
cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4"};
Cvar_RegisterVariable(&r_shadow_realtime_dlight);
Cvar_RegisterVariable(&r_shadow_visiblevolumes);
Cvar_RegisterVariable(&r_shadow_gloss);
+ Cvar_RegisterVariable(&r_shadow_glossintensity);
+ Cvar_RegisterVariable(&r_shadow_gloss2intensity);
Cvar_RegisterVariable(&r_shadow_debuglight);
Cvar_RegisterVariable(&r_shadow_scissor);
Cvar_RegisterVariable(&r_shadow_bumpscale_bumpmap);
return shadowelements;
}
+/*
+// readable version of some code found below
+//if ((t >= trianglerange_start && t < trianglerange_end) ? (t < i && !trianglefacinglight[t]) : (t < 0 || (te = inelement3i + t * 3, v[0] = invertex3f + te[0] * 3, v[1] = invertex3f + te[1] * 3, v[2] = invertex3f + te[2] * 3, !PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+int PointInfrontOfTriangle(const float *p, const float *a, const float *b, const float *c)
+{
+ float dir0[3], dir1[3], normal[3];
+
+ // calculate two mostly perpendicular edge directions
+ VectorSubtract(a, b, dir0);
+ VectorSubtract(c, b, dir1);
+
+ // we have two edge directions, we can calculate a third vector from
+ // them, which is the direction of the surface normal (it's magnitude
+ // is not 1 however)
+ CrossProduct(dir0, dir1, normal);
+
+ // compare distance of light along normal, with distance of any point
+ // of the triangle along the same normal (the triangle is planar,
+ // I.E. flat, so all points give the same answer)
+ return DotProduct(p, normal) > DotProduct(a, normal);
+}
+int checkcastshadowfromedge(int t, int i)
+{
+ int *te;
+ float *v[3];
+ if (t >= trianglerange_start && t < trianglerange_end)
+ {
+ if (t < i && !trianglefacinglight[t])
+ return true;
+ else
+ return false;
+ }
+ else
+ {
+ if (t < 0)
+ return true;
+ else
+ {
+ te = inelement3i + t * 3;
+ v[0] = invertex3f + te[0] * 3;
+ v[1] = invertex3f + te[1] * 3;
+ v[2] = invertex3f + te[2] * 3;
+ if (!PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]))))
+ return true;
+ else
+ return false;
+ }
+ }
+}
+*/
+
int R_Shadow_ConstructShadowVolume(int innumvertices, int trianglerange_start, int trianglerange_end, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *relativelightorigin, float projectdistance)
{
int i, j, tris = 0, numfacing = 0, vr[3], t, outvertices = 0;
}
}
// output the front and back triangles
- outelement3i[3] = vertexremap[e[0]];
- outelement3i[4] = vertexremap[e[1]];
- outelement3i[5] = vertexremap[e[2]];
- outelement3i[0] = vertexremap[e[2]] + 1;
- outelement3i[1] = vertexremap[e[1]] + 1;
- outelement3i[2] = vertexremap[e[0]] + 1;
+ outelement3i[0] = vertexremap[e[0]];
+ outelement3i[1] = vertexremap[e[1]];
+ outelement3i[2] = vertexremap[e[2]];
+ outelement3i[3] = vertexremap[e[2]] + 1;
+ outelement3i[4] = vertexremap[e[1]] + 1;
+ outelement3i[5] = vertexremap[e[0]] + 1;
outelement3i += 6;
tris += 2;
}
// triangle elements and vertices... by clever use of elements we
// can construct the whole shadow from the unprojected vertices and
// the projected vertices
- if ((tris = R_Shadow_ConstructShadowVolume(numverts, 0, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, varray_vertex3f2, relativelightorigin, projectdistance)))
+ if ((tris = R_Shadow_ConstructShadowVolume(numverts, 0, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, varray_vertex3f2, relativelightorigin, r_shadow_projectdistance.value/*projectdistance*/)))
{
GL_VertexPointer(varray_vertex3f2);
if (r_shadowstage == SHADOWSTAGE_STENCIL)
void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *firstmesh)
{
shadowmesh_t *mesh;
- rmeshstate_t m;
- memset(&m, 0, sizeof(m));
if (r_shadowstage == SHADOWSTAGE_STENCIL)
{
// increment stencil if backface is behind depthbuffer
if (r_shadow_texture3d.integer && !gl_texture3d)
Cvar_SetValueQuick(&r_shadow_texture3d, 0);
- //cl.worldmodel->numlights = min(cl.worldmodel->numlights, 1);
if (!r_shadow_attenuation2dtexture
|| (!r_shadow_attenuation3dtexture && r_shadow_texture3d.integer)
|| r_shadow_lightattenuationpower.value != r_shadow_attenpower
|| r_shadow_lightattenuationscale.value != r_shadow_attenscale)
R_Shadow_MakeTextures();
+ memset(&m, 0, sizeof(m));
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(false);
GL_DepthTest(true);
- GL_Color(0, 0, 0, 1);
-
- memset(&m, 0, sizeof(m));
R_Mesh_State_Texture(&m);
-
+ GL_Color(0, 0, 0, 1);
qglDisable(GL_SCISSOR_TEST);
r_shadowstage = SHADOWSTAGE_NONE;
void R_Shadow_Stage_ShadowVolumes(void)
{
rmeshstate_t m;
-
memset(&m, 0, sizeof(m));
R_Mesh_State_Texture(&m);
-
GL_Color(1, 1, 1, 1);
+ qglColorMask(0, 0, 0, 0);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(false);
GL_DepthTest(true);
-
if (r_shadow_polygonoffset.value != 0)
{
qglPolygonOffset(1.0f, r_shadow_polygonoffset.value);
}
else
qglDisable(GL_POLYGON_OFFSET_FILL);
- qglColorMask(0, 0, 0, 0);
qglDepthFunc(GL_LESS);
qglEnable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc(GL_ALWAYS, 128, 0xFF);
r_shadowstage = SHADOWSTAGE_STENCIL;
-
qglClear(GL_STENCIL_BUFFER_BIT);
c_rt_clears++;
// LordHavoc note: many shadow volumes reside entirely inside the world
void R_Shadow_Stage_LightWithoutShadows(void)
{
rmeshstate_t m;
-
memset(&m, 0, sizeof(m));
R_Mesh_State_Texture(&m);
-
- GL_Color(1, 1, 1, 1);
GL_BlendFunc(GL_ONE, GL_ONE);
GL_DepthMask(false);
GL_DepthTest(true);
qglDisable(GL_POLYGON_OFFSET_FILL);
-
- //GL_DepthTest(false);
-
+ GL_Color(1, 1, 1, 1);
qglColorMask(1, 1, 1, 1);
- qglDepthFunc(GL_LEQUAL);
+ qglDepthFunc(GL_EQUAL);
qglDisable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc(GL_EQUAL, 128, 0xFF);
-
r_shadowstage = SHADOWSTAGE_LIGHT;
c_rt_lights++;
}
void R_Shadow_Stage_LightWithShadows(void)
{
rmeshstate_t m;
-
memset(&m, 0, sizeof(m));
R_Mesh_State_Texture(&m);
-
- GL_Color(1, 1, 1, 1);
GL_BlendFunc(GL_ONE, GL_ONE);
GL_DepthMask(false);
GL_DepthTest(true);
qglDisable(GL_POLYGON_OFFSET_FILL);
-
- //GL_DepthTest(false);
-
+ GL_Color(1, 1, 1, 1);
qglColorMask(1, 1, 1, 1);
- qglDepthFunc(GL_LEQUAL);
+ qglDepthFunc(GL_EQUAL);
qglEnable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// only draw light where this geometry was already rendered AND the
// stencil is 128 (values other than this mean shadow)
qglStencilFunc(GL_EQUAL, 128, 0xFF);
-
r_shadowstage = SHADOWSTAGE_LIGHT;
c_rt_lights++;
}
void R_Shadow_Stage_End(void)
{
rmeshstate_t m;
-
memset(&m, 0, sizeof(m));
R_Mesh_State_Texture(&m);
-
- GL_Color(1, 1, 1, 1);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_DepthMask(true);
GL_DepthTest(true);
qglDisable(GL_POLYGON_OFFSET_FILL);
-
+ GL_Color(1, 1, 1, 1);
qglColorMask(1, 1, 1, 1);
qglDisable(GL_SCISSOR_TEST);
qglDepthFunc(GL_LEQUAL);
qglDisable(GL_STENCIL_TEST);
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
qglStencilFunc(GL_ALWAYS, 128, 0xFF);
-
r_shadowstage = SHADOWSTAGE_NONE;
}
-#if 0
-int R_Shadow_ScissorForBBoxAndSphere(const float *mins, const float *maxs, const float *origin, float radius)
-{
- int i, ix1, iy1, ix2, iy2;
- float x1, y1, x2, y2, x, y;
- vec3_t smins, smaxs;
- vec4_t v, v2;
- if (!r_shadow_scissor.integer)
- return false;
- // if view is inside the box, just say yes it's visible
- if (r_origin[0] >= mins[0] && r_origin[0] <= maxs[0]
- && r_origin[1] >= mins[1] && r_origin[1] <= maxs[1]
- && r_origin[2] >= mins[2] && r_origin[2] <= maxs[2])
- {
- qglDisable(GL_SCISSOR_TEST);
- return false;
- }
- VectorSubtract(r_origin, origin, v);
- if (DotProduct(v, v) < radius * radius)
- {
- qglDisable(GL_SCISSOR_TEST);
- return false;
- }
- // create viewspace bbox
- for (i = 0;i < 8;i++)
- {
- v[0] = ((i & 1) ? mins[0] : maxs[0]) - r_origin[0];
- v[1] = ((i & 2) ? mins[1] : maxs[1]) - r_origin[1];
- v[2] = ((i & 4) ? mins[2] : maxs[2]) - r_origin[2];
- v2[0] = DotProduct(v, vright);
- v2[1] = DotProduct(v, vup);
- v2[2] = DotProduct(v, vpn);
- if (i)
- {
- if (smins[0] > v2[0]) smins[0] = v2[0];
- if (smaxs[0] < v2[0]) smaxs[0] = v2[0];
- if (smins[1] > v2[1]) smins[1] = v2[1];
- if (smaxs[1] < v2[1]) smaxs[1] = v2[1];
- if (smins[2] > v2[2]) smins[2] = v2[2];
- if (smaxs[2] < v2[2]) smaxs[2] = v2[2];
- }
- else
- {
- smins[0] = smaxs[0] = v2[0];
- smins[1] = smaxs[1] = v2[1];
- smins[2] = smaxs[2] = v2[2];
- }
- }
- // now we have a bbox in viewspace
- // clip it to the viewspace version of the sphere
- v[0] = origin[0] - r_origin[0];
- v[1] = origin[1] - r_origin[1];
- v[2] = origin[2] - r_origin[2];
- v2[0] = DotProduct(v, vright);
- v2[1] = DotProduct(v, vup);
- v2[2] = DotProduct(v, vpn);
- if (smins[0] < v2[0] - radius) smins[0] = v2[0] - radius;
- if (smaxs[0] < v2[0] - radius) smaxs[0] = v2[0] + radius;
- if (smins[1] < v2[1] - radius) smins[1] = v2[1] - radius;
- if (smaxs[1] < v2[1] - radius) smaxs[1] = v2[1] + radius;
- if (smins[2] < v2[2] - radius) smins[2] = v2[2] - radius;
- if (smaxs[2] < v2[2] - radius) smaxs[2] = v2[2] + radius;
- // clip it to the view plane
- if (smins[2] < 1)
- smins[2] = 1;
- // return true if that culled the box
- if (smins[2] >= smaxs[2])
- return true;
- // ok some of it is infront of the view, transform each corner back to
- // worldspace and then to screenspace and make screen rect
- // initialize these variables just to avoid compiler warnings
- x1 = y1 = x2 = y2 = 0;
- for (i = 0;i < 8;i++)
- {
- v2[0] = (i & 1) ? smins[0] : smaxs[0];
- v2[1] = (i & 2) ? smins[1] : smaxs[1];
- v2[2] = (i & 4) ? smins[2] : smaxs[2];
- v[0] = v2[0] * vright[0] + v2[1] * vup[0] + v2[2] * vpn[0] + r_origin[0];
- v[1] = v2[0] * vright[1] + v2[1] * vup[1] + v2[2] * vpn[1] + r_origin[1];
- v[2] = v2[0] * vright[2] + v2[1] * vup[2] + v2[2] * vpn[2] + r_origin[2];
- v[3] = 1.0f;
- GL_TransformToScreen(v, v2);
- //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
- x = v2[0];
- y = v2[1];
- if (i)
- {
- if (x1 > x) x1 = x;
- if (x2 < x) x2 = x;
- if (y1 > y) y1 = y;
- if (y2 < y) y2 = y;
- }
- else
- {
- x1 = x2 = x;
- y1 = y2 = y;
- }
- }
- /*
- // this code doesn't handle boxes with any points behind view properly
- x1 = 1000;x2 = -1000;
- y1 = 1000;y2 = -1000;
- for (i = 0;i < 8;i++)
- {
- v[0] = (i & 1) ? mins[0] : maxs[0];
- v[1] = (i & 2) ? mins[1] : maxs[1];
- v[2] = (i & 4) ? mins[2] : maxs[2];
- v[3] = 1.0f;
- GL_TransformToScreen(v, v2);
- //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
- if (v2[2] > 0)
- {
- x = v2[0];
- y = v2[1];
-
- if (x1 > x) x1 = x;
- if (x2 < x) x2 = x;
- if (y1 > y) y1 = y;
- if (y2 < y) y2 = y;
- }
- }
- */
- ix1 = x1 - 1.0f;
- iy1 = y1 - 1.0f;
- ix2 = x2 + 1.0f;
- iy2 = y2 + 1.0f;
- //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
- if (ix1 < r_refdef.x) ix1 = r_refdef.x;
- if (iy1 < r_refdef.y) iy1 = r_refdef.y;
- if (ix2 > r_refdef.x + r_refdef.width) ix2 = r_refdef.x + r_refdef.width;
- if (iy2 > r_refdef.y + r_refdef.height) iy2 = r_refdef.y + r_refdef.height;
- if (ix2 <= ix1 || iy2 <= iy1)
- return true;
- // set up the scissor rectangle
- qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1);
- qglEnable(GL_SCISSOR_TEST);
- c_rt_scissored++;
- return false;
-}
-#endif
-
int R_Shadow_ScissorForBBox(const float *mins, const float *maxs)
{
int i, ix1, iy1, ix2, iy2;
void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elements, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *texcoord2f, const float *relativelightorigin, const float *relativeeyeorigin, float lightradius, const float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *glosstexture, rtexture_t *bumptexture, rtexture_t *lightcubemap)
{
int renders;
- float color[3], color2[3];
+ float color[3], color2[3], colorscale;
rmeshstate_t m;
if (!gl_dot3arb || !gl_texturecubemap || !gl_combine.integer || !gl_stencil)
return;
- if (!bumptexture)
- bumptexture = r_shadow_blankbumptexture;
if (!glosstexture)
glosstexture = r_shadow_blankglosstexture;
if (r_shadow_gloss.integer >= 2 || (r_shadow_gloss.integer >= 1 && glosstexture != r_shadow_blankglosstexture))
{
+ colorscale = r_colorscale * r_shadow_glossintensity.value;
+ if (!bumptexture)
+ bumptexture = r_shadow_blankbumptexture;
+ if (glosstexture == r_shadow_blankglosstexture)
+ colorscale *= r_shadow_gloss2intensity.value;
GL_VertexPointer(vertex3f);
GL_Color(1,1,1,1);
if (r_shadow_texture3d.integer && r_textureunits.integer >= 2 && lightcubemap /*&& gl_support_blendsquare*/) // FIXME: detect blendsquare!
GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
+ VectorScale(lightcolor, colorscale, color2);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
color[0] = bound(0, color2[0], 1);
qglColorMask(1,1,1,0);
GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltoattenuationxyz);
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
+ VectorScale(lightcolor, colorscale, color2);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
color[0] = bound(0, color2[0], 1);
GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
if (lightcubemap)
R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
- VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value * 0.25f, color2);
+ VectorScale(lightcolor, colorscale, color2);
for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
{
color[0] = bound(0, color2[0], 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)
{
- int i, j, k, l, maxverts = 256, *mark, tris;
- float *vertex3f = NULL;
+ int i, j, k, l, maxverts = 256, *mark, tris, numsurfaces;
+ float *vertex3f = NULL, mins[3], maxs[3];
worldlight_t *e;
shadowmesh_t *mesh, *castmesh;
mleaf_t *leaf;
msurface_t *surf;
- qbyte *pvs;
surfmesh_t *surfmesh;
if (radius < 15 || DotProduct(color, color) < 0.03)
e->cullradius = e->lightradius;
for (k = 0;k < 3;k++)
{
- e->mins[k] = e->origin[k] - e->lightradius;
- e->maxs[k] = e->origin[k] + e->lightradius;
+ mins[k] = e->origin[k] - e->lightradius;
+ maxs[k] = e->origin[k] + e->lightradius;
}
e->next = r_shadow_worldlightchain;
if (cl.worldmodel)
{
castshadowcount++;
- i = cl.worldmodel->PointContents(cl.worldmodel, e->origin);
+ VectorCopy(e->origin, e->mins);
+ VectorCopy(e->origin, e->maxs);
+ i = CL_PointQ1Contents(e->origin);
if (r_shadow_portallight.integer && i != CONTENTS_SOLID && i != CONTENTS_SKY)
{
qbyte *byteleafpvs;
qbyte *bytesurfacepvs;
- byteleafpvs = Mem_Alloc(tempmempool, cl.worldmodel->numleafs + 1);
- bytesurfacepvs = Mem_Alloc(tempmempool, cl.worldmodel->numsurfaces);
+ 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->leafs + 1;i < cl.worldmodel->numleafs;i++, leaf++)
- if (byteleafpvs[i+1] && BoxesOverlap(leaf->mins, leaf->maxs, e->mins, e->maxs))
- leaf->worldnodeframe = castshadowcount;
+ for (i = 0, leaf = cl.worldmodel->brushq1.leafs;i < cl.worldmodel->brushq1.numleafs;i++, leaf++)
+ {
+ if (byteleafpvs[i] && BoxesOverlap(leaf->mins, leaf->maxs, mins, maxs))
+ {
+ for (k = 0;k < 3;k++)
+ {
+ if (e->mins[k] > leaf->mins[k]) e->mins[k] = leaf->mins[k];
+ if (e->maxs[k] < leaf->maxs[k]) e->maxs[k] = leaf->maxs[k];
+ }
+ }
+ }
- for (i = 0, surf = cl.worldmodel->surfaces;i < cl.worldmodel->numsurfaces;i++, surf++)
- if (bytesurfacepvs[i] && BoxesOverlap(surf->poly_mins, surf->poly_maxs, e->mins, e->maxs))
+ for (i = 0, surf = cl.worldmodel->brushq1.surfaces;i < cl.worldmodel->brushq1.numsurfaces;i++, surf++)
+ if (bytesurfacepvs[i] && BoxesOverlap(surf->poly_mins, surf->poly_maxs, mins, maxs))
surf->castshadow = castshadowcount;
Mem_Free(byteleafpvs);
}
else
{
- leaf = cl.worldmodel->PointInLeaf(cl.worldmodel, origin);
- pvs = cl.worldmodel->LeafPVS(cl.worldmodel, leaf);
- for (i = 0, leaf = cl.worldmodel->leafs + 1;i < cl.worldmodel->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.visleafs;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, mins, maxs))
{
- leaf->worldnodeframe = castshadowcount;
+ for (k = 0;k < 3;k++)
+ {
+ if (e->mins[k] > leaf->mins[k]) e->mins[k] = leaf->mins[k];
+ if (e->maxs[k] < leaf->maxs[k]) e->maxs[k] = leaf->maxs[k];
+ }
for (j = 0, mark = leaf->firstmarksurface;j < leaf->nummarksurfaces;j++, mark++)
{
- surf = cl.worldmodel->surfaces + *mark;
- if (surf->castshadow != castshadowcount && BoxesOverlap(surf->poly_mins, surf->poly_maxs, e->mins, e->maxs))
+ surf = cl.worldmodel->brushq1.surfaces + *mark;
+ if (surf->castshadow != castshadowcount && BoxesOverlap(surf->poly_mins, surf->poly_maxs, mins, maxs))
surf->castshadow = castshadowcount;
}
}
}
}
- e->numleafs = 0;
- for (i = 0, leaf = cl.worldmodel->leafs + 1;i < cl.worldmodel->numleafs;i++, leaf++)
- if (leaf->worldnodeframe == castshadowcount)
- e->numleafs++;
- e->numsurfaces = 0;
- for (i = 0, surf = cl.worldmodel->surfaces + cl.worldmodel->firstmodelsurface;i < cl.worldmodel->nummodelsurfaces;i++, surf++)
- if (surf->castshadow == castshadowcount)
- e->numsurfaces++;
-
- if (e->numleafs)
- e->leafs = Mem_Alloc(r_shadow_mempool, e->numleafs * sizeof(mleaf_t *));
- if (e->numsurfaces)
- e->surfaces = Mem_Alloc(r_shadow_mempool, e->numsurfaces * sizeof(msurface_t *));
- e->numleafs = 0;
- for (i = 0, leaf = cl.worldmodel->leafs + 1;i < cl.worldmodel->numleafs;i++, leaf++)
- if (leaf->worldnodeframe == castshadowcount)
- e->leafs[e->numleafs++] = leaf;
- e->numsurfaces = 0;
- for (i = 0, surf = cl.worldmodel->surfaces + cl.worldmodel->firstmodelsurface;i < cl.worldmodel->nummodelsurfaces;i++, surf++)
- if (surf->castshadow == castshadowcount)
- e->surfaces[e->numsurfaces++] = surf;
-
- // find bounding box of lit leafs
- VectorCopy(e->origin, e->mins);
- VectorCopy(e->origin, e->maxs);
- for (j = 0;j < e->numleafs;j++)
- {
- leaf = e->leafs[j];
- for (k = 0;k < 3;k++)
- {
- if (e->mins[k] > leaf->mins[k]) e->mins[k] = leaf->mins[k];
- if (e->maxs[k] < leaf->maxs[k]) e->maxs[k] = leaf->maxs[k];
- }
- }
-
for (k = 0;k < 3;k++)
{
if (e->mins[k] < e->origin[k] - e->lightradius) e->mins[k] = e->origin[k] - e->lightradius;
}
e->cullradius = RadiusFromBoundsAndOrigin(e->mins, e->maxs, e->origin);
+ numsurfaces = 0;
+ for (i = 0, surf = cl.worldmodel->brushq1.surfaces + cl.worldmodel->brushq1.firstmodelsurface;i < cl.worldmodel->brushq1.nummodelsurfaces;i++, surf++)
+ if (surf->castshadow == castshadowcount)
+ numsurfaces++;
+ if (numsurfaces)
+ e->surfaces = Mem_Alloc(r_shadow_mempool, numsurfaces * sizeof(msurface_t *));
+ e->numsurfaces = 0;
+ for (i = 0, surf = cl.worldmodel->brushq1.surfaces + cl.worldmodel->brushq1.firstmodelsurface;i < cl.worldmodel->brushq1.nummodelsurfaces;i++, surf++)
+ if (surf->castshadow == castshadowcount)
+ e->surfaces[e->numsurfaces++] = surf;
+
if (e->castshadows)
{
castshadowcount++;
Con_Printf("static shadow volume built containing %i triangles\n", l);
}
}
- Con_Printf("%f %f %f, %f %f %f, %f, %f, %d, %d\n", e->mins[0], e->mins[1], e->mins[2], e->maxs[0], e->maxs[1], e->maxs[2], e->cullradius, e->lightradius, e->numleafs, e->numsurfaces);
+ Con_Printf("%f %f %f, %f %f %f, %f, %f, %d\n", e->mins[0], e->mins[1], e->mins[2], e->maxs[0], e->maxs[1], e->maxs[2], e->cullradius, e->lightradius, e->numsurfaces);
}
void R_Shadow_FreeWorldLight(worldlight_t *light)
Mod_ShadowMesh_Free(light->shadowvolume);
if (light->surfaces)
Mem_Free(light->surfaces);
- if (light->leafs)
- Mem_Free(light->leafs);
Mem_Free(light);
}
if (rating >= 0.95)
{
rating /= (1 + 0.0625f * sqrt(DotProduct(temp, temp)));
- if (bestrating < rating && CL_TraceLine(light->origin, r_refdef.vieworg, NULL, NULL, 0, true, NULL) == 1.0f)
+ if (bestrating < rating && CL_TraceLine(light->origin, r_refdef.vieworg, NULL, NULL, true, NULL, SUPERCONTENTS_SOLID) == 1.0f)
{
bestrating = rating;
best = light;
Con_Printf("No map loaded.\n");
return;
}
- data = cl.worldmodel->entities;
+ data = cl.worldmodel->brush.entities;
if (!data)
return;
- for (entnum = 0;COM_ParseToken(&data) && com_token[0] == '{';entnum++)
+ for (entnum = 0;COM_ParseToken(&data, false) && com_token[0] == '{';entnum++)
{
light = 0;
origin[0] = origin[1] = origin[2] = 0;
islight = false;
while (1)
{
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
break; // error
if (com_token[0] == '}')
break; // end of entity
strcpy(key, com_token);
while (key[strlen(key)-1] == ' ') // remove trailing spaces
key[strlen(key)-1] = 0;
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
break; // error
strcpy(value, com_token);
vec_t dist, push, frac;
vec3_t dest, endpos, normal;
VectorMA(r_refdef.vieworg, r_editlights_cursordistance.value, vpn, dest);
- frac = CL_TraceLine(r_refdef.vieworg, dest, endpos, normal, 0, true, NULL);
+ frac = CL_TraceLine(r_refdef.vieworg, dest, endpos, normal, true, NULL, SUPERCONTENTS_SOLID);
if (frac < 1)
{
dist = frac * r_editlights_cursordistance.value;