bvh interface and high perf gate
authorhgn <hgodden00@gmail.com>
Thu, 30 Jun 2022 02:03:58 +0000 (03:03 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 30 Jun 2022 02:03:58 +0000 (03:03 +0100)
12 files changed:
bvh.h [new file with mode: 0644]
character.h
common.h
gate.h
main.c
player.h
rigidbody.h
scene.h
shaders/gate_lq.fs [new file with mode: 0644]
shaders/gatelq.h [new file with mode: 0644]
vg.conf
world.h

diff --git a/bvh.h b/bvh.h
new file mode 100644 (file)
index 0000000..c841939
--- /dev/null
+++ b/bvh.h
@@ -0,0 +1,284 @@
+#ifndef BVH_H
+#define BVH_H
+#include "common.h"
+
+/*
+ * Usage:
+ *
+ * create a bh_system with functions filled out for expand, centroid, and swap.
+ * optionally include item_debug and cast_ray functions if needed, otherwise,
+ *   set them to null
+ *
+ * create a bh_tree struct with:
+ *   user: a pointer back the base of the data you are ordering
+ *   system: the system we created above which will deal with the data
+ *
+ * call bh_create( bh_tree *bh, u32 item_count, u32 item_size )
+ */
+
+typedef struct bh_node bh_node;
+typedef struct bh_tree bh_tree;
+typedef struct bh_system bh_system;
+
+struct bh_node
+{
+   boxf bbx;
+
+   /* if il is 0, this is a leaf */
+   u32 il, count;
+   union{ u32 ir, start; };
+};
+
+struct bh_tree
+{
+   bh_node *nodes;
+   u32 node_count;
+
+   bh_system *system;
+   void *user;
+};
+
+struct bh_system
+{
+   void  (*expand_bound)( void *user, boxf bound, u32 item_index );
+   float (*item_centroid)( void *user, u32 item_index, int axis );
+   void  (*item_swap)( void *user, u32 ia, u32 ib );
+   u32 item_size;
+
+   /*
+    * Optional:
+    *   item_debug   - draw this item quickly usually with lines
+    *   cast_ray     - shoot a ray against the object, if this is not set,
+    *                  raycasts will simply return the hit on the bvh node
+    */
+
+   void  (*item_debug)( void *user, u32 item_index );
+   int   (*cast_ray)( void *user, v3f co, v3f dir, ray_hit *hit );
+};
+
+static void bh_update_bounds( bh_tree *bh, u32 inode )
+{
+   bh_node *node = &bh->nodes[ inode ];
+
+   box_init_inf( node->bbx );
+   for( u32 i=0; i<node->count; i++ )
+   {
+      u32 idx = node->start+i;
+      bh->system->expand_bound( bh->user, node->bbx, idx );
+   }
+}
+
+static void bh_subdivide( bh_tree *bh, u32 inode )
+{
+   bh_node *node = &bh->nodes[ inode ];
+
+   v3f extent;
+   v3_sub( node->bbx[1], node->bbx[0], extent );
+
+   int axis = 0;
+   if( extent[1] > extent[0] ) axis = 1;
+   if( extent[2] > extent[axis] ) axis = 2;
+
+   float split = node->bbx[0][axis] + extent[axis]*0.5f;
+
+   float avg = 0.0;
+   for( u32 t=0; t<node->count; t++ )
+   {
+      u32 idx = node->start+t;
+      avg += bh->system->item_centroid( bh->user, idx, axis );
+   }
+   avg /= (float)node->count;
+
+   split = avg;
+
+   i32 i = node->start,
+       j = i + node->count-1;
+   
+   while( i <= j )
+   {
+      if( bh->system->item_centroid( bh->user, i, axis ) < split )
+         i ++;
+      else
+      {
+         bh->system->item_swap( bh->user, i, j );
+         j --;
+      }
+   }
+
+   u32 left_count = i - node->start;
+   if( left_count == 0 || left_count == node->count ) return;
+
+   u32 il = bh->node_count ++,
+       ir = bh->node_count ++;
+
+   bh_node *lnode = &bh->nodes[il],
+           *rnode = &bh->nodes[ir];
+
+   lnode->start = node->start;
+   lnode->count = left_count;
+   rnode->start = i;
+   rnode->count = node->count - left_count;
+
+   node->il = il;
+   node->ir = ir;
+   node->count = 0;
+
+   /* TODO: Implement max depth, or stack */
+   bh_update_bounds( bh, il );
+   bh_update_bounds( bh, ir );
+   bh_subdivide( bh, il );
+   bh_subdivide( bh, ir );
+}
+
+static void bh_create( bh_tree *bh, bh_system *sys, u32 item_count )
+{
+   bh->system = sys;
+   bh->nodes = malloc( sys->item_size * (item_count*2-1) );
+
+   bh_node *root = &bh->nodes[0];
+   bh->node_count = 1;
+   
+   root->il = 0;
+   root->ir = 0;
+   root->count = item_count;
+   root->start = 0;
+
+   bh_update_bounds( bh, 0 );
+   bh_subdivide( bh, 0 );
+
+   bh->nodes = realloc( bh->nodes, sys->item_size * bh->node_count );
+   vg_success( "BVH done, size: %u/%u\n", bh->node_count, (item_count*2-1) );
+}
+
+static void bh_debug_node( bh_tree *bh, u32 inode, v3f pos, u32 colour )
+{
+   bh_node *node = &bh->nodes[ inode ];
+
+   if( (pos[0] >= node->bbx[0][0] && pos[0] <= node->bbx[1][0]) &&
+       (pos[2] >= node->bbx[0][2] && pos[2] <= node->bbx[1][2]) )
+   {
+      if( !node->count )
+      {
+         vg_line_boxf( node->bbx, colour );
+
+         bh_debug_node( bh, node->il, pos, colour );
+         bh_debug_node( bh, node->ir, pos, colour );
+      }
+      else
+      {
+         vg_line_boxf( node->bbx, 0xff00ff00 );
+
+         if( bh->system->item_debug )
+         {
+            for( u32 i=0; i<node->count; i++ )
+            {
+               u32 idx = node->start+i;
+               bh->system->item_debug( bh->user, idx );
+            }
+         }
+      }
+   }
+}
+
+static int bh_ray( bh_tree *bh, u32 inode, v3f co, v3f dir, ray_hit *hit )
+{
+   int count = 0;
+   u32 stack[100];
+   u32 depth = 2;
+
+   stack[0] = 0;
+   stack[1] = bh->nodes[0].il;
+   stack[2] = bh->nodes[0].ir;
+   
+   while(depth)
+   {
+      bh_node *inode = &bh->nodes[ stack[depth] ];
+      if( ray_aabb( inode->bbx, co, dir, hit->dist ) )
+      {
+         if( inode->count )
+         {
+            for( u32 i=0; i<inode->count; i++ )
+            {
+               u32 idx = inode->start+i;
+
+               if( bh->system->cast_ray )
+                  count += bh->system->cast_ray( bh->user, co, dir, hit );
+               else
+                  count ++;
+            }
+
+            depth --;
+         }
+         else
+         {
+            if( depth+1 >= vg_list_size(stack) )
+            {
+               vg_error( "Maximum stack reached!\n" );
+               return count;
+            }
+
+            stack[depth] = inode->il;
+            stack[depth+1] = inode->ir;
+            depth ++;
+         }
+      }
+      else
+      {
+         depth --;
+      }
+   }
+
+   return count;
+}
+
+static int bh_select( bh_tree *bh, boxf box, u32 *buffer, int len )
+{
+   int count = 0;
+   u32 stack[100];
+   u32 depth = 2;
+
+   stack[0] = 0;
+   stack[1] = bh->nodes[0].il;
+   stack[2] = bh->nodes[0].ir;
+   
+   while(depth)
+   {
+      bh_node *inode = &bh->nodes[ stack[depth] ];
+      if( box_overlap( inode->bbx, box ) )
+      {
+         if( inode->count )
+         {
+            if( count + inode->count >= len )
+            {
+               vg_error( "Maximum buffer reached!\n" );
+               return count;
+            }
+
+            for( u32 i=0; i<inode->count; i++ )
+               buffer[ count ++ ] = inode->start+i;
+
+            depth --;
+         }
+         else
+         {
+            if( depth+1 >= vg_list_size(stack) )
+            {
+               vg_error( "Maximum stack reached!\n" );
+               return count;
+            }
+
+            stack[depth] = inode->il;
+            stack[depth+1] = inode->ir;
+            depth ++;
+         }
+      }
+      else
+      {
+         depth --;
+      }
+   }
+
+   return count;
+}
+
+#endif /* BVH_H */
index bc2ccb5a52c3f8c2d29d7f48de61f19ceb674f59..047b714df02f62db79b113299848d467abdc2691 100644 (file)
@@ -368,6 +368,22 @@ static character_pose pose_stand =
   .cam = {-0.3477f, 1.5884f, -0.0019f}
 };
 
