realtime dlight shadows are now nearly the speed of compiled lights
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 3 Mar 2004 05:25:07 +0000 (05:25 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 3 Mar 2004 05:25:07 +0000 (05:25 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3957 d7cf8633-e32d-0410-b094-e92efae38249

gl_rsurf.c
model_brush.c
model_brush.h
model_shared.h
r_shadow.c
todo

index 5fdbd9c..21ab745 100644 (file)
@@ -39,6 +39,24 @@ cvar_t r_drawcollisionbrushes_polygonfactor = {0, "r_drawcollisionbrushes_polygo
 cvar_t r_drawcollisionbrushes_polygonoffset = {0, "r_drawcollisionbrushes_polygonoffset", "0"};
 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"};
 
+/*
+// FIXME: these arrays are huge!
+int r_q1bsp_maxmarkleafs;
+int r_q1bsp_nummarkleafs;
+mleaf_t *r_q1bsp_maxleaflist[65536];
+int r_q1bsp_maxmarksurfaces;
+int r_q1bsp_nummarksurfaces;
+msurface_t *r_q1bsp_maxsurfacelist[65536];
+
+// FIXME: these arrays are huge!
+int r_q3bsp_maxmarkleafs;
+int r_q3bsp_nummarkleafs;
+q3mleaf_t *r_q3bsp_maxleaflist[65536];
+int r_q3bsp_maxmarksurfaces;
+int r_q3bsp_nummarksurfaces;
+q3mface_t *r_q3bsp_maxsurfacelist[65536];
+*/
+
 static int dlightdivtable[32768];
 
 static int R_IntAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surf)
@@ -1852,9 +1870,11 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
                }
        }
 #else
-       int i, j, t;
+       int t, leafnum, marksurfnum, trianglenum;
        const int *e;
        msurface_t *surf;
+       mleaf_t *leaf;
+       const qbyte *pvs;
        float projectdistance;
        const float *v[3];
        vec3_t lightmins, lightmaxs;
@@ -1863,25 +1883,60 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
        R_Mesh_Matrix(&ent->matrix);
        R_UpdateTextureInfo(ent);
        projectdistance = lightradius + ent->model->radius;//projectdistance = 1000000000.0f;//lightradius + ent->model->radius;
-       //projectdistance = 1000000000.0f;//lightradius + ent->model->radius;
        lightmins[0] = relativelightorigin[0] - lightradius;
        lightmins[1] = relativelightorigin[1] - lightradius;
        lightmins[2] = relativelightorigin[2] - lightradius;
        lightmaxs[0] = relativelightorigin[0] + lightradius;
        lightmaxs[1] = relativelightorigin[1] + lightradius;
        lightmaxs[2] = relativelightorigin[2] + lightradius;
