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++)
                {


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to