+static character_pose pose_stand_reverse =
+{
+  .b0 =  {0.1624f, 1.0688f, -0.0632f},
+  .b1 =  {0.0499f, 1.5564f, -0.0013f},
+  .p =   {0.5423f, 1.2810f, -0.2368f},
+  .fr =  {0.0535f, 0.1312f, -0.3647f},
+  .fl =  {0.0354f, 0.1464f, 0.2917f},
+  .pl =  {-0.4325f, 0.6889f, 0.4591f},
+  .pr =  {-0.4794f, 0.7598f, -0.0842f},
+  .hl =  {0.0498f, 1.0058f, 0.2317f},
+  .hr =  {0.0188f, 0.9786f, -0.2725f},
+  .apl = {0.2898f, 1.3453f, 0.0695f},
+  .apr = {0.4715f, 1.2876f, -0.4982f},
+  .cam = {-0.3477f, 1.5884f, -0.0730f}
+};
+
 static character_pose pose_fly =
 {
   .b0 =  {0.2995f, 0.6819f, -0.1369f},
@@ -831,7 +847,18 @@ static void character_debug_ragdoll( struct character *ch )
 static void character_ragdoll_iter( struct character *ch )
 {
    for( int i=0; i<PART_COUNT; i++ )
-      rb_build_manifold( &ch->ragdoll[i] );
+   {
+      rb_manifold_reset( &ch->ragdoll[i] );
+      rb_build_manifold_terrain( &ch->ragdoll[i] );
+
+      u32 colliders[16];
+      int len = bh_select( &world.bhcubes, ch->ragdoll[i].bbx_world, 
+            colliders, 16 );
+      
+      for( int j=0; j<len; j++ )
+         rb_build_manifold_rb_static( &ch->ragdoll[i], 
+               &world.temp_rbs[colliders[j]] );
+   }
 
    v3f rv;
 
index 51eb1fa1df00dcc1931a6e2fcebd27aec2089af9..1e1ebed3c21aaa8d7dfa65f33fbfeba4943217da 100644 (file)
--- a/common.h
+++ b/common.h
@@ -13,4 +13,13 @@ enum classtype
    k_classtype_gate = 1
 };
 
+/* TODO: he needs a home somewhere */
+typedef struct ray_hit ray_hit;
+struct ray_hit
+{
+   float dist;
+   u32 *tri;
+   v3f pos, normal;
+};
+
 #endif /* COMMON_H */
diff --git a/gate.h b/gate.h
index 9350d2be13996cfad60ff146cad927fa87d51b61..6e9b95f9b8d27fcebe255fe496d1a52b78cda74b 100644 (file)
--- a/gate.h
+++ b/gate.h
@@ -6,6 +6,8 @@
 #include "model.h"
 #include "render.h"
 #include "shaders/gate.h"
+#include "shaders/gatelq.h"
+#include "water.h"
 
 typedef struct teleport_gate teleport_gate;
 
@@ -13,8 +15,15 @@ static struct
 {
    GLuint fb, rgb, rb;
    glmesh mdl;
+
+   int high_qual; /* If in high performance mode, we don't use RT's, and
+                            instead use stencil buffers.
+                            There is therefore no heat warp effect. */
 }
-grender;
+grender =
+{
+   .high_qual = 0
+};
 
 struct teleport_gate
 { 
@@ -42,6 +51,7 @@ static void gate_transform_update( teleport_gate *gate )
 static void gate_register(void)
 {
    shader_gate_register();
+   shader_gatelq_register();
 }
 
 static void gate_init(void)
@@ -70,6 +80,9 @@ static void render_gate( teleport_gate *gate, m4x3f camera )
    if( v3_dot(v0, gatedir) >= 0.0f )
       return;
 
+   if( v3_dist( viewpos, gate->co[0] ) > 100.0f )
+      return;
+
    v3f a,b,c,d;
 
    float sx = gate->dims[0],
@@ -91,10 +104,10 @@ static void render_gate( teleport_gate *gate, m4x3f camera )
    
    vg_line_pt3( cam_new[3], 0.3f, 0xff00ff00 );
 
-   glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
-   glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
-   glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
-
+   m4x3f gate_xform;
+   m4x3_copy( gate->to_world, gate_xform );
+   m4x3_scalev( gate_xform, (v3f){ gate->dims[0], gate->dims[1], 1.0f } );
+   
    m4x3f inverse;
    m4x3_invert_affine( cam_new, inverse );
 
@@ -107,47 +120,87 @@ static void render_gate( teleport_gate *gate, m4x3f camera )
 
    m4x4f projection;
    pipeline_projection( projection, 0.1f, 900.0f );
-
    
    m4x3_mulp( inverse, surface, surface );
    surface[3] = -fabsf(surface[3]);
    plane_clip_projection( projection, surface );
 
    m4x4_mul( projection, view, projection );
-   
-   render_world( projection, cam_new );
-   render_water_texture( cam_new );
-   glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
-   render_water_surface( projection );
-   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-
-   shader_gate_use();
-
-   m4x3f full;
-   m4x3_copy( gate->to_world, full );
-   m4x3_scalev( full, (v3f){ gate->dims[0], gate->dims[1], 1.0f } );
-
-   shader_gate_uPv( vg_pv );
-   shader_gate_uMdl( full );
-
-   glActiveTexture( GL_TEXTURE0 );
-   glBindTexture( GL_TEXTURE_2D, grender.rgb );
-   shader_gate_uCam( viewpos );
-   shader_gate_uTexMain( 0 );
-   shader_gate_uTexWater( 1 );
-   shader_gate_uTime( vg_time*0.25f );
-   shader_gate_uInvRes( (v2f){
-         1.0f / (float)vg_window_x,
-         1.0f / (float)vg_window_y });
-   
-   glEnable(GL_BLEND);
-   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
-   glBlendEquation(GL_FUNC_ADD);
 
-   mesh_bind( &grender.mdl );
-   mesh_draw( &grender.mdl );
+   if( grender.high_qual )
+   {
+      glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
+      glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
+      glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
+   }
+   else
+   {
+      shader_gatelq_use();
+      shader_gatelq_uPv( vg_pv );
+      shader_gatelq_uMdl( gate_xform );
+      shader_gatelq_uCam( viewpos );
+      shader_gatelq_uTime( vg_time*0.25f );
+      shader_gatelq_uInvRes( (v2f){
+            1.0f / (float)vg_window_x,
+            1.0f / (float)vg_window_y });
+
+      glEnable( GL_STENCIL_TEST );
+      glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );  
+      glStencilFunc( GL_ALWAYS, 1, 0xFF ); 
+      glStencilMask( 0xFF );
+
+      mesh_bind( &grender.mdl );
+      mesh_draw( &grender.mdl );
+
+      glClear( GL_DEPTH_BUFFER_BIT );
+      glStencilFunc( GL_EQUAL, 1, 0xFF );
+      glStencilMask( 0x00 ); 
+   }
 
-   glDisable(GL_BLEND);
+   render_world( projection, cam_new );
+   
+   if( grender.high_qual )
+   {
+      /*
+       * TODO: Need to find a way to draw a stencil buffer into the water 
+       *       rendering 
+       */
+
+      render_water_texture( cam_new );
+      glBindFramebuffer( GL_FRAMEBUFFER, grender.fb );
+      render_water_surface( projection );
+      glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+
+      shader_gate_use();
+
+      shader_gate_uPv( vg_pv );
+      shader_gate_uMdl( gate_xform );
+
+      glActiveTexture( GL_TEXTURE0 );
+      glBindTexture( GL_TEXTURE_2D, grender.rgb );
+      shader_gate_uCam( viewpos );
+      shader_gate_uTexMain( 0 );
+      shader_gate_uTexWater( 1 );
+      shader_gate_uTime( vg_time*0.25f );
+      shader_gate_uInvRes( (v2f){
+            1.0f / (float)vg_window_x,
+            1.0f / (float)vg_window_y });
+      
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+      glBlendEquation(GL_FUNC_ADD);
+
+      mesh_bind( &grender.mdl );
+      mesh_draw( &grender.mdl );
+
+      glDisable(GL_BLEND);
+   }
+   else
+   {
+      glStencilMask( 0xFF );
+      glStencilFunc( GL_ALWAYS, 1, 0xFF );
+      glDisable( GL_STENCIL_TEST );
+   }
 }
 
 static int gate_intersect( teleport_gate *gate, v3f pos, v3f last )
