Merge branch 'master' of harrygodden.com:/home/carveJwlIkooP6JGAAIwe30JlM
authorhgn <hgodden00@gmail.com>
Sun, 10 Dec 2023 20:54:04 +0000 (20:54 +0000)
committerhgn <hgodden00@gmail.com>
Sun, 10 Dec 2023 20:54:04 +0000 (20:54 +0000)
33 files changed:
audio.h
bvh.h
ent_traffic.c [new file with mode: 0644]
ent_traffic.h [new file with mode: 0644]
entity.c
menu.h
particle.c
player.c
player_effects.c
player_ragdoll.c
player_remote.c
player_skate.c
player_walk.c
respawn.c [deleted file]
respawn.h [deleted file]
scene.h
skaterift.c
skaterift.h
sound_src/lf0.ogg [new file with mode: 0644]
sound_src/lf1.ogg [new file with mode: 0644]
sound_src/lf2.ogg [new file with mode: 0644]
sound_src/lf3.ogg [new file with mode: 0644]
world.c
world.h
world_audio.c
world_entity.c
world_gen.c
world_load.c
world_map.c [new file with mode: 0644]
world_map.h [new file with mode: 0644]
world_render.c
world_routes.c
world_traffic.c [deleted file]

diff --git a/audio.h b/audio.h
index 5e29a96c08fc6503981dc104f07b4e433e1933db..448906be07e9af05c101b3c07766578dc7612f4d 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -30,6 +30,14 @@ audio_clip audio_taps[] =
    { .path="sound/tap3.ogg" }
 };
 
+audio_clip audio_flips[] =
+{
+   { .path="sound/lf0.ogg" },
+   { .path="sound/lf1.ogg" },
+   { .path="sound/lf2.ogg" },
+   { .path="sound/lf3.ogg" },
+};
+
 audio_clip audio_hits[] =
 {
    { .path="sound/hit0.ogg" },
@@ -139,10 +147,56 @@ audio_clip audio_challenge[] = {
    { .path = "sound/objective_fail.ogg" }
 };
 
+struct air_synth_data {
+   f32 speed;
+
+   /* internal */
+   f32 t;
+   struct dsp_biquad lpf;
+   SDL_SpinLock sl;
+}
+static air_data;
+
+static void audio_air_synth_get_samples( void *_data, f32 *buf, u32 count ){
+   struct air_synth_data *data = _data;
+
+   SDL_AtomicLock( &data->sl );
+   f32 spd = data->speed;
+   SDL_AtomicUnlock( &data->sl );
+
+   f32 s0  = sinf(data->t*2.0f),
+       s1  = sinf(data->t*0.43f),
+       s2  = sinf(data->t*1.333f),
+       sm  = vg_clampf( data->speed / 45.0f, 0, 1 ),
+       ft  = (s0*s1*s2)*0.5f+0.5f,
+       f   = vg_lerpf( 200.0f, 1200.0f, sm*0.7f + ft*0.3f ),
+       vol = 0.25f * sm;
+
+   dsp_init_biquad_butterworth_lpf( &data->lpf, f );
+
+   for( u32 i=0; i<count; i ++ ){
+      f32 v = (vg_randf64(&vg_dsp.rand) * 2.0f - 1.0f) * vol;
+      v = dsp_biquad_process( &data->lpf, v );
+
+      buf[i*2+0] = v;
+      buf[i*2+1] = v;
+   }
+
+   data->t += (f32)(count)/44100.0f;
+};
+
+static audio_clip air_synth = {
+   .flags = k_audio_format_gen,
+   .size = 0,
+   .func = audio_air_synth_get_samples,
+   .data = &air_data
+};
+
 static void audio_init(void)
 {
    audio_clip_loadn( audio_board, vg_list_size(audio_board), NULL );
    audio_clip_loadn( audio_taps, vg_list_size(audio_taps), NULL );
+   audio_clip_loadn( audio_flips, vg_list_size(audio_flips), NULL );
    audio_clip_loadn( audio_hits, vg_list_size(audio_hits), NULL );
    audio_clip_loadn( audio_ambience, vg_list_size(audio_ambience), NULL );
    audio_clip_loadn( &audio_splash, 1, NULL );
@@ -166,6 +220,11 @@ static void audio_init(void)
    audio_lock();
    audio_set_lfo_wave( 0, k_lfo_polynomial_bipolar, 80.0f );
    audio_set_lfo_frequency( 0, 20.0f );
+
+   skaterift.aud_air = audio_get_first_idle_channel();
+   if( skaterift.aud_air ) 
+      audio_channel_init( skaterift.aud_air, &air_synth, 0 );
+
    audio_unlock();
 }
 
@@ -215,12 +274,13 @@ static void audio_ambient_sprites_update( world_instance *world, v3f co )
    
    if( sprite_type != k_audio_sprite_type_none ){
       if( sprite_type == k_audio_sprite_type_grass ){
-         audio_ambient_sprite_play( sprite_pos, &audio_grass[vg_randu32()%4] );
+         audio_ambient_sprite_play( sprite_pos, 
+                                    &audio_grass[vg_randu32(&vg.rand)%4] );
       }
       else if( sprite_type == k_audio_sprite_type_water ){
          if( world->water.enabled ){
             audio_ambient_sprite_play( sprite_pos, 
-                                       &audio_water[vg_randu32()%6] );
+                                       &audio_water[vg_randu32(&vg.rand)%6] );
          }
       }
    }
diff --git a/bvh.h b/bvh.h
index 945d3cbbe1c6f8d4963e28bac9fc93f61056fa62..b04c3de2b95f38342259a85d54386854ce295488 100644 (file)
--- a/bvh.h
+++ b/bvh.h
@@ -55,6 +55,7 @@ struct bh_tree{
 };
 
 struct bh_system{
+   u32 system_type;
    void  (*expand_bound)( void *user, boxf bound, u32 item_index );
    float (*item_centroid)( void *user, u32 item_index, int axis );
    void  (*item_closest)( void *user, u32 item_index, v3f point, v3f closest );
@@ -71,13 +72,20 @@ struct bh_system{
    int   (*cast_ray)( void *user, u32 index, v3f co, v3f dir, ray_hit *hit );
 };
 
+static float scene_bh_centroid( void *user, u32 item_index, int axis );
+static void scene_bh_swap( void *user, u32 ia, u32 ib );
+static void scene_bh_expand_bound( void *user, boxf bound, u32 item_index );
+
 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 );
+      if( bh->system->system_type == 0x1 )
+         scene_bh_expand_bound( bh->user, node->bbx, idx );
+      else
+         bh->system->expand_bound( bh->user, node->bbx, idx );
    }
 }
 
