sparks for player and remote blinking
authorhgn <hgodden00@gmail.com>
Mon, 27 Nov 2023 05:54:16 +0000 (05:54 +0000)
committerhgn <hgodden00@gmail.com>
Mon, 27 Nov 2023 05:54:16 +0000 (05:54 +0000)
12 files changed:
ent_region.c
particle.c
particle.h
player.h
player_effects.c [new file with mode: 0644]
player_effects.h [new file with mode: 0644]
player_remote.c
player_remote.h
player_render.c
player_skate.c
player_skate.h
skaterift.c

index 720cb3c72a2ac369ce5099cded5e41f08c1b3892..026af35d89042fb24231232b354e2cee75c2c8a1 100644 (file)
@@ -29,12 +29,20 @@ static void ent_region_call( world_instance *world, ent_call *call ){
 
       gui_location_print_ccmd( 1, (const char *[]){
             mdl_pstr(&world->meta,region->pstr_title)} );
+
+      if( region->flags & k_ent_route_flag_achieve_gold )
+         localplayer.effect_data.spark.colour = 0xff8ce0fa;
+      else if( region->flags & k_ent_route_flag_achieve_silver )
+         localplayer.effect_data.spark.colour = 0xffc2c2c2;
+      else 
+         localplayer.effect_data.spark.colour = 0x00;
    }
    else if( call->function == 1 ){ /* leave */
       for( u32 i=0; i<mdl_arrcount(&world->ent_route); i ++ ){
          ent_route *route = mdl_arritm( &world->ent_route, i );
          route->flags |= k_ent_route_flag_out_of_zone;
       }
+      localplayer.effect_data.spark.colour = 0x00;
    }
 }
 
index 115c1fe1136f3e6a7dc9f6f896d6bbb35942bca4..13cc5d423c2b364da639e4a06f8d86ed077101a7 100644 (file)
@@ -11,6 +11,27 @@ static void particle_spawn( particle_system *sys,
    p->colour = colour;
 }
 