diff --git a/main.c b/main.c
index aaf58dc2ae0eb90649babd5e0a20729682a5f5bb..6b38fc5401b69366bb36a1872d3b81c7c4451b06 100644 (file)
--- a/main.c
+++ b/main.c
@@ -164,7 +164,7 @@ void vg_render(void)
 
    glDisable( GL_DEPTH_TEST );
    glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
-   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
 
    float speed = freecam? 0.0f: v3_length( player.v );
    v3f shake = { vg_randf()-0.5f, vg_randf()-0.5f, vg_randf()-0.5f };
index 790d71c147351f1524dffce51c0aff6b2a904f6f..984d4e3fe3c62e943c9d10bf6f8b3fbd5d96560a 100644 (file)
--- a/player.h
+++ b/player.h
@@ -152,6 +152,8 @@ static void player_start_air(void)
    float best_velocity_mod = 0.0f,
          best_velocity_delta = -9999.9f;
 
+   float k_bias = 0.97f;
+
    v3f axis, vup;
    m3x3_mulv( player.to_world, (v3f){0.0f,1.0f,0.0f}, vup );
    v3_cross( vup, player.v, axis );
@@ -166,7 +168,7 @@ static void player_start_air(void)
 
       v3f pco, pco1, pv;
       v3_copy( player.co, pco );
