Revision: 15365
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15365
Author:   unclezeiv
Date:     2008-06-27 03:05:31 +0200 (Fri, 27 Jun 2008)

Log Message:
-----------
- added correct computation of scene bounding box diagonal, needed to compute 
cluster similiarity metric during tree building; this completes support for 
oriented lights
- simplified code a bit, as translations were often not needed in many 
calculations; this way I also found out that I was using transposed matrices 
w.r.t. blender convention (they were isolated though, no bugs because of this)

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-26 18:28:33 UTC (rev 15364)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-06-27 01:05:31 UTC (rev 15365)
@@ -40,6 +40,7 @@
 #include "MEM_guardedalloc.h"
 #include "PIL_time.h"
 #include "RE_pipeline.h"
+#include "RE_raytrace.h"
 
 #include "blendef.h"
 #include "render_types.h"
@@ -115,7 +116,6 @@
 
 typedef struct LightcutsData {
        /* NOTE: conservative space estimation */
-       /* TODO: equivalent data structures for sun and spot */
        ListBase pointlights;
 
        LightcutsTree trees[_TREES_SIZE];
@@ -145,10 +145,11 @@
 } LightcutsData;
 
 #define VEC_LEN_SQ(v) (v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
+#define VECCOPYMUL(v1,v2,aS) {*(v1)= *(v2)*aS; *(v1+1)= *(v2+1)*aS; *(v1+2)= 
*(v2+2)*aS;}
+#define VECNEG(v) {*(v)=-*(v); *(v+1)=-*(v+1); *(v+2)=-*(v+2);}
 /* TODO: tentative calculation, will look better into it */
 #define LC_LUMINOSITY(c) (0.299*(c)[0] + 0.587*(c)[1] + 0.114*(c)[2])
 /* #define LC_LUMINOSITY(c) (0.316*c[0] + 0.460*c[1] + 0.224*c[2]) */
-#define VECCOPYMUL(v1,v2,aS) {*(v1)= *(v2)*aS; *(v1+1)= *(v2+1)*aS; *(v1+2)= 
*(v2+2)*aS;}
 #define IS_LEAF(node) (!(node)->child1 && !(node)->child2)
 
 /* XXX: this function looks really slow! */
@@ -464,7 +465,7 @@
                        lar->shadsamp= 
MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample");
                        ls= lar->shadsamp;
 
-                       /* shadfacs actually mean light, let's put them to 1 to 
prevent unitialized accidents */
+                       /* shadfacs actually mean light, let's put them to 1 to 
prevent uninitialized accidents */
                        for(a=0; a<re->r.threads; a++, ls++) {
                                lss= ls->s;
                                for(b=0; b<re->r.osa; b++, lss++) {
@@ -520,7 +521,6 @@
                        lcd->trees[TREE_LOCAL].counter++;
 
                        /* TODO: handle other attenuation models */
-
                        if (lar->dist < lcd->max_local_dist)
                                lcd->max_local_dist = lar->dist;
 
@@ -530,6 +530,8 @@
                        break;
                case LA_SPOT:
                        /* TODO: check if it's a valid spot */
+                       
+                       /* TODO: handle other attenuation models */
                        if (lar->dist < lcd->max_spot_dist)
                                lcd->max_spot_dist= lar->dist;
                        
@@ -560,7 +562,7 @@
                gonew->recalc= go->recalc;
                /*
                 * XXX: probably wrong, more a test to see if it is used 
somewhere
-                * or dealloacated
+                * or deallocated
                 * The point here is that we create new lights with no 
corresponding
                 * objects... do we need objects there?
                 */
@@ -599,9 +601,12 @@
        lcd->error_rate= re->r.lightcuts_max_error;
        lcd->max_cut= MIN2(re->r.lightcuts_max_cut, lcd->light_counter);
        lcd->start_time= PIL_check_seconds_timer();
-       /* XXX: TODO: get proper scene diagonal */
-       lcd->bb_diag_sq= 11.747*11.747;
        
+       /* we need the scene's diagonal squared */
+       lcd->bb_diag_sq= RE_ray_tree_max_size(re->raytree);
+       printf("Scene diagonal %f\n", lcd->bb_diag_sq);
+       lcd->bb_diag_sq*= lcd->bb_diag_sq;
+       
        re->i.infostr= "Building light trees";
        re->stats_draw(&re->i);
 
@@ -611,7 +616,6 @@
                        lightcuts_fill_array(pointlights, &lcd->trees[i], i);
                        printf("Lightcuts: building %s tree - ", tree_names[i]);
                        lightcuts_build_tree(&lcd->trees[i], lcd->bb_diag_sq);
-                       /* TODO: put square of scene bounding box diagonale 
instead of 0.0f */
                }
        }
        