+static void particle_spawn_cone( particle_system *sys, 
+                                 v3f co, v3f dir, f32 angle, f32 speed, 
+                                 f32 lifetime, u32 colour ){
+   if( sys->alive == sys->max ) return;
+
+   particle *p = &sys->array[ sys->alive ++ ];
+
+   v3f tx, ty;
+   v3_tangent_basis( dir, tx, ty );
+
+   v3f rand;
+   vg_rand_cone( 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 );
+
+   p->life = lifetime;
+   p->colour = colour;
+   v3_copy( co, p->co );
+}
+
 static void particle_system_update( particle_system *sys, f32 dt ){
    u32 i = 0;
 iter: if( i == sys->alive ) return;
@@ -73,7 +94,7 @@ static void async_particle_init( void *payload, u32 size ){
    VG_CHECK_GL_ERR();
 }
 
-static void particle_init( particle_system *sys, u32 max ){
+static void particle_alloc( particle_system *sys, u32 max ){
    static int reg = 1;
    if( reg ){
       shader_particle_register();
@@ -82,11 +103,9 @@ static void particle_init( particle_system *sys, u32 max ){
 
    size_t stride = sizeof(particle_vert);
 
-   particles_grind.max = max;
-   particles_grind.array = 
-      vg_linear_alloc( vg_mem.rtmemory, max*sizeof(particle) );
-   particles_grind.vertices =
-      vg_linear_alloc( vg_mem.rtmemory, max*stride*4 );
+   sys->max = max;
+   sys->array = vg_linear_alloc( vg_mem.rtmemory, max*sizeof(particle) );
+   sys->vertices = vg_linear_alloc( vg_mem.rtmemory, max*stride*4 );
 
    vg_async_item *call = 
       vg_async_alloc( sizeof(particle_system *) + max*sizeof(u16)*6 );
@@ -112,10 +131,13 @@ static void particle_system_prerender( particle_system *sys ){
 
       v3f v, right;
       v3_copy( p->v, v );
-      v3_normalize( v );
+   
+      f32 vm = v3_length( p->v );
+      v3_muls( v, 1.0f/vm, v );
       v3_cross( v, (v3f){0,1,0}, right );
 
-      f32 l = 0.3f, w = 0.025f;
+      f32 l = (sys->scale+sys->velocity_scale*vm), 
+          w = sys->width;
 
       v3f p0, p1;
       v3_muladds( p->co, p->v,  l, p0 );
@@ -141,7 +163,7 @@ static void particle_system_prerender( particle_system *sys ){
 
 static void particle_system_render( particle_system *sys, camera *cam ){
    glDisable( GL_CULL_FACE );
-   glDisable( GL_DEPTH_TEST );
+   glEnable( GL_DEPTH_TEST );
 
    shader_particle_use();
    shader_particle_uPv( cam->mtx.pv );
index e4080be6c702e7ceeb45f7cded2f6087a1f7c981..14b2e66e94314199948a92a27d5013e6dc5797ca 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef PARTICLE_H
 #define PARTICLE_H
 
+#include "skaterift.h"
+
 typedef struct particle_system particle_system;
 typedef struct particle particle;
 typedef struct particle_vert particle_vert;
@@ -23,12 +25,27 @@ struct particle_system {
 
    u32 alive, max;
    GLuint vao, vbo, ebo;
+
+   /* render settings */
+   f32 scale, velocity_scale, width;
 }
-static particles_grind;
+static particles_grind = {
+   .scale = 0.02f,
+   .velocity_scale = 0.001f,
+   .width = 0.0125f
+};
+
+static void particle_alloc( particle_system *sys, u32 max );
+static void particle_system_update( particle_system *sys, f32 dt );
+static void particle_system_debug( particle_system *sys );
+static void particle_system_prerender( particle_system *sys );
+static void particle_system_render( particle_system *sys, camera *cam );
 
 static void particle_spawn( particle_system *sys, 
                             v3f co, v3f v, f32 lifetime, u32 colour );
-static void particle_init( particle_system *sys, u32 max );
+static void particle_spawn_cone( particle_system *sys, 
+                                 v3f co, v3f dir, f32 angle, f32 speed, 
+                                 f32 lifetime, u32 colour );
 
 #include "shaders/particle.h"
 
index 1378ce86ac0e88f3c9acd9790a6ec73a2297d559..18936a7ade2248844468cc7e182299c46ea14042 100644 (file)
--- a/player.h
+++ b/player.h
@@ -4,6 +4,7 @@
 #include "skaterift.h"
 #include "player_common.h"
 #include "network_compression.h"
+#include "player_effects.h"
 
 enum player_subsystem{
    k_player_subsystem_walk = 0,
@@ -43,6 +44,8 @@ struct player_subsystem_interface{
    void(*im_gui)(void);
    void(*animate)(void);
    void(*pose)( void *animator, player_pose *pose );
+   void(*effects)( void *animator, m4x3f *final_mtx, struct player_board *board,
+                   struct player_effects_data *effect_data );
    void(*post_animate)(void);
    void(*network_animator_exchange)( bitpack_ctx *ctx, void *data );
    void(*sfx_oneshot)( u8 id, v3f pos, f32 volume );
@@ -157,6 +160,8 @@ struct {
        id_wheel_r,
        id_board,
        id_eyes;
+
+   struct player_effects_data effect_data;
 }
 static localplayer = {
    .rb = {
diff --git a/player_effects.c b/player_effects.c
new file mode 100644 (file)
index 0000000..0092f19
--- /dev/null
@@ -0,0 +1,33 @@
+#include "player_effects.h"
+#include "particle.h"
+
+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->l = 0.08f;
+   }
+
+   pose->keyframes[ localplayer.id_eyes-1 ].s[1] = ef->l > 0.0f? 0.2f: 1.0f;
+
+   ef->t -= dt;
+   ef->l -= dt;
+}
+
+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;
+
+      v3f dir;
+      v3_copy( v, dir );
+      dir[1] += 1.0f;
+      f32 l = v3_length(dir);
+      v3_muls( dir, 1.0f/l, dir );
+
+      particle_spawn_cone( &particles_grind, co, dir, VG_PIf/2.0f, l, 
+                           4.0f, ef->colour );
+   }
+   else
+      ef->t -= dt;
+}
diff --git a/player_effects.h b/player_effects.h
new file mode 100644 (file)
index 0000000..ae0f95e
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef PLAYER_EFFECTS
+#define PLAYER_EFFECTS
+
+#include "skaterift.h"
+
+typedef struct effect_blink effect_blink;
+typedef struct effect_spark effect_spark;
+
+struct effect_blink {
+   f32 t, l;
+};
+
+struct effect_spark {
+   u32 colour;
+   f32 t;
+};
+
+static void effect_blink_apply( effect_blink *ef, player_pose *pose, f32 dt );
+static void effect_spark_apply( effect_spark *ef, v3f co, v3f v, f32 dt );
+
+struct player_effects_data {
+   effect_blink blink;
+   effect_spark spark;
+};
+
+#endif /* PLAYER_EFFECTS */
index 07acd9a947254455aea608959c96bfe38e4e659c..9e46321fc35e5ea6da930c0ab4977b6278050ab0 100644 (file)
@@ -445,6 +445,11 @@ static void remote_player_network_imgui( m4x4f pv ){
    }
 }
 
+static void remote_player_effect( struct network_player *player, 
+                                  player_pose *final_pose ){
+   /* effects */
+}
+
 /*
  * write the remote players final_mtx 
  */
@@ -462,6 +467,9 @@ static void pose_remote_player( u32 index,
    struct player_subsystem_interface *sys0 = player_subsystems[f0->subsystem],
                                      *sys1 = NULL;
 
+   struct player_board *board = 
+      addon_cache_item_if_loaded( k_addon_type_board, player->board_view_slot );
+
    player_pose pose0, pose1, posed;
    sys0->pose( &f0->data, &pose0 );
 
@@ -485,15 +493,28 @@ static void pose_remote_player( u32 index,
       }
 
       instance_id = f1->instance_id;
-
       lerp_player_pose( &pose0, &pose1, t, &posed );
+      effect_blink_apply( &player->effect_data.blink, &posed, vg.time_delta );
+
       apply_full_skeleton_pose( sk, &posed, final_mtx );
+
+      if( t < 0.5f ){
+         if( sys0->effects ) 
+            sys0->effects( &f0->data, final_mtx, board, &player->effect_data );
+      }
+      else{
+         if( sys1->effects ) 
+            sys1->effects( &f1->data, final_mtx, board, &player->effect_data );
+      }
+
       memcpy( board_pose, &posed.board, sizeof(*board_pose) );
    }
    else {
       instance_id = f0->instance_id;
-
+      effect_blink_apply( &player->effect_data.blink, &pose0, vg.time_delta );
       apply_full_skeleton_pose( sk, &pose0, final_mtx );
+      if( sys0->effects ) 
+         sys0->effects( &f0->data, final_mtx, board, &player->effect_data );
       memcpy( board_pose, &pose0.board, sizeof(*board_pose) );
    }
 
index 5ba0105277bacf456073da567a08c6b6b32be2f1..4dfb2fa36121863d73292f552faaab9b90c179ac 100644 (file)
@@ -4,6 +4,7 @@
 #include "player.h"
 #include "network.h"
 #include "network_common.h"
+#include "player_effects.h"
 
 #define NETWORK_SFX_QUEUE_LENGTH 12
 
@@ -31,6 +32,8 @@ struct {
 
       u32 down_bytes;
       f32 down_kbs;
+      
+      struct player_effects_data effect_data;
    }
    list[ NETWORK_MAX_PLAYERS ];
 
index 4793637bbda83e96f745fa8e0a7d9bd5981b8c38..aed6caf099359f9993c050344ebb1ef17c77a7c3 100644 (file)
@@ -201,6 +201,10 @@ static void player__animate(void){
    struct player_subsystem_interface *sys = 
       player_subsystems[localplayer.subsystem];
 
+   struct player_board *board = 
+      addon_cache_item_if_loaded( k_addon_type_board, 
+                                  localplayer.board_view_slot );
+
    assert( sys->animate );
    assert( sys->pose );
    assert( sys->animator_data );
@@ -225,20 +229,15 @@ static void player__animate(void){
       localplayer.holdout_time -= vg.time_frame_delta * 2.0f;
    }
 
-   static float blinkt = 1.0f,
-                blinkl = 0.0f;
-
-   if( blinkt < 0.0f ){
-      blinkt = (1.0f-powf(vg_randf64(),4.0f))*4.0f;
-      blinkl = 0.08f;
+   effect_blink_apply( &localplayer.effect_data.blink,
+                       &localplayer.pose, vg.time_delta );
+   apply_full_skeleton_pose( sk, &localplayer.pose, localplayer.final_mtx );
+   
+   if( sys->effects ){
+      sys->effects( sys->animator_data, localplayer.final_mtx, board,
+                    &localplayer.effect_data );
    }
 
-   pose->keyframes[ localplayer.id_eyes-1 ].s[1] = blinkl > 0.0f? 0.2f: 1.0f;
-
-   blinkt -= vg.time_delta;
-   blinkl -= vg.time_delta;
-
-   apply_full_skeleton_pose( sk, &localplayer.pose, localplayer.final_mtx );
    skeleton_debug( sk, localplayer.final_mtx );
 
    if( sys->post_animate )
index 63315a80d6830889219717348ff47c5641d9ef96..e591d171db98f6a3c46ee2e3d91855fa97e88914 100644 (file)
@@ -2716,6 +2716,7 @@ static void player__skate_animate(void){
 
    animator->grind_balance = vg_lerpf( animator->grind_balance, grind_frame, 
                                 5.0f*vg.time_delta );
+   animator->activity = state->activity;
 
    /* pushing */
    animator->push_time = vg.time - state->start_push;
@@ -2872,6 +2873,7 @@ static void player__skate_animate(void){
    }
    else q_identity( animator->qfixuptotal );
    rb_extrapolate( &localplayer.rb, animator->root_co, animator->root_q );
+   v3_copy( localplayer.rb.v, animator->root_v );
 }
                         
 static void player__skate_pose( void *_animator, player_pose *pose ){
@@ -3097,6 +3099,63 @@ static void player__skate_pose( void *_animator, player_pose *pose ){
    }
 }
 
+static void player__skate_effects( void *_animator, m4x3f *final_mtx,
+                                   struct player_board *board,
+                                   struct player_effects_data *effect_data ){
+
+   struct skeleton *sk = &localplayer.skeleton;
+   struct player_skate_animator *animator = _animator;
+
+   if( animator->grind > 0.5f ){
+      v3f vp0, vp1, vpc;
+      if( board ){
+         v3_copy((v3f){0.0f,0.02f, board->truck_positions[0][2]}, vp1 );
+         v3_copy((v3f){0.0f,0.02f, board->truck_positions[1][2]}, vp0 );
+      }
+      else{
+         v3_zero( vp0 );
+         v3_zero( vp1 );
+      }
+
+      v3f *board_mtx = final_mtx[ localplayer.id_board ];
+      m4x3_mulv( board_mtx, vp0, vp0 );
+      m4x3_mulv( board_mtx, vp1, vp1 );
+      v3_add( vp0, vp1, vpc );
+      v3_muls( vpc, 0.5f, vpc );
+
+      int back = 0, front = 0, mid = 0;
+
+      if( animator->activity == k_skate_activity_grind_5050 ){
+         back = 1;
+         front = 1;
+      }
+      else if( animator->activity == k_skate_activity_grind_back50 ){
+         back = 1;
+      }
+      else if( animator->activity == k_skate_activity_grind_front50 ){
+         front = 1;
+      }
+      else if( animator->activity == k_skate_activity_grind_boardslide ){
+         mid = 1;
+      }
+
+      if( back ){
+         effect_spark_apply( &effect_data->spark, vp0,
+                              animator->root_v, vg.time_delta );
+      }
+
+      if( front ){
+         effect_spark_apply( &effect_data->spark, vp1,
+                              animator->root_v, vg.time_delta );
+      }
+
+      if( mid ){
+         effect_spark_apply( &effect_data->spark, vpc,
+                              animator->root_v, vg.time_delta );
+      }
+   }
+}
+
 static void player__skate_post_animate(void){
    struct player_skate_state *state = &player_skate.state;
    localplayer.cam_velocity_influence = 1.0f;
@@ -3205,6 +3264,8 @@ static void player__skate_animator_exchange( bitpack_ctx *ctx, void *data ){
 
    bitpack_qf32( ctx, 16,  0.0f, 120.0f, &animator->push_time );
    bitpack_qf32( ctx, 16,  0.0f, 120.0f, &animator->jump_time );
+   bitpack_qv3f( ctx, 16, -100.0f, 100.0f, animator->root_v );
+   bitpack_bytes( ctx, 1, &animator->activity );
 }
 
 static void player__skate_sfx_oneshot( u8 id, v3f pos, f32 volume ){
index ba2cfcef65172b07a7a4457b383f375ee178894b..c6a7860833077d8845bed38b8c22063f688a0ddf 100644 (file)
@@ -82,6 +82,7 @@ struct player_skate{
    struct player_skate_animator {
       v3f root_co;
       v4f root_q;
+      v3f root_v;
 
       v3f offset,
           local_cog;
@@ -120,6 +121,7 @@ struct player_skate{
       f32 push_time, jump_time;
       u8 jump_dir;
       u8 trick_type;
+      u8 activity;
    }
    animator;
 
@@ -293,6 +295,9 @@ static void player__skate_post_update  (void);
 static void player__skate_im_gui       (void);
 static void player__skate_animate      (void);
 static void player__skate_pose         (void *animator, player_pose *pose);
+static void player__skate_effects( void *_animator, m4x3f *final_mtx,
+                                   struct player_board *board,
+                                   struct player_effects_data *effect_data );
 static void player__skate_post_animate (void);
 static void player__skate_animator_exchange( bitpack_ctx *ctx, void *data );
 static void player__skate_sfx_oneshot  ( u8 id, v3f pos, f32 volume );
@@ -310,6 +315,7 @@ struct player_subsystem_interface static player_subsystem_skate = {
    .im_gui = player__skate_im_gui,
    .animate = player__skate_animate,
    .pose = player__skate_pose,
+   .effects = player__skate_effects,
    .post_animate = player__skate_post_animate,
    .network_animator_exchange = player__skate_animator_exchange,
    .sfx_oneshot = player__skate_sfx_oneshot,
index 14529f67e0e3ea20bd447cad1c72124993e95304..2152fb1e65269db3a1047ad104de9284ab612691 100644 (file)
@@ -57,6 +57,7 @@
 #include "vg/vg_audio_dsp.h"
 #include "world_routes_ui.c"
 #include "particle.c"
+#include "player_effects.c"
 
 static int k_tools_mode = 0;
 
@@ -195,7 +196,7 @@ static void vg_load(void){
    skaterift.replay.size = bytes;
    replay_clear( &skaterift.replay );
 
-   particle_init( &particles_grind, 300 );
+   particle_alloc( &particles_grind, 300 );
 
    player_load_animation_reference( "models/ch_none.mdl" );
    player_model_load( &localplayer.fallback_model, "models/ch_none.mdl" );
@@ -479,15 +480,16 @@ 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 );
    particle_system_render( &particles_grind, &skaterift.cam );
 
-
    /* 
     * render transition 
     */