numerous input and physics
[carveJwlIkooP6JGAAIwe30JlM.git] / bvh.h
diff --git a/bvh.h b/bvh.h
index 9fdbe985040f51e0cadfd0a183b921240c82a036..9e4528604d59c8cf205f20d3d172b671102085e1 100644 (file)
--- a/bvh.h
+++ b/bvh.h
@@ -32,6 +32,7 @@ struct bh_tree
 
    bh_system *system;
    void *user;
+   u32 max_per_leaf;
 
    struct bh_node
    {
@@ -77,6 +78,9 @@ VG_STATIC void bh_subdivide( bh_tree *bh, u32 inode )
 {
    bh_node *node = &bh->nodes[ inode ];
 
+   if( node->count <= bh->max_per_leaf )
+      return;
+
    v3f extent;
    v3_sub( node->bbx[1], node->bbx[0], extent );
 
@@ -135,12 +139,24 @@ VG_STATIC void bh_subdivide( bh_tree *bh, u32 inode )
 }
 
 VG_STATIC bh_tree *bh_create( void *lin_alloc, bh_system *system, 
-                              void *user, u32 item_count )
+                              void *user, u32 item_count, u32 max_per_leaf )
 {
+   assert( max_per_leaf > 0 );
+
+   if( item_count == 0 )
+   {
+      bh_tree *bh = vg_linear_alloc( lin_alloc, sizeof(bh_tree) );
+      bh->node_count = 0;
+      bh->system = system;
+      bh->user = user;
+      return bh;
+   }
+
    u32 totsize = sizeof(bh_tree) + sizeof(bh_node)*(item_count*2-1);
    bh_tree *bh = vg_linear_alloc( lin_alloc, totsize );
    bh->system = system;
    bh->user = user;
+   bh->max_per_leaf = max_per_leaf;
 
    bh_node *root = &bh->nodes[0];
    bh->node_count = 1;
@@ -192,6 +208,9 @@ VG_STATIC void bh_debug_node( bh_tree *bh, u32 inode, v3f pos, u32 colour )
 
 VG_STATIC int bh_ray( bh_tree *bh, v3f co, v3f dir, ray_hit *hit )
 {
+   if( bh->node_count < 2 )
+      return 0;
+
    int count = 0;
    u32 stack[100];
    u32 depth = 2;
@@ -243,6 +262,9 @@ VG_STATIC int bh_ray( bh_tree *bh, v3f co, v3f dir, ray_hit *hit )
 
 VG_STATIC int bh_select( bh_tree *bh, boxf box, u32 *buffer, int len )
 {
+   if( bh->node_count < 2 )
+      return 0;
+
    int count = 0;
    u32 stack[100];
    u32 depth = 2;