organize world modules
authorhgn <hgodden00@gmail.com>
Sun, 11 Jun 2023 06:00:58 +0000 (07:00 +0100)
committerhgn <hgodden00@gmail.com>
Sun, 11 Jun 2023 06:00:58 +0000 (07:00 +0100)
world.c
world_render.c
world_sfd.c
world_traffic.c [new file with mode: 0644]
world_volumes.c

diff --git a/world.c b/world.c
index 5cc7841641acfe46e91e686079431440694bade0..0183acbbd12997d4e3be23296e601bdad6b2c07d 100644 (file)
--- a/world.c
+++ b/world.c
@@ -14,36 +14,6 @@ static world_instance *world_current_instance(void){
 
 static void world_init(void)
 {
-   VG_VAR_F32( k_day_length );
-   VG_VAR_I32( k_debug_light_indices );
-   VG_VAR_I32( k_debug_light_complexity );
-   VG_VAR_I32( k_light_preview );
-
-   world_render.sky_rate = 1.0;
-   world_render.sky_target_rate = 1.0;
-
-   shader_scene_standard_register();
-   shader_scene_standard_alphatest_register();
-   shader_scene_vertex_blend_register();
-   shader_scene_terrain_register();
-   shader_scene_depth_register();
-   shader_scene_position_register();
-
-   shader_model_sky_register();
-
-   vg_info( "Loading world resources\n" );
-   
-   vg_linear_clear( vg_mem.scratch );
-
-   mdl_context msky;
-   mdl_open( &msky, "models/rs_skydome.mdl", vg_mem.scratch );
-   mdl_load_metadata_block( &msky, vg_mem.scratch );
-   mdl_async_load_glmesh( &msky, &world_render.skydome );
-   mdl_close( &msky );
-
-   /* Other systems */
-   vg_info( "Loading other world systems\n" );
-
    vg_loader_step( world_render_init, NULL );
    vg_loader_step( world_sfd_init, NULL );
    vg_loader_step( world_water_init, NULL );
@@ -67,6 +37,7 @@ static void world_init(void)
 #include "world_water.c"
 #include "world_audio.c"
 #include "world_routes.c"
+#include "world_traffic.c"
 
 VG_STATIC void world_update( world_instance *world, v3f pos )
 {
@@ -77,221 +48,9 @@ VG_STATIC void world_update( world_instance *world, v3f pos )
 
    world_routes_update_timer_texts( world );
    world_routes_update( world );
-   //world_routes_debug( world );
-   
-   /* ---- traffic -------- */
-
-   for( u32 i=0; i<mdl_arrcount( &world->ent_traffic ); i++ ){
-      ent_traffic *traffic = mdl_arritm( &world->ent_traffic, i );
-      
-      u32 i1 = traffic->index,
-          i0,
-          i2 = i1+1;
-
-      if( i1 == 0 ) i0 = traffic->node_count-1;
-      else i0 = i1-1;
-
-      if( i2 >= traffic->node_count ) i2 = 0;
-
-      i0 += traffic->start_node;
-      i1 += traffic->start_node;
-      i2 += traffic->start_node;
-      
-      v3f h[3];
-
-      ent_route_node *rn0 = mdl_arritm( &world->ent_route_node, i0 ),
-                     *rn1 = mdl_arritm( &world->ent_route_node, i1 ),
-                     *rn2 = mdl_arritm( &world->ent_route_node, i2 );
-
-      v3_copy( rn1->co, h[1] );
-      v3_lerp( rn0->co, rn1->co, 0.5f, h[0] );
-      v3_lerp( rn1->co, rn2->co, 0.5f, h[2] );
-
-      float const k_sample_dist = 0.0025f;
-      v3f pc, pd;
-      eval_bezier3( h[0], h[1], h[2], traffic->t, pc );
-      eval_bezier3( h[0], h[1], h[2], traffic->t+k_sample_dist, pd );
-
-      v3f v0;
-      v3_sub( pd, pc, v0 );
-      float length = vg_maxf( 0.0001f, v3_length( v0 ) );
-      v3_muls( v0, 1.0f/length, v0 );
-
-      float mod = k_sample_dist / length;
-
-      traffic->t += traffic->speed * vg.time_delta * mod;
-
-      if( traffic->t > 1.0f ){
-         traffic->t -= 1.0f;
-
-         if( traffic->t > 1.0f ) traffic->t = 0.0f;
-
-         traffic->index ++;
-
-         if( traffic->index >= traffic->node_count ) 
-            traffic->index = 0;
-      }
-
-      v3_copy( pc, traffic->transform.co );
-
-      float a = atan2f( -v0[0], v0[2] );
-      q_axis_angle( traffic->transform.q, (v3f){0.0f,1.0f,0.0f}, -a );
-
-      vg_line_pt3( traffic->transform.co, 0.3f, VG__BLUE );
-   }
-
-   /* ---- SFD ------------ */
-   
-   if( mdl_arrcount( &world->ent_route ) ){
-      u32 closest = 0;
-      float min_dist = INFINITY;
-
-      for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
-         ent_route *route = mdl_arritm( &world->ent_route, i );
-         float dist = v3_dist2( route->board_transform[3], pos );
-
-         if( dist < min_dist ){
-            min_dist = dist;
-            closest = i;
-         }
-      }
-
-      if( (world_sfd.active_route_board != closest) || network_scores_updated )
-      {
-         network_scores_updated = 0;
-         world_sfd.active_route_board = closest;
-
-         ent_route *route = mdl_arritm( &world->ent_route, closest );
-         u32 id = route->official_track_id;
-
-         if( id != 0xffffffff ){
-            struct netmsg_board *local_board = 
-               &scoreboard_client_data.boards[id];
-
-            for( int i=0; i<13; i++ ){
-               sfd_encode( i, &local_board->data[27*i] );
-            }
-         }else{
-            sfd_encode( 0, mdl_pstr( &world->meta, route->pstr_name ) );
-            sfd_encode( 1, "No data" );
-         }
-      }
-   }
-   sfd_update();
-
-   /* volumes
-    * -------------------------------------------------------------------------
-    */
-
-   /* filter and check the existing ones 
-    * TODO: on change world, clear volumes list */
-   u32 j=0;
-   for( u32 i=0; i<world_static.active_trigger_volume_count; i++ ){
-      i32 idx = world_static.active_trigger_volumes[i];
-      ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
-
-      v3f local;
-      m4x3_mulv( volume->to_local, pos, local );
-      if( (fabsf(local[0]) <= 1.0f) &&
-          (fabsf(local[1]) <= 1.0f) &&
-          (fabsf(local[2]) <= 1.0f) )
-      {
-         world_static.active_trigger_volumes[ j ++ ] = idx;
-         boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
-         vg_line_boxf_transformed( volume->to_world, cube, 0xff00ccff );
-         /* triggr on stay ..... */
-      }
-      else{
-         /* trigger on exit...... */
-      }
-   }
-   world_static.active_trigger_volume_count = j;
-
-   static float random_accum = 0.0f;
-   random_accum += vg.time_delta;
-
-   u32 random_ticks = 0;
-
-   while( random_accum > 0.1f ){
-      random_accum -= 0.1f;
-      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] );
-
-   bh_iter it;
-   bh_iter_init_box( 0, &it, volume_proximity );
-   i32 idx;
-
-   while( bh_next( world->volume_bh, &it, &idx ) ){
-      ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
-
-      boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
-      
-      if( volume->type == k_volume_subtype_trigger ){
-         for( u32 i=0; i<world_static.active_trigger_volume_count; i++ )
-            if( world_static.active_trigger_volumes[i] == idx )
-               goto next_volume;
-
-         if( world_static.active_trigger_volume_count > 
-               vg_list_size(world_static.active_trigger_volumes) ) continue;
-
-         v3f local;
-         m4x3_mulv( volume->to_local, pos, local );
-
-         if( (fabsf(local[0]) <= 1.0f) &&
-             (fabsf(local[1]) <= 1.0f) &&
-             (fabsf(local[2]) <= 1.0f) )
-         {
-            ent_call basecall;
-            basecall.function = k_ent_function_trigger;
-            basecall.id = mdl_entity_id( k_ent_volume, idx );
-            basecall.data = NULL;
-
-            entity_call( world, &basecall );
-            world_static.active_trigger_volumes[ 
-               world_static.active_trigger_volume_count ++ ] = idx;
-         }
-         else
-            vg_line_boxf_transformed( volume->to_world, cube, 0xffcccccc );
-      }
-      else if( volume->type == k_volume_subtype_particle ){
-         vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff );
-
-         for( int j=0; j<random_ticks; j++ ){
-            ent_call basecall;
-            basecall.id = mdl_entity_id( k_ent_volume, idx );
-            basecall.data = NULL;
-
-            entity_call( world, &basecall );
-         }
-      }
-next_volume:;
-   }
-
-#if 0
-   if( k_debug_light_indices )
-   {
-      for( int i=0; i<world->light_count; i++ ){
-         struct world_light *light = &world->lights[i];
-         struct classtype_world_light *inf = light->inf;
-
-         u32 colour = 0xff000000;
-         u8 r = inf->colour[0] * 255.0f,
-            g = inf->colour[1] * 255.0f,
-            b = inf->colour[2] * 255.0f;
-
-         colour |= r;
-         colour |= g << 8;
-         colour |= b << 16;
-
-         vg_line_pt3( light->node->co, 0.25f, colour );
-      }
-   }
-#endif
+   world_traffic_update( world, pos );
+   world_sfd_update( world, pos );
+   world_volumes_update( world, pos );
 }
 
 #endif /* WORLD_C */