@@ -96,10 +104,13 @@ static void bh_subdivide( bh_tree *bh, u32 inode ){
 
    float split = node->bbx[0][axis] + extent[axis]*0.5f;
    float avg = 0.0;
-   for( u32 t=0; t<node->count; t++ )
-   {
+   for( u32 t=0; t<node->count; t++ ){
       u32 idx = node->start+t;
-      avg += bh->system->item_centroid( bh->user, idx, axis );
+
+      if( bh->system->system_type == 0x1 )
+         avg += scene_bh_centroid( bh->user, idx, axis );
+      else 
+         avg += bh->system->item_centroid( bh->user, idx, axis );
    }
    avg /= (float)node->count;
    split = avg;
@@ -109,10 +120,20 @@ static void bh_subdivide( bh_tree *bh, u32 inode ){
        j = i + node->count-1;
    
    while( i <= j ){
-      if( bh->system->item_centroid( bh->user, i, axis ) < split )
+      f32 centroid;
+      
+      if( bh->system->system_type == 0x1 )
+         centroid = scene_bh_centroid( bh->user, i, axis );
+      else
+         centroid = bh->system->item_centroid( bh->user, i, axis );
+
+      if( centroid < split )
          i ++;
       else{
-         bh->system->item_swap( bh->user, i, j );
+         if( bh->system->system_type == 0x1 )
+            scene_bh_swap( bh->user, i, j );
+         else
+            bh->system->item_swap( bh->user, i, j );
          j --;
       }
    }
diff --git a/ent_traffic.c b/ent_traffic.c
new file mode 100644 (file)
index 0000000..f7167f2
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef ENT_TRAFFIC_C
+#define ENT_TRAFFIC_C
+
+#include "world.h"
+
+static void ent_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_point( traffic->transform.co, 0.3f, VG__BLUE );
+   }
+}
+
+#endif /* ENT_TRAFFIC_C */
diff --git a/ent_traffic.h b/ent_traffic.h
new file mode 100644 (file)
index 0000000..bebee23
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef ENT_TRAFFIC_H
+#define ENT_TRAFFIC_H
+
+#include "world.h"
+static void ent_traffic_update( world_instance *world, v3f pos );
+
+#endif /* ENT_TRAFFIC_H */
index 59e9219abcfe58a7baaab9a574b19c5b83091b16..44b00df235f0f1d9e8ddc4d60f17390abd109c32 100644 (file)
--- a/entity.c
+++ b/entity.c
@@ -13,6 +13,7 @@
 #include "ent_portal.c"
 #include "ent_miniworld.c"
 #include "ent_region.c"
+#include "ent_traffic.c"
 
 typedef void (*fn_entity_call_handler)( world_instance *, ent_call *);
 
diff --git a/menu.h b/menu.h
index cb823b4ea6208a0291142717bc0cfa3ac2900e1e..ca7cec188289979a340f960bffe58bab16525cb6 100644 (file)
--- a/menu.h
+++ b/menu.h
@@ -9,7 +9,7 @@
 #include "audio.h"
 #include "input.h"
 #include "workshop.h"
-#include "respawn.h"
+#include "world_map.h"
 #include "gui.h"
 #include "ent_miniworld.h"
 
@@ -250,11 +250,9 @@ static void menu_trigger_item( ent_menuitem *item ){
       if( MDL_CONST_PSTREQ( &menu.model, q, "quit" ) ){
          vg.window_should_close = 1;
       }
-
       else if( MDL_CONST_PSTREQ( &menu.model, q, "map" ) ){
-
          menu_close();
-         respawn_begin_chooser();
+         world_map_enter();
       }
       else if( MDL_CONST_PSTREQ( &menu.model, q, "hub" ) ){
          if( world_static.active_instance == k_world_purpose_client ){
index 13cc5d423c2b364da639e4a06f8d86ed077101a7..d12a87a024e3db67de24a1134810655e884775d2 100644 (file)
@@ -22,7 +22,7 @@ static void particle_spawn_cone( particle_system *sys,
    v3_tangent_basis( dir, tx, ty );
 
    v3f rand;
-   vg_rand_cone( rand, angle );
+   vg_rand_cone( &vg.rand, rand, angle );
    v3_muls(          tx,  rand[0]*speed, p->v );
    v3_muladds( p->v, ty,  rand[1]*speed, p->v );
    v3_muladds( p->v, dir, rand[2]*speed, p->v );
index 07e5f306ac7f3e6163cf694f9e22bd6190cd8026..1d95c8b852e90ac00726d94df4dff9e0fa9586d7 100644 (file)
--- a/player.c
+++ b/player.c
 #include "ent_miniworld.h"
 #include "gui.h"
 
+#include "shaders/model_entity.h"
+#include "shaders/model_character_view.h"
+#include "shaders/model_board_view.h"
+
 static int localplayer_cmd_respawn( int argc, const char *argv[] ){
    ent_spawn *rp = NULL, *r;
    world_instance *world = world_current_instance();
@@ -35,7 +39,6 @@ static int localplayer_cmd_respawn( int argc, const char *argv[] ){
 static void player_init(void){
    for( u32 i=0; i<vg_list_size(player_subsystems); i++ ){
       struct player_subsystem_interface *sys = player_subsystems[i];
-
       if( sys->system_register ) sys->system_register();
    }
 
@@ -51,6 +54,10 @@ static void player_init(void){
    vg_console_reg_var( "cinema_fixed", &k_cinema_fixed, k_var_dtype_i32, 0 );
    vg_console_reg_var( "invert_y", &k_invert_y, 
                         k_var_dtype_i32, VG_VAR_PERSISTENT );
+
+   shader_model_character_view_register();
+   shader_model_board_view_register();
+   shader_model_entity_register();
 }
 
 static void player__debugtext( int size, const char *fmt, ... ){
@@ -110,6 +117,10 @@ static void player__update(void){
 static void player__post_update(void){
    if( player_subsystems[ localplayer.subsystem ]->post_update )
       player_subsystems[ localplayer.subsystem ]->post_update();
+
+   SDL_AtomicLock( &air_data.sl );
+   air_data.speed = v3_length( localplayer.rb.v );
+   SDL_AtomicUnlock( &air_data.sl );
 }
 
 /*
@@ -163,8 +174,6 @@ static void player__pass_gate( u32 id ){
 }
 
 static void player_apply_transport_to_cam( m4x3f transport ){
-   /* FIXME: Applies to skaterift.cam directly! */
-
    /* Pre-emptively edit the camera matrices so that the motion vectors 
     * are correct */
    m4x3f transport_i;
@@ -215,7 +224,7 @@ static void player__im_gui(void){
                                        [k_skaterift_replay]    = "replay",
                                        [k_skaterift_ent_focus] = "ent_focus",
                                        [k_skaterift_default]   = "default",
-                                       [k_skaterift_respawning]= "map"
+                                       [k_skaterift_world_map] = "world map"
                      } [skaterift.activity] );
    player__debugtext( 1, "time_rate: %.4f", skaterift.time_rate );
 
index 0092f19a0c3bbab18a1e5730755a2cf4887a8387..2bfc3bf3bcfcaad691c4ec16471a079a3e64eac1 100644 (file)
@@ -3,7 +3,7 @@
 
 static void effect_blink_apply( effect_blink *ef, player_pose *pose, f32 dt ){
    if( ef->t < 0.0f ){
-      ef->t = (1.0f-powf(vg_randf64(),4.0f))*4.0f;
+      ef->t = (1.0f-powf(vg_randf64(&vg.rand),4.0f))*4.0f;
       ef->l = 0.08f;
    }
 
@@ -17,7 +17,7 @@ static void effect_spark_apply( effect_spark *ef, v3f co, v3f v, f32 dt ){
    if( !ef->colour ) return;
 
    if( ef->t < 0.0f ){
-      ef->t = 0.05f+vg_randf64()*0.1f;
+      ef->t = 0.05f+vg_randf64(&vg.rand)*0.1f;
 
       v3f dir;
       v3_copy( v, dir );
index ac6e90240fc9fd3a6743dafa057b246777d86da5..f0a6f88c7b5de75bd31888f0fe70a699d6e7d72b 100644 (file)
@@ -436,7 +436,8 @@ static void player_ragdoll_iter( struct player_ragdoll *rd ){
    if( stress ){
       temp_filter = 20;
       audio_lock();
-      audio_oneshot_3d( &audio_hits[vg_randu32()%5], stress->co, 20.0f, 1.0f );
+      audio_oneshot_3d( &audio_hits[vg_randu32(&vg.rand)%5], 
+                        stress->co, 20.0f, 1.0f );
       audio_unlock();
    }
 }
index 2234c6dc994aa3f50b8fdc0cf217603762dd551a..e910170ca3f2d4462adc4a9d1b42811fe4bc39ff 100644 (file)
@@ -642,10 +642,12 @@ static int remote_players_randomize( int argc, const char *argv[] ){
    for( int i=0; i<NETWORK_MAX_PLAYERS; i ++ ){
       struct network_player *player = &netplayers.list[i];
 
-      player->active = (vg_randu32() & 0x1)? 2: 0;
-      player->isfriend = vg_randu32() & vg_randu32() & 0x1;
-      player->isblocked = vg_randu32() & vg_randu32() & vg_randu32() & 0x1;
-      player->world_match[ 0 ] = vg_randu32() & 0x1;
+      player->active = (vg_randu32(&vg.rand) & 0x1)? 2: 0;
+      player->isfriend = vg_randu32(&vg.rand) & vg_randu32(&vg.rand) & 0x1;
+      player->isblocked = vg_randu32(&vg.rand) & 
+                          vg_randu32(&vg.rand) & 
+                          vg_randu32(&vg.rand) & 0x1;
+      player->world_match[ 0 ] = vg_randu32(&vg.rand) & 0x1;
       player->world_match[ 1 ] = 0;
 
       if( player->world_match[0] )
@@ -654,20 +656,20 @@ static int remote_players_randomize( int argc, const char *argv[] ){
          player->active_world = NULL;
 
       for( int i=0; i<sizeof(player->username)-1; i ++ ){
-         player->username[i] = 'a' + (vg_randu32() % 30);
+         player->username[i] = 'a' + (vg_randu32(&vg.rand) % 30);
          player->username[i+1] = '\0';
 
-         if( (vg_randu32() % 8) == 3 )
+         if( (vg_randu32(&vg.rand) % 8) == 3 )
             break;
       }
 
       for( int i=0; i<3; i ++ ){
-         player->medals[i] = vg_randu32() % 3;
+         player->medals[i] = vg_randu32(&vg.rand) % 3;
       }
 
       v3f pos;
 
-      vg_rand_sphere( pos );
+      vg_rand_sphere( &vg.rand, pos );
       v3_muladds( localplayer.rb.co, pos, 100.0f,
                   netplayers.final_mtx[ i*localplayer.skeleton.bone_count][3] );
    }
index 1ad7231609e2f0dcc2b5abd1a2a94d9e03ce63b8..7f4bc37f741991deb72b99cca2495cfe0a2731af 100644 (file)
@@ -715,7 +715,7 @@ static void skate_apply_trick_model(void){
       if( v3_length2( state->trick_vel ) < 0.0001f )
          return;
 
-      int carry_on = player_skate_trick_input();
+      int carry_on = state->trick_type == player_skate_trick_input();
 
       /* we assume velocities share a common divisor, in which case the 
        * interval is the minimum value (if not zero) */
@@ -729,24 +729,29 @@ static void skate_apply_trick_model(void){
       }
 
       float interval = 1.0f / min_rate,
-            current  = floorf( state->trick_time / interval ),
-            next_end = (current+1.0f) * interval;
+            current  = floorf( state->trick_time ),
+            next_end = current+1.0f;
 
 
       /* integrate trick velocities */
       v3_muladds( state->trick_euler, state->trick_vel, k_rb_delta,
                   state->trick_euler );
 
-      if( !carry_on && (state->trick_time + k_rb_delta >= next_end) ){
+      if( !carry_on && (state->trick_time + k_rb_delta/interval >= next_end) ){
          state->trick_time = 0.0f;
          state->trick_euler[0] = roundf( state->trick_euler[0] );
          state->trick_euler[1] = roundf( state->trick_euler[1] );
          state->trick_euler[2] = roundf( state->trick_euler[2] );
          v3_copy( state->trick_vel, state->trick_residualv );
          v3_zero( state->trick_vel );
-      }
 
-      state->trick_time += k_rb_delta;
+         audio_lock();
+         audio_oneshot_3d( &audio_flips[vg_randu32(&vg.rand)%4], 
+               localplayer.rb.co, 40.0f, 1.0f );
+         audio_unlock();
+      }
+      else 
+         state->trick_time += k_rb_delta / interval;
    }
    else{
       if( (v3_length2(state->trick_vel) >= 0.0001f ) &&
@@ -1098,9 +1103,15 @@ static void player__skate_pre_update(void){
    if( state->activity <= k_skate_activity_air_to_grind ){
       enum trick_type trick = k_trick_type_none;
       if( (trick = player_skate_trick_input()) ){
-         if( (vg.time - state->jump_time) < 0.1f ){
+         if( state->trick_time == 0.0f ){
+            audio_lock();
+            audio_oneshot_3d( &audio_flips[vg_randu32(&vg.rand)%4], 
+                  localplayer.rb.co, 40.0f, 1.0f );
+            audio_unlock();
+         }
+
+         if( state->trick_time < 0.1f ){
             v3_zero( state->trick_vel );
-            state->trick_time = 0.0f;
 
             if( trick == k_trick_type_kickflip ){
                state->trick_vel[0] = 3.0f;
@@ -2629,7 +2640,8 @@ static void player__skate_im_gui(void){
                            state->trick_vel[0],
                            state->trick_vel[1],
                            state->trick_vel[2] );
-   player__debugtext( 1, "tricke: %.2f %.2f %.2f", 
+   player__debugtext( 1, "tricke: %.2fs %.2f %.2f %.2f", 
+                           state->trick_time,
                            state->trick_euler[0],
                            state->trick_euler[1],
                            state->trick_euler[2] );
@@ -2659,7 +2671,7 @@ static void player__skate_animate(void){
 
    float curspeed  = v3_length( localplayer.rb.v ),
          kickspeed = vg_clampf( curspeed*(1.0f/40.0f), 0.0f, 1.0f ),
-         kicks     = (vg_randf64()-0.5f)*2.0f*kickspeed,
+         kicks     = (vg_randf64(&vg.rand)-0.5f)*2.0f*kickspeed,
          sign      = vg_signf( kicks );
 
    animator->wobble[0] = vg_lerpf( animator->wobble[0], kicks*kicks*sign, 
@@ -2805,10 +2817,14 @@ static void player__skate_animate(void){
    animator->subslap = vg_lerpf( animator->subslap, slapm, 
                                  vg.time_delta*10.0f );
 
+#if 0
    f32 l = ((state->activity < k_skate_activity_ground) &&
              v3_length2(state->trick_vel) > 0.1f )? 1: 0;
    animator->trick_foot = vg_lerpf( animator->trick_foot, l, 
                                     8.4f*vg.time_delta );
+#endif
+
+   animator->trick_foot = vg_exp_impulse( state->trick_time, 5.0f );
 
    /* grab */
    v2f grab_input;
@@ -3052,15 +3068,18 @@ static void player__skate_pose( void *_animator, player_pose *pose ){
    kf_board->co[1]  += animator->slap * animator->subslap;
    kf_hip->co[1] += animator->slap * 0.25f;
 
+   /* kickflip and shuvit are in the wrong order for some reason */
    if( animator->trick_type == k_trick_type_kickflip ){
-      kf_foot_l->co[0] += animator->trick_foot * 0.2f;
+      kf_foot_l->co[0] += animator->trick_foot * 0.15f;
+      kf_foot_r->co[0] -= animator->trick_foot * 0.15f;
       kf_foot_l->co[1] -= animator->trick_foot * 0.18f;
+      kf_foot_r->co[1] -= animator->trick_foot * 0.18f;
    }
    else if( animator->trick_type == k_trick_type_shuvit ){
-      kf_foot_l->co[0] += animator->trick_foot * 0.1f;
-      kf_foot_r->co[0] -= animator->trick_foot * 0.15f;
+      kf_foot_l->co[0] += animator->trick_foot * 0.2f;
       kf_foot_l->co[1] -= animator->trick_foot * 0.18f;
-      kf_foot_r->co[1] -= animator->trick_foot * 0.18f;
+      kf_foot_r->co[0] -= animator->trick_foot * 0.1f;
+      kf_foot_r->co[1] += animator->trick_foot * 0.09f;
    }
    else if( animator->trick_type == k_trick_type_treflip ){
       kf_foot_l->co[0] += animator->trick_foot * 0.2f;
@@ -3292,16 +3311,20 @@ static void player__skate_sfx_oneshot( u8 id, v3f pos, f32 volume ){
    audio_lock();
 
    if( id == k_player_skate_soundeffect_jump ){
-      audio_oneshot_3d( &audio_jumps[vg_randu32()%2], pos, 40.0f, volume );
+      audio_oneshot_3d( &audio_jumps[vg_randu32(&vg.rand)%2], 
+                        pos, 40.0f, volume );
    }
    else if( id == k_player_skate_soundeffect_tap ){
-      audio_oneshot_3d( &audio_taps[vg_randu32()%4], pos, 40.0f, volume );
+      audio_oneshot_3d( &audio_taps[vg_randu32(&vg.rand)%4], 
+                        pos, 40.0f, volume );
    }
    else if( id == k_player_skate_soundeffect_land_good ){
-      audio_oneshot_3d( &audio_lands[vg_randu32()%3], pos, 40.0f, volume );
+      audio_oneshot_3d( &audio_lands[vg_randu32(&vg.rand)%3], 
+                        pos, 40.0f, volume );
    }
    else if( id == k_player_skate_soundeffect_land_bad ){
-      audio_oneshot_3d( &audio_lands[vg_randu32()%2+3], pos, 40.0f, volume );
+      audio_oneshot_3d( &audio_lands[vg_randu32(&vg.rand)%2+3], 
+                        pos, 40.0f, volume );
    }
    else if( id == k_player_skate_soundeffect_grind_metal ){
       audio_oneshot_3d( &audio_board[3], pos, 40.0f, volume );
index 717411c88476cdd7bd56f74f060e186c22cd005a..34ad072a8a5b5d9d27f1cf38dc174f1386cddd28 100644 (file)
@@ -711,20 +711,21 @@ static void player__walk_post_update(void){
       audio_lock();
       if( w->surface == k_surface_prop_concrete ){
          audio_oneshot_3d( 
-               &audio_footsteps[vg_randu32()%vg_list_size(audio_footsteps)], 
+               &audio_footsteps[vg_randu32(&vg.rand) % 
+                                 vg_list_size(audio_footsteps)], 
                localplayer.rb.co, 40.0f, 1.0f 
          );
       }
       else if( w->surface == k_surface_prop_grass ){
          audio_oneshot_3d( 
-           &audio_footsteps_grass[ vg_randu32()%
+           &audio_footsteps_grass[ vg_randu32(&vg.rand) %
                                     vg_list_size(audio_footsteps_grass)],
             localplayer.rb.co, 40.0f, 1.0f 
          );
       }
       else if( w->surface == k_surface_prop_wood ){
          audio_oneshot_3d( 
-           &audio_footsteps_wood[ vg_randu32()%
+           &audio_footsteps_wood[ vg_randu32(&vg.rand) %
                                     vg_list_size(audio_footsteps_wood)],
             localplayer.rb.co, 40.0f, 1.0f 
          );
diff --git a/respawn.c b/respawn.c
deleted file mode 100644 (file)
index d8c470a..0000000
--- a/respawn.c
+++ /dev/null
@@ -1,256 +0,0 @@
-#ifndef RESPAWN_C
-#define RESPAWN_C
-
-#if 1
-#include "respawn.h"
-#include "skaterift.h"
-#include "world.h"
-#include "input.h"
-#include "gui.h"
-#include "menu.h"
-#include "scene.h"
-
-static void respawn_chooser_get_dir( v3f dir ){
-   /* idk */
-   dir[0] = -sqrtf(0.5f);
-   dir[2] =  sqrtf(0.5f);
-   dir[1] =  1.0f;
-   v3_normalize(dir);
-}
-
-static void respawn_chooser_get_plane( v4f plane ){
-   world_instance *world = &world_static.instances[ respawn_chooser.world_id ];
-   f32 h = localplayer.rb.co[1];
-   if( respawn_chooser.world_id != world_static.active_instance )
-      h = (world->scene_geo.bbx[0][1] + world->scene_geo.bbx[1][1]) * 0.5f;
-
-   v4_copy( (v4f){0.0f,1.0f,0.0f,h}, plane );
-}
-
-static void respawn_world_to_plane_pos( v3f pos, v2f plane_pos ){
-   v3f dir;
-   respawn_chooser_get_dir( dir );
-   v3_negate(dir,dir);
-   v4f plane;
-   respawn_chooser_get_plane( plane );
-
-   v3f co;
-   f32 t = ray_plane( plane, pos, dir );
-   v3_muladds( pos, dir, t, co );
-   plane_pos[0] = co[0];
-   plane_pos[1] = co[2];
-}
-
-static void respawn_chooser_setworld( u32 next ){
-   world_instance *nw = &world_static.instances[next];
-   if( nw->status == k_world_status_loaded ){
-      respawn_chooser.world_id = next;
-
-      v3f target;
-      if( next == world_static.active_instance )
-         v3_copy( localplayer.rb.co, target );
-      else {
-         scene_context *sc = &nw->scene_geo;
-         v3_lerp( sc->bbx[0], sc->bbx[1], 0.5f, target );
-      }
-      respawn_world_to_plane_pos( target, respawn_chooser.plane_pos );
-   }
-}
-
-static void respawn_chooser_gohome(void){
-   respawn_chooser_setworld(0);
-   world_instance *world = &world_static.instances[ respawn_chooser.world_id ];
-   
-   const char **alias = respawn_homes[respawn_chooser.home_select];
-   ent_spawn *spawn = world_find_spawn_by_name( world, alias[0] );
-
-   if( spawn ){
-      respawn_world_to_plane_pos( spawn->transform.co, 
-                                  respawn_chooser.plane_pos );
-
-      gui_location_print_ccmd( 1, (const char *[]){ alias[1] } );
-   }
-   else
-      gui_location_print_ccmd( 1, (const char *[]){ "Invalid home ID" } );
-}
-
-static void respawn_map_draw_icon( camera *cam, 
-                                      enum gui_icon icon, v3f pos ){
-   v4f v;
-   v3_copy( pos, v );
-   v[3] = 1.0f;
-   m4x4_mulv( cam->mtx.pv, v, v );
-   v2_divs( v, v[3], v );
-
-   gui_draw_icon( icon, (v2f){ v[0]*0.5f+0.5f,v[1]*0.5f+0.5f }, 1.0f );
-}
-
-static void respawn_chooser_pre_update(void){
-   if( skaterift.activity != k_skaterift_respawning ) return;
-
-   if( button_down( k_srbind_mback ) ){
-      gui_helper_clear();
-      srinput.state = k_input_state_resume;
-      skaterift.activity = k_skaterift_menu;
-      menu.page = 0xffffffff;
-      menu_open_page( "Main Menu", k_ent_menuitem_stack_append );
-      return;
-   }
-
-   if( button_down( k_srbind_maccept ) ){
-      skaterift.activity = k_skaterift_default;
-      srinput.state = k_input_state_resume;
-
-      if( respawn_chooser.spawn ){
-         world_static.active_instance = respawn_chooser.world_id;
-         player__spawn( respawn_chooser.spawn );
-      }
-      return;
-   }
-
-   world_instance *world = &world_static.instances[ respawn_chooser.world_id ];
-   v3f *bbx = world->scene_geo.bbx;
-   f32 *pos = respawn_chooser.plane_pos;
-
-   v2f steer;
-   joystick_state( k_srjoystick_steer, steer );
-   v2_normalize_clamp( steer );
-
-   m2x2f rm;
-   m2x2_create_rotation( rm, -0.25f*VG_PIf );
-   m2x2_mulv( rm, steer, steer );
-
-   v2_muladds( pos, steer, vg.time_frame_delta * 200.0f, pos );
-   v2_minv( (v2f){ bbx[1][0], bbx[1][2] }, pos, pos );
-   v2_maxv( (v2f){ bbx[0][0], bbx[0][2] }, pos, pos );
-
-   /* update camera */
-   camera *cam = &respawn_chooser.cam;
-   v3f dir;
-   respawn_chooser_get_dir(dir);
-
-   v4f plane;
-   respawn_chooser_get_plane( plane );
-
-   v3f co = { pos[0], plane[3]*plane[1], pos[1] };
-   v3_muladds( co, dir, respawn_chooser.boom_dist, cam->pos );
-
-   vg_line_cross( co, VG__RED, 10.0f );
-
-   cam->angles[0] = 0.25f * VG_PIf;
-   cam->angles[1] = 0.25f * VG_PIf;
-   cam->farz = 5000.0f;
-   cam->nearz = 10.0f;
-   cam->fov = 40.0f;
-
-   camera_update_transform( cam );
-   camera_update_view( cam );
-   camera_update_projection( cam );
-   camera_finalize( cam );
-
-   /* pick spawn */
-   respawn_chooser.spawn = NULL;
-   f32 closest2 = INFINITY;
-
-   for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i++ ){
-      ent_spawn *spawn = mdl_arritm(&world->ent_spawn,i);
-
-      v4f v;
-      v3_copy( spawn->transform.co, v );
-      v[3] = 1.0f;
-      m4x4_mulv( cam->mtx.pv, v, v );
-      v2_divs( v, v[3], v );
-
-      f32 d2 = v2_length2(v);
-      if( d2 < closest2 ){
-         respawn_chooser.spawn = spawn;
-         closest2 = d2;
-      }
-   }
-
-   /* icons
-    * ---------------------*/
-   for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
-
-      enum gui_icon icon = k_gui_icon_exclaim_2d;
-      if( challenge->status )
-         icon = k_gui_icon_tick_2d;
-
-      respawn_map_draw_icon( cam, icon, challenge->transform.co );
-   }
-
-   for( u32 i=0; i<mdl_arrcount(&world->ent_skateshop); i++ ){
-      ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, i );
-      if( shop->type == k_skateshop_type_boardshop ){
-         respawn_map_draw_icon( cam, k_gui_icon_board, shop->transform.co );
-      }
-      else if( shop->type == k_skateshop_type_worldshop ){
-         respawn_map_draw_icon( cam, k_gui_icon_world, shop->transform.co );
-      }
-   }
-
-   for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
-      if( gate->flags & k_ent_gate_nonlocal ){
-         respawn_map_draw_icon( cam, k_gui_icon_rift, gate->co[0] );
-      }
-   }
-
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-      ent_route *route = mdl_arritm( &world->ent_route, i );
-
-      v4f colour;
-      v4_copy( route->colour, colour );
-      v3_muls( colour, 1.6666f, colour );
-      gui_icon_setcolour( colour );
-      respawn_map_draw_icon( cam, k_gui_icon_rift_run_2d, 
-                             route->board_transform[3] );
-   }
-}
-
-static void respawn_begin_chooser(void){
-   skaterift.activity = k_skaterift_respawning;
-   respawn_chooser.world_id = world_static.active_instance;
-
-   world_instance *world = &world_static.instances[ respawn_chooser.world_id ];
-   v3f *bbx = world->scene_geo.bbx;
-
-   respawn_world_to_plane_pos( localplayer.rb.co, respawn_chooser.plane_pos );
-   respawn_chooser.boom_dist = 400.0f;
-   respawn_chooser.home_select = 0;
-
-   gui_helper_clear();
-
-   vg_str text;
-   if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text ) )
-      vg_strcat( &text, "move" );
-
-   if( gui_new_helper( input_button_list[k_srbind_maccept], &text ) )
-      vg_strcat( &text, "spawn" );
-
-   if( gui_new_helper( input_button_list[k_srbind_mback], &text ) )
-      vg_strcat( &text, "exit" );
-}
-
-#if 0
-static void respawn_chooser_shader_uniforms(void){
-   v4f uPlayerPos, uSpawnPos;
-   v4_zero( uPlayerPos );
-   v4_zero( uSpawnPos );
-
-   v3_copy( localplayer.rb.co, uPlayerPos );
-   
-   if( respawn_chooser.spawn )
-      v3_copy( respawn_chooser.spawn->transform.co, uSpawnPos );
-
-   uPlayerPos[3] = v3_dist(uPlayerPos,uSpawnPos);
-   uSpawnPos[3] = 1.0f/uPlayerPos[3];
-
-   shader_scene_override_uPlayerPos( uPlayerPos );
-   shader_scene_override_uSpawnPos( uSpawnPos );
-}
-#endif
-#endif
-
-#endif /* RESPAWN_C */
diff --git a/respawn.h b/respawn.h
deleted file mode 100644 (file)
index fed65fd..0000000
--- a/respawn.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef RESPAWN_H
-#define RESPAWN_H
-
-#include "skaterift.h"
-
-struct {
-   v2f plane_pos;
-   f32 boom_dist;
-   u32 world_id;
-   u32 home_select;
-
-   ent_spawn *spawn;
-   camera cam;
-}
-static respawn_chooser;
-
-static const char *respawn_homes[][2] = {
-   { "skateshop", "Skateshop" },
-   { "world_select", "World Selector" },
-};
-
-static void respawn_begin_chooser(void);
-static void respawn_chooser_shader_uniforms(void);
-
-#endif /* RESPAWN_H */
diff --git a/scene.h b/scene.h
index 8aaafe9239538035cc43c74d55491d2409209ac0..ba23ffbfa4efcc9183153d9cc55f976e0d442bf4 100644 (file)
--- a/scene.h
+++ b/scene.h
@@ -389,6 +389,7 @@ static bh_system bh_system_scene =
    .item_closest = scene_bh_closest,
    .item_swap = scene_bh_swap,
    .item_debug = scene_bh_debug,
+   .system_type = 0x1
 };
 
 /*
index 23b1db0311dd68a53079e491f714f16bd94d1983..e488f778f0cfa63e613b36bd39ee850a1e8b08e5 100644 (file)
  * =============================================================================
  */
 
-#if 1
-
 #define SR_NETWORKED
-#define SR_USE_LOCALHOST
+#define VG_AUDIO_FORCE_COMPRESSED
 
 #ifndef VG_RELEASE
  #define VG_DEVWINDOW
@@ -51,7 +49,7 @@
 #include "addon.c"
 #include "highscores.c"
 #include "save.c"
-#include "respawn.c"
+#include "world_map.c"
 #include "network.c"
 #include "player_remote.c"
 #include "vg/vg_audio_dsp.h"
@@ -114,13 +112,6 @@ vg_info("            '        ' '--' [] '----- '----- '     ' '---'  "
    vg_loader_step( network_init, network_end );
 }
 
-static void load_playermodels(void){
-   /* FIXME: hack */
-   shader_model_character_view_register();
-   shader_model_board_view_register();
-   shader_model_entity_register();
-}
-
 static void async_skaterift_player_start( void *payload, u32 size ){
    world_switch_instance(0);
 }
@@ -173,6 +164,38 @@ static addon_reg *skaterift_mount_world_unloadable( const char *path, u32 ext ){
    return reg;
 }
 
+static void skaterift_load_world_content(void){
+   /* hub world */
+   addon_reg *hub = skaterift_mount_world_unloadable( "maps/dev_hub", 0 );
+   skaterift_mount_world_unloadable( "maps/mp_spawn", 
+         ADDON_REG_CITY|ADDON_REG_PREMIUM );
+   skaterift_mount_world_unloadable( "maps/mp_mtzero", 
+         ADDON_REG_MTZERO|ADDON_REG_PREMIUM );
+   skaterift_mount_world_unloadable( "maps/dev_tutorial", 0 );
+
+   world_static.load_state = k_world_loader_load;
+
+   struct world_load_args args = {
+      .purpose = k_world_purpose_hub,
+      .reg = hub
+   };
+   skaterift_world_load_thread( &args );
+}
+
+static void skaterift_load_player_content(void){
+   u32 bytes = 1024*1024*10;
+   skaterift.replay.data = vg_linear_alloc( vg_mem.rtmemory, bytes );
+   skaterift.replay.size = bytes;
+   replay_clear( &skaterift.replay );
+
+   particle_alloc( &particles_grind, 300 );
+
+   player_load_animation_reference( "models/ch_none.mdl" );
+   player_model_load( &localplayer.fallback_model, "models/ch_none.mdl" );
+   player__bind();
+   player_board_load( &localplayer.fallback_board, "models/board_none.mdl" );
+}
+
 static void vg_load(void){
    if( k_tools_mode ){
       vg_async_call( async_call_ready, NULL, 0 );
@@ -199,23 +222,8 @@ static void vg_load(void){
    vg_loader_step( addon_system_init, NULL );
    vg_loader_step( workshop_init, NULL );
    vg_loader_step( skateshop_init, NULL );
-   
-   /* ----------------- */
-   vg_loader_step( load_playermodels, NULL );
   
-   /* player setup */
-   u32 bytes = 1024*1024*10;
-   skaterift.replay.data = vg_linear_alloc( vg_mem.rtmemory, bytes );
-   skaterift.replay.size = bytes;
-   replay_clear( &skaterift.replay );
-
-   particle_alloc( &particles_grind, 300 );
-
-   player_load_animation_reference( "models/ch_none.mdl" );
-   player_model_load( &localplayer.fallback_model, "models/ch_none.mdl" );
-   player__bind();
-
-   player_board_load( &localplayer.fallback_board, "models/board_none.mdl" );
+   vg_loader_step( skaterift_load_player_content, NULL );
 
    /* --------------------- */
 
@@ -228,23 +236,8 @@ static void vg_load(void){
     * -------------------------------------
     */
 
-   /* hub world */
-   addon_reg *hub = skaterift_mount_world_unloadable( "maps/dev_hub", 0 );
-   skaterift_mount_world_unloadable( "maps/mp_spawn", 
-         ADDON_REG_CITY|ADDON_REG_PREMIUM );
-   skaterift_mount_world_unloadable( "maps/mp_mtzero", 
-         ADDON_REG_MTZERO|ADDON_REG_PREMIUM );
-   skaterift_mount_world_unloadable( "maps/dev_tutorial", 0 );
-
    /* load home/permanent world manually */
-   world_static.load_state = k_world_loader_load;
-
-   struct world_load_args args = {
-      .purpose = k_world_purpose_hub,
-      .reg = hub
-   };
-   skaterift_world_load_thread( &args );
-
+   vg_loader_step( skaterift_load_world_content, NULL );
    vg_async_call( async_skaterift_player_start, NULL, 0 );
    vg_async_stall();
 
@@ -297,7 +290,7 @@ static void vg_pre_update(void){
    /* time rate */
    f32 target = 1;
    if( skaterift.activity & (k_skaterift_replay|k_skaterift_menu|
-                             k_skaterift_respawning) ){
+                             k_skaterift_world_map) ){
       target = 0;
    }
 
@@ -314,7 +307,7 @@ static void vg_pre_update(void){
 
    world_update( world_current_instance(), localplayer.rb.co );
    audio_ambient_sprites_update( world_current_instance(), localplayer.rb.co );
-   respawn_chooser_pre_update();
+   world_map_pre_update();
 }
 
 static void vg_fixed_update(void){
@@ -466,7 +459,7 @@ static void render_scene(void){
       }
    }
 
-   if( skaterift.activity == k_skaterift_respawning ){
+   if( skaterift.activity == k_skaterift_world_map ){
       world_instance *world = world_current_instance();
       glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } );
       
@@ -489,7 +482,7 @@ static void render_scene(void){
       m4x3f identity;
       m4x3_identity( identity );
       render_world_override( world, world, identity, &skaterift.cam, 
-                             respawn_chooser.spawn, 
+                             world_map.spawn, 
                              (v4f){world->tar_min, world->tar_max, 1.0f, 0.0f});
       render_world_routes( world, world, identity, &skaterift.cam, 0, 1 );
       return;
@@ -498,11 +491,6 @@ static void render_scene(void){
    world_instance *view_world = get_view_world();
    render_world( view_world, &skaterift.cam, 0, 0, 1, 1 );
 
-#if 0
-   particle_spawn( &particles_grind, localplayer.rb.co, 
-                  (v3f){vg_randf64()*2.0f,vg_randf64()*3.0f,vg_randf64()*2.0f}, 
-                  vg_randf64(), 0xff0000ff );
-#endif
    particle_system_update( &particles_grind, vg.time_delta );
    //particle_system_debug( &particles_grind );
    particle_system_prerender( &particles_grind );
@@ -564,8 +552,8 @@ static void skaterift_composite_maincamera(void){
    skaterift.cam.nearz = 0.1f;
    skaterift.cam.farz  = 2100.0f;
 
-   if( skaterift.activity == k_skaterift_respawning ){
-      camera_copy( &respawn_chooser.cam, &skaterift.cam );
+   if( skaterift.activity == k_skaterift_world_map ){
+      camera_copy( &world_map.cam, &skaterift.cam );
       skaterift.cam.nearz = 4.0f;
       skaterift.cam.farz = 3100.0f;
    }
@@ -576,12 +564,9 @@ static void skaterift_composite_maincamera(void){
       global_miniworld.t += s * dt;
 
       if( (global_miniworld.t > 1.0f) || (global_miniworld.t < 0.0f) ){
-         /* TODO: maybe next frame! */
          global_miniworld.t = vg_clampf( global_miniworld.t, 0.0f, 1.0f );
          global_miniworld.transition = 0;
       }
-      else {
-      }
    }
 
    camera_update_transform( &skaterift.cam );
@@ -604,7 +589,7 @@ static void render_main_game(void){
    skaterift_composite_maincamera();
 
    /* --------------------------------------------------------------------- */
-   if( skaterift.activity != k_skaterift_respawning ){
+   if( skaterift.activity != k_skaterift_world_map ){
       world_instance *world = world_current_instance();
       render_world_cubemaps( world );
 
@@ -631,7 +616,7 @@ static void render_main_game(void){
 
    /* continue with variable rate */
    if( !global_miniworld.transition && 
-         (skaterift.activity != k_skaterift_respawning) ){
+         (skaterift.activity != k_skaterift_world_map) ){
       render_fb_bind( gpipeline.fb_main, 1 );
       render_world_gates( get_view_world(), &skaterift.cam );
    }
@@ -694,7 +679,7 @@ static void vg_gui(void){
    render_view_framebuffer_ui();
    remote_player_network_imgui( vg.pv );
 
-   if( skaterift.activity == k_skaterift_respawning ){
+   if( skaterift.activity == k_skaterift_world_map ){
       remote_players_imgui_world( world_current_instance(), vg.pv, 2000.0f, 0 );
       remote_players_imgui_lobby();
    }
@@ -703,10 +688,3 @@ static void vg_gui(void){
       remote_players_imgui_world( world_current_instance(), vg.pv, 100.0f, 1 );
    }
 }
-
-
-#else
-
-#include "skaterift_imgui_dev.c"
-
-#endif
index 35ac9bfd7126ce3630e2b65622a17688abb4cace..f96d17c61b470fae836be8a9cdb2bf592d58bd90 100644 (file)
@@ -57,7 +57,7 @@ struct{
       k_skaterift_replay     = 0x01,
       k_skaterift_ent_focus  = 0x02,
       k_skaterift_menu       = 0x04,
-      k_skaterift_respawning = 0x08,
+      k_skaterift_world_map  = 0x08,
    }
    activity;
 
@@ -66,6 +66,8 @@ struct{
 
    u32 achievements;
    int demo_mode;
+
+   audio_channel *aud_air;
 }
 static skaterift = { 
    .op = k_async_op_clientloading, .time_rate = 1.0f, .demo_mode = 1 };
diff --git a/sound_src/lf0.ogg b/sound_src/lf0.ogg
new file mode 100644 (file)
index 0000000..e291439
Binary files /dev/null and b/sound_src/lf0.ogg differ
diff --git a/sound_src/lf1.ogg b/sound_src/lf1.ogg
new file mode 100644 (file)
index 0000000..d0ea026
Binary files /dev/null and b/sound_src/lf1.ogg differ
diff --git a/sound_src/lf2.ogg b/sound_src/lf2.ogg
new file mode 100644 (file)
index 0000000..03d3562
Binary files /dev/null and b/sound_src/lf2.ogg differ
diff --git a/sound_src/lf3.ogg b/sound_src/lf3.ogg
new file mode 100644 (file)
index 0000000..00f6e48
Binary files /dev/null and b/sound_src/lf3.ogg differ
diff --git a/world.c b/world.c
index f8d7168a1ca781a99c60fe1a733d2394035bedff..5a97d944b5f0bb6c79899765a636bab0398b450e 100644 (file)
--- a/world.c
+++ b/world.c
@@ -91,7 +91,6 @@ static void skaterift_world_get_save_path( enum world_purpose which,
 #include "world_water.c"
 #include "world_audio.c"
 #include "world_routes.c"
-#include "world_traffic.c"
 
 static void world_update( world_instance *world, v3f pos ){
    world_render.sky_time += world_render.sky_rate * vg.time_delta;
@@ -101,7 +100,7 @@ static void world_update( world_instance *world, v3f pos ){
 
    world_routes_update_timer_texts( world );
    world_routes_update( world );
-   world_traffic_update( world, pos );
+   ent_traffic_update( world, pos );
    world_sfd_update( world, pos );
    world_volumes_update( world, pos );
 }
diff --git a/world.h b/world.h
index 9d8cd4970dc8c037d98b30eb03ce5f4d48e844ff..642e7578b44a6d32ce042a36ba9be4ff2e4ca97e 100644 (file)
--- a/world.h
+++ b/world.h
@@ -58,6 +58,8 @@ static i32   k_debug_light_indices   = 0,
              k_debug_light_complexity= 0,
              k_light_preview         = 0;
 
+#define WORLD_SURFACE_HAS_TRAFFIC 0x1
+#define WORLD_SURFACE_HAS_PROPS   0x2
 
 struct world_instance {
    /* Fixed items
@@ -155,6 +157,7 @@ struct world_instance {
       mdl_material info;
       mdl_submesh sm_geo,
                   sm_no_collide;
+      u32 flags;
    }
    * surfaces;
    u32 surface_count;
index 1e902fad724f3581941a999b25d35dc159cb376e..0ecb6eb5d0c03443ff8ceeccc3cf778c0690d9c3 100644 (file)
@@ -30,11 +30,10 @@ static void world_fadeout_audio( world_instance *world )
  * Trace out a random point, near the player to try and determine water areas
  */
 static 
-enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output)
-{
-   v3f chance = { (vg_randf64()-0.5f) * 30.0f, 
-                  8.0f,
-                  (vg_randf64()-0.5f) * 30.0f };
+enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output){
+   v3f chance = { (vg_randf64(&vg.rand)-0.5f) * 30.0f, 
+                  8,
+                  (vg_randf64(&vg.rand)-0.5f) * 30.0f };
    
    v3f pos;
    v3_add( chance, origin, pos );
index 02bbeb2b342d26141ef52c4a674688106cc50732..ec7c2fe13426a5cbc0d773ef7711080bee0b0e80 100644 (file)
@@ -11,6 +11,7 @@
 #include "ent_challenge.h"
 #include "ent_skateshop.h"
 #include "ent_route.h"
+#include "ent_traffic.h"
 
 static void world_entity_focus( u32 entity_id ){
    localplayer.immobile = 1;
@@ -276,8 +277,7 @@ ent_spawn *world_find_spawn_by_name( world_instance *world, const char *name )
    return rp;
 }
 
-static void ent_volume_call( world_instance *world, ent_call *call )
-{
+static void ent_volume_call( world_instance *world, ent_call *call ){
    u32 index = mdl_entity_id_id( call->id );
    ent_volume *volume = mdl_arritm( &world->ent_volume, index );
    if( !volume->target ) return;
@@ -287,9 +287,9 @@ static void ent_volume_call( world_instance *world, ent_call *call )
 
       if( volume->flags & k_ent_volume_flag_particles ){
          float *co = alloca( sizeof(float)*3 );
-         co[0] = vg_randf64()*2.0f-1.0f;
-         co[1] = vg_randf64()*2.0f-1.0f;
-         co[2] = vg_randf64()*2.0f-1.0f;
+         co[0] = vg_randf64(&vg.rand)*2.0f-1.0f;
+         co[1] = vg_randf64(&vg.rand)*2.0f-1.0f;
+         co[2] = vg_randf64(&vg.rand)*2.0f-1.0f;
          m4x3_mulv( volume->to_world, co, co );
 
          call->function = k_ent_function_particle_spawn;
@@ -335,7 +335,7 @@ static void ent_audio_call( world_instance *world, ent_call *call ){
    else
       return;
 
-   float chance = vg_randf64()*100.0f,
+   float chance = vg_randf64(&vg.rand)*100.0f,
          bar = 0.0f;
 
    for( u32 i=0; i<audio->clip_count; i++ ){
index b94c689bc0d0246b2a79dc8b252e1b609f10ad01..e2ec14af8edd774ad28c7f441b624d3c66109d4c 100644 (file)
@@ -46,7 +46,7 @@ static void world_add_all_if_material( m4x3f transform, scene_context *scene,
  * |        |
  * |________|
  */
-static void world_gen_add_blob( world_instance *world,
+static void world_gen_add_blob( vg_rand *rand, world_instance *world,
                                    scene_context *scene, ray_hit *hit )
 {
    m4x3f transform;
@@ -57,7 +57,7 @@ static void world_gen_add_blob( world_instance *world,
 
    float angle = v3_dot(hit->normal,(v3f){0.0f,1.0f,0.0f});
    q_axis_angle( qsurface, axis, angle );
-   q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf64()*VG_TAUf );
+   q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf64(rand)*VG_TAUf );
    q_mul( qsurface, qrandom, qsurface );
    q_m3x3( qsurface, transform );
    v3_copy( hit->pos, transform[3] );
@@ -123,9 +123,10 @@ static void world_apply_procedural_foliage( world_instance *world,
    float area = volume[0]*volume[2];
    u32 particles = 0.08f * area;
 
-   /* TODO: Quasirandom? */
    vg_info( "Map area: %f. Max particles: %u\n", area, particles );
 
+   u64 t0 = SDL_GetPerformanceCounter();
+#if 0
    for( u32 i=0; i<particles; i++ ){
       v3f pos;
       v3_mul( volume, (v3f){ vg_randf64(), 1000.0f, vg_randf64() }, pos );
@@ -144,8 +145,52 @@ static void world_apply_procedural_foliage( world_instance *world,
          }
       }
    }
+#else
 
-   vg_info( "%d foliage models added\n", count );
+   vg_rand rand;
+   vg_rand_seed( &rand, 3030 );
+   
+   const f32 tile_scale = 16.0f;
+   v2i tiles = { volume[0]/tile_scale, volume[2]/tile_scale };
+
+   u32 per_tile = particles/(tiles[0]*tiles[1]);
+
+   for( i32 x=0; x<tiles[0]; x ++ ){
+      for( i32 z=0; z<tiles[1]; z ++ ){
+         for( u32 i=0; i<per_tile; i ++ ){
+            v3f co = { (f32)x+vg_randf64(&rand), 0, (f32)z+vg_randf64(&rand) };
+            v3_muls( co, tile_scale, co );
+            co[1] = 1000.0f;
+            v3_add( co, world->scene_geo.bbx[0], co );
+
+            ray_hit hit;
+            hit.dist = INFINITY;
+
+            if( ray_world( world, co, (v3f){0.0f,-1.0f,0.0f}, &hit, 
+                           k_material_flag_ghosts )){
+               struct world_surface *m1 = ray_hit_surface( world, &hit );
+               if((hit.normal[1] > 0.8f) && (m1 == mat) &&
+                  (hit.pos[1] > 0.0f+10.0f)){
+                  world_gen_add_blob( &rand, world, scene, &hit );
+                  count ++;
+               }
+            }
+
+         }
+      }
+   }
+
+#endif
+
+
+
+   u64 t1 = SDL_GetPerformanceCounter(),
+       utime_blobs = t1-t0,
+       ufreq = SDL_GetPerformanceFrequency();
+   f64 ftime_blobs = ((f64)utime_blobs / (f64)ufreq)*1000.0;
+
+   vg_info( "%d foliage models added. %f%% (%fms)\n", count, 
+            100.0*((f64)count/(f64)particles), ftime_blobs);
 }
 
 static 
@@ -272,6 +317,7 @@ static void world_gen_generate_meshes( world_instance *world ){
          mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
                                        vehc->submesh_start+j );
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
+         world->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_TRAFFIC;
       }
    }
 
@@ -317,6 +363,7 @@ static void world_gen_generate_meshes( world_instance *world ){
       for( u32 j=0; j<prop->submesh_count; j ++ ){
          mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
                                        prop->submesh_start+j );
+         world->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_PROPS;
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
       }
    }
@@ -713,8 +760,9 @@ static void world_gen_load_surfaces( world_instance *world ){
    memset( errmat, 0, sizeof(struct world_surface) );
                        
    for( u32 i=0; i<mdl_arrcount(&world->meta.materials); i++ ){
-      world->surfaces[i+1].info = 
-         *(mdl_material *)mdl_arritm( &world->meta.materials, i );
+      struct world_surface *surf = &world->surfaces[i+1];
+      surf->info = *(mdl_material *)mdl_arritm( &world->meta.materials, i );
+      surf->flags = 0;
    }
 }
 
index 5ab2dfb0793e80ce9e5670bd0b4e055fbba5ac83..b1363b7a9a056c9d55a29685e80bfb4b0c024350 100644 (file)
@@ -15,8 +15,6 @@
  * load the .mdl file located in path as a world instance
  */
 static void world_instance_load_mdl( u32 instance_id, const char *path ){
-   vg_rand_seed( 9001 );
-
    world_instance *world = &world_static.instances[ instance_id ];
    world_init_blank( world );
    world->status = k_world_status_loading;
@@ -98,16 +96,39 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
    world->time += (world->info.timezone/24.0);
 
    /* process resources from pack */
+   u64 t4 = SDL_GetPerformanceCounter();
    world_gen_load_surfaces( world );
+   u64 t5 = SDL_GetPerformanceCounter();
    world_gen_routes_ent_init( world );
    world_gen_entities_init( world );
+   u64 t6 = SDL_GetPerformanceCounter();
    
    /* main bulk */
+   u64 t0 = SDL_GetPerformanceCounter();
    world_gen_generate_meshes( world );
+   u64 t1 = SDL_GetPerformanceCounter();
    world_gen_routes_generate( instance_id );
+   u64 t2 = SDL_GetPerformanceCounter();
    world_gen_compute_light_indices( world );
+   u64 t3 = SDL_GetPerformanceCounter();
    mdl_close( meta );
 
+   u64 utime_mesh = t1-t0,
+       utime_route = t2-t1,
+       utime_indices = t3-t2,
+       utime_tex = t5-t4,
+       utime_ent = t6-t5,
+       ufreq = SDL_GetPerformanceFrequency();
+
+   f64 ftime_mesh = ((f64)utime_mesh / (f64)ufreq)*1000.0,
+       ftime_route = ((f64)utime_route / (f64)ufreq)*1000.0,
+       ftime_ind = ((f64)utime_route / (f64)ufreq)*1000.0,
+       ftime_tex = ((f64)utime_tex / (f64)ufreq)*1000.0,
+       ftime_ent = ((f64)utime_ent / (f64)ufreq)*1000.0;
+
+   vg_info( "wtime:mesh %.2fms route %.2fms ind %.2fms tex %.2fms ent %.2fms\n",
+               ftime_mesh, ftime_route, ftime_ind, ftime_tex, ftime_ent );
+
    /* init player position.
     *   - this is overriden by the save state when(if) it loads */
    ent_spawn *rp = world_find_spawn_by_name( world, "start" );
diff --git a/world_map.c b/world_map.c
new file mode 100644 (file)
index 0000000..e2fbe7a
--- /dev/null
@@ -0,0 +1,202 @@
+#ifndef RESPAWN_C
+#define RESPAWN_C
+
+#include "world_map.h"
+#include "skaterift.h"
+#include "world.h"
+#include "input.h"
+#include "gui.h"
+#include "menu.h"
+#include "scene.h"
+
+static void world_map_get_dir( v3f dir ){
+   /* idk */
+   dir[0] = -sqrtf(0.5f);
+   dir[2] =  sqrtf(0.5f);
+   dir[1] =  1.0f;
+   v3_normalize(dir);
+}
+
+static void world_map_get_plane( v4f plane ){
+   world_instance *world = &world_static.instances[ world_map.world_id ];
+   f32 h = localplayer.rb.co[1];
+   if( world_map.world_id != world_static.active_instance )
+      h = (world->scene_geo.bbx[0][1] + world->scene_geo.bbx[1][1]) * 0.5f;
+
+   v4_copy( (v4f){0.0f,1.0f,0.0f,h}, plane );
+}
+
+static void respawn_world_to_plane_pos( v3f pos, v2f plane_pos ){
+   v3f dir;
+   world_map_get_dir( dir );
+   v3_negate(dir,dir);
+   v4f plane;
+   world_map_get_plane( plane );
+
+   v3f co;
+   f32 t = ray_plane( plane, pos, dir );
+   v3_muladds( pos, dir, t, co );
+   plane_pos[0] = co[0];
+   plane_pos[1] = co[2];
+}
+
+static void respawn_map_draw_icon( camera *cam, 
+                                      enum gui_icon icon, v3f pos ){
+   v4f v;
+   v3_copy( pos, v );
+   v[3] = 1.0f;
+   m4x4_mulv( cam->mtx.pv, v, v );
+   v2_divs( v, v[3], v );
+
+   gui_draw_icon( icon, (v2f){ v[0]*0.5f+0.5f,v[1]*0.5f+0.5f }, 1.0f );
+}
+
+static void world_map_pre_update(void){
+   if( skaterift.activity != k_skaterift_world_map ) return;
+
+   if( button_down( k_srbind_mback ) ){
+      gui_helper_clear();
+      srinput.state = k_input_state_resume;
+      skaterift.activity = k_skaterift_menu;
+      menu.page = 0xffffffff;
+      menu_open_page( "Main Menu", k_ent_menuitem_stack_append );
+      return;
+   }
+
+   if( button_down( k_srbind_maccept ) ){
+      skaterift.activity = k_skaterift_default;
+      srinput.state = k_input_state_resume;
+
+      if( world_map.spawn ){
+         world_static.active_instance = world_map.world_id;
+         player__spawn( world_map.spawn );
+      }
+      return;
+   }
+
+   world_instance *world = &world_static.instances[ world_map.world_id ];
+   v3f *bbx = world->scene_geo.bbx;
+   f32 *pos = world_map.plane_pos;
+
+   v2f steer;
+   joystick_state( k_srjoystick_steer, steer );
+   v2_normalize_clamp( steer );
+
+   m2x2f rm;
+   m2x2_create_rotation( rm, -0.25f*VG_PIf );
+   m2x2_mulv( rm, steer, steer );
+
+   v2_muladds( pos, steer, vg.time_frame_delta * 200.0f, pos );
+   v2_minv( (v2f){ bbx[1][0], bbx[1][2] }, pos, pos );
+   v2_maxv( (v2f){ bbx[0][0], bbx[0][2] }, pos, pos );
+
+   /* update camera */
+   camera *cam = &world_map.cam;
+   v3f dir;
+   world_map_get_dir(dir);
+
+   v4f plane;
+   world_map_get_plane( plane );
+
+   v3f co = { pos[0], plane[3]*plane[1], pos[1] };
+   v3_muladds( co, dir, world_map.boom_dist, cam->pos );
+
+   vg_line_cross( co, VG__RED, 10.0f );
+
+   cam->angles[0] = 0.25f * VG_PIf;
+   cam->angles[1] = 0.25f * VG_PIf;
+   cam->farz = 5000.0f;
+   cam->nearz = 10.0f;
+   cam->fov = 40.0f;
+
+   camera_update_transform( cam );
+   camera_update_view( cam );
+   camera_update_projection( cam );
+   camera_finalize( cam );
+
+   /* pick spawn */
+   world_map.spawn = NULL;
+   f32 closest2 = INFINITY;
+
+   for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i++ ){
+      ent_spawn *spawn = mdl_arritm(&world->ent_spawn,i);
+
+      v4f v;
+      v3_copy( spawn->transform.co, v );
+      v[3] = 1.0f;
+      m4x4_mulv( cam->mtx.pv, v, v );
+      v2_divs( v, v[3], v );
+
+      f32 d2 = v2_length2(v);
+      if( d2 < closest2 ){
+         world_map.spawn = spawn;
+         closest2 = d2;
+      }
+   }
+
+   /* icons
+    * ---------------------*/
+   for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
+      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
+
+      enum gui_icon icon = k_gui_icon_exclaim_2d;
+      if( challenge->status )
+         icon = k_gui_icon_tick_2d;
+
+      respawn_map_draw_icon( cam, icon, challenge->transform.co );
+   }
+
+   for( u32 i=0; i<mdl_arrcount(&world->ent_skateshop); i++ ){
+      ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, i );
+      if( shop->type == k_skateshop_type_boardshop ){
+         respawn_map_draw_icon( cam, k_gui_icon_board, shop->transform.co );
+      }
+      else if( shop->type == k_skateshop_type_worldshop ){
+         respawn_map_draw_icon( cam, k_gui_icon_world, shop->transform.co );
+      }
+   }
+
+   for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
+      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
+      if( gate->flags & k_ent_gate_nonlocal ){
+         respawn_map_draw_icon( cam, k_gui_icon_rift, gate->co[0] );
+      }
+   }
+
+   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
+      ent_route *route = mdl_arritm( &world->ent_route, i );
+
+      v4f colour;
+      v4_copy( route->colour, colour );
+      v3_muls( colour, 1.6666f, colour );
+      gui_icon_setcolour( colour );
+      respawn_map_draw_icon( cam, k_gui_icon_rift_run_2d, 
+                             route->board_transform[3] );
+   }
+}
+
+static void world_map_enter(void){
+   skaterift.activity = k_skaterift_world_map;
+   world_map.world_id = world_static.active_instance;
+
+   world_instance *world = &world_static.instances[ world_map.world_id ];
+   v3f *bbx = world->scene_geo.bbx;
+
+   respawn_world_to_plane_pos( localplayer.rb.co, world_map.plane_pos );
+   world_map.boom_dist = 400.0f;
+   world_map.home_select = 0;
+
+   gui_helper_clear();
+
+   vg_str text;
+   if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text ) )
+      vg_strcat( &text, "move" );
+
+   if( gui_new_helper( input_button_list[k_srbind_maccept], &text ) )
+      vg_strcat( &text, "spawn" );
+
+   if( gui_new_helper( input_button_list[k_srbind_mback], &text ) )
+      vg_strcat( &text, "exit" );
+}
+
+#endif /* RESPAWN_C */
diff --git a/world_map.h b/world_map.h
new file mode 100644 (file)
index 0000000..4fbd6fc
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef RESPAWN_H
+#define RESPAWN_H
+
+#include "skaterift.h"
+
+struct {
+   v2f plane_pos;
+   f32 boom_dist;
+   u32 world_id;
+   u32 home_select;
+
+   ent_spawn *spawn;
+   camera cam;
+}
+static world_map;
+static void world_map_enter(void);
+
+#endif /* RESPAWN_H */
index 33814858c1eacc564be511b85718678b2bb6279e..613d3bffa6af21c473ff170938391b7357971624 100644 (file)
@@ -9,7 +9,7 @@
 #include "world_render.h"
 #include "font.h"
 #include "gui.h"
-#include "respawn.h"
+#include "world_map.h"
 #include "ent_miniworld.h"
 #include "player_remote.h"
 #include "ent_skateshop.h"
@@ -23,8 +23,7 @@ static int ccmd_set_time( int argc, const char *argv[] ){
    return 0;
 }
 
-static void async_world_render_init( void *payload, u32 size )
-{
+static void async_world_render_init( void *payload, u32 size ){
    vg_info( "Allocate uniform buffers\n" );
    for( int i=0; i<k_world_max; i++ ){
       world_instance *world = &world_static.instances[i];
@@ -66,8 +65,7 @@ static void async_world_render_init( void *payload, u32 size )
    }
 }
 
-static void world_render_init(void)
-{
+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 );
@@ -107,6 +105,10 @@ static void world_render_init(void)
    vg_async_call( async_world_render_init, NULL, 0 );
 }
 
+/* 
+ * standard uniform bindings
+ * ----------------------------------------------------------------------------
+ */
 static void world_link_lighting_ub( world_instance *world, GLuint shader ){
    GLuint idx = glGetUniformBlockIndex( shader, "ub_world_lighting" );   
    glUniformBlockBinding( shader, idx, world->ubo_bind_point );
@@ -135,17 +137,31 @@ static void world_bind_light_index( world_instance *world,
    glUniform1i( location, slot );
 }
 
-static void render_world_depth( world_instance *world, camera *cam );
-
-/*
- * Rendering
- */
-
 static void bind_terrain_noise(void){
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise );
 }
 
+/* 
+ * Get OpenGL texture name from texture ID.
+ */
+static GLuint world_get_texture( world_instance *world, u32 id ){
+   if( id & 0x80000000 ) return skaterift.rt_textures[id & ~0x80000000];
+   else                  return world->textures[ id ];
+}
+
+static void bindpoint_diffuse_texture1( world_instance *world,
+                                           struct world_surface *mat ){
+   glActiveTexture( GL_TEXTURE1 );
+   glBindTexture( GL_TEXTURE_2D, 
+                  world_get_texture(world,mat->info.tex_diffuse) );
+}
+
+/*
+ * Passes Rendering
+ * ----------------------------------------------------------------------------
+ */
+
 struct world_pass{
    camera *cam;
    enum mdl_shader shader;
@@ -158,82 +174,76 @@ struct world_pass{
    void (*fn_set_uNormalMtx)( m3x3f mnorm );
 };
 
-/* FIXME: we gotta do something about this crap, maybe batch lists. something..
- * anything but this. */
-static
-void world_render_props( world_instance *world, u32 material_id,
-                         struct world_pass *pass ){
-   if( !mdl_arrcount( &world->ent_prop ) ) return;
+static void render_world_depth( world_instance *world, camera *cam );
+
+/*
+ * Render a run of submeshes, only of those which match material_id
+ */
+static void world_render_submeshes( world_instance *world,
+                                    struct world_pass *pass, 
+                                    mdl_transform *transform, 
+                                    u32 start, u32 count, u32 material_id ){
+   for( u32 k=0; k<count; k++ ){
+      mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, start+k );
+      if( sm->material_id != material_id ) continue;
+
+      m4x3f mmdl;
+      mdl_transform_m4x3( transform, mmdl );
 
+      m4x4f m4mdl;
+      m4x3_expand( mmdl, m4mdl );
+      m4x4_mul( pass->cam->mtx_prev.pv, m4mdl, m4mdl );
+
+      pass->fn_set_mdl( mmdl );
+      pass->fn_set_uPvmPrev( m4mdl );
+
+      mdl_draw_submesh( sm );
+   }
+}
 
+/*
+ * Render props attached to this material
+ */
+static void world_render_props( world_instance *world, u32 material_id,
+                                struct world_pass *pass ){
    struct world_surface *mat = &world->surfaces[ material_id ];
+   if( !(mat->flags & WORLD_SURFACE_HAS_PROPS) ) return;
+
    pass->fn_bind_textures( world, mat );
 
    for( u32 j=0; j<mdl_arrcount( &world->ent_prop ); j++ ){
       ent_prop *prop = mdl_arritm( &world->ent_prop, j );
       if( prop->flags & 0x1 ) continue;
-      
-      for( u32 k=0; k<prop->submesh_count; k++ ){
-         mdl_submesh *sm = 
-            mdl_arritm( &world->meta.submeshs, prop->submesh_start+k );
-
-         if( sm->material_id != material_id ) continue;
-
-         m4x3f mmdl;
-         mdl_transform_m4x3( &prop->transform, mmdl );
-
-         m4x4f m4mdl;
-         m4x3_expand( mmdl, m4mdl );
-         m4x4_mul( pass->cam->mtx_prev.pv, m4mdl, m4mdl );
-
-         pass->fn_set_mdl( mmdl );
-         pass->fn_set_uPvmPrev( m4mdl );
 
-         mdl_draw_submesh( sm );
-      }
+      world_render_submeshes( world, pass, &prop->transform, 
+            prop->submesh_start, prop->submesh_count, material_id );
    }
 }
 
-static
-void world_render_traffic( world_instance *world, u32 material_id,
-                           struct world_pass *pass ){
-   if( !mdl_arrcount( &world->ent_traffic ) ) return;
-
-   /* HACK: use the first material for every traffic entity */
-   ent_traffic *first = mdl_arritm( &world->ent_traffic, 0 );
-   if( !first->submesh_count ) return;
-
-   mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, first->submesh_start );
-   if( sm->material_id != material_id ) return;
-
+/*
+ * Render traffic models attactched to this material
+ */
+static void world_render_traffic( world_instance *world, u32 material_id,
+                                  struct world_pass *pass ){
    struct world_surface *mat = &world->surfaces[ material_id ];
+   if( !(mat->flags & WORLD_SURFACE_HAS_TRAFFIC) ) return;
+
    pass->fn_bind_textures( world, mat );
 
    for( u32 j=0; j<mdl_arrcount( &world->ent_traffic ); j++ ){
       ent_traffic *traffic = mdl_arritm( &world->ent_traffic, j );
-      
-      for( u32 k=0; k<traffic->submesh_count; k++ ){
-         sm = mdl_arritm( &world->meta.submeshs, 
-                           traffic->submesh_start+k );
-
-         m4x3f mmdl;
-         q_m3x3( traffic->transform.q, mmdl );
-         v3_copy( traffic->transform.co, mmdl[3] );
-
-         m4x4f m4mdl;
-         m4x3_expand( mmdl, m4mdl );
-         m4x4_mul( pass->cam->mtx_prev.pv, m4mdl, m4mdl );
 
-         pass->fn_set_mdl( mmdl );
-         pass->fn_set_uPvmPrev( m4mdl );
-
-         mdl_draw_submesh( sm );
-      }
+      world_render_submeshes( world, pass, &traffic->transform,
+                              traffic->submesh_start, traffic->submesh_count,
+                              material_id );
    }
 }
 
-static 
-void world_render_pass( world_instance *world, struct world_pass *pass ){
+/*
+ * Iterate and render all materials which match the passes shader and geometry
+ * type. Includes props/traffic.
+ */
+static void world_render_pass( world_instance *world, struct world_pass *pass ){
    for( int i=0; i<world->surface_count; i++ ){
       struct world_surface *mat = &world->surfaces[i];
 
@@ -263,9 +273,13 @@ void world_render_pass( world_instance *world, struct world_pass *pass ){
    }
 }
 
-static 
-void world_render_both_stages( world_instance *world, struct world_pass *pass )
-{
+/*
+ * Specific shader instructions
+ * ----------------------------------------------------------------------------
+ */
+
+static void world_render_both_stages( world_instance *world, 
+                                      struct world_pass *pass ){
    mesh_bind( &world->mesh_geo );
    pass->geo_type = k_world_geo_type_solid;
    world_render_pass( world, pass );
@@ -277,51 +291,11 @@ void world_render_both_stages( world_instance *world, struct world_pass *pass )
    glEnable( GL_CULL_FACE );
 }
 
-static GLuint world_get_texture( world_instance *world, u32 id ){
-   if( id & 0x80000000 )
-      return skaterift.rt_textures[id & ~0x80000000];
-   else 
-      return world->textures[ id ];
-}
-
-static void bindpoint_diffuse_texture1( world_instance *world,
-                                           struct world_surface *mat ){
-   glActiveTexture( GL_TEXTURE1 );
-   glBindTexture( GL_TEXTURE_2D, 
-                  world_get_texture(world,mat->info.tex_diffuse) );
-}
-
-static void bindpoint_diffuse1_and_cubemap10( world_instance *world,
-                                                 struct world_surface *mat ){
-   glActiveTexture( GL_TEXTURE1 );
-   glBindTexture( GL_TEXTURE_2D, 
-                  world_get_texture(world,mat->info.tex_diffuse) );
-
-   u32 cubemap_id = mat->info.tex_none0,
-       cubemap_index = 0;
-
-   if( mdl_entity_id_type( cubemap_id ) == k_ent_cubemap ){
-      cubemap_index = mdl_entity_id_id( cubemap_id );
-   }
-
-   ent_cubemap *cm = mdl_arritm( &world->ent_cubemap, cubemap_index );
-   glActiveTexture( GL_TEXTURE10 );
-   glBindTexture( GL_TEXTURE_CUBE_MAP, cm->texture_id );
-
-   shader_scene_cubemapped_uColour( mat->info.colour );
-}
-
 static void render_world_vb( world_instance *world, camera *cam ){
    shader_scene_vertex_blend_use();
    shader_scene_vertex_blend_uTexGarbage(0);
    shader_scene_vertex_blend_uTexGradients(1);
-   world_link_lighting_ub( world, _shader_scene_vertex_blend.id );
-   world_bind_position_texture( world, _shader_scene_vertex_blend.id, 
-                                _uniform_scene_vertex_blend_g_world_depth, 2 );
-   world_bind_light_array( world, _shader_scene_vertex_blend.id,
-                                _uniform_scene_vertex_blend_uLightsArray, 3 );
-   world_bind_light_index( world, _shader_scene_vertex_blend.id,
-                                _uniform_scene_vertex_blend_uLightsIndex, 4 );
+   WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_vertex_blend );
 
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise );
@@ -345,14 +319,7 @@ static void world_shader_standard_bind( world_instance *world, camera *cam ){
    shader_scene_standard_uTexGarbage(0);
    shader_scene_standard_uTexMain(1);
    shader_scene_standard_uPv( cam->mtx.pv );
-
-   world_link_lighting_ub( world, _shader_scene_standard.id );
-   world_bind_position_texture( world, _shader_scene_standard.id, 
-                                _uniform_scene_standard_g_world_depth, 2 );
-   world_bind_light_array( world, _shader_scene_standard.id,
-                                _uniform_scene_standard_uLightsArray, 3 );
-   world_bind_light_index( world, _shader_scene_standard.id,
-                                _uniform_scene_standard_uLightsIndex, 4 );
+   WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_standard );
 
    bind_terrain_noise();
    shader_scene_standard_uCamera( cam->transform[3] );
@@ -371,6 +338,26 @@ static void render_world_standard( world_instance *world, camera *cam ){
    world_render_both_stages( world, &pass );
 }
 
+static void bindpoint_diffuse1_and_cubemap10( world_instance *world,
+                                                 struct world_surface *mat ){
+   glActiveTexture( GL_TEXTURE1 );
+   glBindTexture( GL_TEXTURE_2D, 
+                  world_get_texture(world,mat->info.tex_diffuse) );
+
+   u32 cubemap_id = mat->info.tex_none0,
+       cubemap_index = 0;
+
+   if( mdl_entity_id_type( cubemap_id ) == k_ent_cubemap ){
+      cubemap_index = mdl_entity_id_id( cubemap_id );
+   }
+
+   ent_cubemap *cm = mdl_arritm( &world->ent_cubemap, cubemap_index );
+   glActiveTexture( GL_TEXTURE10 );
+   glBindTexture( GL_TEXTURE_CUBE_MAP, cm->texture_id );
+
+   shader_scene_cubemapped_uColour( mat->info.colour );
+}
+
 static void render_world_cubemapped( world_instance *world, camera *cam,
                                      int enabled ){
    if( !mdl_arrcount( &world->ent_cubemap ) )
@@ -396,13 +383,7 @@ static void render_world_cubemapped( world_instance *world, camera *cam,
       shader_scene_cubemapped_uTexCubemap(10);
       shader_scene_cubemapped_uPv( cam->mtx.pv );
 
-      world_link_lighting_ub( world, _shader_scene_cubemapped.id );
-      world_bind_position_texture( world, _shader_scene_cubemapped.id, 
-                                   _uniform_scene_cubemapped_g_world_depth, 2 );
-      world_bind_light_array( world, _shader_scene_cubemapped.id,
-                                   _uniform_scene_cubemapped_uLightsArray, 3 );
-      world_bind_light_index( world, _shader_scene_cubemapped.id,
-                                   _uniform_scene_cubemapped_uLightsIndex, 4 );
+      WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_cubemapped );
 
       bind_terrain_noise();
       shader_scene_cubemapped_uCamera( cam->transform[3] );
@@ -425,20 +406,10 @@ static void render_world_alphatest( world_instance *world, camera *cam ){
    shader_scene_standard_alphatest_uTexMain(1);
    shader_scene_standard_alphatest_uPv( cam->mtx.pv );
 
-   world_link_lighting_ub( world, _shader_scene_standard_alphatest.id );
-   world_bind_position_texture( world, _shader_scene_standard_alphatest.id, 
-                        _uniform_scene_standard_alphatest_g_world_depth, 2 );
-   world_bind_light_array( world, _shader_scene_standard_alphatest.id,
-                        _uniform_scene_standard_alphatest_uLightsArray, 3 );
-   world_bind_light_index( world, _shader_scene_standard_alphatest.id,
-                           _uniform_scene_standard_alphatest_uLightsIndex, 4 );
-
+   WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_standard_alphatest );
 
    bind_terrain_noise();
-
-   
    shader_scene_standard_alphatest_uCamera( cam->transform[3] );
-
    glDisable(GL_CULL_FACE);
 
    struct world_pass pass = {
@@ -450,7 +421,6 @@ static void render_world_alphatest( world_instance *world, camera *cam ){
    };
 
    world_render_both_stages( world, &pass );
-
    glEnable(GL_CULL_FACE);
 }
 
@@ -646,14 +616,7 @@ static void render_world_fxglow( world_instance *host_world,
    shader_scene_fxglow_uUvOffset( (v2f){ 0.0f, 0.0f } );
    shader_scene_fxglow_uTexMain(1);
    shader_scene_fxglow_uPv( cam->mtx.pv );
-
-   world_link_lighting_ub( host_world, _shader_scene_fxglow.id );
-   world_bind_position_texture( host_world, _shader_scene_fxglow.id, 
-                        _uniform_scene_fxglow_g_world_depth, 2 );
-   world_bind_light_array( host_world, _shader_scene_fxglow.id,
-                        _uniform_scene_fxglow_uLightsArray, 3 );
-   world_bind_light_index( host_world, _shader_scene_fxglow.id,
-                           _uniform_scene_fxglow_uLightsIndex, 4 );
+   WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_fxglow );
 
    shader_scene_fxglow_uCamera( cam->transform[3] );
    glDisable(GL_CULL_FACE);
@@ -1027,10 +990,9 @@ static void render_world( world_instance *world, camera *cam,
 static void render_world_override_pass( world_instance *world,
                                         struct world_pass *pass,
                                         m4x3f mmdl, m3x3f mnormal,
-                                       m4x4f mpvm_prev ){
+                                        m4x4f mpvm_prev ){
    for( int i=0; i<world->surface_count; i++ ){
       struct world_surface *mat = &world->surfaces[i];
-
       if( mat->info.flags & k_material_flag_ghosts ) continue;
 
       mdl_submesh *sm;
@@ -1182,6 +1144,11 @@ static void render_world_cubemaps( world_instance *world ){
    }
 }
 
+/*
+ * Geo shaders
+ * ---------------------------------------------
+ */
+
 static void render_world_depth( world_instance *world, camera *cam ){
    m4x3f identity_matrix;
    m4x3_identity( identity_matrix );
index 2fe52a66367e61c76441c31b01295f64ada2610b..ca072e62985290569c6a7d780e2ed0b588efea99 100644 (file)
@@ -488,7 +488,6 @@ static void world_gen_routes_generate( u32 instance_id ){
    vg_info( "Generating route meshes\n" );
    vg_async_stall();
 
-   vg_rand_seed( 2000 );
    vg_async_item *call_scene = scene_alloc_async( &world->scene_lines, 
                                                   &world->mesh_route_lines,
                                                   200000, 300000 );
@@ -698,7 +697,7 @@ static void world_routes_fixedupdate( world_instance *world ){
    rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
 
    for( int i=0; i<rb_contact_count; i++ ){
-      rb_contact_restitution( rb_contact_buffer+i, vg_randf64() );
+      rb_contact_restitution( rb_contact_buffer+i, vg_randf64(&vg.rand) );
    }
 
    for( int i=0; i<6; i++ ){
@@ -882,13 +881,13 @@ static void world_routes_fracture( world_instance *world, ent_gate *gate,
             v3_muls( origin, -1.0f, particle->mlocal[3] );
 
             v3_copy( world_co, particle->obj.rb.co );
-            v3_muls( imp_v, 1.0f+vg_randf64(), particle->obj.rb.v );
+            v3_muls( imp_v, 1.0f+vg_randf64(&vg.rand), particle->obj.rb.v );
             particle->obj.rb.v[1] += 2.0f;
 
             v4_copy( q, particle->obj.rb.q );
-            particle->obj.rb.w[0] = vg_randf64()*2.0f-1.0f;
-            particle->obj.rb.w[1] = vg_randf64()*2.0f-1.0f;
-            particle->obj.rb.w[2] = vg_randf64()*2.0f-1.0f;
+            particle->obj.rb.w[0] = vg_randf64(&vg.rand)*2.0f-1.0f;
+            particle->obj.rb.w[1] = vg_randf64(&vg.rand)*2.0f-1.0f;
+            particle->obj.rb.w[2] = vg_randf64(&vg.rand)*2.0f-1.0f;
 
             particle->obj.type = k_rb_shape_sphere;
             particle->obj.inf.sphere.radius = r*0.6f;
diff --git a/world_traffic.c b/world_traffic.c
deleted file mode 100644 (file)
index 0083aae..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#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_point( traffic->transform.co, 0.3f, VG__BLUE );
-   }
-}
-
-#endif /* WORLD_TRAFFIC_C */