[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15184] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: Minor changes:

Davide Vercelli davide.vercelli at gmail.com
Tue Jun 10 01:54:24 CEST 2008


Revision: 15184
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15184
Author:   unclezeiv
Date:     2008-06-10 01:54:22 +0200 (Tue, 10 Jun 2008)

Log Message:
-----------
Minor changes:
- added some debug code (switched off by default); more to come
- added additional sanity checks (these will go away as the code matures)
- other cosmetic changes such as consistent naming and a bit of code shuffling

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-06-09 23:12:27 UTC (rev 15183)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-06-09 23:54:22 UTC (rev 15184)
@@ -43,6 +43,8 @@
 #include "blendef.h"
 #include "render_types.h"
 
+/* #define LIGHTCUTS_DEBUG */
+
 /* = LA_X + 1 */
 #define CLUSTER_EMPTY 0
 #define CLUSTER_LOCAL 1
@@ -57,6 +59,9 @@
 	int id; /* must be able to accomodate millions of lights */
 	int child1;
 	int child2;
+#ifdef LIGHTCUTS_DEBUG
+	int dbg_parent;
+#endif
 	float intensity;
 	float min[3];
 	float max[3];
@@ -96,6 +101,10 @@
 	
 	CutNode *cut_nodes;
 	int cut_nodes_size;
+#ifdef LIGHTCUTS_DEBUG
+	short dbg_first_pixel;
+	short dbg_jolly;
+#endif
 } LightcutsData;
 
 #define VEC_LEN_SQ(v) (v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
@@ -136,6 +145,11 @@
 	dest->child1 = minpair->first;
 	dest->child2 = minpair->second;
 	dest->luminance = one->luminance + two->luminance;
+
+#ifdef LIGHTCUTS_DEBUG
+	dest->dbg_parent = -1;
+	one->dbg_parent = two->dbg_parent = dest->id;
+#endif 
 	
 	/* compute new bounding box */
 	VECCOPY(dest->min, one->min);
@@ -234,7 +248,8 @@
 	}
 }
 
-static void debug_print_tree(LightcutsCluster *array, int root, int lev)
+#ifdef LIGHTCUTS_DEBUG
+static void dbg_print_tree(LightcutsCluster *array, int root, int lev)
 {
 	LightcutsCluster *el= &array[root];
 	int i;
@@ -244,10 +259,26 @@
 	
 	if (el->child1 == 0 && el->child2 == 0)
 		return;
+		
+	dbg_print_tree(array, el->child1, lev + 1);
+	dbg_print_tree(array, el->child2, lev + 1);		
+}
+
+static void dbg_check_tree(LightcutsCluster *array, int root)
+{
+	LightcutsCluster *el= &array[root];
 	
-	debug_print_tree(array, el->child1, lev + 1);
-	debug_print_tree(array, el->child2, lev + 1);		
+	if (el->child1 == 0 && el->child2 == 0)
+		return;
+		
+	if ((el->id != array[el->child1].dbg_parent) ||
+		(el->id != array[el->child2].dbg_parent))
+		printf("id %d wrong!\n", el->id);
+	
+	dbg_check_tree(array, el->child1);
+	dbg_check_tree(array, el->child2);		
 }
+#endif
 	
 static void lightcuts_build_tree(LightcutsData *lcd)
 {	
@@ -297,13 +328,17 @@
 	
 	/* the last cluster added is the root of the tree */	
 	lcd->root_local = cluster_id;
-	
+
+#ifdef LIGHTCUTS_DEBUG
+	dbg_check_tree(lcd->array_local, lcd->root_local);
+	/* dbg_print_tree(lcd->array_local, lcd->root_local, 0); */
+#endif
 	printf("Lightcuts tree built: %d\n", lcd->root_local);
-	/* debug_print_tree(lcd->array_local, lcd->root_local, 0); */
 	
 	MEM_freeN(pair_array);
 }
 
