[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15993] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: Changed tree building to use BLI_kdtree_find_callback.
Davide Vercelli
davide.vercelli at gmail.com
Wed Aug 6 22:52:16 CEST 2008
Revision: 15993
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15993
Author: unclezeiv
Date: 2008-08-06 22:52:15 +0200 (Wed, 06 Aug 2008)
Log Message:
-----------
Changed tree building to use BLI_kdtree_find_callback. This seems to cut building times roughly by an additional 33%.
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-08-06 20:37:15 UTC (rev 15992)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 2008-08-06 20:52:15 UTC (rev 15993)
@@ -179,6 +179,12 @@
short do_phongcorr;
} SampleCoordInfo;
+typedef struct KDSearchCallbackData {
+ float c;
+ LightcutsCluster *one;
+ LightcutsCluster *array;
+} KDSearchCallbackData;
+
#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);}
@@ -331,70 +337,24 @@
}
}
+static void cb_update_metric_max_dist(void *data, int index, float *val, float *dist)
+{
+ KDSearchCallbackData *p = (KDSearchCallbackData*) data;
+ *val= lightcuts_compute_metric(p->c, p->one, &p->array[index]);
+ *dist= *val / p->one->luminance;
+}
+
/* this one uses kd tree */
static void find_and_insert_new_min2(Heap * heap, KDTree * tree, KDTreeNearest *nearest, LightcutsCluster * array, LightcutsClusterPair * pair, int id, float c)
{
LightcutsCluster *one= &array[id];
- int near_idx= -1;
- float pair_metric, metric;
- float max_dist;
- int found, j, other= -1;
+ KDSearchCallbackData data= {c, one, array};
- /* find nearest light in kdtree */
- found= BLI_kdtree_find_n_nearest(tree, 2, one->lar->co, NULL, nearest);
+ int other= BLI_kdtree_find_callback(tree, one->lar->co, NULL, one->id, cb_update_metric_max_dist, &data, nearest);
- /*
- * TODO: XXX: a bit hackish way to exclude the current element:
- * we look for the 2 nearest elements and discard the current one
- */
- for (j= 0; j < found; j++)
- if (nearest[j].index!= id)
- near_idx= nearest[j].index;
-
- /* when a single element is remaining, the search fails */
- if (near_idx== -1)
- return;
-
- /* compute metric w.r.t. the nearest element */
- pair_metric= lightcuts_compute_metric(c, one, &array[near_idx]);
- metric= pair_metric;
- other= near_idx;
-
- /*
- * compute maximum interesting distance:
- * we are sure that elements further away have a greater metric value
- */
- max_dist= sqrtf(pair_metric / one->luminance);
-
- /* get all lights within that distance */
- found= BLI_kdtree_find_in_sphere(tree, max_dist, one->lar->co, NULL, nearest);
-
- /* for each light compute metric and maximum distance */
- /*
- * TODO: better yet would be to take advantage of such knowledge
- * while traversing the kdtree
- */
- for (j= 0; j < found; j++) {
- LightcutsCluster *two= &array[nearest[j].index];
-
- if (nearest[j].index== id)
- continue;
-
- /* note: elements in "nearest" are sorted by distance */
- if (nearest[j].dist > max_dist)
- break;
-
- pair_metric= lightcuts_compute_metric(c, one, two);
- max_dist= sqrtf(pair_metric / one->luminance);
-
- if (pair_metric < metric) {
- other= two->id;
- metric= pair_metric;
- }
- }
-
if (other != -1)
{
+ float metric= lightcuts_compute_metric(c, one, &array[other]);
pair->first = id;
pair->second = other;
More information about the Bf-blender-cvs
mailing list