-      v3_copy( player.v, pv );
+      v3_muls( player.v, k_bias, pv );
 
       /* 
        * Try different 'rotations' of the velocity to find the best possible
@@ -181,7 +183,7 @@ static void player_start_air(void)
       q_m3x3( vr_q, vr );
 
       m3x3_mulv( vr, pv, pv );
-      v3_muladds( pco, pv, ktimestep, pco );
+      v3_muladds( pco, pv, pstep, pco );
 
       for( int i=0; i<50; i++ )
       {
@@ -413,9 +415,6 @@ static void draw_cross(v3f pos,u32 colour, float scale)
 static void player_physics_air(void)
 {
    m3x3_mulv( player.vr, player.v, player.v );
-   for( int i=0; i<player.land_log_count; i++ )
-      draw_cross( player.land_target_log[i], player.land_target_colours[i], 1);
-
    draw_cross( player.land_target, 0xff0000ff, 1 );
 
    v3f ground_pos;
@@ -583,10 +582,6 @@ static void player_do_motion(void)
    player.angles[0] = atan2f(  player.vl[0], -player.vl[2] );
    player.angles[1] = atan2f( -player.vl[1], sqrtf(player.vl[0]*player.vl[0]+
                                             player.vl[2]*player.vl[2]) ) * 0.3f;
-
-   player.air_blend = vg_lerpf( player.air_blend, player.in_air, 0.04f );
-   v3_muladds( player.camera_pos, player.v, -0.05f*player.air_blend, 
-         player.camera_pos );
 }
 
 static int player_walkgrid_tri_walkable( u32 tri[3] )
@@ -1770,10 +1765,14 @@ static void player_animate(void)
          amt_aero = amt_std * (1.0f-fstand),
          amt_slide = amt_ground * fslide;
 
-   character_final_pose( &player.mdl, offset, &pose_stand, amt_stand );
+   character_final_pose( &player.mdl, offset, &pose_stand, amt_stand*fdirz );
+   character_final_pose( &player.mdl, offset, 
+         &pose_stand_reverse, amt_stand * (1.0f-fdirz) );
+
    character_final_pose( &player.mdl, offset, &pose_aero, amt_aero*fdirz );
    character_final_pose( &player.mdl, offset, 
          &pose_aero_reverse, amt_aero * (1.0f-fdirz) );
+
    character_final_pose( &player.mdl, offset, &pose_slide, amt_slide*fdirx );
    character_final_pose( &player.mdl, offset, 
          &pose_slide1, amt_slide*(1.0f-fdirx) );
@@ -1788,6 +1787,10 @@ static void player_animate(void)
    player.camera_pos[1] = vg_clampf( player.camera_pos[1], 0.3f, kheight );
    m4x3_mulv( player.to_world, player.camera_pos, player.camera_pos );
 
+   player.air_blend = vg_lerpf( player.air_blend, player.in_air, 0.04f );
+   v3_muladds( player.camera_pos, player.v, -0.05f*player.air_blend, 
+         player.camera_pos );
+
    /* 
     * Additive effects
     * ==========================
@@ -1914,9 +1917,11 @@ static int giftwrapXZ( v3f *points, int *output, int len )
 
       for( int i=0; i<len; i++ )
       {
-         if( (points[i][2]-points[p][2])*(points[q][0]-points[i][0]) -
-             (points[i][0]-points[p][0])*(points[q][2]-points[i][2]) 
-             > 0.0001f )
+         float orient = 
+             (points[i][2]-points[p][2])*(points[q][0]-points[i][0]) -
+             (points[i][0]-points[p][0])*(points[q][2]-points[i][2]);
+
+         if( orient > 0.0001f )
          {
             q = i;
          }
@@ -1959,7 +1964,6 @@ static void player_do_collision( rigidbody *rb )
        m4x3_mulv( compound, (v3f){ a[0], b[1], a[2] }, verts[1] );
        m4x3_mulv( compound, (v3f){ b[0], b[1], a[2] }, verts[2] );
        m4x3_mulv( compound, (v3f){ b[0], a[1], a[2] }, verts[3] );
-
        m4x3_mulv( compound, (v3f){ a[0], a[1], b[2] }, verts[4] );
        m4x3_mulv( compound, (v3f){ a[0], b[1], b[2] }, verts[5] );
        m4x3_mulv( compound, (v3f){ b[0], b[1], b[2] }, verts[6] );
@@ -1974,6 +1978,31 @@ static void player_do_collision( rigidbody *rb )
    int hull_indices[12*2 + 8];
    int hull_len = 0;
 
+   for( int i=0; i<8; i++ )
+   {
+      int ia = indices[i][0];
+      float ya = verts[ia][1];
+
+      if( ya > 0.2f && ya < kheight )
+      {
+         int add_point = 1;
+         for( int j=0; j<hull_len; j++ )
+         {
+            v2f delta = { verts[ia][0]-hull[j][0], verts[ia][2]-hull[j][2] };
+            if( v2_length2( delta ) < 0.0004f )
+            {
+               add_point = 0;
+               break;
+            }
+         }
+
+         if( add_point )
+            v3_copy( verts[ia], hull[hull_len] );
+
+         hull[hull_len ++][1] = 0.2f;
+      }
+   }
+
    for( int i=0; i<vg_list_size(indices); i++ )
    {
       int ia = indices[i][0],
@@ -1986,39 +2015,34 @@ static void player_do_collision( rigidbody *rb )
             d = 1.0f/(yb-ya),
             qa;
 
-      if( (ya-0.2f) * (yb-0.2f) < 0.0f )
+      float planes[] = { 0.2f, kheight };
+      
+      for( int k=0; k<vg_list_size(planes); k++ )
       {
-         v3_muls( verts[ia], (yb-0.2f)*d, p0 );
-         v3_muladds( p0, verts[ib], -(ya-0.2f)*d, p0 );
-         
-         v3_copy( p0, hull[hull_len] );
-         hull[hull_len ++][1] = 0.2f;
-
-         m4x3_mulv( player.to_world, p0, p0 );
-         vg_line_pt3( p0, 0.1f, 0xffffff00 );
-      }
+         float clip = planes[k];
 
-      if( (ya-kheight) * (yb-kheight) < 0.0f )
-      {
-         v3_muls( verts[ia], (yb-kheight)*d, p0 );
-         v3_muladds( p0, verts[ib], -(ya-kheight)*d, p0 );
+         if( (ya-clip) * (yb-clip) < 0.0f )
+         {
+            v3_muls( verts[ia], (yb-clip)*d, p0 );
+            v3_muladds( p0, verts[ib], -(ya-clip)*d, p0 );
+            
+            int add_point = 1;
+            for( int j=0; j<hull_len; j++ )
+            {
+               v2f delta = { p0[0]-hull[j][0], p0[2]-hull[j][2] };
+               if( v2_length2( delta ) < 0.0004f )
+               {
+                  add_point = 0;
+                  break;
+               }
+            }
 
-         v3_copy( p0, hull[hull_len] );
-         hull[hull_len ++][1] = 0.2f;
+            if( add_point )
+               v3_copy( p0, hull[hull_len ++] );
 
-         m4x3_mulv( player.to_world, p0, p0 );
-         vg_line_pt3( p0, 0.1f, 0xff00ffff );
-      }
-   }
-   for( int i=0; i<8; i++ )
-   {
-      int ia = indices[i][0];
-      float ya = verts[ia][1];
-
-      if( ya > 0.2f && ya < kheight )
-      {
-         v3_copy( verts[ia], hull[hull_len] );
-         hull[hull_len ++][1] = 0.2f;
+            m4x3_mulv( player.to_world, p0, p0 );
+            vg_line_pt3( p0, 0.1f, 0xffffff00 );
+         }
       }
    }
 
@@ -2031,6 +2055,8 @@ static void player_do_collision( rigidbody *rb )
       v3f p0, p1, p2, p3;
       v3_copy( hull[hull_indices[i]], p0 );
       v3_copy( hull[hull_indices[(i+1)%len]], p1 );
+      p0[1] = 0.2f;
+      p1[1] = 0.2f;
       v3_add( p0, (v3f){0,kheight-0.2f,0}, p2 );
       v3_add( p1, (v3f){0,kheight-0.2f,0}, p3 );
          
@@ -2044,82 +2070,102 @@ static void player_do_collision( rigidbody *rb )
       vg_line( p0, p2, 0xff00ffa0 );
    }
 
-   int collide = 1;
-   float min_dist = 99999.9f;
-   v2f normal;
-   for( int i=0; i<len; i++ )
+   v2f endpoints[] = {{ 0.0f, -1.0f },{ 0.0f, 1.0f }};
+   
+   for( int j=0; j<vg_list_size(endpoints); j++ )
    {
-      v2f p0, p1;
-      p0[0] = hull[hull_indices[i]][0];
-      p0[1] = hull[hull_indices[i]][2];
-      p1[0] = hull[hull_indices[(i+1)%len]][0];
-      p1[1] = hull[hull_indices[(i+1)%len]][2];
-      
-      v2f t,n, rel;
-      v2_sub( p1, p0, t );
-      n[0] = -t[1];
-      n[1] =  t[0];
-      v2_normalize(n);
-      
-      v2_sub( (v2f){ 0.0f, -1.0f }, p0, rel );
-      float d = -v2_dot( n, rel ) + 0.5f;
+      v2f point;
+      v2_copy( endpoints[j], point );
 
-      if( d < 0.0f )
+      int collide = 1;
+      float min_dist = 99999.9f;
+      v2f normal;
+      for( int i=0; i<len; i++ )
       {
-         collide = 0;
-         break;
-      }
+         v2f p0, p1;
+         p0[0] = hull[hull_indices[i]][0];
+         p0[1] = hull[hull_indices[i]][2];
+         p1[0] = hull[hull_indices[(i+1)%len]][0];
+         p1[1] = hull[hull_indices[(i+1)%len]][2];
+         
+         v2f t,n, rel;
+         v2_sub( p1, p0, t );
+         n[0] = -t[1];
+         n[1] =  t[0];
+         v2_normalize(n);
+         
+         v2_sub( point, p0, rel );
+         float d = -v2_dot( n, rel ) + 0.5f;
 
-      if( d < min_dist )
-      {
-         min_dist = d;
-         v2_copy( n, normal );
-      }
-   }
+         if( d < 0.0f )
+         {
+            collide = 0;
+            break;
+         }
 
-   if( collide )
-   {
-      v3f p0, p1;
-      p0[0] =  0.0f;
-      p0[1] =  0.2f;
-      p0[2] = -1.0f;
+         if( d < min_dist )
+         {
+            min_dist = d;
+            v2_copy( n, normal );
+         }
+      }
 
-      p1[0] = p0[0] + normal[0]*min_dist;
-      p1[1] = p0[1];
-      p1[2] = p0[2] + normal[1]*min_dist;
-      
-      m4x3_mulv( player.to_world, p0, p0 );
-      m4x3_mulv( player.to_world, p1, p1 );
+      if( collide )
+      {
+         v3f p0, p1;
+         p0[0] =  0.0f;
+         p0[1] =  0.2f;
+         p0[2] = -1.0f;
+
+         p1[0] = p0[0] + normal[0]*min_dist;
+         p1[1] = p0[1];
+         p1[2] = p0[2] + normal[1]*min_dist;
+         
+         m4x3_mulv( player.to_world, p0, p0 );
+         m4x3_mulv( player.to_world, p1, p1 );
 
-      vg_line( p0, p1, 0xffffffff );
+         vg_line( p0, p1, 0xffffffff );
+         
+         v3f vel;
+         m3x3_mulv( player.to_local, player.v, vel );
+         vel[1] = vel[2];
 
-      v2f impulse;
-      v2_muls( normal, min_dist, impulse );
-      float rotation = v2_cross( (v2f){0.0f,-1.0f}, impulse )*0.08f;
-      
-      v3f vel;
-      m3x3_mulv( player.to_local, player.v, vel );
-      vel[1] = vel[2];
+         float vn = vg_maxf( -v2_dot( vel, normal ), 0.0f );
+         vn += -0.2f * (1.0f/k_rb_delta) * vg_minf( 0.0f, -min_dist+0.04f );
+         
+         v2f impulse;
+         if( vn > 14.0f )
+         {
+            player.is_dead = 1;
+            character_ragdoll_copypose( &player.mdl, player.v );
+            return;
+         }
 
-      float vn = vg_maxf( -v2_dot( vel, normal ), 0.0f );
-      vn += -0.2f * (1.0f/k_rb_delta) * vg_minf( 0.0f, -min_dist+0.04f );
+         if( vn > 0.0f )
+         {
+            v2_muls( normal, min_dist, impulse );
+            float rotation = v2_cross( point, impulse )*0.08f;
+            v4f rot;
+            v3f up = {0.0f,1.0f,0.0f};
+            m3x3_mulv( player.to_world, up, up );
+            q_axis_angle( rot, up, -rotation );
+            q_mul( rot, player.rot, player.rot );
+         }
 
-      v2_muls( normal, vn*0.03f, impulse );
-      v3f impulse_world = { impulse[0], 0.0f, impulse[1] };
+         v2_muls( normal, vn*0.03f, impulse );
+         v3f impulse_world = { impulse[0], 0.0f, impulse[1] };
 
-      m3x3_mulv( player.to_world, impulse_world, impulse_world );
-      v3_add( impulse_world, player.v, player.v );
-      
-      v4f rot;
-      v3f up = {0.0f,1.0f,0.0f};
-      m3x3_mulv( player.to_world, up, up );
-      q_axis_angle( rot, up, -rotation );
-      q_mul( rot, player.rot, player.rot );
+         m3x3_mulv( player.to_world, impulse_world, impulse_world );
+         v3_add( impulse_world, player.v, player.v );
+      }
    }
 }
 
 static void player_update(void)
 {
+   for( int i=0; i<player.land_log_count; i++ )
+      draw_cross( player.land_target_log[i], player.land_target_colours[i], 1);
+
    if( vg_get_axis("grabl")>0.0f)
       reset_player(0,NULL);
 
@@ -2138,8 +2184,17 @@ static void player_update(void)
       {
          if( player.on_board )
          {
-            for( int i=0; i<world.rb_count; i++ )
-               player_do_collision( &world.temp_rbs[i] );
+            bh_debug_node(&world.bhcubes, 0, 
+                  player.camera_pos, 0xff80ff00 );
+
+            u32 colliders[16];
+            boxf wbox = {{ -2.0f, -2.0f, -2.0f },
+                         {  2.0f,  2.0f,  2.0f }};
+            m4x3_transform_aabb( player.to_world, wbox );
+            int len = bh_select( &world.bhcubes, wbox, colliders, 32 );
+
+            for( int i=0; i<len; i++ )
+               player_do_collision( &world.temp_rbs[colliders[i]] );
 
             player_do_motion();
             player_animate();
index 82e793437994f2bbf0616bd79e6af3d356ca667b..e374f3fbd6e773cdbc5f33349a5202f576125903 100644 (file)
@@ -3,12 +3,14 @@
  *            qu3e  - Randy Gaul
  */
 
