From f014a592925b224f846d8adfc6559539fae1a096 Mon Sep 17 00:00:00 2001 From: hgn Date: Wed, 19 Jul 2023 22:11:31 +0100 Subject: [PATCH] simple challenge system done --- bvh.h | 56 ++++++++++++++++++++++++++++++++++++++----------- world_entity.c | 25 ++++++++++++++++++++++ world_entity.h | 4 +++- world_render.c | 28 ++++++++++++++++++++----- world_volumes.c | 7 ++----- 5 files changed, 97 insertions(+), 23 deletions(-) diff --git a/bvh.h b/bvh.h index fa51c59..1997bed 100644 --- 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 --; diff --git a/world_entity.c b/world_entity.c index d431bed..db1d244 100644 --- a/world_entity.c +++ b/world_entity.c @@ -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 */ diff --git a/world_entity.h b/world_entity.h index 3baaa23..eca698a 100644 --- a/world_entity.h +++ b/world_entity.h @@ -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 diff --git a/world_render.c b/world_render.c index 3693a28..a33d774 100644 --- a/world_render.c +++ b/world_render.c @@ -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; ient_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 } ); diff --git a/world_volumes.c b/world_volumes.c index 2f0569d..dac790e 100644 --- a/world_volumes.c +++ b/world_volumes.c @@ -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 ) ){ -- 2.25.1