[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17152] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: Minor improvement: implemented a new function to provide bounding cones for clusters of oriented lights .

Davide Vercelli davide.vercelli at gmail.com
Tue Oct 21 22:21:48 CEST 2008


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;





More information about the Bf-blender-cvs mailing list