-#include "vg/vg.h"
+#include "common.h"
 static void rb_tangent_basis( v3f n, v3f tx, v3f ty );
 
 #ifndef RIGIDBODY_H
 #define RIGIDBODY_H
 
+#include "bvh.h"
+
 #define RB_DEPR 
 
 #define k_rb_delta (1.0f/60.0f)
@@ -18,7 +20,7 @@ struct rigidbody
 {
    v3f co, v, I;
    v4f q;
-   boxf bbx;
+   boxf bbx, bbx_world;
    float inv_mass;
 
    struct contact
@@ -27,7 +29,7 @@ struct rigidbody
       v3f t[2];
       float bias, norm_impulse, tangent_impulse[2];
    }
-   manifold[4];
+   manifold[12];
    int manifold_count;
 
    v3f delta;  /* where is the origin of this in relation to a parent body */
@@ -41,6 +43,9 @@ static void rb_update_transform( rigidbody *rb )
    v3_copy( rb->co, rb->to_world[3] );
 
    m4x3_invert_affine( rb->to_world, rb->to_local );
+
+   box_copy( rb->bbx, rb->bbx_world );
+   m4x3_transform_aabb( rb->to_world, rb->bbx_world );
 }
 
 static void rb_init( rigidbody *rb )
@@ -108,7 +113,12 @@ static void rb_tangent_basis( v3f n, v3f tx, v3f ty )
 
 #include "world.h"
 