+       /*
        R_Shadow_PrepareShadowMark(ent->model->brush.shadowmesh->numtriangles);
-       for (i = 0, surf = ent->model->brushq1.surfaces + ent->model->brushq1.firstmodelsurface;i < ent->model->brushq1.nummodelsurfaces;i++, surf++)
+       maxmarksurfaces = sizeof(surfacelist) / sizeof(surfacelist[0]);
+       ent->model->brushq1.GetVisible(ent->model, relativelightorigin, lightmins, lightmaxs, 0, NULL, NULL, maxmarkleafs, markleaf, &nummarkleafs);
+       for (marksurfacenum = 0;marksurfacenum < nummarksurfaces;marksurfacenum++)
        {
-               if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && surf->texinfo->texture->rendertype == SURFRENDER_OPAQUE && (surf->flags & SURF_SHADOWCAST))
+               surf = marksurface[marksurfacenum];
+               if (surf->shadowmark != shadowmarkcount)
                {
-                       for (j = 0, t = surf->num_firstshadowmeshtriangle, e = ent->model->brush.shadowmesh->element3i + t * 3;j < surf->mesh.num_triangles;j++, t++, e += 3)
+                       surf->shadowmark = shadowmarkcount;
+                       if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && surf->texinfo->texture->rendertype == SURFRENDER_OPAQUE && (surf->flags & SURF_SHADOWCAST))
                        {
-                               v[0] = ent->model->brush.shadowmesh->vertex3f + e[0] * 3;
-                               v[1] = ent->model->brush.shadowmesh->vertex3f + e[1] * 3;
-                               v[2] = ent->model->brush.shadowmesh->vertex3f + e[2] * 3;
-                               if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
-                                       shadowmarklist[numshadowmark++] = t;
+                               for (trianglenum = 0, t = surf->num_firstshadowmeshtriangle, e = ent->model->brush.shadowmesh->element3i + t * 3;trianglenum < surf->mesh.num_triangles;trianglenum++, t++, e += 3)
+                               {
+                                       v[0] = ent->model->brush.shadowmesh->vertex3f + e[0] * 3;
+                                       v[1] = ent->model->brush.shadowmesh->vertex3f + e[1] * 3;
+                                       v[2] = ent->model->brush.shadowmesh->vertex3f + e[2] * 3;
+                                       if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                                               shadowmarklist[numshadowmark++] = t;
+                               }
+                       }
+               }
+       }
+       */
+       R_Shadow_PrepareShadowMark(ent->model->brush.shadowmesh->numtriangles);
+       pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+       for (leafnum = 0, leaf = ent->model->brushq1.data_leafs;leafnum < ent->model->brushq1.num_leafs;leafnum++, leaf++)
+       {
+               if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
+               {
+                       for (marksurfnum = 0;marksurfnum < leaf->nummarksurfaces;marksurfnum++)
+                       {
+                               surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[marksurfnum];
+                               if (surf->shadowmark != shadowmarkcount)
+                               {
+                                       surf->shadowmark = shadowmarkcount;
+                                       if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && surf->texinfo->texture->rendertype == SURFRENDER_OPAQUE && (surf->flags & SURF_SHADOWCAST))
+                                       {
+                                               for (trianglenum = 0, t = surf->num_firstshadowmeshtriangle, e = ent->model->brush.shadowmesh->element3i + t * 3;trianglenum < surf->mesh.num_triangles;trianglenum++, t++, e += 3)
+                                               {
+                                                       v[0] = ent->model->brush.shadowmesh->vertex3f + e[0] * 3;
+                                                       v[1] = ent->model->brush.shadowmesh->vertex3f + e[1] * 3;
+                                                       v[2] = ent->model->brush.shadowmesh->vertex3f + e[2] * 3;
+                                                       if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                                                               shadowmarklist[numshadowmark++] = t;
+                                               }
+                                       }
+                               }
                        }
                }
        }
@@ -1891,10 +1946,12 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
 
 void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
-       int surfnum;
+       int leafnum, marksurfnum;
        msurface_t *surf;
+       mleaf_t *leaf;
+       const qbyte *pvs;
        texture_t *t;
-       float f, lightmins[3], lightmaxs[3];
+       float lightmins[3], lightmaxs[3];
        if (ent->model == NULL)
                return;
        R_Mesh_Matrix(&ent->matrix);
@@ -1905,20 +1962,27 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
        lightmaxs[1] = relativelightorigin[1] + lightradius;
        lightmaxs[2] = relativelightorigin[2] + lightradius;
        R_UpdateTextureInfo(ent);
-       for (surfnum = 0, surf = ent->model->brushq1.surfaces + ent->model->brushq1.firstmodelsurface;surfnum < ent->model->brushq1.nummodelsurfaces;surfnum++, surf++)
+       shadowmarkcount++;
+       pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+       for (leafnum = 0, leaf = ent->model->brushq1.data_leafs;leafnum < ent->model->brushq1.num_leafs;leafnum++, leaf++)
        {
-               if ((ent != &cl_entities[0].render || surf->visframe == r_framecount) && BoxesOverlap(surf->poly_mins, surf->poly_maxs, lightmins, lightmaxs))
+               if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
                {
-                       f = PlaneDiff(relativelightorigin, surf->plane);
-                       if (surf->flags & SURF_PLANEBACK)
-                               f = -f;
-                       if (f >= -0.1 && f < lightradius)
+                       for (marksurfnum = 0;marksurfnum < leaf->nummarksurfaces;marksurfnum++)
                        {
-                               t = surf->texinfo->texture->currentframe;
-                               if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+                               surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[marksurfnum];
+                               if (surf->shadowmark != shadowmarkcount)
                                {
-                                       R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap);
-                                       R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap);
+                                       surf->shadowmark = shadowmarkcount;
+                                       if ((ent != &cl_entities[0].render || surf->visframe == r_framecount) && BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs))
+                                       {
+                                               t = surf->texinfo->texture->currentframe;
+                                               if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+                                               {
+                                                       R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap);
+                                                       R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap);
+                                               }
+                                       }
                                }
                        }
                }
