[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