Revision: 21592
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21592
Author:   jaguarandi
Date:     2009-07-15 01:08:55 +0200 (Wed, 15 Jul 2009)

Log Message:
-----------
Just another experimental stuff to optimize the expected number of BB test on 
bvh trees
 *tree pushdowns after the pushsups :P (its still not local optimum)

Modified Paths:
--------------
    branches/soc-2009-jaguarandi/source/blender/blenlib/intern/BLI_memarena.c
    
branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h
    
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
    
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_vbvh.cpp

Modified: 
branches/soc-2009-jaguarandi/source/blender/blenlib/intern/BLI_memarena.c
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/blenlib/intern/BLI_memarena.c   
2009-07-14 22:32:14 UTC (rev 21591)
+++ branches/soc-2009-jaguarandi/source/blender/blenlib/intern/BLI_memarena.c   
2009-07-14 23:08:55 UTC (rev 21592)
@@ -95,3 +95,4 @@
        
        return ptr;
 }
+

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-14 22:32:14 UTC (rev 21591)
+++ 
branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h
       2009-07-14 23:08:55 UTC (rev 21592)
@@ -92,6 +92,7 @@
 float bb_area(float *min, float *max);
 float bb_volume(float *min, float *max);
 int bb_largest_axis(float *min, float *max);
+int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float 
*inner_max); /* only returns 0 if merging inner and outerbox would create a box 
larger than outer box */
 
 #ifdef __cplusplus
 }

Modified: 
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
===================================================================
--- 
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
    2009-07-14 22:32:14 UTC (rev 21591)
+++ 
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
    2009-07-14 23:08:55 UTC (rev 21592)
@@ -529,3 +529,15 @@
                        return 2;
        }       
 }
+
+int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float 
*inner_max)
+{
+       int i;
+       for(i=0; i<3; i++)
+               if(outer_min[i] > inner_min[i]) return 0;
+
+       for(i=0; i<3; i++)
+               if(outer_max[i] < inner_max[i]) return 0;
+
+       return 1;       
+}

Modified: 
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
===================================================================
--- 
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
       2009-07-14 22:32:14 UTC (rev 21591)
+++ 
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
       2009-07-14 23:08:55 UTC (rev 21592)
@@ -128,6 +128,41 @@
 }
 
 
+static int tot_pushup   = 0;
+static int tot_pushdown = 0;
+
+template<class Node>
+void pushdown(Node *parent)
+{
+       Node **s_child = &parent->child;
+       Node * child = parent->child;
+       
+       while(child && RayObject_isAligned(child))
+       {
+               Node *next = child->sibling;
+               
+               assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, 
child->bb+3));
+               
+               for(Node *i = parent->child; RayObject_isAligned(i) && i; i = 
i->sibling)
+               if(child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, 
child->bb+3))
+               {
+//                     todo optimize (hsould the one with the smallest area
+//                     float ia = bb_area(i->bb, i->bb+3)
+//                     if(child->i)
+                       *s_child = child->sibling;
+                       child->sibling = i->child;
+                       i->child = child;
+                       
+                       tot_pushdown++;
+                       break;
+               }
+               child = next;
+       }
+       
+       for(Node *i = parent->child; RayObject_isAligned(i) && i; i = 
i->sibling)
+               pushdown( i );  
+}
+
 template<class Tree, class Node, class Builder>
 Node *bvh_rearrange(Tree *tree, Builder *builder, float *cost)
 {
@@ -177,6 +212,7 @@
                                        rtbuild_get_child(&b, i, &tmp);
                                        childs.push(tmp);
                                }
+                               tot_pushup++;
                                
                        }
                        else
@@ -207,38 +243,76 @@
 
        
        obj->root = bvh_rearrange<BVHTree,BVHNode,RTBuilder>( obj, 
obj->builder, &obj->cost );
+       pushdown(obj->root);
        obj->cost = 1.0;
        
        rtbuild_free( obj->builder );
        obj->builder = NULL;
 }
 
