Revision: 15338
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15338
Author:   unclezeiv
Date:     2008-06-24 02:52:12 +0200 (Tue, 24 Jun 2008)

Log Message:
-----------
preliminary changes for upcoming oriented lights support:
- added function to get bounding cone of cluster of oriented lights (sketched, 
not tested yet)
- cluster metric takes bounding cone into account

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-23 21:47:31 UTC (rev 15337)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-06-24 00:52:12 UTC (rev 15338)
@@ -63,7 +63,9 @@
 #define CLUSTER_TYPE_TO_ARRAY_IDX(c) ((c)-1)
 
 /* strings for guarded alloc */
-char *array_names[]= {"lc_array_local", "lc_array_sun", "lc_array_spot"};
+static char *array_names[]= {"lc_array_local", "lc_array_sun", 
"lc_array_spot"};
+/* strings for textual output */  
+static char *tree_names[]= {"local (Lamp)", "directional (Sun)", "oriented 
(Spot)"};
 
 /* node of the lightcuts tree */
 typedef struct LightcutsCluster
@@ -80,6 +82,9 @@
        float min[3];
        float max[3];
        float col[3];
+       /* cone_* variables only for oriented lights */
+       float cone_dir[3]; /* store normalized */
+       float cone_angle;
        float luminance;
        LampRen * lar;
 } LightcutsCluster;
@@ -132,6 +137,7 @@
        int stat_samples;
        int stat_cut_size;
        int stat_rays_shot;
+       float bb_diag_sq;
        
        double start_time;
        double tree_creation_time;
@@ -144,9 +150,32 @@
 #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)
 
-static float lightcuts_compute_metric(LightcutsCluster * one, LightcutsCluster 
* two)
+/* XXX: this function looks really slow! */
+static float get_bounding_cone(LightcutsCluster * one, LightcutsCluster * two, 
float *vec)
 {
-       /* TODO: compute metric also for oriented lights */
+       float angle, angle_new;
+       
+       angle= NormalizedVecAngle2(one->cone_dir, two->cone_dir);
+       angle_new= MAX2(one->cone_angle, two->cone_angle);
+       
+       if (angle > angle_new)
+               angle_new= (angle + angle_new) * 0.5f;
+       
+       if (vec) {
+               float axis[3];
+               float mat[3][3];
+               VECCOPY(vec, one->cone_dir);
+               Crossf(axis, one->cone_dir, two->cone_dir);
+               /* TODO: XXX: check signs */
+               VecRotToMat3(axis, angle_new, mat);
+               Mat3MulVecfl(mat, vec);
+       }
+       
+       return angle_new;
+}
+
+static float lightcuts_compute_metric(float c, LightcutsCluster * one, 
LightcutsCluster * two)
+{
        float diff[3], min[3], max[3];
 
        VECCOPY(min, one->min);
@@ -156,6 +185,12 @@
        DO_MINMAX(two->max, min, max);
 
        VECSUB(diff, max, min);
+       
+       if (one->type == CLUSTER_SPOT) {
+               float cos_a= cosf(get_bounding_cone(one, two, NULL));
+               float term = (1 - cos_a) * (1 - cos_a);
+               return (one->luminance + two->luminance) * (VEC_LEN_SQ(diff) + 
c * term);
+       }
 
        return (one->luminance + two->luminance) * VEC_LEN_SQ(diff);
 }
@@ -202,7 +237,7 @@
        (*root)++;
 }
 
-static void find_and_insert_new_min(Heap * heap, LightcutsCluster * array, int 
size, LightcutsClusterPair * pair, int id, int from)
+static void find_and_insert_new_min(Heap * heap, LightcutsCluster * array, int 
size, LightcutsClusterPair * pair, int id, int from, float c)
 {
        LightcutsCluster * el = &array[id];
        LightcutsCluster * el2;
@@ -223,7 +258,7 @@
                if (el2->in_tree)
                        continue;
 
-               pair_metric = lightcuts_compute_metric(el, el2);
+               pair_metric = lightcuts_compute_metric(c, el, el2);
                if (pair_metric < metric)
                {
                        metric = pair_metric;
@@ -325,7 +360,7 @@
 }
 #endif
 
-static void lightcuts_build_tree(LightcutsTree *tree)
+static void lightcuts_build_tree(LightcutsTree *tree, float c)
 {
        int i, cluster_id = 0;
        LightcutsCluster *array= tree->array;
@@ -339,7 +374,7 @@
                if (array[i].type == CLUSTER_EMPTY)
                        break;
 
-               find_and_insert_new_min(heap, array, tree->counter * 2, 
&pair_array[i], i, i + 1);
+               find_and_insert_new_min(heap, array, tree->counter * 2, 
&pair_array[i], i, i + 1, c);
        }
 
        /* now we have a nice heap with shortest metric for each element */
@@ -358,7 +393,7 @@
                /* we look for another minimum */
                if (in_tree2)
                {
-                       find_and_insert_new_min(heap, array, tree->counter * 2, 
minpair, minpair->first, 0);
+                       find_and_insert_new_min(heap, array, tree->counter * 2, 
minpair, minpair->first, 0, c);
                        continue;
                }
 
@@ -367,7 +402,7 @@
                add_new_cluster(array, minpair, &tree->free);
 
                /* new search, avoid considering in_tree children */
-               find_and_insert_new_min(heap, array, tree->counter * 2, 
minpair, cluster_id, 0);
+               find_and_insert_new_min(heap, array, tree->counter * 2, 
minpair, cluster_id, 0, c);
        }
 
        BLI_heap_free(heap, 0);
@@ -442,6 +477,7 @@
        ListBase *pointlights;
        LampRen *lar;
        char tree_time_str[12]; /* length 12 required by BLI_timestr */
+       int i;
 
 #ifdef LIGHTCUTS_CURRENTLY_UNUSED
        LampRen *larnew;
@@ -548,19 +584,15 @@
        re->i.infostr= "Building light trees";
        re->stats_draw(&re->i);
 
-       /* build LA_LOCAL tree */
-       if (lcd->trees[TREE_LOCAL].counter > 0) {
-               lightcuts_fill_array(pointlights, &lcd->trees[TREE_LOCAL], 
LA_LOCAL);
-               printf("Lightcuts: local (Lamp) lights tree built - ");
-               lightcuts_build_tree(&lcd->trees[TREE_LOCAL]);
+       /* build light trees */
+       for (i= 0; i < _TREES_SIZE; i++) {
+               if (lcd->trees[i].counter > 0) {
+                       lightcuts_fill_array(pointlights, &lcd->trees[i], i);
+                       printf("Lightcuts: building %s tree - ", tree_names[i]);
+                       lightcuts_build_tree(&lcd->trees[i], 0.0f);
+                       /* TODO: put square of scene bounding box diagonale 
instead of 0.0f */
+               }
        }
-
-       /* build LA_SUN tree */
-       if (lcd->trees[TREE_SUN].counter > 0) {
-               lightcuts_fill_array(pointlights, &lcd->trees[TREE_SUN], 
LA_SUN);
-               printf("Lightcuts: directional (Sun) lights tree built - ");
-               lightcuts_build_tree(&lcd->trees[TREE_SUN]);
-       }
        
        lcd->tree_creation_time= PIL_check_seconds_timer() - lcd->start_time;
        BLI_timestr(lcd->tree_creation_time, tree_time_str);


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

Reply via email to