@@ -2433,9 +2497,12 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
                                        R_Shadow_VolumeFromSphere(face->num_vertices, face->num_triangles, face->data_vertex3f, face->data_element3i, face->data_neighbor3i, relativelightorigin, projectdistance, lightradius);
        }
 #else
-       int i, j, t;
+       int j, t, leafnum, marksurfnum;
        const int *e;
+       const qbyte *pvs;
+       const float *v[3];
        q3mface_t *face;
+       q3mleaf_t *leaf;
        vec3_t modelorg, lightmins, lightmaxs;
        model_t *model;
        float projectdistance;
@@ -2452,18 +2519,29 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
                lightmaxs[1] = relativelightorigin[1] + lightradius;
                lightmaxs[2] = relativelightorigin[2] + lightradius;
                R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles);
-               for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
+               pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+               for (leafnum = 0, leaf = ent->model->brushq3.data_leafs;leafnum < ent->model->brushq3.num_leafs;leafnum++, leaf++)
                {
-                       if (BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs))
+                       if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
                        {
-                               for (j = 0, t = face->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;j < face->num_triangles;j++, t++, e += 3)
+                               for (marksurfnum = 0;marksurfnum < leaf->numleaffaces;marksurfnum++)
                                {
-                                       const float *v[3];
-                                       v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
-                                       v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
-                                       v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
-                                       if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
-                                               shadowmarklist[numshadowmark++] = t;
+                                       face = leaf->firstleafface[marksurfnum];
+                                       if (face->shadowmark != shadowmarkcount)
+                                       {
+                                               face->shadowmark = shadowmarkcount;
+                                               if (BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs))
+                                               {
+                                                       for (j = 0, t = face->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;j < face->num_triangles;j++, t++, e += 3)
+                                                       {
+                                                               v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
+                                                               v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
+                                                               v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
+                                                               if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                                                                       shadowmarklist[numshadowmark++] = t;
+                                                       }
+                                               }
+                                       }
                                }
                        }
                }
index e9bcca8..ca02eaa 100644 (file)
@@ -2814,6 +2814,54 @@ static void Mod_Q1BSP_RoundUpToHullSize(model_t *cmodel, const vec3_t inmins, co
        VectorAdd(inmins, hull->clip_size, outmaxs);
 }
 
+/*
+void Mod_Q1BSP_RecursiveGetVisible(mnode_t *node, model_t *model, const vec3_t point, const vec3_t mins, const vec3_t maxs, int maxleafs, mleaf_t *leaflist, int *numleafs, int maxsurfaces, msurface_t *surfacelist, int *numsurfaces, const qbyte *pvs)
+{
+       mleaf_t *leaf;
+       for (;;)
+       {
+               if (!BoxesOverlap(node->mins, node->maxs, mins, maxs))
+                       return;
+               if (!node->plane)
+                       break;
+               Mod_Q1BSP_RecursiveGetVisible(node->children[0], model, point, mins, maxs, maxleafs, leaflist, numleafs, maxsurfaces, surfacelist, numsurfaces, pvs);
+               node = node->children[1];
+       }
+       leaf = (mleaf_t *)node;
+       if ((pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
+       {
+               int marksurfacenum;
+               msurface_t *surf;
+               if (maxleafs && *numleafs < maxleafs)
+                       leaflist[(*numleafs)++] = leaf;
+               if (maxsurfaces)
+               {
+                       for (marksurfacenum = 0;marksurfacenum < leaf->nummarksurfaces;marksurfacenum++)
+                       {
+                               surf = model->brushq1.surfaces + leaf->firstmarksurface[marksurfacenum];
+                               if (surf->shadowmark != shadowmarkcount)
+                               {
+                                       surf->shadowmark = shadowmarkcount;
+                                       if (BoxesOverlap(mins, maxs, surf->poly_mins, surf->poly_maxs) && ((surf->flags & SURF_PLANEBACK) ? PlaneDiff(point, surf->plane) < 0 : PlaneDiff(point, surf->plane) > 0) && *numsurfaces < maxsurfaces)
+                                               surfacelist[(*numsurfaces)++] = surf;
+                               }
+                       }
+               }
+       }
+}
+
+void Mod_Q1BSP_GetVisible(model_t *model, const vec3_t point, const vec3_t mins, const vec3_t maxs, int maxleafs, mleaf_t *leaflist, int *numleafs, int maxsurfaces, msurface_t *surfacelist, int *numsurfaces)
+{
+       // FIXME: support portals
+       if (maxsurfaces)
+               *numsurfaces = 0;
+       if (maxleafs)
+               *numleafs = 0;
+       pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+       Mod_Q1BSP_RecursiveGetVisible(ent->model->brushq1.nodes + ent->model->brushq1.firstclipnode, model, point, mins, maxs, maxleafs, leaflist, numleafs, maxsurfaces, surfacelist, numsurfaces);
+}
+*/
+
 extern void R_Model_Brush_DrawSky(entity_render_t *ent);
 extern void R_Model_Brush_Draw(entity_render_t *ent);
 extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
