[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15338] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: preliminary changes for upcoming oriented lights support:

Davide Vercelli davide.vercelli at gmail.com
Tue Jun 24 02:52:16 CEST 2008


Revision: 15338
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15338
Author:   unclezeiv
Date:     2008-06-24 02:52:12 +0200 (Tue, 24 Jun 2008)

Log Message:
-----------
preliminary changes for upcoming oriented lights support:
- added function to get bounding cone of cluster of oriented lights (sketched, not tested yet)
- cluster metric takes bounding cone into account

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-23 21:47:31 UTC (rev 15337)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-06-24 00:52:12 UTC (rev 15338)
@@ -63,7 +63,9 @@
 #define CLUSTER_TYPE_TO_ARRAY_IDX(c) ((c)-1)
 
 /* strings for guarded alloc */
-char *array_names[]= {"lc_array_local", "lc_array_sun", "lc_array_spot"};
+static char *array_names[]= {"lc_array_local", "lc_array_sun", "lc_array_spot"};
+/* strings for textual output */  
+static char *tree_names[]= {"local (Lamp)", "directional (Sun)", "oriented (Spot)"};
 
 /* node of the lightcuts tree */
 typedef struct LightcutsCluster
@@ -80,6 +82,9 @@
 	float min[3];
 	float max[3];
 	float col[3];
+	/* cone_* variables only for oriented lights */
+	float cone_dir[3]; /* store normalized */
+	float cone_angle;
 	float luminance;
 	LampRen * lar;
 } LightcutsCluster;
@@ -132,6 +137,7 @@
 	int stat_samples;
 	int stat_cut_size;
 	int stat_rays_shot;
+	float bb_diag_sq;
 	
 	double start_time;
 	double tree_creation_time;
@@ -144,9 +150,32 @@
 #define VECCOPYMUL(v1,v2,aS) {*(v1)= *(v2)*aS; *(v1+1)= *(v2+1)*aS; *(v1+2)= *(v2+2)*aS;}
 #define IS_LEAF(node) (!(node)->child1 && !(node)->child2)
 
-static float lightcuts_compute_metric(LightcutsCluster * one, LightcutsCluster * two)
+/* XXX: this function looks really slow! */
+static float get_bounding_cone(LightcutsCluster * one, LightcutsCluster * two, float *vec)
 {
-	/* TODO: compute metric also for oriented lights */
+	float angle, angle_new;
+	
+	angle= NormalizedVecAngle2(one->cone_dir, two->cone_dir);
+	angle_new= MAX2(one->cone_angle, two->cone_angle);
+	
+	if (angle > angle_new)
+		angle_new= (angle + angle_new) * 0.5f;
+	
+	if (vec) {
+		float axis[3];
+		float mat[3][3];
+		VECCOPY(vec, one->cone_dir);
+		Crossf(axis, one->cone_dir, two->cone_dir);
+		/* TODO: XXX: check signs */
+		VecRotToMat3(axis, angle_new, mat);
+		Mat3MulVecfl(mat, vec);
+	}
+	
+	return angle_new;
+}
+
+static float lightcuts_compute_metric(float c, LightcutsCluster * one, LightcutsCluster * two)
+{
 	float diff[3], min[3], max[3];
 
 	VECCOPY(min, one->min);
@@ -156,6 +185,12 @@
 	DO_MINMAX(two->max, min, max);
 
 	VECSUB(diff, max, min);
+	
+	if (one->type == CLUSTER_SPOT) {
+		float cos_a= cosf(get_bounding_cone(one, two, NULL));
+		float term = (1 - cos_a) * (1 - cos_a);
+		return (one->luminance + two->luminance) * (VEC_LEN_SQ(diff) + c * term);
+	}
 
 	return (one->luminance + two->luminance) * VEC_LEN_SQ(diff);
 }
@@ -202,7 +237,7 @@
 	(*root)++;
 }
 