@@ -627,18 +631,17 @@
 }
 
 /* Adapted from "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, 
"Graphics Gems", Academic Press, 1990 */
-static void transform_aabb(float tsm[4][4], float min[3], float max[3], float 
rmin[3], float rmax[3], int do_transl)
+static void transform_aabb(float tsm[3][3], float min[3], float max[3], float 
rmin[3], float rmax[3])
 {
        int i, j;
        float a, b;
 
        for (i = 0; i < 3; i++) {
-               /* translation */
-               rmin[i]= rmax[i]= (do_transl ? tsm[i][3] : 0.0f);
+               rmin[i]= rmax[i]= 0.0f;
 
                for (j = 0; j < 3; j++) {
-                       a= tsm[i][j] * min[j];
-                       b= tsm[i][j] * max[j];
+                       a= tsm[j][i] * min[j];
+                       b= tsm[j][i] * max[j];
                        if (a < b) {
                                rmin[i]+= a;
                                rmax[i]+= b;
@@ -667,45 +670,32 @@
        return max[2] / sqrt(xsq + ysq + max[2]*max[2]);
 }
 
-/* fill in tangent space matrix tsm given normal and position; please note, 
it's also a translation matrix */
-/* TODO: scrap the translation part, use a 3x3 and transform the vector when 
needed */
-static void get_tangent_space_matrix(float tsm[4][4], float *nor, float *pos, 
int negate)
+/* fill in tangent space matrix tsm given normal */
+static void get_tangent_space_matrix(float tsm[3][3], float *nor)
 {
-       float normat[4][4];
-
-       /* warning: we fill it transposed as it's easier */
-       /* XXX: shi->vn seems to point inside the mesh, investigate; works 
inverted like this */
-       if (negate) {
-               normat[2][0] = -nor[0];
-               normat[2][1] = -nor[1];
-               normat[2][2] = -nor[2];
-       }
-       else
-               VECCOPY(normat[2], nor);
-
+       float normat[3][3];
+       
+       VECCOPY(normat[2], nor);
        VecOrthoBasisf(normat[2], normat[0], normat[1]);
 
-       VECCOPY(normat[3], pos);
-
-       normat[0][3]= normat[1][3]= normat[2][3]= 0.0f;
-       normat[3][3]= 1.0f;
-
-       Mat4Transp(normat);
        /* now we have a proper tangent-to-world matrix: let's invert it */
-       Mat4Invert(tsm, normat);
+       Mat3Inv(tsm, normat);
 }
 
 /* error bound: material term */
 /* TODO: currently supporting only diffuse */
-static float calc_material_eb(float tsm[4][4], LightcutsCluster *clus)
+static float calc_material_eb(float tsm[3][3], LightcutsCluster *clus, float 
*pos)
 {
        float tmin[3], tmax[3];
-       transform_aabb(tsm, clus->min, clus->max, tmin, tmax, 
(clus->type!=CLUSTER_SUN));
+       transform_aabb(tsm, clus->min, clus->max, tmin, tmax);
+       if (clus->type != CLUSTER_SUN) {
+               VECADD(tmin, pos, tmin);
+               VECADD(tmax, pos, tmax);
+       }
        return MAX2(compute_cosine_bound(tmin, tmax), 0.0);
 }
 
 /* error bound: geometric term */
-/* TODO: missing LA_SPOT eb */
 static float calc_geometric_eb(LightcutsData *lcd, LightcutsCluster *clus, 
float *pos)
 {
        /* find the nearest point in the bounding box */
@@ -734,14 +724,14 @@
                float newmin[3], transmin[3];
                float newmax[3], transmax[3];
                float cos_t, angle;
-               float tsm[4][4];
+               float tsm[3][3];
                
-               get_tangent_space_matrix(tsm, clus->cone_dir, pos, 0);
+               get_tangent_space_matrix(tsm, clus->cone_dir);
                
                VECSUB(newmax, pos, clus->min);
                VECSUB(newmin, pos, clus->max);
                
-               transform_aabb(tsm, newmin, newmax, transmin, transmax, 0);
+               transform_aabb(tsm, newmin, newmax, transmin, transmax);
                
                cos_t= compute_cosine_bound(transmin, transmax);
                angle= acosf(cos_t);
@@ -773,11 +763,13 @@
        int it= 0;
        int used= 0;
        float i, i_noshad;
-       float tsm[4][4]; /* tangent space matrix */
+       float tsm[3][3]; /* tangent space matrix */
+       float tspos[3];
        LightcutsCluster *array;
 
-       /* this heap maintaines the current cut */
-       /* TODO: its maximum size is known in advance, this allows to
+       /* 
+        * 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();
@@ -791,9 +783,17 @@
 
        float dbg_totlum = 0.0f;
 #endif
+       
+       /* XXX: shi->vn seems to point inside the mesh, investigate; works 
inverted like this */
+       VECCOPY(tspos, shi->vn);
+       VECNEG(tspos);
+       get_tangent_space_matrix(tsm, tspos);
+       
+       /* get sample coordinates in tangent space */
+       VECCOPY(tspos, shi->co);
+       Mat3MulVecfl(tsm, tspos);
+       VECNEG(tspos);
 
-       get_tangent_space_matrix(tsm, shi->vn, shi->co, 1);
-
        cut_nodes= lcd->cut_nodes + shi->thread * lcd->cut_nodes_size;
 
        /* initial nodes in the queue */
@@ -810,7 +810,7 @@
 
                                root->id= tree->root;
                                root->type= clus->type;
-                               root->error_bound= calc_geometric_eb(lcd, clus, 
shi->co) * calc_material_eb(tsm, clus) * shi->refl;
+                               root->error_bound= calc_geometric_eb(lcd, clus, 
shi->co) * calc_material_eb(tsm, clus, tspos) * shi->refl;
 #ifdef LIGHTCUTS_DEBUG
                                dbg_convert[tree->root]= 0;
 #endif
@@ -903,15 +903,11 @@
 #ifdef LIGHTCUTS_DEBUG
                        dbg_totlum-= cn_hinode->contr_factor * 
hinode->luminance;
 #endif
-
-                       /* this is a strong assumption on linearity of 
intensity contribution... is it strong indeed?
-                        * and numerically questionable again */
-                       /* TODO: there is room to reuse the same block here */
-
-                       /* for the reprsented light we can reuse most 
calculations */
+                       
+                       /* for the represented light we can reuse most 
calculations */
                        cn_rep->id= rep->id;
                        cn_rep->type= rep->type;
-                       cn_rep->error_bound= calc_geometric_eb(lcd, rep, 
shi->co) * calc_material_eb(tsm, rep) * shi->refl;
+                       cn_rep->error_bound= calc_geometric_eb(lcd, rep, 
shi->co) * calc_material_eb(tsm, rep, tspos) * shi->refl;
 
                        if (cn_rep->error_bound > FLT_EPSILON) {
                                cn_rep->contr_factor= cn_hinode->contr_factor;
@@ -932,7 +928,7 @@
                        /* for the "unrepresented" light we have to compute 
stuff from scratch */
                        cn_unrep->id= unrep->id;
                        cn_unrep->type= unrep->type;
-                       cn_unrep->error_bound= calc_geometric_eb(lcd, unrep, 
shi->co) * calc_material_eb(tsm, unrep) * shi->refl;
+                       cn_unrep->error_bound= calc_geometric_eb(lcd, unrep, 
shi->co) * calc_material_eb(tsm, unrep, tspos) * shi->refl;
 
                        if (cn_unrep->error_bound > FLT_EPSILON) {
                                get_contrib(unrep->lar, shi, &i, &i_noshad);


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

Reply via email to