simple challenge system done
authorhgn <hgodden00@gmail.com>
Wed, 19 Jul 2023 21:11:31 +0000 (22:11 +0100)
committerhgn <hgodden00@gmail.com>
Wed, 19 Jul 2023 21:11:31 +0000 (22:11 +0100)
bvh.h
world_entity.c
world_entity.h
world_render.c
world_volumes.c

diff --git a/bvh.h b/bvh.h
index fa51c5936157d261028f3468099154050e281d86..1997bedc964dcb30c25fad9c8ffe08ba034c816a 100644 (file)
--- a/bvh.h
+++ b/bvh.h
@@ -268,7 +268,8 @@ struct bh_iter{
 
    enum bh_query_type{
       k_bh_query_box,
-      k_bh_query_ray
+      k_bh_query_ray,
+      k_bh_query_range
    }
    query;
 
@@ -283,34 +284,54 @@ struct bh_iter{
          f32 max_dist;
       }
       ray;
+
+      struct {
+         v3f co;
+         f32 dist_sqr;
+      }
+      range;
    };
 
    i32 depth, i;
 };
 
-VG_STATIC void bh_iter_init_box( i32 root, bh_iter *it, boxf box ){
-   it->query = k_bh_query_box;
+VG_STATIC void bh_iter_init_generic( i32 root, bh_iter *it ){
    it->stack[0].id = root;
    it->stack[0].depth = 0;
    it->depth = 0;
    it->i = 0;
+}
+
+VG_STATIC void bh_iter_init_box( i32 root, bh_iter *it, boxf box ){
+   bh_iter_init_generic( root, it );
+   it->query = k_bh_query_box;
 
    box_copy( box, it->box.box );
 }
 
 VG_STATIC void bh_iter_init_ray( i32 root, bh_iter *it, v3f co, 
                                  v3f dir, f32 max_dist ){
+   bh_iter_init_generic( root, it );
    it->query = k_bh_query_ray;
-   it->stack[0].id = root;
-   it->stack[0].depth = 0;
-   it->depth = 0;
-   it->i = 0;
    
    v3_div( (v3f){1.0f,1.0f,1.0f}, dir, it->ray.inv_dir );
    v3_copy( co, it->ray.co );
    it->ray.max_dist = max_dist;
 }
 
+VG_STATIC void bh_iter_init_range( i32 root, bh_iter *it, v3f co, f32 range ){
+   bh_iter_init_generic( root, it );
+   it->query = k_bh_query_range;
+
+   v3_copy( co, it->range.co );
+   it->range.dist_sqr = range*range;
+}
+
+/* NOTE: does not compute anything beyond the leaf level. element level tests
+ *       should be implemented by the users code.
+ *
+ *       this is like a 'broad phase only' deal.
+ */
 VG_STATIC i32 bh_next( bh_tree *bh, bh_iter *it, i32 *em ){
    while( it->depth >= 0 ){
       bh_node *inode = &bh->nodes[ it->stack[it->depth].id ];
@@ -318,11 +339,22 @@ VG_STATIC i32 bh_next( bh_tree *bh, bh_iter *it, i32 *em ){
       /* Only process overlapping nodes */
       i32 q = 0;
 
-      if( it->query == k_bh_query_box )
-         q = box_overlap( inode->bbx, it->box.box );
-      else
-         q = ray_aabb1( inode->bbx, it->ray.co, 
-                        it->ray.inv_dir, it->ray.max_dist );
+      if( it->i ) /* already checked */
+         q = 1;
+      else{
+         if( it->query == k_bh_query_box )
+            q = box_overlap( inode->bbx, it->box.box );
+         else if( it->query == k_bh_query_ray )
+            q = ray_aabb1( inode->bbx, it->ray.co, 
+                           it->ray.inv_dir, it->ray.max_dist );
+         else {
+            v3f nearest;
+            closest_point_aabb( it->range.co, inode->bbx, nearest );
+
+            if( v3_dist2( nearest, it->range.co ) <= it->range.dist_sqr )
+               q = 1;
+         }
+      }
 
       if( !q ){
          it->depth --;
index d431bedc20f88dfd0cb1043bf16143bbc21841d5..db1d244f490506165b3e45a9744aae764fdd3bb3 100644 (file)
@@ -415,4 +415,29 @@ VG_STATIC void entity_bh_debug( void *user, u32 item_index ){
    }
 }
 
+VG_STATIC void entity_bh_closest( void *user, u32 item_index, v3f point,
+                                  v3f closest ){
+   world_instance *world = user;
+
+   u32 id    = world->entity_list[ item_index ],
+       type  = mdl_entity_id_type( id ),
+       index = mdl_entity_id_id( id );
+
+   if( type == k_ent_gate ){
+      ent_gate *gate = mdl_arritm( &world->ent_gate, index );
+      v3_copy( gate->to_world[3], closest );
+   }
+   else if( type == k_ent_challenge ){
+      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+      v3_copy( challenge->transform.co, closest );
+   }
+   else if( type == k_ent_volume ){
+      ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+      v3_copy( volume->to_world[3], closest );
+   }
+   else{
+      vg_fatal_error( "Programming error\n" );
+   }
+}
+
 #endif /* WORLD_ENTITY_C */
index 3baaa2385a591aac82a822e3ff719af234ee4e59..eca698ad8bfaa7db84bc2d813f7f883e997e2ae5 100644 (file)
@@ -19,11 +19,13 @@ VG_STATIC void entity_bh_expand_bound( void *user, boxf bound, u32 item_index );
 VG_STATIC float entity_bh_centroid( void *user, u32 item_index, int axis );
 VG_STATIC void entity_bh_swap( void *user, u32 ia, u32 ib );
 VG_STATIC void entity_bh_debug( void *user, u32 item_index );
+VG_STATIC void entity_bh_closest( void *user, u32 item_index, v3f point,
+                                  v3f closest );
 
 static bh_system bh_system_entity_list = {
    .expand_bound = entity_bh_expand_bound,
    .item_centroid = entity_bh_centroid,
-   .item_closest = NULL,
+   .item_closest = entity_bh_closest,
    .item_swap = entity_bh_swap,
    .item_debug = entity_bh_debug,
    .cast_ray = NULL
index 3693a28920108f5978b1080b323a131a4fa19682..a33d774cbfbfeeeb1f10c0d156e47515ae015d1b 100644 (file)
@@ -340,7 +340,8 @@ VG_STATIC void render_world_alphatest( world_instance *world, camera *cam )
 }
 
 VG_STATIC
-void world_render_challenges( world_instance *world, struct world_pass *pass ){
+void world_render_challenges( world_instance *world, struct world_pass *pass,
+                              v3f pos ){
    if( !world ) return;
 
    glDisable( GL_CULL_FACE );
@@ -348,9 +349,26 @@ void world_render_challenges( world_instance *world, struct world_pass *pass ){
 
    u32 last_material = 0;
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
-      ent_challenge *challenge = mdl_arritm(&world->ent_challenge,i);
-      
+   const f32 radius = 40.0f;
+
+   bh_iter it;
+   bh_iter_init_range( 0, &it, pos, radius );
+   i32 idx;
+
+   while( bh_next( world->entity_bh, &it, &idx ) ){
+      u32 id    = world->entity_list[ idx ],
+          type  = mdl_entity_id_type( id ),
+          index = mdl_entity_id_id( id );
+
+      if( type != k_ent_challenge ) continue;
+
+      ent_challenge *challenge = mdl_arritm(&world->ent_challenge,index);
+
+      f32 dist = v3_dist( challenge->transform.co, pos ) * (1.0f/radius),
+          scale = vg_smoothstepf( vg_clampf( 10.0f-dist*10.0f, 0.0f,1.0f ) );
+
+      v3_fill( challenge->transform.s, scale );
+
       m4x3f mmdl;
       mdl_transform_m4x3( &challenge->transform, mmdl );
       shader_scene_fxglow_uMdl( mmdl );
@@ -397,7 +415,7 @@ VG_STATIC void render_world_fxglow( world_instance *world, camera *cam ){
    };
 
    world_render_both_stages( world, &pass );
-   world_render_challenges( world, &pass );
+   world_render_challenges( world, &pass, cam->pos );
 
    glEnable(GL_CULL_FACE);
    //glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 } );
index 2f0569df364df22a93eedbc3a2797c2887bc79e4..dac790e9baa0d99387186ab20a5b03fc2d20a218 100644 (file)
@@ -37,13 +37,10 @@ static void world_volumes_update( world_instance *world, v3f pos ){
       random_ticks ++;
    }
 
-   float radius = 25.0f;
-   boxf volume_proximity;
-   v3_add( pos, (v3f){ radius, radius, radius }, volume_proximity[1] );
-   v3_sub( pos, (v3f){ radius, radius, radius }, volume_proximity[0] );
+   float radius = 32.0f;
 
    bh_iter it;
-   bh_iter_init_box( 0, &it, volume_proximity );
+   bh_iter_init_range( 0, &it, pos, radius );
    i32 idx;
 
    while( bh_next( world->entity_bh, &it, &idx ) ){