[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16771] branches/soc-2008-unclezeiv/source /blender: Refactoring to prepare for "multiple representative" feature.

Davide Vercelli davide.vercelli at gmail.com
Sat Sep 27 23:09:32 CEST 2008


Revision: 16771
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16771
Author:   unclezeiv
Date:     2008-09-27 23:09:31 +0200 (Sat, 27 Sep 2008)

Log Message:
-----------
Refactoring to prepare for "multiple representative" feature.

Modified Paths:
--------------
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
    branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.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-09-27 19:57:32 UTC (rev 16770)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-09-27 21:09:31 UTC (rev 16771)
@@ -101,10 +101,13 @@
 #define LC_OPT_ENV_NOSPEC  0x0040
 #define LC_OPT_IND_NOSPEC  0x0080
 #define LC_OPT_NO_RAND_CLS 0x0100
+#define LC_OPT_MULT_REPR   0x0200
 
 #define LC_LAR_INDIRECT  0x01
 #define LC_LAR_GENERATED 0x02
 
+#define LC_MAX_MULT_REPR   16
+
 /*
  * This is a table to select the "worst falloff" for a cluster, given the
  * falloff types of its children.
@@ -124,6 +127,12 @@
 /* strings for textual output */  
 static char *tree_names[]= {"local (Lamp)", "directional (Sun)", "oriented (Spot)"};
 
+typedef struct ClusRep
+{
+	LampRen *lar;
+	float intensity;
+} ClusRep;
+
 /* node of the lightcuts tree */
 typedef struct LightcutsCluster
 {
@@ -144,6 +153,9 @@
 	short falloff_type, sphere;
 	float falloff_dist;
 	float sphere_dist;
+	short mrep_len;
+	short pad;
+	ClusRep *mrep_list;
 #ifdef LIGHTCUTS_DEBUG
 	int dbg_parent;
 	int dbg_options;
@@ -231,6 +243,21 @@
 	short do_phongcorr;
 } SampleCoordInfo;
 
+typedef struct SampleInfo {
+	SampleCoordInfo sci;
+	float totest_shad[3];
+	float totest_spec[3];
+	float totest_noshad[3];
+	Heap *cut;
+	int free_node;
+	ShadeInput *shi;
+	int used;
+	int used_type[3];
+	CutNode *cut_nodes;
+	int vpl_to_cap;
+	int *vpl_queue;
+} SampleInfo;
+
 typedef struct KDSearchCallbackData {
 	float c, mindir;
 	LightcutsCluster *one;
@@ -291,8 +318,21 @@
 	return (one->luminance + two->luminance) * VEC_LEN_SQ(diff);
 }
 
+static int cmp_clusrep(const void *a, const void *b)
+{
+	ClusRep *lar1= (ClusRep *)a;
+	ClusRep *lar2= (ClusRep *)b;
+	
+	float temp= lar1->intensity - lar2->intensity;
+	if (temp > 0)
+		return 1;
+	if (temp < 0)
+		return -1;
+	return 0;
+}
+
 /* returns 0 if the new cluster uses the first child as representative, 1 otherwise */