-template<>
-int bvh_intersect<BVHTree>(BVHTree *obj, Isect* isec)
+template<int StackSize>
+int intersect(BVHTree *obj, Isect* isec)
 {
        if(RayObject_isAligned(obj->root))
-               return 
bvh_node_stack_raycast<BVHNode,DFS_STACK_SIZE>(obj->root, isec);
+               return bvh_node_stack_raycast<BVHNode,StackSize>(obj->root, 
isec);
        else
                return RE_rayobject_intersect( (RayObject*) obj->root, isec );
 }
 
+
+void bfree(BVHTree *tree)
+{
+       if(tot_pushup + tot_pushdown)
+       {
+               printf("tot pushups: %d\n", tot_pushup);
+               printf("tot pushdowns: %d\n", tot_pushdown);
+               tot_pushup = 0;
+               tot_pushdown = 0;
+       }
+       bvh_free(tree);
+}
+
 /* the cast to pointer function is needed to workarround gcc bug: 
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
-static RayObjectAPI bvh_api =
+template<int STACK_SIZE>
+static RayObjectAPI make_api()
 {
-       (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) 
&bvh_intersect<BVHTree>),
-       (RE_rayobject_add_callback)     ((void(*)(BVHTree*,RayObject*)) 
&bvh_add<BVHTree>),
-       (RE_rayobject_done_callback)    ((void(*)(BVHTree*))       
&bvh_done<BVHTree>),
-       (RE_rayobject_free_callback)    ((void(*)(BVHTree*))       
&bvh_free<BVHTree>),
-       (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) 
&bvh_bb<BVHTree>),
-       (RE_rayobject_cost_callback)    ((float(*)(BVHTree*))      
&bvh_cost<BVHTree>)
-};
+       static RayObjectAPI api = 
+       {
+               (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) 
&intersect<STACK_SIZE>),
+               (RE_rayobject_add_callback)     ((void(*)(BVHTree*,RayObject*)) 
&bvh_add<BVHTree>),
+               (RE_rayobject_done_callback)    ((void(*)(BVHTree*))       
&bvh_done<BVHTree>),
+//             (RE_rayobject_free_callback)    ((void(*)(BVHTree*))       
&bvh_free<BVHTree>),
+               (RE_rayobject_free_callback)    ((void(*)(BVHTree*))       
&bfree),
+               
(RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) 
&bvh_bb<BVHTree>),
+               (RE_rayobject_cost_callback)    ((float(*)(BVHTree*))      
&bvh_cost<BVHTree>)
+       };
+       
+       return api;
+}
 
+static RayObjectAPI* get_api(int maxstacksize)
+{
+//     static RayObjectAPI bvh_api16  = make_api<16>();
+//     static RayObjectAPI bvh_api32  = make_api<32>();
+//     static RayObjectAPI bvh_api64  = make_api<64>();
+       static RayObjectAPI bvh_api128 = make_api<128>();
+       static RayObjectAPI bvh_api256 = make_api<256>();
+       
+//     if(maxstacksize <= 16 ) return &bvh_api16;
+//     if(maxstacksize <= 32 ) return &bvh_api32;
+//     if(maxstacksize <= 64 ) return &bvh_api64;
+       if(maxstacksize <= 128) return &bvh_api128;
+       if(maxstacksize <= 256) return &bvh_api256;
+       assert(maxstacksize <= 256);
+       return 0;
+}
+
 RayObject *RE_rayobject_vbvh_create(int size)
 {
        BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree");
        assert( RayObject_isAligned(obj) ); /* RayObject API assumes real data 
to be 4-byte aligned */  
        
-       obj->rayobj.api = &bvh_api;
+       obj->rayobj.api = get_api(DFS_STACK_SIZE);
        obj->root = NULL;
        
        obj->node_arena = NULL;


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

Reply via email to