try to cache fewer animations for entities when r_shadows is used by using cull box
authoreihrul <eihrul@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 5 Feb 2010 01:09:58 +0000 (01:09 +0000)
committereihrul <eihrul@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 5 Feb 2010 01:09:58 +0000 (01:09 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9934 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
r_shadow.c
r_shadow.h

index 74cf0cb..22c99ef 100644 (file)
@@ -6716,11 +6716,6 @@ void R_AnimCache_CacheVisibleEntities(void)
        for (i = 0;i < r_refdef.scene.numentities;i++)
                if (r_refdef.viewcache.entityvisible[i])
                        R_AnimCache_GetEntity(r_refdef.scene.entities[i], wantnormals, wanttangents);
-
-       if (r_shadows.integer)
-               for (i = 0;i < r_refdef.scene.numentities;i++)
-                       if (!r_refdef.viewcache.entityvisible[i])
-                               R_AnimCache_GetEntity(r_refdef.scene.entities[i], false, false);
 }
 
 //==================================================================================
@@ -8357,6 +8352,8 @@ void R_RenderScene(void)
                R_TimeReport("animation");
 
        R_Shadow_PrepareLights();
+       if (r_shadows.integer > 0 && r_refdef.lightmapintensity > 0)
+               R_Shadow_PrepareModelShadows();
        if (r_timereport_active)
                R_TimeReport("preparelights");
 
index be7f4fa..106bcc8 100644 (file)
@@ -4203,6 +4203,66 @@ extern cvar_t r_shadows_castfrombmodels;
 extern cvar_t r_shadows_throwdistance;
 extern cvar_t r_shadows_throwdirection;
 
+void R_Shadow_PrepareModelShadows(void)
+{
+       int i;
+       float scale, size, radius, dot1, dot2;
+       vec3_t shadowdir, shadowforward, shadowright, shadoworigin, shadowmins, shadowmaxs;
+       entity_render_t *ent;
+
+       if (!r_refdef.scene.numentities)
+               return;
+
+       switch (r_shadow_shadowmode)
+       {
+       case R_SHADOW_SHADOWMODE_SHADOWMAP2D:
+       case R_SHADOW_SHADOWMODE_SHADOWMAPRECTANGLE:
+               break;
+       case R_SHADOW_SHADOWMODE_STENCIL;
+               for (i = 0;i < r_refdef.scene.numentities;i++)
+               {
+                       ent = r_refdef.scene.entities[i];
+                       if (!ent->animcache_vertex3f && ent->model && ent->model->DrawShadowVolume != NULL && (!ent->model->brush.submodel || r_shadows_castfrombmodels.integer) && (ent->flags & RENDER_SHADOW))
+                               R_AnimCache_GetEntity(ent false, false);
+               }
+               return;
+       default:
+               return;
+       }
+
+       size = 2*r_shadow_shadowmapmaxsize;
+       scale = r_shadow_shadowmapping_precision.value;
+       radius = 0.5f * size / scale;
+       Math_atov(r_shadows_throwdirection.string, shadowdir);
+       VectorNormalize(shadowdir);
+       dot1 = DotProduct(r_refdef.view.forward, shadowdir);
+       dot2 = DotProduct(r_refdef.view.up, shadowdir);
+       if (fabs(dot1) <= fabs(dot2))
+               VectorMA(r_refdef.view.forward, -dot1, shadowdir, shadowforward);
+       else
+               VectorMA(r_refdef.view.up, -dot2, shadowdir, shadowforward);
+       VectorNormalize(shadowforward);
+       CrossProduct(shadowdir, shadowforward, shadowright);
+       VectorMA(r_refdef.view.origin, (1.0f - fabs(dot1)) * radius, shadowforward, shadoworigin);
+
+       shadowmins[0] = shadoworigin[0] - r_shadows_throwdistance.value * fabs(shadowdir[0]) - radius * (fabs(shadowforward[0]) + fabs(shadowright[0]));
+       shadowmins[1] = shadoworigin[1] - r_shadows_throwdistance.value * fabs(shadowdir[1]) - radius * (fabs(shadowforward[1]) + fabs(shadowright[1]));
+       shadowmins[2] = shadoworigin[2] - r_shadows_throwdistance.value * fabs(shadowdir[2]) - radius * (fabs(shadowforward[2]) + fabs(shadowright[2]));
+       shadowmaxs[0] = shadoworigin[0] + r_shadows_throwdistance.value * fabs(shadowdir[0]) + radius * (fabs(shadowforward[0]) + fabs(shadowright[0]));
+       shadowmaxs[1] = shadoworigin[1] + r_shadows_throwdistance.value * fabs(shadowdir[1]) + radius * (fabs(shadowforward[1]) + fabs(shadowright[1]));
+       shadowmaxs[2] = shadoworigin[2] + r_shadows_throwdistance.value * fabs(shadowdir[2]) + radius * (fabs(shadowforward[2]) + fabs(shadowright[2]));
+
+       for (i = 0;i < r_refdef.scene.numentities;i++)
+       {
+               ent = r_refdef.scene.entities[i];
+               if (!BoxesOverlap(ent->mins, ent->maxs, shadowmins, shadowmaxs))
+                       continue;
+               // cast shadows from anything of the map (submodels are optional)
+               if (!ent->animcache_vertex3f && ent->model && ent->model->DrawShadowMap != NULL && (!ent->model->brush.submodel || r_shadows_castfrombmodels.integer) && (ent->flags & RENDER_SHADOW))
+                       R_AnimCache_GetEntity(ent, false, false);
+       }
+}
+
 void R_DrawModelShadowMaps(void)
 {
        int i;
index 93ccb2b..5997605 100644 (file)
@@ -90,6 +90,8 @@ extern unsigned char *shadowsides;
 extern int *shadowsideslist;
 void R_Shadow_PrepareShadowSides(int numtris);
 
+void R_Shadow_PrepareModelShadows(void);
+
 void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const vec3_t p, int dynamic);
 
 #endif