Revision: 22360
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22360
Author:   jaguarandi
Date:     2009-08-11 02:33:51 +0200 (Tue, 11 Aug 2009)

Log Message:
-----------
*Added a tree structure with a variable number of childs per node, but with 
groupped childs (for SIMD)
*SIMD support for the first 4*N childs of each node
*Some bvh code organized

Modified Paths:
--------------
    branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/bvh.h
    
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
    
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/reorganize.h

Added Paths:
-----------
    branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/svbvh.h

Modified: 
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/bvh.h
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/bvh.h    
2009-08-10 21:53:19 UTC (rev 22359)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/bvh.h    
2009-08-11 00:33:51 UTC (rev 22360)
@@ -28,6 +28,9 @@
  */
 #include <xmmintrin.h>
 
+#ifndef RE_RAYTRACE_BVH_H
+#define RE_RAYTRACE_BVH_H
+
 inline int test_bb_group4(__m128 *bb_group, const Isect *isec)
 {
        
@@ -53,6 +56,12 @@
        rtbuild_add( obj->builder, ob );
 }
 
+template<class Node>
+inline bool is_leaf(Node *node)
+{
+       return !RayObject_isAligned(node);
+}
+
 template<class Tree> static void bvh_done(Tree *obj);
 
 template<class Tree>
@@ -93,14 +102,14 @@
 template<class Node>
 static void bvh_node_merge_bb(Node *node, float *min, float *max)
 {
-       if(RayObject_isAligned(node))
+       if(is_leaf(node))
        {
-               DO_MIN(node->bb  , min);
-               DO_MAX(node->bb+3, max);
+               RE_rayobject_merge_bb( (RayObject*)node, min, max);
        }
        else
        {
-               RE_rayobject_merge_bb( (RayObject*)node, min, max);
+               DO_MIN(node->bb  , min);
+               DO_MAX(node->bb+3, max);
        }
 }
 
@@ -117,7 +126,7 @@
        Node *stack[MAX_STACK_SIZE];
        int hit = 0, stack_pos = 0;
                
-       if(!TEST_ROOT && RayObject_isAligned(root))
+       if(!TEST_ROOT && !is_leaf(root))
                bvh_node_push_childs(root, isec, stack, stack_pos);
        else
                stack[stack_pos++] = root;
