Revision: 17152
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17152
Author:   unclezeiv
Date:     2008-10-21 22:21:48 +0200 (Tue, 21 Oct 2008)

Log Message:
-----------
Minor improvement: implemented a new function to provide bounding cones for 
clusters of oriented lights. This should lead to tighter bounds and, 
ultimately, to better light trees, according to the paper "Fast Agglomerative 
Clustering" (http://www.graphics.cornell.edu/~bjw/papers.html).

Also added yet another check for nan values in VPLs.

Modified Paths:
--------------
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-10-21 17:59:56 UTC (rev 17151)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-10-21 20:21:48 UTC (rev 17152)
@@ -147,6 +147,8 @@
        /* cone_* variables only for oriented lights */
        float cone_dir[3]; /* store normalized */
        float cone_angle;
+       float cone_min[3]; /* for auxiliary bounding box */
+       float cone_max[3];
        float luminance;
        short falloff_type, sphere;
        float falloff_dist;
@@ -275,9 +277,40 @@
 
 static void add_virtual_point_light(Render * re, LightcutsData *lcd, LampRen 
*orig, float *col, short lev, float weight);
 
-/* XXX: this function looks really slow! */
-static float get_bounding_cone(LightcutsCluster * one, LightcutsCluster * two, 
float *vec)
+static float get_bounding_cone_cos(LightcutsCluster * dest, LightcutsCluster * 
one, LightcutsCluster * two)
 {
+       float diag[3], center[3], dist, rad_sq;
+       float cone_min[3], cone_max[3];
+       
+       /* update auxiliary bounding box */
+       VECCOPY(cone_min, one->cone_min);
+       VECCOPY(cone_max, one->cone_max);
+       DO_MINMAX(two->cone_min, cone_min, cone_max);
+       DO_MINMAX(two->cone_max, cone_min, cone_max);
+       
+       VECSUB(diag, cone_max, cone_min);
+       VECADDFAC(center, cone_min, diag, 0.5f);
+       
+       if (dest) {
+               VECCOPY(dest->cone_dir, center);
+               Normalize(dest->cone_dir);
+               VECCOPY(dest->cone_min, cone_min);
+               VECCOPY(dest->cone_max, cone_max);
+       }
+       
+       dist= sqrt(VEC_LEN_SQ(center));
+       rad_sq= VEC_LEN_SQ(diag) * 0.25f;
+       
+       /* center and radius of circle in intersection */
+       if (sqrt(rad_sq) > dist + 1.0f)
+               return -1;
+       
+       return 0.5f * ((1.0f - rad_sq) / dist + dist);
+}
+
+#if 0
+static float get_bounding_cone_old(LightcutsCluster * dest, LightcutsCluster * 
one, LightcutsCluster * two)
+{
        float angle, angle_new;
        
        angle= NormalizedVecAngle2(one->cone_dir, two->cone_dir);
@@ -286,18 +319,19 @@
        if (angle > angle_new)
                angle_new= (angle + angle_new) * 0.5f;
        
-       if (vec) {
+       if (dest) {
                float axis[3];
                float mat[3][3];
-               VECCOPY(vec, one->cone_dir);
+               VECCOPY(dest->cone_dir, one->cone_dir);
                Crossf(axis, one->cone_dir, two->cone_dir);
                /* TODO: XXX: check signs */
                VecRotToMat3(axis, angle_new, mat);
-               Mat3MulVecfl(mat, vec);
+               Mat3MulVecfl(mat, dest->cone_dir);
        }
        
        return angle_new;
 }
+#endif
 
 static float lightcuts_compute_metric(float csq, LightcutsCluster * one, 
LightcutsCluster * two)
 {
@@ -312,7 +346,7 @@
        VECSUB(diff, max, min);
        
        if (one->type == CLUSTER_SPOT) {
-               float cos_a= cosf(get_bounding_cone(one, two, NULL));
+               float cos_a= get_bounding_cone_cos(NULL, one, two);
                float term = (1 - cos_a) * (1 - cos_a);
                return (one->luminance + two->luminance) * (VEC_LEN_SQ(diff) + 
csq * term);
        }
@@ -365,7 +399,7 @@
        
        /* if LA_SPOT, compute new bounding cone */
        if (one->type == CLUSTER_SPOT)
-               dest->cone_angle= get_bounding_cone(one, two, dest->cone_dir);
+               dest->cone_angle= acosf(get_bounding_cone_cos(dest, one, two));
        
        /* worst case falloff type/dist for conservative error estimation */
        dest->falloff_type= falloff_merge[one->falloff_type][two->falloff_type];
@@ -438,7 +472,7 @@
                        }
                        
                        if (!found)
-                               printf("BUG: no representative selected for %d: 
tot_lum %f\n", one->id, tot_lum);
+                               printf("BUG: no representative selected for %d 
(%d + %d): tot_lum %f\n", dest->id, one->id, two->id, tot_lum);
                }
                
                /* sort list and allocate list */
@@ -595,6 +629,8 @@
                        VECCOPY(clus->min, lar->co);
                        VECCOPY(clus->max, lar->co);
                        VECCOPY(clus->cone_dir, lar->vec);
+                       VECCOPY(clus->cone_min, lar->vec);
+                       VECCOPY(clus->cone_max, lar->vec);
                        clus->cone_angle= 0.0f;
                        break;
                }
@@ -1565,6 +1601,11 @@
        }
 // #endif
        
+       if (isnan(fac)) {
+               lcd->stat_discard_nan++;
+               return;
+       }
+       
        lar= MEM_callocN(sizeof(LampRen), "lampren");
        lamp_init(re, lar);
        lar->dist= lcd->indir_dist;


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to