-void R_DrawFakeShadows (void)
-{
- int i;
- entity_render_t *ent;
-
- ent = &cl_entities[0].render;
- if (ent->model && ent->model->DrawFakeShadow)
- ent->model->DrawFakeShadow(ent);
-
- if (!r_drawentities.integer)
- return;
- for (i = 0;i < r_refdef.numentities;i++)
- {
- ent = r_refdef.entities[i];
- if (ent->model && ent->model->DrawFakeShadow)
- ent->model->DrawFakeShadow(ent);
- }
-}
-
-#include "r_shadow.h"
-
-int shadowframecount = 0;
-
-int Light_CullBox(const vec3_t mins, const vec3_t maxs)
-{
- int stackpos, sides;
- mnode_t *node, *stack[4096];
- stackpos = 0;
- stack[stackpos++] = cl.worldmodel->nodes;
- while (stackpos)
- {
- node = stack[--stackpos];
- if (node->contents < 0)
- {
- if (((mleaf_t *)node)->worldnodeframe == shadowframecount)
- return false;
- }
- else
- {
- sides = BoxOnPlaneSide(mins, maxs, node->plane);
- if (sides & 2 && stackpos < 4096)
- stack[stackpos++] = node->children[1];
- if (sides & 1 && stackpos < 4096)
- stack[stackpos++] = node->children[0];
- }
- }
- return true;
-}
-
-int LightAndVis_CullBox(const vec3_t mins, const vec3_t maxs)
-{
- int stackpos, sides;
- mnode_t *node, *stack[4096];
- if (R_CullBox(mins, maxs))
- return true;
- stackpos = 0;
- stack[stackpos++] = cl.worldmodel->nodes;
- while (stackpos)
- {
- node = stack[--stackpos];
- if (node->contents < 0)
- {
- if (((mleaf_t *)node)->visframe == r_framecount && ((mleaf_t *)node)->worldnodeframe == shadowframecount)
- return false;
- }
- else
- {
- sides = BoxOnPlaneSide(mins, maxs, node->plane);
- if (sides & 2 && stackpos < 4096)
- stack[stackpos++] = node->children[1];
- if (sides & 1 && stackpos < 4096)
- stack[stackpos++] = node->children[0];
- }
- }
- return true;
-}
-
-
-void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float cullradius, float lightradius, vec3_t clipmins, vec3_t clipmaxs)
-{
- int i;
- vec3_t p, p2, temp, relativelightorigin, mins, maxs;
- float dist, projectdistance;
- // rough checks
- if (ent->model && ent->model->DrawShadowVolume)
- {
- temp[0] = bound(ent->mins[0], lightorigin[0], ent->maxs[0]) - lightorigin[0];
- temp[1] = bound(ent->mins[1], lightorigin[1], ent->maxs[1]) - lightorigin[1];
- temp[2] = bound(ent->mins[2], lightorigin[2], ent->maxs[2]) - lightorigin[2];
- dist = DotProduct(temp, temp);
- if (dist < cullradius * cullradius)
- {
- if (!Light_CullBox(ent->mins, ent->maxs))
- {
- projectdistance = cullradius - sqrt(dist);
- // calculate projected bounding box and decide if it is on-screen
- VectorCopy(ent->mins, mins);
- VectorCopy(ent->maxs, maxs);
- for (i = 0;i < 8;i++)
- {
- p[0] = i & 1 ? ent->maxs[0] : ent->mins[0];
- p[1] = i & 2 ? ent->maxs[1] : ent->mins[1];
- p[2] = i & 4 ? ent->maxs[2] : ent->mins[2];
- VectorSubtract(p, lightorigin, temp);
- dist = projectdistance / sqrt(DotProduct(temp, temp));
- VectorMA(p, dist, temp, p2);
- if (mins[0] > p2[0]) mins[0] = p2[0];if (maxs[0] < p2[0]) maxs[0] = p2[0];
- if (mins[1] > p2[1]) mins[1] = p2[1];if (maxs[1] < p2[1]) maxs[1] = p2[1];
- if (mins[2] > p2[2]) mins[2] = p2[2];if (maxs[2] < p2[2]) maxs[2] = p2[2];
- }
- if (mins[0] < clipmaxs[0] && maxs[0] > clipmins[0]
- && mins[1] < clipmaxs[1] && maxs[1] > clipmins[1]
- && mins[2] < clipmaxs[2] && maxs[2] > clipmins[2]
- && !LightAndVis_CullBox(mins, maxs))
- {
- Matrix4x4_Transform(&ent->inversematrix, lightorigin, relativelightorigin);
- ent->model->DrawShadowVolume (ent, relativelightorigin, lightradius);
- }
- }
- }
- }
-}
-
-void R_Shadow_DrawWorldLightShadowVolume(matrix4x4_t *matrix, worldlight_t *light);
-
-#define SHADOWSPHERE_SEGMENTS 16
-
-shadowmesh_t *shadowsphere;
-void R_CreateShadowSphere(void)