[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21409] branches/soc-2009-jaguarandi/ source/blender/render/intern: *added Object SAH support to rtbuild:
André Pinto
andresusanopinto at gmail.com
Tue Jul 7 17:42:08 CEST 2009
Revision: 21409
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21409
Author: jaguarandi
Date: 2009-07-07 17:42:08 +0200 (Tue, 07 Jul 2009)
Log Message:
-----------
*added Object SAH support to rtbuild:
only for 2childs splits
with "worse case heuristic" means each child is considered to have a cost linear on the number of leafs
no termination criteria
number of BB test/hits expected to "reduced" by some factor
tree building is also expected to be slower as previous split was "object mean", which is quite fast to evaluate
Modified Paths:
--------------
branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h
branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c
branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c
Modified: branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h 2009-07-07 13:05:53 UTC (rev 21408)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h 2009-07-07 15:42:08 UTC (rev 21409)
@@ -67,10 +67,15 @@
/* Calculates child partitions and returns number of efectively needed partitions */
int rtbuild_get_largest_axis(RTBuilder *b);
+//Object partition
int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis);
int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds);
+int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds);
+
+//Space partition
int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis);
int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds);
+
#endif
Modified: branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c 2009-07-07 13:05:53 UTC (rev 21408)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c 2009-07-07 15:42:08 UTC (rev 21409)
@@ -39,10 +39,11 @@
#define DYNAMIC_ALLOC
-#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */
+//#define SPLIT_OVERLAP_MEAN_LONGEST_AXIS /* objects mean split on the longest axis, childs BB are allowed to overlap */
//#define SPLIT_OVERLAP_MEDIAN_LONGEST_AXIS /* space median split on the longest axis, childs BB are allowed to overlap */
+#define SPLIT_OBJECTS_SAH /* split objects using heuristic */
-#define BVH_NCHILDS 4
+#define BVH_NCHILDS 2
typedef struct BVHTree BVHTree;
static int bvh_intersect(BVHTree *obj, Isect *isec);
@@ -281,6 +282,8 @@
nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS);
#elif defined(SPLIT_OVERLAP_MEDIAN_LONGEST_AXIS)
nc = rtbuild_median_split_largest_axis(builder, BVH_NCHILDS);
+#elif defined(SPLIT_OBJECTS_SAH)
+ nc = rtbuild_heuristic_object_split(builder, BVH_NCHILDS);
#else
assert(0);
#endif
Modified: branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c 2009-07-07 13:05:53 UTC (rev 21408)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c 2009-07-07 15:42:08 UTC (rev 21409)
@@ -209,7 +209,135 @@
return rtbuild_median_split(b, separators, nchilds, la);
}
-//Heuristics Splitter
+//Heuristics Object Splitter
+typedef struct CostObject CostObject;
+struct CostObject
+{
+ RayObject *obj;
+ float bb[6];
+};
+
+//Ugly.. but using qsort and no globals its the cleaner I can get
+#define costobject_cmp(axis) costobject_cmp##axis
+#define define_costobject_cmp(axis) \
+int costobject_cmp(axis)(const CostObject *a, const CostObject *b) \
+{ \
+ if(a->bb[axis] < b->bb[axis]) return -1; \
+ if(a->bb[axis] > b->bb[axis]) return 1; \
+ if(a->obj < b->obj) return -1; \
+ if(a->obj > b->obj) return 1; \
+ return 0; \
+}
+
+define_costobject_cmp(0)
+define_costobject_cmp(1)
+define_costobject_cmp(2)
+define_costobject_cmp(3)
+define_costobject_cmp(4)
+define_costobject_cmp(5)
+
+void costobject_sort(CostObject *begin, CostObject *end, int axis)
+{
+ //TODO introsort
+ if(axis == 0) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(0));
+ else if(axis == 1) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(1));
+ else if(axis == 2) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(2));
+ else if(axis == 3) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(3));
+ else if(axis == 4) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(4));
+ else if(axis == 5) qsort(begin, end-begin, sizeof(*begin), (int(*)(const void *, const void *)) costobject_cmp(5));
+}
+
+float bb_volume(float *min, float *max)
+{
+ return (max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]);
+}
+
+float bb_area(float *min, float *max)
+{
+ float sub[3];
+ sub[0] = max[0]-min[0];
+ sub[1] = max[1]-min[1];
+ sub[2] = max[2]-min[2];
+
+ return (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2;
+}
+
+int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
+{
+ int size = rtbuild_size(b);
+ assert(nchilds == 2);
+
+ if(size <= nchilds)
+ {
+ return rtbuild_mean_split_largest_axis(b, nchilds);
+ }
+ else
+ {
+ float bcost = FLT_MAX;
+ int i, axis, baxis, boffset;
+ CostObject *cost = MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" );
+ float *acc_bb = MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" );
+
+ for(i=0; i<size; i++)
+ {
+ cost[i].obj = b->begin[i];
+ INIT_MINMAX(cost[i].bb, cost[i].bb+3);
+ RE_rayobject_merge_bb(b->begin[i], cost[i].bb, cost[i].bb+3);
+ }
+
+ for(axis=0; axis<3; axis++)
+ {
+ float other_bb[6];
+
+ costobject_sort(cost, cost+size, axis);
+ for(i=size-1; i>=0; i--)
+ {
+ float *bb = acc_bb+i*6;
+ if(i == size-1)
+ {
+ INIT_MINMAX( bb, bb+3 );
+ }
+ else
+ {
+ VECCOPY( bb, bb+6 );
+ VECCOPY( bb+3, bb+6+3 );
+ }
+ RE_rayobject_merge_bb( cost[i].obj, bb, bb+3 );
+ }
+
+ INIT_MINMAX(other_bb, other_bb+3);
+ DO_MINMAX( cost[0].bb, other_bb, other_bb+3 );
+ DO_MINMAX( cost[0].bb+3, other_bb, other_bb+3 );
+
+ for(i=1; i<size; i++)
+ {
+ //Worst case heuristic (cost of each child is linear)
+ float hcost = bb_area(other_bb, other_bb+3)*(i+log(i)) + bb_area(acc_bb+i*6, acc_bb+i*6+3)*(size-i+log(size-i));
+ if(hcost < bcost)
+ {
+ bcost = hcost;
+ baxis = axis;
+ boffset = i;
+ }
+ DO_MINMAX( cost[i].bb, other_bb, other_bb+3 );
+ DO_MINMAX( cost[i].bb+3, other_bb, other_bb+3 );
+ }
+ }
+ costobject_sort(cost, cost+size, baxis);
+ for(i=0; i<size; i++)
+ b->begin[i] = cost[i].obj;
+
+ b->child_offset[0] = 0;
+ b->child_offset[1] = boffset;
+ b->child_offset[2] = size;
+
+ MEM_freeN(acc_bb);
+ MEM_freeN(cost);
+ return nchilds;
+ }
+}
+
+//Heuristic Area Splitter
typedef struct CostEvent CostEvent;
struct CostEvent
@@ -232,24 +360,26 @@
//TODO introsort
qsort(begin, sizeof(*begin), end-begin, (int(*)(const void *, const void *)) costevent_cmp);
}
-
/*
int rtbuild_heuristic_split(RTBuilder *b, int nchilds)
{
- int size = rtbuild_size(b);
-
+ int size = rtbuild_size(b);
+
+ assert(nchilds == 2);
+
if(size <= nchilds)
{
return rtbuild_mean_split_largest_axis(b, nchilds);
}
else
{
- CostEvent *events[3], *ev[3];
+ CostEvent *events, *ev;
RayObject *index;
int a = 0;
+ events = MEM_malloc( sizeof(CostEvent)*2*size, "RTBuilder.SweepSplitCostEvent" );
for(a = 0; a<3; a++)
- ev[a] = events[a] = MEM_malloc( sizeof(CostEvent)*2*size, "RTBuilder.SweepSplitCostEvent" );
+
for(index = b->begin; b != b->end; b++)
{
More information about the Bf-blender-cvs
mailing list