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;


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

Reply via email to