@@ -5301,6 +5349,69 @@ static int Mod_Q3BSP_NativeContentsFromSuperContents(model_t *model, int superco
        return nativecontents;
 }
 
+/*
+void Mod_Q3BSP_RecursiveGetVisible(q3mnode_t *node, model_t *model, const vec3_t point, const vec3_t mins, const vec3_t maxs, int maxleafs, q3mleaf_t *leaflist, int *numleafs, int maxsurfaces, q3msurface_t *surfacelist, int *numsurfaces, const qbyte *pvs)
+{
+       mleaf_t *leaf;
+       for (;;)
+       {
+               if (!BoxesOverlap(node->mins, node->maxs, mins, maxs))
+                       return;
+               if (!node->plane)
+                       break;
+               Mod_Q3BSP_RecursiveGetVisible(node->children[0], model, point, mins, maxs, maxleafs, leaflist, numleafs, maxsurfaces, surfacelist, numsurfaces, pvs);
+               node = node->children[1];
+       }
+       leaf = (mleaf_t *)node;
+       if ((pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
+       {
+               int marksurfacenum;
+               q3mface_t *surf;
+               if (maxleafs && *numleafs < maxleafs)
+                       leaflist[(*numleaf)++] = leaf;
+               if (maxsurfaces)
+               {
+                       for (marksurfacenum = 0;marksurfacenum < leaf->nummarksurfaces;marksurfacenum++)
+                       {
+                               face = leaf->firstleafface[marksurfacenum];
+                               if (face->shadowmark != shadowmarkcount)
+                               {
+                                       face->shadowmark = shadowmarkcount;
+                                       if (BoxesOverlap(mins, maxs, face->mins, face->maxs) && *numsurfaces < maxsurfaces)
+                                               surfacelist[(*numsurfaces)++] = face;
+                               }
+                       }
+               }
+       }
+}
+
+void Mod_Q3BSP_GetVisible(model_t *model, const vec3_t point, const vec3_t mins, const vec3_t maxs, int maxleafs, q3mleaf_t *leaflist, int *numleafs, int maxsurfaces, q3msurface_t *surfacelist, int *numsurfaces)
+{
+       // FIXME: support portals
+       if (maxsurfaces)
+               *numsurfaces = 0;
+       if (maxleafs)
+               *numleafs = 0;
+       if (model->submodel)
+       {
+               if (maxsurfaces)
+               {
+                       for (marksurfacenum = 0;marksurfacenum < leaf->nummarksurfaces;marksurfacenum++)
+                       {
+                               face = ent->model->brushq3.surfaces + leaf->firstmarksurface[marksurfacenum];
+                               if (BoxesOverlap(mins, maxs, face->mins, face->maxs) && *numsurfaces < maxsurfaces)
+                                       surfacelist[(*numsurfaces)++] = face;
+                       }
+               }
+       }
+       else
+       {
+               pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+               Mod_Q3BSP_RecursiveGetVisible(ent->model->brushq3.data_nodes, model, point, mins, maxs, maxleafs, leaflist, numleafs, maxsurfaces, surfacelist, numsurfaces, pvs);
+       }
+}
+*/
+
 extern void R_Q3BSP_DrawSky(struct entity_render_s *ent);
 extern void R_Q3BSP_Draw(struct entity_render_s *ent);
 extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
index b4f76ac..62448da 100644 (file)
@@ -227,6 +227,9 @@ typedef struct msurface_s
        //struct msurface_s **neighborsurfaces;
        // currently used only for generating static shadow volumes
        int lighttemp_castshadow;
+
+       // avoid redundent surface shadows
+       int shadowmark;
 }
 msurface_t;
 
index b16ee20..a8fac65 100644 (file)
@@ -450,6 +450,9 @@ typedef struct q3mface_s
 
        // index into model->brush.shadowmesh
        int num_firstshadowmeshtriangle;
+       
+       // used for shadow volume generation
+       int shadowmark;
 
        // temporary use by light processing
        int lighttemp_castshadow;