-static int add_new_cluster(LightcutsCluster *array, LightcutsClusterPair *minpair, int *root, float *colw, int random)
+static int add_new_cluster(LightcutsData *lcd, LightcutsCluster *array, LightcutsClusterPair *minpair, int *root)
 {
 	LightcutsCluster *one = &array[minpair->first];
 	LightcutsCluster *two = &array[minpair->second];
@@ -325,10 +365,10 @@
 	if (one->type == CLUSTER_SPOT)
 		dest->cone_angle= get_bounding_cone(one, two, dest->cone_dir);
 
-	if (random)
+	if (lcd->options & LC_OPT_NO_RAND_CLS)
+		use_one_as_repr= one->luminance > two->luminance;
+	else
 		use_one_as_repr= BLI_frand() * (one->luminance + two->luminance) < one->luminance;
-	else
-		use_one_as_repr= one->luminance > two->luminance;
 	
 	/* the representative light is chosen randomly among children */
 	if (use_one_as_repr) {
@@ -341,7 +381,7 @@
 		VECCOPY(dest->col, two->col);
 		rep= 1;
 	}
-	dest->intensity= dest->luminance / INPR(colw, dest->col);
+	dest->intensity= dest->luminance / INPR(lcd->colw, dest->col);
 	
 	/* worst case falloff type/dist for conservative error estimation */
 	dest->falloff_type= falloff_merge[one->falloff_type][two->falloff_type];
@@ -717,7 +757,7 @@
 
 		/* valid pair: build cluster out of it, mark children as used */
 		cluster_id = tree->free;
-		rep= add_new_cluster(array, minpair, &tree->free, lcd->colw, !(lcd->options & LC_OPT_NO_RAND_CLS));
+		rep= add_new_cluster(lcd, array, minpair, &tree->free);
 		
 		if (rep==0) {
 			BLI_kdtree_weak_delete(kdtree, minpair->second);
@@ -2053,33 +2093,80 @@
 
 void single_light_contrib(LampRen *lar, ShadeInput *shi, float *pi, float *pi_noshad, float *pt);
 
+static void fill_cut_node(LightcutsData *lcd, CutNode *node, LightcutsCluster *clus, SampleInfo *si)
+{
+	float i, i_noshad, t;
+	
+	node->id= clus->id;
+	node->type= clus->type;
+	node->error_bound= calc_geometric_eb(lcd, clus, si->shi->co) * calc_material_eb(clus, si->shi, &si->sci);
+#ifdef LIGHTCUTS_DEBUG
+	dbg_convert[tree->node]= 0;
+#endif
+	if (node->error_bound > FLT_EPSILON) {
+		single_light_contrib(clus->lar, si->shi, &i, &i_noshad, &t);
+		lcd->stat_rays_shot++;
+		node->contr_factor= MAX2(i, 0.0f);
+		node->contr_factor_spec= MAX2(t, 0.0f);
+		node->f_clus= node->contr_factor * clus->intensity;
+		node->f_clus_spec= node->contr_factor_spec * clus->intensity;
+		VECADDFAC(si->totest_shad, si->totest_shad, clus->col, node->f_clus);
+		VECADDFAC(si->totest_spec, si->totest_spec, clus->col, node->f_clus_spec);
+
+		/* XXX this part only for root ? */
+		if(si->shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
+			node->contr_factor_noshad= MAX2(i_noshad, 0.0f);
+			node->f_clus_noshad= node->contr_factor_noshad * clus->intensity;
+			VECADDFAC(si->totest_noshad, si->totest_noshad, clus->col, node->f_clus_noshad);
+		}
+#ifdef LIGHTCUTS_DEBUG
+		dbg_totlum+= node->contr_factor * clus->luminance;
+#endif
+
+		if (!IS_LEAF(clus))
+			BLI_heap_insert(si->cut, -node->error_bound * clus->luminance, node);
+		else {
+			si->used++;
+			
+			/* XXX unneeded for root ? */
+			if (clus->lar->lightcuts_options & LC_LAR_INDIRECT) {
+				si->vpl_queue[si->vpl_to_cap]= node - si->cut_nodes;
+				si->vpl_to_cap++;
+			}
+			
+#ifdef LIGHTCUTS_DEBUG
+			if (lcd->dbg_options & LC_DBG_TRAV_A_NODE_PRINT && lcd->dbg_first_pixel==0)
+				printf("A t:%d id:%4d eb:%7.5f fc:%7.5f\n",
+						CLUSTER_TYPE_TO_ARRAY_IDX(node->type), node->id, node->error_bound, node->f_clus);
+#endif
+		}
+	}
+	else
+		si->used++;
+	si->used_type[CLUSTER_TYPE_TO_ARRAY_IDX(node->type)]++;
+}
+
 void lightcuts_do_lights(LightcutsData *lcd, ShadeInput *shi, ShadeResult *shr)
 {
-	CutNode *cut_nodes;
-	int free_node= 0;
+	LightcutsCluster *array;
+	SampleInfo si;
+	
 	int it= 0;
-	int used= 0;
-	int used_type[3]= {0, 0, 0};
 	float i, i_noshad, t;
-	SampleCoordInfo sci;
 	float noropp[3];
 	float mirdir[3];
-	LightcutsCluster *array;
-	int vpl_to_cap= 0;
-	int *vpl_queue= 0;
+	
+	memset(&si, 0, sizeof(SampleInfo));
+	
+	si.shi= shi;
 
 	/* 
 	 * this heap maintains the current cut
 	 * TODO: its maximum size is known in advance, this allows to
 	 * preallocate it and share it between subsequent executions
 	 */
-	Heap *cut= BLI_heap_new();
+	si.cut= BLI_heap_new();
 
-	/* this is the total radiance estimate, continuously updated */
-	float totest_shad[3]= {0.0f, 0.0f, 0.0f};
-	float totest_noshad[3]= {0.0f, 0.0f, 0.0f};
-	float totest_spec[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 */
 
@@ -2087,51 +2174,51 @@
 #endif
 	
 	/* XXX: shi->vn seems to point inside the mesh, investigate; works inverted like this */
-	VECCOPY(noropp, shi->vn);
+	VECCOPY(noropp, si.shi->vn);
 	VECNEG(noropp);
-	get_axis_matrix(sci.tsm, noropp);
+	get_axis_matrix(si.sci.tsm, noropp);
 	
 	/* get sample coordinates in tangent space */
-	VECCOPY(sci.tspos, shi->co);
-	Mat3MulVecfl(sci.tsm, sci.tspos);
-	VECNEG(sci.tspos);
+	VECCOPY(si.sci.tspos, si.shi->co);
+	Mat3MulVecfl(si.sci.tsm, si.sci.tspos);
+	VECNEG(si.sci.tspos);
 	
 	/* compute downwards tangent space matrix */
-	VECCOPY(sci.dtsm[0], sci.tsm[1]);
-	VECCOPY(sci.dtsm[1], sci.tsm[0]);
-	VECCOPY(sci.dtsm[2], sci.tsm[2]);
-	VECNEG(sci.dtsm[2]);
-	VECCOPY(sci.dtspos, shi->co);
-	Mat3MulVecfl(sci.dtsm, sci.dtspos);
-	VECNEG(sci.dtspos);
+	VECCOPY(si.sci.dtsm[0], si.sci.tsm[1]);
+	VECCOPY(si.sci.dtsm[1], si.sci.tsm[0]);
+	VECCOPY(si.sci.dtsm[2], si.sci.tsm[2]);
+	VECNEG(si.sci.dtsm[2]);
+	VECCOPY(si.sci.dtspos, si.shi->co);
+	Mat3MulVecfl(si.sci.dtsm, si.sci.dtspos);
+	VECNEG(si.sci.dtspos);
 	
 	/* create mirror direction space */
 	{
 		float nor2[3];
 		VECCOPY(nor2, noropp);
-		VECCOPY(mirdir, shi->co);
+		VECCOPY(mirdir, si.shi->co);
 		Normalize(mirdir);
 		VecMulf(nor2, -2 * Inpf(mirdir, nor2));
 		VecAddf(mirdir, nor2, mirdir);
 		
-		get_axis_matrix(sci.msm, mirdir);
-		VECCOPY(sci.mspos, shi->co);
-		Mat3MulVecfl(sci.msm, sci.mspos);
-		VECNEG(sci.mspos);
+		get_axis_matrix(si.sci.msm, mirdir);
+		VECCOPY(si.sci.mspos, si.shi->co);
+		Mat3MulVecfl(si.sci.msm, si.sci.mspos);
+		VECNEG(si.sci.mspos);
 	}
 	
-	if(shi->mat->mode & MA_SHADOW) {
-		sci.phongcorr_thresh= 0.0f;
-		if((shi->mat->mode & MA_RAYBIAS) && (shi->vlr->flag & R_SMOOTH))
-			sci.phongcorr_thresh= shi->obr->ob->smoothresh;
-		else if(shi->mat->sbias!=0.0f)
-			sci.phongcorr_thresh= shi->mat->sbias;
-		if (sci.phongcorr_thresh!=0.0f)
-			sci.do_phongcorr= 1;
+	if(si.shi->mat->mode & MA_SHADOW) {
+		si.sci.phongcorr_thresh= 0.0f;
+		if((si.shi->mat->mode & MA_RAYBIAS) && (si.shi->vlr->flag & R_SMOOTH))
+			si.sci.phongcorr_thresh= si.shi->obr->ob->smoothresh;
+		else if(si.shi->mat->sbias!=0.0f)
+			si.sci.phongcorr_thresh= si.shi->mat->sbias;
+		if (si.sci.phongcorr_thresh!=0.0f)
+			si.sci.do_phongcorr= 1;
 	}
 
-	cut_nodes= lcd->cut_nodes + shi->thread * lcd->cut_nodes_size;
-	vpl_queue= lcd->vpl_to_cap + shi->thread * lcd->max_cut;
+	si.cut_nodes= lcd->cut_nodes + si.shi->thread * lcd->cut_nodes_size;
+	si.vpl_queue= lcd->vpl_to_cap + si.shi->thread * lcd->max_cut;
 
 	/* initial nodes in the queue */
 	{
@@ -2142,64 +2229,26 @@
 
 			if (tree->counter > 0) {
 				LightcutsCluster *clus= &tree->array[tree->root];
-				CutNode *root= &cut_nodes[free_node];
-
-				root->id= tree->root;
-				root->type= clus->type;
-				root->error_bound= calc_geometric_eb(lcd, clus, shi->co) * calc_material_eb(clus, shi, &sci);
-#ifdef LIGHTCUTS_DEBUG
-				dbg_convert[tree->root]= 0;
-#endif
-				if (root->error_bound > FLT_EPSILON) {
-					single_light_contrib(clus->lar, shi, &i, &i_noshad, &t);
-					lcd->stat_rays_shot++;
-					root->contr_factor= MAX2(i, 0.0f);
-					root->contr_factor_spec= MAX2(t, 0.0f);
-					root->f_clus= root->contr_factor * clus->intensity;
-					root->f_clus_spec= root->contr_factor_spec * clus->intensity;
-					VECADDFAC(totest_shad, totest_shad, clus->col, root->f_clus);
-					VECADDFAC(totest_spec, totest_spec, clus->col, root->f_clus_spec);
-
-					if(shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
-						root->contr_factor_noshad= MAX2(i_noshad, 0.0f);
-						root->f_clus_noshad= root->contr_factor_noshad * clus->intensity;
-						VECADDFAC(totest_noshad, totest_noshad, clus->col, root->f_clus_noshad);
-					}
-#ifdef LIGHTCUTS_DEBUG
-					dbg_totlum+= root->contr_factor * clus->luminance;
-#endif
-
-					if (!IS_LEAF(clus)) {
-						BLI_heap_insert(cut, -root->error_bound * clus->luminance, root);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list