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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to