+#ifdef LIGHTCUTS_CURRENTLY_UNUSED
 /*
  * TODO: this is a temporary function, I need a proper initializer
  * right now this code is partly copied from add_render_lamp()
@@ -351,6 +386,7 @@
 		}
 	}
 }
+#endif
 
 void lightcuts_init(Render * re)
 {
@@ -358,8 +394,12 @@
 	GroupObject *go, *gonew;
 	ListBase *lights = &re->lights;
 	ListBase *pointlights;
-	LampRen *lar, *larnew;
+	LampRen *lar;
+
+#ifdef LIGHTCUTS_CURRENTLY_UNUSED
+	LampRen *larnew;
 	float r, g, b, n;
+#endif
 	
 	re->lcdata = lcd = MEM_callocN(sizeof(LightcutsData), "LightcutsData");
 	pointlights= &lcd->pointlights;
@@ -392,7 +432,7 @@
 		
 		lcd->light_counter++;
 		
-#if 0
+#ifdef LIGHTCUTS_CURRENTLY_UNUSED
 		/*
 		 * proof-of-concept functionality:
 		 * for each existing "lamp" or "sun", add another one, identical but:
@@ -455,16 +495,16 @@
 
 /* error bound: geometric term */
 /* TODO: right now is working only for point lights */
