[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15338] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: preliminary changes for upcoming oriented lights support:
Davide Vercelli
davide.vercelli at gmail.com
Tue Jun 24 02:52:16 CEST 2008
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);
More information about the Bf-blender-cvs
mailing list