@@ -125,7 +134,7 @@
        while(stack_pos)
        {
                Node *node = stack[--stack_pos];
-               if(RayObject_isAligned(node))
+               if(!is_leaf(node))
                {
                        if(bvh_node_hit_test(node,isec))
                        {
@@ -157,9 +166,9 @@
                
        if(!TEST_ROOT)
        {
-               if(RayObject_isAligned(root))
+               if(!is_leaf(root))
                {
-                       if(RayObject_isAligned(root->child))
+                       if(!is_leaf(root->child))
                                bvh_node_push_childs(root, isec, stack, 
stack_pos);
                        else
                                return RE_rayobject_intersect( 
(RayObject*)root->child, isec);
@@ -169,7 +178,7 @@
        }
        else
        {
-               if(RayObject_isAligned(root))
+               if(!is_leaf(root))
                        stack[stack_pos++] = root;
                else
                        return RE_rayobject_intersect( (RayObject*)root, isec);
@@ -214,7 +223,7 @@
                        for(int i=0; i<4; i++)
                        {
                                Node *t = stack[stack_pos+i];
-                               assert(RayObject_isAligned(t));
+                               assert(!is_leaf(t));
                                
                                float *bb = ((float*)t_bb)+i;
                                bb[4*0] = t->bb[0];
@@ -237,7 +246,7 @@
                        if(res & (1<<i))
                        {
                                RE_RC_COUNT(isec->raycounter->bb.hit);
-                               if(RayObject_isAligned(t_node[i]))
+                               if(!is_leaf(t_node[i]))
                                {
                                        for(Node *t=t_node[i]; t; t=t->sibling)
                                        {
@@ -255,11 +264,11 @@
                else if(stack_pos > 0)
                {       
                        Node *node = stack[--stack_pos];
-                       assert(RayObject_isAligned(node));
+                       assert(!is_leaf(node));
                        
                        if(bvh_node_hit_test(node,isec))
                        {
-                               if(RayObject_isAligned(node->child))
+                               if(!is_leaf(node->child))
                                {
                                        bvh_node_push_childs(node, isec, stack, 
stack_pos);
                                        assert(stack_pos <= MAX_STACK_SIZE);
@@ -291,7 +300,7 @@
                {
                        int i;
                        for(i=0; i<BVH_NCHILDS; i++)
-                               if(RayObject_isAligned(node->child[i]))
+                               if(!is_leaf(node->child[i]))
                                {
                                        if(node->child[i] == 0) break;
                                        
@@ -308,7 +317,7 @@
                {
                        int i;
                        for(i=BVH_NCHILDS-1; i>=0; i--)
-                               if(RayObject_isAligned(node->child[i]))
+                               if(!is_leaf(node->child[i]))
                                {
                                        if(node->child[i])
                                        {
@@ -326,3 +335,5 @@
        return hit;
 }
 */
+
+#endif

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-08-10 21:53:19 UTC (rev 22359)
+++ 
branches/soc-2009-jaguarandi/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
       2009-08-11 00:33:51 UTC (rev 22360)
@@ -26,6 +26,12 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  */
+#define RE_USE_HINT    (0)
+static int tot_pushup   = 0;
+static int tot_pushdown = 0;
+static int tot_hints    = 0;
+
+
 extern "C"
 {
 #include <assert.h>
@@ -41,22 +47,21 @@
 #include "rayobject_hint.h"
 #include "reorganize.h"
 #include "bvh.h"
+#include "svbvh.h"
 #include <queue>
 
-#define BVHNode VBVHNode
-#define BVHTree VBVHTree
 
-
 #define RE_DO_HINTS    (0)
 #define RAY_BB_TEST_COST (0.2f)
 #define DFS_STACK_SIZE 256
 //#define DYNAMIC_ALLOC_BB
 
+
 //#define rtbuild_split        rtbuild_mean_split_largest_axis         /* 
objects mean split on the longest axis, childs BB are allowed to overlap */
 //#define rtbuild_split        rtbuild_median_split_largest_axis       /* 
space median split on the longest axis, childs BB are allowed to overlap */
 #define rtbuild_split  rtbuild_heuristic_object_split          /* split 
objects using heuristic */
 
-struct BVHNode
+struct VBVHNode
 {
 #ifdef DYNAMIC_ALLOC_BB
        float *bb;
@@ -64,15 +69,15 @@
        float   bb[6];
 #endif
 
-       BVHNode *child;
-       BVHNode *sibling;
+       VBVHNode *child;
+       VBVHNode *sibling;
 };
 
-struct BVHTree
+struct VBVHTree
 {
        RayObject rayobj;
 
-       BVHNode *root;
+       SVBVHNode *root;
 
        MemArena *node_arena;
 
@@ -81,6 +86,54 @@
 };
 
 
+
+
+template<class Tree,class OldNode>
+struct Reorganize_VBVH
+{
+       Tree *tree;
+       
+       Reorganize_VBVH(Tree *t)
+       {
+               tree = t;
+       }
+       
+       VBVHNode *create_node()
+       {
+               VBVHNode *node = 
(VBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode));
+               return node;
+       }
+       
+       void copy_bb(VBVHNode *node, OldNode *old)
+       {
+               std::copy( old->bb, old->bb+6, node->bb );
+       }
+       
+       VBVHNode *transform(OldNode *old)
+       {
+               if(is_leaf(old))
+                       return (VBVHNode*)old;
+
+               VBVHNode *node = create_node();
+               VBVHNode **child_ptr = &node->child;
+               node->sibling = 0;
+
+               copy_bb(node,old);
+
+               for(OldNode *o_child = old->child; o_child; o_child = 
o_child->sibling)
+               {
+                       VBVHNode *n_child = transform(o_child);
+                       *child_ptr = n_child;
+                       if(is_leaf(n_child)) return node;
+                       child_ptr = &n_child->sibling;
+               }
+               *child_ptr = 0;
+               
+               return node;
+       }       
+};
+
+
 /*
  * Push nodes (used on dfs)
  */
@@ -89,7 +142,7 @@
 {
        Node *child = node->child;
 
-       if(!RayObject_isAligned(child))
+       if(is_leaf(child))
        {
                stack[stack_pos++] = child;
        }
@@ -99,7 +152,7 @@
                {
                        //Skips BB tests on primitives
 /*
-                       if(!RayObject_isAligned(child->child))
+                       if(is_leaf(child->child))
                                stack[stack_pos++] = child->child;
                        else
 */
@@ -113,9 +166,9 @@
 /*
  * BVH done
  */
-static BVHNode *bvh_new_node(BVHTree *tree)
+static VBVHNode *bvh_new_node(VBVHTree *tree)
 {
-       BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, 
sizeof(BVHNode));
+       VBVHNode *node = (VBVHNode*)BLI_memarena_alloc(tree->node_arena, 
sizeof(VBVHNode));
        
        if( (((intptr_t)node) & (0x0f)) != 0 )
        {
@@ -132,79 +185,16 @@
        return node;
 }
 
-template<class Builder>
-float rtbuild_area(Builder *builder)
-{
-       float min[3], max[3];
-       INIT_MINMAX(min, max);
-       rtbuild_merge_bb(builder, min, max);
-       return bb_area(min, max);       
-}
 
-template<class Node>
-void bvh_update_bb(Node *node)
-{
-       INIT_MINMAX(node->bb, node->bb+3);
-       Node *child = node->child;
-       
-       while(child)
-       {
-               bvh_node_merge_bb(child, node->bb, node->bb+3);
-               if(RayObject_isAligned(child))
-                       child = child->sibling;
-               else
-                       child = 0;
-       }
-}
 
-
-static int tot_pushup   = 0;
-static int tot_pushdown = 0;
-static int tot_hints    = 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;
-               Node **next_s_child = &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) && RayObject_isAligned(i->child))
-               {
-//                     todo optimize (should 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;
-                       next_s_child = s_child;
-                       
-                       tot_pushdown++;
-                       break;
-               }
-               child = next;
-               s_child = next_s_child;
-       }
-       
-       for(Node *i = parent->child; RayObject_isAligned(i) && i; i = 
i->sibling)
-               pushdown( i );  
-}
-
-template<class Node>
 int count_childs(Node *parent)
 {
        int n = 0;
        for(Node *i = parent->child; i; i = i->sibling)
        {
                n++;
-               if(!RayObject_isAligned(i))
+               if(is_leaf(i))
                        break;
        }
                
@@ -220,40 +210,7 @@
        node->sibling = sibling;
 }
 
-template<class Node>
-void pushup(Node *parent)
-{
-       float p_area = bb_area(parent->bb, parent->bb+3);
-       Node **prev = &parent->child;
-       for(Node *child = parent->child; RayObject_isAligned(child) && child; )
-       {
-               float c_area = bb_area(child->bb, child->bb+3) ;
-               int nchilds = count_childs(child);
-               float original_cost = (c_area / p_area)*nchilds + 1;
-               float flatten_cost = nchilds;
-               if(flatten_cost < original_cost && nchilds >= 2)
-               {
-                       append_sibling(child, child->child);
-                       child = child->sibling;
-                       *prev = child;
 
-//                     *prev = child->child;
-//                     append_sibling( *prev, child->sibling );
-//                     child = *prev;
-                       tot_pushup++;
-               }
-               else
-               {
-                       *prev = child;
-                       prev = &(*prev)->sibling;
-                       child = *prev;
-               }               
-       }
-       
-       for(Node *child = parent->child; RayObject_isAligned(child) && child; 
child = child->sibling)
-               pushup(child);
-}
-
 template<class Tree, class Node, class Builder>
 Node *bvh_rearrange(Tree *tree, Builder *builder)
 {
@@ -264,7 +221,7 @@
                Node *node = bvh_new_node(tree);
                INIT_MINMAX(node->bb, node->bb+3);
                rtbuild_merge_bb(builder, node->bb, node->bb+3);                
-               node->child = (BVHNode*) rtbuild_get_primitive( builder, 0 );
+               node->child = (VBVHNode*) rtbuild_get_primitive( builder, 0 );
                return node;
        }
        else
@@ -292,30 +249,8 @@
        }
 }
 
-template<class Node>
-float bvh_refit(Node *node)
-{
-       if(!RayObject_isAligned(node)) return 0;        
-       if(!RayObject_isAligned(node->child)) return 0;
-       
-       float total = 0;
-       
-       for(Node *child = node->child; child; child = child->sibling)
-               total += bvh_refit(child);
-               
-       float old_area = bb_area(node->bb, node->bb+3);
-       INIT_MINMAX(node->bb, node->bb+3);
-       for(Node *child = node->child; child; child = child->sibling)
-       {
-               DO_MIN(child->bb, node->bb);
-               DO_MAX(child->bb+3, node->bb+3);
-       }
-       total += old_area - bb_area(node->bb, node->bb+3);
-       return total;
-}
-
 template<>
-void bvh_done<BVHTree>(BVHTree *obj)
+void bvh_done<VBVHTree>(VBVHTree *obj)
 {
        rtbuild_done(obj->builder);
        
@@ -323,18 +258,47 @@
        if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE)
                needed_nodes = BLI_MEMARENA_STD_BUFSIZE;
 
-       obj->node_arena = BLI_memarena_new(needed_nodes);

@@ Diff output truncated at 10240 characters. @@

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

Reply via email to