-float calc_geometric_eb(LightcutsData *lcd, int id, float *pos)
+static float calc_geometric_eb(LightcutsData *lcd, int id, float *pos)
 {
 	/* find the nearest point in the bounding box */
 	float *min= lcd->array_local[id].min;
 	float *max= lcd->array_local[id].max;
 	float nearest[3];
 	float len_sq;
-	nearest[0]= pos[0] < min[0] ? min[0] : pos[0] > max[0] ? max[0] : pos[0];
-	nearest[1]= pos[1] < min[1] ? min[1] : pos[1] > max[1] ? max[1] : pos[1];
-	nearest[2]= pos[2] < min[2] ? min[2] : pos[2] > max[2] ? max[2] : pos[2];
+	nearest[0]= pos[0] < min[0] ? min[0] : (pos[0] > max[0] ? max[0] : pos[0]);
+	nearest[1]= pos[1] < min[1] ? min[1] : (pos[1] > max[1] ? max[1] : pos[1]);
+	nearest[2]= pos[2] < min[2] ? min[2] : (pos[2] > max[2] ? max[2] : pos[2]);
 	
 	VECSUB(nearest, nearest, pos);
 	len_sq= VEC_LEN_SQ(nearest);
@@ -499,6 +539,10 @@
 	/* this is the total radiance estimate, continuously updated */
 	float totest[3]= {0.0f, 0.0f, 0.0f};
 	float totest_noshad[3]= {0.0f, 0.0f, 0.0f};
+
+#ifdef LIGHTCUTS_DEBUG
+	int dbg_convert[lcd->max_lights * 2]; /* from cluster id to index in cut_nodes */
+#endif
 	
 	cut_nodes= lcd->cut_nodes + shi->thread * lcd->cut_nodes_size;
 	
@@ -508,6 +552,9 @@
 		
 		root->id= lcd->root_local;
 		root->error_bound= calc_geometric_eb(lcd, lcd->root_local, shi->co);
+#ifdef LIGHTCUTS_DEBUG
+		dbg_convert[lcd->root_local]= 0;
+#endif
 		
 		get_contrib(clus->lar, shi, &i, &i_noshad);
 		root->contr_factor= i;
@@ -525,41 +572,53 @@
 	
 	/* at each iteration the heap grows by one, but we have a maximum size */
 	while (BLI_heap_size(cut) < (lcd->max_lights - used) && BLI_heap_size(cut) > 0) {
-		CutNode *node; 
-		LightcutsCluster *parent;
+		LightcutsCluster *c_hinode;
+		CutNode *hinode;
 		
-		node= BLI_heap_popmin(cut);
-		if (node < cut_nodes || node >= (cut_nodes + lcd->cut_nodes_size)) {
+		it++;
+		
+		hinode= BLI_heap_popmin(cut);
+		if (hinode < cut_nodes || hinode >= (cut_nodes + lcd->cut_nodes_size)) {
 			printf("tricky node! at %d, %d (it=%d)\n", shi->xs, shi->ys, it);
 			break;
 		}
-		parent= &lcd->array_local[node->id];
-		it++;
+		if (hinode->error_bound < hinode->contr_factor) {
+			printf("troublesome node! at %d, %d (it=%d): eb %7.5f < cf %7.5f\n",
+			shi->xs, shi->ys, it, hinode->error_bound, hinode->contr_factor);
+			break;
+		}
+		c_hinode= &lcd->array_local[hinode->id];
 		
-		if (parent->child1==0 && parent->child2==0) {
+		if (c_hinode->child1==0 && c_hinode->child2==0) {
+			/* can't go further down */
 			used++;
 			continue;
 		}
 		
-		if (LC_LUMINOSITY(totest) * lcd->error_rate > node->error_bound * parent->intensity) {
+		if (LC_LUMINOSITY(totest) * lcd->error_rate > hinode->error_bound * c_hinode->intensity) {
 			break;
 		} else {
-			LightcutsCluster *rep= &lcd->array_local[parent->child1];
-			LightcutsCluster *unrep= &lcd->array_local[parent->child2];
+			LightcutsCluster *rep= &lcd->array_local[c_hinode->child1];
+			LightcutsCluster *unrep= &lcd->array_local[c_hinode->child2];
 			CutNode *c_rep= &cut_nodes[free_node];
 			CutNode *c_unrep= &cut_nodes[free_node + 1];
 			
+			if (c_hinode->lar != rep->lar)
+				SWAP(LightcutsCluster*, rep, unrep);
+
+#ifdef LIGHTCUTS_DEBUG
+			dbg_convert[rep->id]= free_node;
+			dbg_convert[unrep->id]= free_node + 1;
+#endif
+
 			free_node += 2;
 			
-			if (parent->lar != rep->lar)
-				SWAP(LightcutsCluster*, rep, unrep);
-						
 			/*
 			 * XXX: numerically questionable
 			 * but please note that it's the same quantity
 			 * we are not calculating it in different ways
 			 */
-			VECADDFAC(totest, totest, rep->col, -node->f_clus);
+			VECADDFAC(totest, totest, rep->col, -hinode->f_clus);
 			
 			/* this is a strong assumption on linearity of intensity contribution... is it strong indeed?
 			 * and numerically questionable again */
@@ -568,8 +627,8 @@
 			/* for the reprsented light we can reuse most calculations */
 			c_rep->id= rep->id;
 			c_rep->error_bound= calc_geometric_eb(lcd, rep->id, shi->co);
-			c_rep->contr_factor= node->contr_factor;
-			c_rep->f_clus= node->contr_factor * rep->intensity;
+			c_rep->contr_factor= hinode->contr_factor;
+			c_rep->f_clus= hinode->contr_factor * rep->intensity;
 			VECADDFAC(totest, totest, rep->col, c_rep->f_clus);
 						
 			BLI_heap_insert(cut, -c_rep->error_bound * rep->intensity, c_rep);
@@ -585,10 +644,10 @@
 			BLI_heap_insert(cut, -c_unrep->error_bound * unrep->intensity, c_unrep);
 			
 			if(shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
-				VECADDFAC(totest_noshad, totest_noshad, rep->col, -node->f_clus_noshad);
+				VECADDFAC(totest_noshad, totest_noshad, rep->col, -hinode->f_clus_noshad);
 				
-				c_rep->contr_factor_noshad= node->contr_factor_noshad;
-				c_rep->f_clus_noshad= node->contr_factor_noshad * rep->intensity;
+				c_rep->contr_factor_noshad= hinode->contr_factor_noshad;
+				c_rep->f_clus_noshad= hinode->contr_factor_noshad * rep->intensity;
 				VECADDFAC(totest_noshad, totest_noshad, rep->col, c_rep->f_clus_noshad);
 				
 				c_unrep->contr_factor_noshad= i_noshad;





More information about the Bf-blender-cvs mailing list