[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15184] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: Minor changes:
Davide Vercelli
davide.vercelli at gmail.com
Tue Jun 10 01:54:24 CEST 2008
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;
More information about the Bf-blender-cvs
mailing list