-static void rb_build_manifold( rigidbody *rb )
+static void rb_manifold_reset( rigidbody *rb )
+{
+   rb->manifold_count = 0;
+}
+
+static void rb_build_manifold_terrain( rigidbody *rb )
 {
    v3f *box = rb->bbx;
    v3f pts[8]; 
@@ -134,7 +144,7 @@ static void rb_build_manifold( rigidbody *rb )
    m4x3_mulv( rb->to_world, p110, p110 );
    m4x3_mulv( rb->to_world, p111, p111 );
 
-   rb->manifold_count = 0;
+   int count = 0;
 
    for( int i=0; i<8; i++ )
    {
@@ -171,7 +181,8 @@ static void rb_build_manifold( rigidbody *rb )
          ct->tangent_impulse[1] = 0.0f;
 
          rb->manifold_count ++;
-         if( rb->manifold_count == 4 )
+         count ++;
+         if( count == 4 )
             break;
       }
    }
@@ -242,8 +253,7 @@ struct rb_angle_limit
    float impulse, bias;
 };
 
-static int rb_angle_limit_force( 
-                                  rigidbody *rba, v3f va, 
+static int rb_angle_limit_force(  rigidbody *rba, v3f va, 
                                   rigidbody *rbb, v3f vb,
                                   float max )
 {
@@ -481,4 +491,101 @@ static int rb_point_in_body( rigidbody *rb, v3f pos, float *pen, v3f normal )
    return 0;
 }
 
+static void rb_build_manifold_rb_static( rigidbody *ra, rigidbody *rb_static )
+{
+   v3f verts[8];
+
+   v3f a, b;
+   v3_copy( ra->bbx[0], a );
+   v3_copy( ra->bbx[1], b );
+   
+       m4x3_mulv( ra->to_world, (v3f){ a[0], a[1], a[2] }, verts[0] );
+       m4x3_mulv( ra->to_world, (v3f){ a[0], b[1], a[2] }, verts[1] );
+       m4x3_mulv( ra->to_world, (v3f){ b[0], b[1], a[2] }, verts[2] );
+       m4x3_mulv( ra->to_world, (v3f){ b[0], a[1], a[2] }, verts[3] );
+       m4x3_mulv( ra->to_world, (v3f){ a[0], a[1], b[2] }, verts[4] );
+       m4x3_mulv( ra->to_world, (v3f){ a[0], b[1], b[2] }, verts[5] );
+       m4x3_mulv( ra->to_world, (v3f){ b[0], b[1], b[2] }, verts[6] );
+       m4x3_mulv( ra->to_world, (v3f){ b[0], a[1], b[2] }, verts[7] );
+
+   int count = 0;
+
+   for( int i=0; i<8; i++ )
+   {
+      if( ra->manifold_count == vg_list_size(ra->manifold) )
+         return;
+
+      struct contact *ct = &ra->manifold[ ra->manifold_count ];
+      
+      float p;
+      v3f normal;
+
+      if( rb_point_in_body( rb_static, verts[i], &p, normal ))
+      {
+         v3_copy( normal, ct->n );
+         v3_muladds( verts[i], ct->n, p*0.5f, ct->co );
+         v3_sub( ct->co, ra->co, ct->delta );
+
+         vg_line_pt3( ct->co, 0.0125f, 0xffff00ff );
+         
+         ct->bias = -0.2f * (1.0f/k_rb_delta) * vg_minf( 0.0f, -p+0.04f );
+         rb_tangent_basis( ct->n, ct->t[0], ct->t[1] );
+
+         ct->norm_impulse = 0.0f;
+         ct->tangent_impulse[0] = 0.0f;
+         ct->tangent_impulse[1] = 0.0f;
+
+         ra->manifold_count ++;
+         count ++;
+         if( count == 4 )
+            return;
+      }
+   }
+}
+
+/*
+ * BVH implementation, this is ONLY for static rigidbodies, its to slow for
+ * realtime use.
+ */
+
+static void rb_bh_expand_bound( void *user, boxf bound, u32 item_index )
+{
+   rigidbody *rb = &((rigidbody *)user)[ item_index ];
+   box_concat( bound, rb->bbx_world );
+}
+
+static float rb_bh_centroid( void *user, u32 item_index, int axis )
+{
+   rigidbody *rb = &((rigidbody *)user)[ item_index ];
+   return (rb->bbx_world[axis][0] + rb->bbx_world[1][axis]) * 0.5f;
+}
+
+static void rb_bh_swap( void *user, u32 ia, u32 ib )
+{
+   rigidbody temp, *rba, *rbb;
+   rba = &((rigidbody *)user)[ ia ];
+   rbb = &((rigidbody *)user)[ ib ];
+
+   temp = *rba;
+   *rba = *rbb;
+   *rbb = temp;
+}
+
+static void rb_bh_debug( void *user, u32 item_index )
+{
+   rigidbody *rb = &((rigidbody *)user)[ item_index ];
+   rb_debug( rb, 0xff00ffff );
+}
+
+static bh_system bh_system_rigidbodies =
+{
+   .expand_bound = rb_bh_expand_bound,
+   .item_centroid = rb_bh_centroid,
+   .item_swap = rb_bh_swap,
+   .item_debug = rb_bh_debug,
+   .cast_ray = NULL,
+
+   .item_size = sizeof(rigidbody)
+};
+
 #endif /* RIGIDBODY_H */
diff --git a/scene.h b/scene.h
index d6cfb0a081b2c2ab2959bcb75f7e643053012689..c5c94f53329e2f59b774b1ab020169c16177381c 100644 (file)
--- a/scene.h
+++ b/scene.h
@@ -1,7 +1,7 @@
 #ifndef SCENE_H
 #define SCENE_H
 
-#include "vg/vg.h"
+#include "common.h"
 #include "model.h"
 
 typedef struct scene scene;
@@ -369,6 +369,15 @@ static void sample_scene_normal( scene *pscene, v3f pos, v3f normal )
    normal[2] = 0.0f;
 }
 