index 8255d5355b35ffa31bbc418d17851ad08c51ef3c..1c030a6b66f79a90165856589caaa6832fb49c54 100644 (file)
@@ -8,6 +8,17 @@
 #include "world.h"
 #include "world_render.h"
 
+static int ccmd_set_time( int argc, const char *argv[] ){
+   if( argc == 1 ){
+      world_instance *world = world_current_instance();
+      world->time = atof( argv[0] );
+   }
+   else {
+      vg_error( "Usage set_time <0-1.0>\n" );
+   }
+   return 0;
+}
+
 VG_STATIC void async_world_render_init( void *payload, u32 size )
 {
    vg_info( "Allocate uniform buffers\n" );
@@ -53,6 +64,15 @@ VG_STATIC void async_world_render_init( void *payload, u32 size )
 
 VG_STATIC void world_render_init(void)
 {
+   VG_VAR_F32( k_day_length );
+   VG_VAR_I32( k_debug_light_indices );
+   VG_VAR_I32( k_debug_light_complexity );
+   VG_VAR_I32( k_light_preview );
+   vg_console_reg_cmd( "set_time", ccmd_set_time, NULL );
+
+   world_render.sky_rate = 1.0;
+   world_render.sky_target_rate = 1.0;
+
    shader_scene_standard_register();
    shader_scene_standard_alphatest_register();
    shader_scene_vertex_blend_register();
@@ -61,6 +81,15 @@ VG_STATIC void world_render_init(void)
    shader_scene_position_register();
    shader_model_sky_register();
 
+   vg_info( "Loading world resources\n" );
+   vg_linear_clear( vg_mem.scratch );
+
+   mdl_context msky;
+   mdl_open( &msky, "models/rs_skydome.mdl", vg_mem.scratch );
+   mdl_load_metadata_block( &msky, vg_mem.scratch );
+   mdl_async_load_glmesh( &msky, &world_render.skydome );
+   mdl_close( &msky );
+
    vg_info( "Loading default world textures\n" );
    vg_tex2d_load_qoi_async_file( "textures/garbage.qoi", 
                                  VG_TEX2D_NEAREST|VG_TEX2D_REPEAT, 
@@ -423,7 +452,8 @@ VG_STATIC void render_world_gates( world_instance *world, camera *cam,
 
 VG_STATIC void world_prerender( world_instance *world )
 {
-   world->time += vg.time_delta * (1.0/(k_day_length*60.0));
+   f32 day_length = vg_maxf(0.1f, fabsf(k_day_length)) * vg_signf(k_day_length);
+   world->time += vg.time_delta * (1.0/(day_length*60.0));
 
    struct ub_world_lighting *state = &world->ub_lighting;
 
index 9fe2d68e76743060909b200e8ef97fc54152c0c3..a5ba3f6d82981fa6103fc51b2546a6118ef6f8e6 100644 (file)
@@ -59,8 +59,43 @@ VG_STATIC void sfd_encode( u32 row, const char *str )
    }
 }
 
-VG_STATIC void sfd_update(void)
-{
+VG_STATIC void world_sfd_update( world_instance *world, v3f pos ){
+   if( mdl_arrcount( &world->ent_route ) ){
+      u32 closest = 0;
+      float min_dist = INFINITY;
+
+      for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
+         ent_route *route = mdl_arritm( &world->ent_route, i );
+         float dist = v3_dist2( route->board_transform[3], pos );
+
+         if( dist < min_dist ){
+            min_dist = dist;
+            closest = i;
+         }
+      }
+
+      if( (world_sfd.active_route_board != closest) || network_scores_updated )
+      {
+         network_scores_updated = 0;
+         world_sfd.active_route_board = closest;
+
+         ent_route *route = mdl_arritm( &world->ent_route, closest );
+         u32 id = route->official_track_id;
+
+         if( id != 0xffffffff ){
+            struct netmsg_board *local_board = 
+               &scoreboard_client_data.boards[id];
+
+            for( int i=0; i<13; i++ ){
+               sfd_encode( i, &local_board->data[27*i] );
+            }
+         }else{
+            sfd_encode( 0, mdl_pstr( &world->meta, route->pstr_name ) );
+            sfd_encode( 1, "No data" );
+         }
+      }
+   }
+
    for( int i=0; i<world_sfd.w*world_sfd.h; i++ ){
       float *target = &world_sfd.buffer[i*2+0],
             *cur =    &world_sfd.buffer[i*2+1];
diff --git a/world_traffic.c b/world_traffic.c
new file mode 100644 (file)
index 0000000..dd8da07
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef WORLD_TRAFFIC_C
+#define WORLD_TRAFFIC_C
+
+#include "world.h"
+
+static void world_traffic_update( world_instance *world, v3f pos ){
+   for( u32 i=0; i<mdl_arrcount( &world->ent_traffic ); i++ ){
+      ent_traffic *traffic = mdl_arritm( &world->ent_traffic, i );
+      
+      u32 i1 = traffic->index,
+          i0,
+          i2 = i1+1;
+
+      if( i1 == 0 ) i0 = traffic->node_count-1;
+      else i0 = i1-1;
+
+      if( i2 >= traffic->node_count ) i2 = 0;
+
+      i0 += traffic->start_node;
+      i1 += traffic->start_node;
+      i2 += traffic->start_node;
+      
+      v3f h[3];
+
+      ent_route_node *rn0 = mdl_arritm( &world->ent_route_node, i0 ),
+                     *rn1 = mdl_arritm( &world->ent_route_node, i1 ),
+                     *rn2 = mdl_arritm( &world->ent_route_node, i2 );
+
+      v3_copy( rn1->co, h[1] );
+      v3_lerp( rn0->co, rn1->co, 0.5f, h[0] );
+      v3_lerp( rn1->co, rn2->co, 0.5f, h[2] );
+
+      float const k_sample_dist = 0.0025f;
+      v3f pc, pd;
+      eval_bezier3( h[0], h[1], h[2], traffic->t, pc );
+      eval_bezier3( h[0], h[1], h[2], traffic->t+k_sample_dist, pd );
+
+      v3f v0;
+      v3_sub( pd, pc, v0 );
+      float length = vg_maxf( 0.0001f, v3_length( v0 ) );
+      v3_muls( v0, 1.0f/length, v0 );
+
+      float mod = k_sample_dist / length;
+
+      traffic->t += traffic->speed * vg.time_delta * mod;
+
+      if( traffic->t > 1.0f ){
+         traffic->t -= 1.0f;
+
+         if( traffic->t > 1.0f ) traffic->t = 0.0f;
+
+         traffic->index ++;
+
+         if( traffic->index >= traffic->node_count ) 
+            traffic->index = 0;
+      }
+
+      v3_copy( pc, traffic->transform.co );
+
+      float a = atan2f( -v0[0], v0[2] );
+      q_axis_angle( traffic->transform.q, (v3f){0.0f,1.0f,0.0f}, -a );
+
+      vg_line_pt3( traffic->transform.co, 0.3f, VG__BLUE );
+   }
+}
+
+#endif /* WORLD_TRAFFIC_C */
index c08fe43155de12533c5e106b8779f72a6bfc9895..0cc1ed608929b03aaf094afd49ff4e4cba7cb5ac 100644 (file)
@@ -3,6 +3,96 @@
 
 #include "world_volumes.h"
 
+static void world_volumes_update( world_instance *world, v3f pos ){
+   /* filter and check the existing ones */
+   u32 j=0;
+   for( u32 i=0; i<world_static.active_trigger_volume_count; i++ ){
+      i32 idx = world_static.active_trigger_volumes[i];
+      ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
+
+      v3f local;
+      m4x3_mulv( volume->to_local, pos, local );
+      if( (fabsf(local[0]) <= 1.0f) &&
+          (fabsf(local[1]) <= 1.0f) &&
+          (fabsf(local[2]) <= 1.0f) )
+      {
+         world_static.active_trigger_volumes[ j ++ ] = idx;
+         boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
+         vg_line_boxf_transformed( volume->to_world, cube, 0xff00ccff );
+         /* triggr on stay ..... */
+      }
+      else{
+         /* trigger on exit...... */
+      }
+   }
+   world_static.active_trigger_volume_count = j;
+
+   static float random_accum = 0.0f;
+   random_accum += vg.time_delta;
+
+   u32 random_ticks = 0;
+
+   while( random_accum > 0.1f ){
+      random_accum -= 0.1f;
+      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] );
+
+   bh_iter it;
+   bh_iter_init_box( 0, &it, volume_proximity );
+   i32 idx;
+
+   while( bh_next( world->volume_bh, &it, &idx ) ){
+      ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
+
+      boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
+      
+      if( volume->type == k_volume_subtype_trigger ){
+         for( u32 i=0; i<world_static.active_trigger_volume_count; i++ )
+            if( world_static.active_trigger_volumes[i] == idx )
+               goto next_volume;
+
+         if( world_static.active_trigger_volume_count > 
+               vg_list_size(world_static.active_trigger_volumes) ) continue;
+
+         v3f local;
+         m4x3_mulv( volume->to_local, pos, local );
+
+         if( (fabsf(local[0]) <= 1.0f) &&
+             (fabsf(local[1]) <= 1.0f) &&
+             (fabsf(local[2]) <= 1.0f) )
+         {
+            ent_call basecall;
+            basecall.function = k_ent_function_trigger;
+            basecall.id = mdl_entity_id( k_ent_volume, idx );
+            basecall.data = NULL;
+
+            entity_call( world, &basecall );
+            world_static.active_trigger_volumes[ 
+               world_static.active_trigger_volume_count ++ ] = idx;
+         }
+         else
+            vg_line_boxf_transformed( volume->to_world, cube, 0xffcccccc );
+      }
+      else if( volume->type == k_volume_subtype_particle ){
+         vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff );
+
+         for( int j=0; j<random_ticks; j++ ){
+            ent_call basecall;
+            basecall.id = mdl_entity_id( k_ent_volume, idx );
+            basecall.data = NULL;
+
+            entity_call( world, &basecall );
+         }
+      }
+next_volume:;
+   }
+}
+
 /*
  * BVH implementation
  * ----------------------------------------------------------------------------