From: hgn Date: Mon, 27 Nov 2023 05:54:16 +0000 (+0000) Subject: sparks for player and remote blinking X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=71b7175073e0c764c3c5cb0c7ceee0f8cca09e58;p=carveJwlIkooP6JGAAIwe30JlM.git sparks for player and remote blinking --- diff --git a/ent_region.c b/ent_region.c index 720cb3c..026af35 100644 --- a/ent_region.c +++ b/ent_region.c @@ -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; ient_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; } } diff --git a/particle.c b/particle.c index 115c1fe..13cc5d4 100644 --- a/particle.c +++ b/particle.c @@ -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 ); diff --git a/particle.h b/particle.h index e4080be..14b2e66 100644 --- a/particle.h +++ b/particle.h @@ -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" diff --git a/player.h b/player.h index 1378ce8..18936a7 100644 --- 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 index 0000000..0092f19 --- /dev/null +++ b/player_effects.c @@ -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 index 0000000..ae0f95e --- /dev/null +++ b/player_effects.h @@ -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 */ diff --git a/player_remote.c b/player_remote.c index 07acd9a..9e46321 100644 --- a/player_remote.c +++ b/player_remote.c @@ -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) ); } diff --git a/player_remote.h b/player_remote.h index 5ba0105..4dfb2fa 100644 --- a/player_remote.h +++ b/player_remote.h @@ -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 ]; diff --git a/player_render.c b/player_render.c index 4793637..aed6caf 100644 --- a/player_render.c +++ b/player_render.c @@ -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 ) diff --git a/player_skate.c b/player_skate.c index 63315a8..e591d17 100644 --- a/player_skate.c +++ b/player_skate.c @@ -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 ){ diff --git a/player_skate.h b/player_skate.h index ba2cfce..c6a7860 100644 --- a/player_skate.h +++ b/player_skate.h @@ -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, diff --git a/skaterift.c b/skaterift.c index 14529f6..2152fb1 100644 --- a/skaterift.c +++ b/skaterift.c @@ -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 */