Revision: 21391
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21391
Author:   jaguarandi
Date:     2009-07-06 21:45:00 +0200 (Mon, 06 Jul 2009)

Log Message:
-----------
*Added BLI_memarena on bvh
*Median split support on rtbuild

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-06 17:29:32 UTC (rev 21390)
+++ 
branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h
       2009-07-06 19:45:00 UTC (rev 21391)
@@ -65,8 +65,12 @@
 RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp);
 
 /* Calculates child partitions and returns number of efectively needed 
partitions */
+int rtbuild_get_largest_axis(RTBuilder *b);
+
 int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis);
 int rtbuild_mean_split_largest_axis(RTBuilder *b, int nchilds);
-int rtbuild_get_largest_axis(RTBuilder *b);
 
+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-06 17:29:32 UTC (rev 21390)
+++ 
branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c
    2009-07-06 19:45:00 UTC (rev 21391)
@@ -32,10 +32,16 @@
 #include "MEM_guardedalloc.h"
 #include "BKE_utildefines.h"
 #include "BLI_arithb.h"
+#include "BLI_memarena.h"
 #include "RE_raytrace.h"
 #include "rayobject_rtbuild.h"
 #include "rayobject.h"
 
+#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_MEDIAN_LONGEST_AXIS    /* space median split on the 
longest axis, childs BB are allowed to overlap */
+
 #define BVH_NCHILDS    4
 typedef struct BVHTree BVHTree;
 
@@ -58,7 +64,11 @@
 struct BVHNode
 {
        BVHNode *child[BVH_NCHILDS];
+#ifdef DYNAMIC_ALLOC
+       float   bb[6];
+#else
        float   *bb; //[6]; //[2][3];
+#endif
        int split_axis;
 };
 
@@ -68,8 +78,12 @@
 
        BVHNode *root;
 
+#ifdef DYNAMIC_ALLOC
+       MemArena *node_arena;
+#else
        BVHNode *node_alloc, *node_next;
        float *bb_alloc, *bb_next;
+#endif
        RTBuilder *builder;
 
 };
@@ -83,8 +97,12 @@
        obj->rayobj.api = &bvh_api;
        obj->root = NULL;
        
+#ifdef DYNAMIC_ALLOC
+       obj->node_arena = NULL;
+#else
        obj->node_alloc = obj->node_next = NULL;
        obj->bb_alloc   = obj->bb_next = NULL;
+#endif
        obj->builder    = rtbuild_create( size );
        
        return RayObject_unalignRayAPI((RayObject*) obj);
@@ -95,11 +113,16 @@
        if(obj->builder)
                rtbuild_free(obj->builder);
 
+#ifdef DYNAMIC_ALLOC
+       if(obj->node_arena)
+               BLI_memarena_free(obj->node_arena);
+#else
        if(obj->node_alloc)
                MEM_freeN(obj->node_alloc);
 
        if(obj->bb_alloc)
                MEM_freeN(obj->bb_alloc);
+#endif
 
        MEM_freeN(obj);
 }
@@ -190,6 +213,10 @@
 
 static BVHNode *bvh_new_node(BVHTree *tree, int nid)
 {
+#ifdef DYNAMIC_ALLOC
+       BVHNode *node = BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode));
+       return node;
+#else
        BVHNode *node = tree->node_alloc + nid - 1;
        assert(RayObject_isAligned(node));
        if(node+1 > tree->node_next)
@@ -199,6 +226,7 @@
        tree->bb_next += 6;
        
        return node;
+#endif
 }
 
 static int child_id(int pid, int nchild)
@@ -209,6 +237,9 @@
 
 static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid)
 {
+       if(rtbuild_size(builder) == 0)
+               return 0;
+
        if(rtbuild_size(builder) == 1)
        {
                RayObject *child = builder->begin[0];
@@ -242,11 +273,18 @@
        else
        {
                int i;
-               int nc = rtbuild_mean_split_largest_axis(builder, BVH_NCHILDS);
                RTBuilder tmp;
-       
                BVHNode *parent = bvh_new_node(tree, nid);
+               int nc; 
 
+#ifdef SPLIT_OVERLAP_MEAN_LONGEST_AXIS
+               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);
+#else
+               assert(0);
+#endif 
+
                INIT_MINMAX(parent->bb, parent->bb+3);
                parent->split_axis = builder->split_axis;
                for(i=0; i<nc; i++)
@@ -261,31 +299,48 @@
        }
 }
 
+/*
 static void bvh_info(BVHTree *obj)
 {
        printf("BVH: Used %d nodes\n", obj->node_next - obj->node_alloc);
 }
+*/
        
 static void bvh_done(BVHTree *obj)
 {
+
+
+#ifdef DYNAMIC_ALLOC
+       int needed_nodes = (rtbuild_size(obj->builder)+1)*2;
+       if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE)
+               needed_nodes = BLI_MEMARENA_STD_BUFSIZE;
+
+       obj->node_arena = BLI_memarena_new(needed_nodes);
+       BLI_memarena_use_malloc(obj->node_arena);
+
+#else
        int needed_nodes;
-       assert(obj->root == NULL && obj->node_alloc == NULL && obj->bb_alloc == 
NULL && obj->builder);
 
        //TODO exact calculate needed nodes
        needed_nodes = (rtbuild_size(obj->builder)+1)*2;
        assert(needed_nodes > 0);
 
+       BVHNode *node = BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode));
+       return node;
        obj->node_alloc = (BVHNode*)MEM_mallocN( sizeof(BVHNode)*needed_nodes, 
"BVHTree.Nodes");
        obj->node_next  = obj->node_alloc;
 
        obj->bb_alloc = (float*)MEM_mallocN( sizeof(float)*6*needed_nodes, 
"BVHTree.NodesBB");
        obj->bb_next  = obj->bb_alloc;