-static void find_and_insert_new_min(Heap * heap, LightcutsCluster * array, int size, LightcutsClusterPair * pair, int id, int from)
+static void find_and_insert_new_min(Heap * heap, LightcutsCluster * array, int size, LightcutsClusterPair * pair, int id, int from, float c)
 {
 	LightcutsCluster * el = &array[id];
 	LightcutsCluster * el2;
@@ -223,7 +258,7 @@
 		if (el2->in_tree)
 			continue;
 
-		pair_metric = lightcuts_compute_metric(el, el2);
+		pair_metric = lightcuts_compute_metric(c, el, el2);
 		if (pair_metric < metric)
 		{
 			metric = pair_metric;
@@ -325,7 +360,7 @@
 }
 #endif
 
-static void lightcuts_build_tree(LightcutsTree *tree)
+static void lightcuts_build_tree(LightcutsTree *tree, float c)
 {
 	int i, cluster_id = 0;
 	LightcutsCluster *array= tree->array;
@@ -339,7 +374,7 @@
 		if (array[i].type == CLUSTER_EMPTY)
 			break;
 
-		find_and_insert_new_min(heap, array, tree->counter * 2, &pair_array[i], i, i + 1);
+		find_and_insert_new_min(heap, array, tree->counter * 2, &pair_array[i], i, i + 1, c);
 	}
 
 	/* now we have a nice heap with shortest metric for each element */
@@ -358,7 +393,7 @@
 		/* we look for another minimum */
 		if (in_tree2)
 		{
-			find_and_insert_new_min(heap, array, tree->counter * 2, minpair, minpair->first, 0);
+			find_and_insert_new_min(heap, array, tree->counter * 2, minpair, minpair->first, 0, c);
 			continue;
 		}
 
@@ -367,7 +402,7 @@
 		add_new_cluster(array, minpair, &tree->free);
 
 		/* new search, avoid considering in_tree children */
-		find_and_insert_new_min(heap, array, tree->counter * 2, minpair, cluster_id, 0);
+		find_and_insert_new_min(heap, array, tree->counter * 2, minpair, cluster_id, 0, c);
 	}
 
 	BLI_heap_free(heap, 0);
@@ -442,6 +477,7 @@
 	ListBase *pointlights;
 	LampRen *lar;
 	char tree_time_str[12]; /* length 12 required by BLI_timestr */
+	int i;
 
 #ifdef LIGHTCUTS_CURRENTLY_UNUSED
 	LampRen *larnew;
@@ -548,19 +584,15 @@
 	re->i.infostr= "Building light trees";
 	re->stats_draw(&re->i);
 
-	/* build LA_LOCAL tree */
-	if (lcd->trees[TREE_LOCAL].counter > 0) {
-		lightcuts_fill_array(pointlights, &lcd->trees[TREE_LOCAL], LA_LOCAL);
-		printf("Lightcuts: local (Lamp) lights tree built - ");
-		lightcuts_build_tree(&lcd->trees[TREE_LOCAL]);
+	/* build light trees */
+	for (i= 0; i < _TREES_SIZE; i++) {
+		if (lcd->trees[i].counter > 0) {
+			lightcuts_fill_array(pointlights, &lcd->trees[i], i);
+			printf("Lightcuts: building %s tree - ", tree_names[i]);
+			lightcuts_build_tree(&lcd->trees[i], 0.0f);
+			/* TODO: put square of scene bounding box diagonale instead of 0.0f */
+		}
 	}
-
-	/* build LA_SUN tree */
-	if (lcd->trees[TREE_SUN].counter > 0) {
-		lightcuts_fill_array(pointlights, &lcd->trees[TREE_SUN], LA_SUN);
-		printf("Lightcuts: directional (Sun) lights tree built - ");
-		lightcuts_build_tree(&lcd->trees[TREE_SUN]);
-	}
 	
 	lcd->tree_creation_time= PIL_check_seconds_timer() - lcd->start_time;
 	BLI_timestr(lcd->tree_creation_time, tree_time_str);





More information about the Bf-blender-cvs mailing list