+
+/*
+ *
+ *
+ *            TODO: THIS SHIT IS DEPRECATED FOR THE NEW SHIT IN BVH.H
+ *
+ *
+ */
+
 struct bvh_node
 {
    boxf bbx;
@@ -409,18 +418,14 @@ static void bvh_subdiv( scene *s, u32 inode )
 
    float split = node->bbx[0][axis] + extent[axis]*0.5f;
 
-   /* To beat: 121,687 / 136,579 
-    *          136,375
-    */
-
    float avg = 0.0;
    for( u32 t=0; t<node->count; t++ )
    {
       u32 *ti = &s->indices[(node->start+t)*3];
       float a = s->verts[ti[0]].co[axis],
-             b = s->verts[ti[1]].co[axis],
-             c = s->verts[ti[2]].co[axis];
-      avg += (a+b+c)/3.0;
+            b = s->verts[ti[1]].co[axis],
+            c = s->verts[ti[2]].co[axis];
+      avg += (a+b+c) * (1.0f/3.0f);
    }
    avg /= (float)node->count;
 
@@ -437,7 +442,7 @@ static void bvh_subdiv( scene *s, u32 inode )
             b = s->verts[ti[1]].co[axis],
             c = s->verts[ti[2]].co[axis];
 
-      if( ((a+b+c) / 3.0f) < split )
+      if( (a+b+c) * (1.0f/3.0f) < split )
          i ++;
       else
       {
@@ -545,34 +550,6 @@ static void bvh_debug( scene *s, v3f pos )
    bvh_debug_node( s, 0, pos, 0x4000ffa8 );
 }
 
-typedef struct ray_hit ray_hit;
-struct ray_hit
-{
-   float dist;
-   u32 *tri;
-   v3f pos, normal;
-};
-
-int ray_aabb( boxf box, v3f co, v3f dir, float dist )
-{
-   v3f v0, v1;
-   float tmin, tmax;
-
-   v3_sub( box[0], co, v0 );
-   v3_sub( box[1], co, v1 );
-   v3_div( v0, dir, v0 );
-   v3_div( v1, dir, v1 );
-   
-   tmin = vg_minf( v0[0], v1[0] );
-   tmax = vg_maxf( v0[0], v1[0] );
-   tmin = vg_maxf( tmin, vg_minf( v0[1], v1[1] ));
-   tmax = vg_minf( tmax, vg_maxf( v0[1], v1[1] ));
-   tmin = vg_maxf( tmin, vg_minf( v0[2], v1[2] ));
-   tmax = vg_minf( tmax, vg_maxf( v0[2], v1[2] ));
-
-   return tmax >= tmin && tmin < dist && tmax > 0;
-}
-
 static int bvh_ray_tri( scene *sc, u32 *tri, v3f co, v3f dir, ray_hit *hit )
 {
    v3f positions[3];
@@ -595,6 +572,7 @@ static int bvh_ray_tri( scene *sc, u32 *tri, v3f co, v3f dir, ray_hit *hit )
 
 static int bvh_ray( scene *s, u32 inode, v3f co, v3f dir, ray_hit *hit )
 {
+#if 0
    bvh_node *node = &s->bvh.nodes[ inode ];
    
    if( !ray_aabb( node->bbx, co, dir, hit->dist )) 
@@ -616,6 +594,51 @@ static int bvh_ray( scene *s, u32 inode, v3f co, v3f dir, ray_hit *hit )
       count += bvh_ray( s, node->ir, co, dir, hit );
    }
 
+   return count;
+#endif
+
+   int count = 0;
+   u32 stack[100];
+   u32 depth = 2;
+
+   stack[0] = 0;
+   stack[1] = s->bvh.nodes[0].il;
+   stack[2] = s->bvh.nodes[0].ir;
+   
+   while(depth)
+   {
+      bvh_node *inode = &s->bvh.nodes[ stack[depth] ];
+      if( ray_aabb( inode->bbx, co, dir, hit->dist ) )
+      {
+         if( inode->count )
+         {
+            for( u32 i=0; i<inode->count; i++ )
+            {
+               u32 *indices = &s->indices[ (inode->start+i)*3 ];
+               count += bvh_ray_tri( s, indices, co, dir, hit );
+            }
+
+            depth --;
+         }
+         else
+         {
+            if( depth+1 >= vg_list_size(stack) )
+            {
+               vg_error( "Maximum stack reached!\n" );
+               return count;
+            }
+
+            stack[depth] = inode->il;
+            stack[depth+1] = inode->ir;
+            depth ++;
+         }
+      }
+      else
+      {
+         depth --;
+      }
+   }
+
    return count;
 }
 
diff --git a/shaders/gate_lq.fs b/shaders/gate_lq.fs
new file mode 100644 (file)
index 0000000..c455126
--- /dev/null
@@ -0,0 +1,23 @@
+out vec4 FragColor;
+
+uniform float uTime;
+uniform vec3 uCam;
+uniform vec2 uInvRes;
+
+in vec3 aNorm;
+in vec2 aUv;
+in vec3 aCo;
+
+void main()
+{
+   vec2 ssuv = gl_FragCoord.xy;
+   float opacity = 1.0-smoothstep(0.4,1.0,aUv.y);
+   
+   vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );
+   float dither = fract( vDither.g / 71.0 ) - 0.5;
+
+   if( opacity+dither<0.5 )
+      discard;
+
+   FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );
+}
diff --git a/shaders/gatelq.h b/shaders/gatelq.h
new file mode 100644 (file)
index 0000000..0bedde2
--- /dev/null
@@ -0,0 +1,96 @@
+#ifndef SHADER_gatelq_H
+#define SHADER_gatelq_H
+static void shader_gatelq_link(void);
+static void shader_gatelq_register(void);
+static struct vg_shader _shader_gatelq = {
+   .name = "gatelq",
+   .link = shader_gatelq_link,
+   .vs = 
+{
+.orig_file = "../shaders/gate.vs",
+.static_src = 
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec4 a_colour;\n"
+"layout (location=3) in vec2 a_uv;\n"
+"\n"
+"#line      2        0 \n"
+"uniform mat4 uPv;\n"
+"uniform mat4x3 uMdl;\n"
+"\n"
+"out vec3 aNorm;\n"
+"out vec2 aUv;\n"
+"out vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+"   vec3 world_pos = uMdl * vec4( a_co, 1.0 );\n"
+"   gl_Position = uPv * vec4(world_pos,1.0);\n"
+"\n"
+"   aNorm = a_norm;\n"
+"   aCo = world_pos;\n"
+"   aUv = a_uv;\n"
+"}\n"
+""},
+   .fs = 
+{
+.orig_file = "../shaders/gate_lq.fs",
+.static_src = 
+"out vec4 FragColor;\n"
+"\n"
+"uniform float uTime;\n"
+"uniform vec3 uCam;\n"
+"uniform vec2 uInvRes;\n"
+"\n"
+"in vec3 aNorm;\n"
+"in vec2 aUv;\n"
+"in vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+"   vec2 ssuv = gl_FragCoord.xy;\n"
+"   float opacity = 1.0-smoothstep(0.4,1.0,aUv.y);\n"
+"   \n"
+"   vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+"   float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+"   if( opacity+dither<0.5 )\n"
+"      discard;\n"
+"\n"
+"   FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_gatelq_uPv;
+static GLuint _uniform_gatelq_uMdl;
+static GLuint _uniform_gatelq_uTime;
+static GLuint _uniform_gatelq_uCam;
+static GLuint _uniform_gatelq_uInvRes;
+static void shader_gatelq_uPv(m4x4f m){
+   glUniformMatrix4fv( _uniform_gatelq_uPv, 1, GL_FALSE, (float *)m );
+}
+static void shader_gatelq_uMdl(m4x3f m){
+   glUniformMatrix4x3fv( _uniform_gatelq_uMdl, 1, GL_FALSE, (float *)m );
+}
+static void shader_gatelq_uTime(float f){
+   glUniform1f( _uniform_gatelq_uTime, f );
+}
+static void shader_gatelq_uCam(v3f v){
+   glUniform3fv( _uniform_gatelq_uCam, 1, v );
+}
+static void shader_gatelq_uInvRes(v2f v){
+   glUniform2fv( _uniform_gatelq_uInvRes, 1, v );
+}
+static void shader_gatelq_register(void){
+   vg_shader_register( &_shader_gatelq );
+}
+static void shader_gatelq_use(void){ glUseProgram(_shader_gatelq.id); }
+static void shader_gatelq_link(void){
+   _uniform_gatelq_uPv = glGetUniformLocation( _shader_gatelq.id, "uPv" );
+   _uniform_gatelq_uMdl = glGetUniformLocation( _shader_gatelq.id, "uMdl" );
+   _uniform_gatelq_uTime = glGetUniformLocation( _shader_gatelq.id, "uTime" );
+   _uniform_gatelq_uCam = glGetUniformLocation( _shader_gatelq.id, "uCam" );
+   _uniform_gatelq_uInvRes = glGetUniformLocation( _shader_gatelq.id, "uInvRes" );
+}
+#endif /* SHADER_gatelq_H */
diff --git a/vg.conf b/vg.conf
index e383b597abdcd4cb43551e051acbe16b0ed10184..99fc92eda4c04ea11ad775254be68a94231381bb 100644 (file)
--- a/vg.conf
+++ b/vg.conf
@@ -7,5 +7,6 @@ shader standard standard.vs standard.fs
 shader unlit standard.vs unlit.fs
 shader character character.vs character.fs
 shader gate gate.vs gate.fs
+shader gatelq gate.vs gate_lq.fs
 shader water water.vs water.fs
 shader sky standard.vs sky.fs
diff --git a/world.h b/world.h
index cfa3d6b79f51b4f16e690758c1ccf949b3748b9d..7272b802c78201b30cfdff58bb460f654046ab3c 100644 (file)
--- a/world.h
+++ b/world.h
@@ -10,6 +10,7 @@
 #include "water.h"
 #include "rigidbody.h"
 #include "gate.h"
+#include "bvh.h"
 
 #include "shaders/standard.h"
 
@@ -27,12 +28,16 @@ static struct gworld
 
    teleport_gate gates[16];
    u32 gate_count;
-
+   
    rigidbody temp_rbs[32];
    u32 rb_count;
+
+   bh_tree bhcubes;
 }
 world;
 
+
+
 static void render_world( m4x4f projection, m4x3f camera )
 {
    render_sky( camera );
@@ -66,6 +71,7 @@ static int ray_hit_is_ramp( ray_hit *hit )
    return hit->tri[0] < world.sm_road.vertex_count;
 }
 
+static bh_system bh_system_rigidbodies;
 static void world_load(void)
 {
    /* Setup scene */
@@ -157,15 +163,6 @@ static void world_load(void)
     *
     *       then compute bvh
     */
-#if 0
-   scene_add_foliage( &world.foliage, mworld, boxtest, world.box.to_world );
-#endif
-   
-
-#if 0
-   submodel *boxtest = submodel_get( mworld, "cubey" );
-
-#endif
    
    for( int i=0; i<mworld->layer_count; i++ )
    {
@@ -189,7 +186,6 @@ static void world_load(void)
       rb_update_transform( rb );
    }
 
-
    free( mworld );
 
    v3f volume;
@@ -241,6 +237,9 @@ static void world_load(void)
 
    free( mfoliage );
    scene_upload( &world.foliage );
+   
+   world.bhcubes.user = world.temp_rbs;
+   bh_create( &world.bhcubes, &bh_system_rigidbodies, world.rb_count );
 }
 
 #endif /* WORLD_H */