+#endif
        
        obj->root = bvh_rearrange( obj, obj->builder, 1 );
+       
+#ifndef DYNAMIC_ALLOC
+       assert(obj->node_alloc+needed_nodes >= obj->node_next);
+#endif
 
        rtbuild_free( obj->builder );
        obj->builder = NULL;
-       
-       assert(obj->node_alloc+needed_nodes >= obj->node_next);
 }
 

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-06 17:29:32 UTC (rev 21390)
+++ 
branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c
        2009-07-06 19:45:00 UTC (rev 21391)
@@ -1,5 +1,6 @@
 #include <assert.h>
 #include <math.h>
+#include <stdlib.h>
 
 #include "rayobject_rtbuild.h"
 #include "MEM_guardedalloc.h"
@@ -8,6 +9,7 @@
 
 static int partition_nth_element(RTBuilder *b, int _begin, int _end, int n);
 static void split_leafs(RTBuilder *b, int *nth, int partitions, int 
split_axis);
+static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane);
 
 
 static void rtbuild_init(RTBuilder *b, RayObject **begin, RayObject **end)
@@ -61,12 +63,9 @@
                RE_rayobject_merge_bb(*index, min, max);
 }
 
-int rtbuild_get_largest_axis(RTBuilder *b)
+static int largest_axis(float *min, float *max)
 {
-       float min[3], max[3], sub[3];
-
-       INIT_MINMAX(min, max);
-       merge_bb( b, min, max);
+       float sub[3];
        
        sub[0] = max[0]-min[0];
        sub[1] = max[1]-min[1];
@@ -87,7 +86,22 @@
        }       
 }
 
+int rtbuild_get_largest_axis(RTBuilder *b)
+{
+       float min[3], max[3];
 
+       INIT_MINMAX(min, max);
+       merge_bb( b, min, max);
+
+       return largest_axis(min,max);
+}
+
+
+/*
+int rtbuild_median_split(RTBuilder *b, int nchilds, int axis)
+{
+}
+*/
 //Left balanced tree
 int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis)
 {
@@ -146,8 +160,125 @@
        return rtbuild_mean_split(b, nchilds, axis);
 }
 
+/*
+ * "separators" is an array of dim NCHILDS-1
+ * and indicates where to cut the childs
+ */
+int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int 
axis)
+{
+       int size = rtbuild_size(b);
+               
+       assert(nchilds <= RTBUILD_MAX_CHILDS);
+       if(size <= nchilds)
+       {
+               return rtbuild_mean_split(b, nchilds, axis);
+       }
+       else
+       {
+               int i;
 
+               b->split_axis = axis;
+               
+               //Calculate child offsets
+               b->child_offset[0] = 0;
+               for(i=0; i<nchilds-1; i++)
+                       b->child_offset[i+1] = split_leafs_by_plane(b, 
b->child_offset[i], size, separators[i]);
+               b->child_offset[nchilds] = size;
+               
+               for(i=0; i<nchilds; i++)
+                       if(b->child_offset[i+1] - b->child_offset[i] == size)
+                               return rtbuild_mean_split(b, nchilds, axis);
+               
+               return nchilds;
+       }       
+}
+
+int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds)
+{
+       int la, i;
+       float separators[RTBUILD_MAX_CHILDS];
+       float min[3], max[3];
+
+       INIT_MINMAX(min, max);
+       merge_bb( b, min, max);
+
+       la = largest_axis(min,max);
+       for(i=1; i<nchilds; i++)
+               separators[i-1] = (max[la]-min[la])*i / nchilds;
+               
+       return rtbuild_median_split(b, separators, nchilds, la);
+}
+
+//Heuristics Splitter
+typedef struct CostEvent CostEvent;
+
+struct CostEvent
+{
+       float key;
+       float value;
+};
+
+int costevent_cmp(const CostEvent *a, const CostEvent *b)
+{
+       if(a->key < b->key) return -1;
+       if(a->key > b->key) return  1;
+       if(a->value < b->value) return -1;
+       if(a->value > b->value) return  1;
+       return 0;
+}
+
+void costevent_sort(CostEvent *begin, CostEvent *end)
+{
+       //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);
+               
+       if(size <= nchilds)
+       {
+               return rtbuild_mean_split_largest_axis(b, nchilds);
+       }
+       else
+       {
+               CostEvent *events[3], *ev[3];
+               RayObject *index;
+               int a = 0;
+
+               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++)
+               {
+                       float min[3], max[3];
+                       INIT_MINMAX(min, max);
+                       RE_rayobject_merge_bb(index, min, max);
+                       for(a = 0; a<3; a++)
+                       {
+                               ev[a]->key = min[a];
+                               ev[a]->value = 1;
+                               ev[a]++;
+               
+                               ev[a]->key = max[a];
+                               ev[a]->value = -1;
+                               ev[a]++;
+                       }
+               }
+               for(a = 0; a<3; a++)
+                       costevent_sort(events[a], ev[a]);
+                       
+               
+               
+               for(a = 0; a<3; a++)
+                       MEM_freeN(ev[a]);
+       }
+}
+*/
+
+/*
  * Helper code
  * PARTITION code / used on mean-split
  * basicly this a std::nth_element (like on C++ STL algorithm)
@@ -268,3 +399,17 @@
                partition_nth_element(b, nth[i],  nth[i+1], nth[partitions] );
        }
 }
+
+static int split_leafs_by_plane(RTBuilder *b, int begin, int end, float plane)
+{
+       int i;
+       for(i = begin; i != end; i++)
+       {
+               if(sort_get_value(b, i) < plane)
+               {
+                       sort_swap(b, i, begin);
+                       begin++;
+               }
+       }
+       return begin;
+}


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

Reply via email to