index a9440ac..4f5e1ca 100644 (file)
@@ -1698,7 +1698,6 @@ void R_RTLight_UpdateFromDLight(rtlight_t *rtlight, const dlight_t *light, int i
 // (undone by R_FreeCompiledRTLight, which R_UpdateLight calls)
 void R_RTLight_Compile(rtlight_t *rtlight)
 {
-#if 0
        int i, j, k, l, maxverts = 256, tris;
        float *vertex3f = NULL, mins[3], maxs[3];
        shadowmesh_t *mesh, *castmesh = NULL;
@@ -1908,7 +1907,19 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                        for (mesh = castmesh;mesh;mesh = mesh->next)
                        {
                                Mod_BuildTriangleNeighbors(mesh->neighbor3i, mesh->element3i, mesh->numtriangles);
-                               if ((tris = R_Shadow_ConstructShadowVolume(castmesh->numverts, 0, castmesh->numtriangles, castmesh->element3i, castmesh->neighbor3i, castmesh->vertex3f, NULL, shadowelements, vertex3f, rtlight->shadoworigin, r_shadow_projectdistance.value)))
+                               R_Shadow_PrepareShadowMark(mesh->numtriangles);
+                               for (i = 0;i < mesh->numtriangles;i++)
+                               {
+                                       const float *v[3];
+                                       v[0] = mesh->vertex3f + mesh->element3i[i*3+0] * 3;
+                                       v[1] = mesh->vertex3f + mesh->element3i[i*3+1] * 3;
+                                       v[2] = mesh->vertex3f + mesh->element3i[i*3+2] * 3;
+                                       if (PointInfrontOfTriangle(rtlight->shadoworigin, v[0], v[1], v[2]) && rtlight->cullmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && rtlight->cullmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && rtlight->cullmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && rtlight->cullmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && rtlight->cullmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && rtlight->cullmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                                               shadowmarklist[numshadowmark++] = i;
+                               }
+                               if (maxshadowelements < numshadowmark * 24)
+                                       R_Shadow_ResizeShadowElements((numshadowmark + 256) * 24);
+                               if ((tris = R_Shadow_ConstructShadowVolume(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->neighbor3i, mesh->vertex3f, NULL, shadowelements, vertex3f, rtlight->shadoworigin, r_shadow_projectdistance.value, numshadowmark, shadowmarklist)))
                                        Mod_ShadowMesh_AddMesh(r_shadow_mempool, rtlight->static_meshchain_shadow, NULL, NULL, NULL, vertex3f, NULL, NULL, NULL, NULL, tris, shadowelements);
                        }
                        Mem_Free(vertex3f);
@@ -1930,7 +1941,6 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                for (mesh = rtlight->static_meshchain_light;mesh;mesh = mesh->next)
                        l += mesh->numtriangles;
        Con_DPrintf("static light built: %f %f %f : %f %f %f box, %i shadow volume triangles, %i light triangles\n", rtlight->cullmins[0], rtlight->cullmins[1], rtlight->cullmins[2], rtlight->cullmaxs[0], rtlight->cullmaxs[1], rtlight->cullmaxs[2], k, l);
-#endif
 }
 
 void R_RTLight_Uncompile(rtlight_t *rtlight)
diff --git a/todo b/todo
index b98d5ad..cf4fcb5 100644 (file)
--- a/todo
+++ b/todo
@@ -95,6 +95,10 @@ d darkplaces: add tenebrae light entity properties, like cubemap and style and s
 -n darkplaces: implement cubemap support on rtlights (romi, Vermeulen, Mitchell)
 d darkplaces: add r_shadow_realtime_world_lightmaps cvar to control lightmap brightness (Mitchell)
 -n darkplaces: add gl_lightmaps cvar to disable texturing except lightmaps for testing (Vic)
+0 darkplaces: adaptive patch subdivision levels on X and Y based on r_subdivisions cvar
+0 darkplaces: put patches on a delayed queue in q3bsp collision code so the trace is first clipped by brushes
+2 darkplaces: do culling traces against patch bbox
+0 darkplaces: cap packet size at 1k for non-local connections, regardless of their rate setting
 0 hmap2: release hmap2 (Vic, Supajoe)
 4 darkplaces: add capability for qc entities to act as bones in a model, and send them as compressed origins in the parent entity's updates, with perhaps a limit of 16 bones, this would allow some simple serverside ragdoll (Mitchell, Deej)
 d darkplaces: worked around Intel precision bug with view blends (they were not covering one line of the screen, due to being so huge that it had precision problems, on ATI and NVIDIA) (Sajt)