From: hgn Date: Fri, 15 Dec 2023 15:49:37 +0000 (+0000) Subject: handplants X-Git-Url: https://harrygodden.com/git/?p=carveJwlIkooP6JGAAIwe30JlM.git;a=commitdiff_plain;h=23897aeb79caa65b4c19de6c2f20f05bf3d86114 handplants --- diff --git a/input.h b/input.h index e93409b..9d10fbd 100644 --- a/input.h +++ b/input.h @@ -39,7 +39,7 @@ enum sr_bind{ k_srbind_miniworld_teleport, k_srbind_miniworld_resume, - + k_srbind_devbutton, k_srbind_max, }; @@ -116,6 +116,7 @@ static vg_input_op *input_button_list[] = { [k_srbind_miniworld_teleport]= INPUT_BASIC( SDLK_q, SDL_CONTROLLER_BUTTON_LEFTSHOULDER ), [k_srbind_skid] = (vg_input_op[]){ vg_keyboard, SDLK_LCTRL, vg_end }, +[k_srbind_devbutton] = (vg_input_op[]){ vg_keyboard, SDLK_3, vg_end }, [k_srbind_max]=NULL }; diff --git a/maps_src/dev_flatworld/main.mdl b/maps_src/dev_flatworld/main.mdl index e86aba5..7860b3f 100644 Binary files a/maps_src/dev_flatworld/main.mdl and b/maps_src/dev_flatworld/main.mdl differ diff --git a/models_src/ch_none.mdl b/models_src/ch_none.mdl index fa90273..1af0270 100644 Binary files a/models_src/ch_none.mdl and b/models_src/ch_none.mdl differ diff --git a/player.h b/player.h index 4396cbe..3a3d0f7 100644 --- a/player.h +++ b/player.h @@ -161,7 +161,8 @@ struct { id_wheel_l, id_wheel_r, id_board, - id_eyes; + id_eyes, + id_world; u8 skeleton_mirror[32]; diff --git a/player_render.c b/player_render.c index 5b9b3be..2636f80 100644 --- a/player_render.c +++ b/player_render.c @@ -28,6 +28,7 @@ static void player_load_animation_reference( const char *path ){ struct skeleton *sk = &localplayer.skeleton; skeleton_setup( sk, vg_mem.rtmemory, meta ); + localplayer.id_world = skeleton_bone_id( sk, "world" ); localplayer.id_hip = skeleton_bone_id( sk, "hips" ); localplayer.id_chest = skeleton_bone_id( sk, "chest" ); localplayer.id_ik_hand_l = skeleton_bone_id( sk, "hand.IK.L" ); @@ -540,4 +541,25 @@ static void player__render( camera *cam ){ SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); } +static void player_mirror_pose( mdl_keyframe pose[32], + mdl_keyframe mirrored[32] ){ + mdl_keyframe temp[32]; + + struct skeleton *sk = &localplayer.skeleton; + for( u32 i=1; ibone_count; i ++ ){ + mdl_keyframe *dest = &temp[i-1]; + u8 mapping = localplayer.skeleton_mirror[i]; + + if( mapping ) *dest = pose[mapping-1]; /* R */ + else *dest = pose[i-1]; /* L */ + + dest->co[2] *= -1.0f; + dest->q[0] *= -1.0f; + dest->q[1] *= -1.0f; + } + + for( u32 i=0; ibone_count-1; i ++ ){ + mirrored[i] = temp[i]; + } +} #endif /* PLAYER_RENDER_C */ diff --git a/player_render.h b/player_render.h index 21a53b7..02a1c6b 100644 --- a/player_render.h +++ b/player_render.h @@ -71,5 +71,7 @@ static void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose, m4x3f *final_mtx ); static void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t, player_pose *posed ); +static void player_mirror_pose( mdl_keyframe pose[32], + mdl_keyframe mirrored[32] ); #endif /* PLAYER_RENDER_H */ diff --git a/player_skate.c b/player_skate.c index dd0157b..72c2096 100644 --- a/player_skate.c +++ b/player_skate.c @@ -24,7 +24,8 @@ static void player__skate_bind(void){ { &player_skate.anim_push_reverse, "push_reverse" }, { &player_skate.anim_ollie, "ollie" }, { &player_skate.anim_ollie_reverse,"ollie_reverse" }, - { &player_skate.anim_grabs, "grabs" } + { &player_skate.anim_grabs, "grabs" }, + { &player_skate.anim_handplant, "handplant" } }; for( u32 i=0; i 0.6f ) return; + if( !( button_press(k_srbind_skid) || (fabsf(state->skid)>0.1f)) ) return; + + v3f lco = { 0.0f, -0.2f, -state->reverse }, + co, dir; + m4x3_mulv( localplayer.rb.to_world, lco, co ); + v3_muls( localplayer.rb.to_world[2], state->reverse, dir ); + vg_line_arrow( co, dir, 0.13f, 0xff000000 ); + + ray_hit hit = { .dist = 2.0f }; + if( ray_world( world_current_instance(), co, dir, + &hit, k_material_flag_ghosts )) { + vg_line( co, hit.pos, 0xff000000 ); + vg_line_point( hit.pos, 0.1f, 0xff000000 ); + + if( hit.normal[1] < 0.7f ) return; + if( hit.dist < 0.95f ) return; + + state->activity = k_skate_activity_handplant; + state->handplant_t = 0.0f; + v3_copy( localplayer.rb.co, state->store_co ); + v3_copy( localplayer.rb.v, state->air_init_v ); + v4_copy( localplayer.rb.q, state->store_q ); + v3_copy( state->cog, state->store_cog ); + v3_copy( state->cog_v, state->store_cog_v ); + v4_copy( state->smoothed_rotation, state->store_smoothed ); + } +} + static void skate_apply_pump_model(void){ struct player_skate_state *state = &player_skate.state; @@ -1113,6 +1146,61 @@ static enum trick_type player_skate_trick_input(void){ static void player__skate_pre_update(void){ struct player_skate_state *state = &player_skate.state; + if( state->activity == k_skate_activity_handplant ){ + state->handplant_t += vg.time_delta; + mdl_keyframe hpose[32]; + + int end = !skeleton_sample_anim_clamped( + &localplayer.skeleton, player_skate.anim_handplant, + state->handplant_t, hpose ); + + if( state->reverse < 0.0f ) + player_mirror_pose( hpose, hpose ); + + mdl_keyframe *kf_world = &hpose[ localplayer.id_world -1 ]; + m4x3f world, mmdl, world_view; + q_m3x3( kf_world->q, world ); + v3_copy( kf_world->co, world[3] ); + + /* original mtx */ + q_m3x3( state->store_q, mmdl ); + v3_copy( state->store_co, mmdl[3] ); + m4x3_mul( mmdl, world, world_view ); + + vg_line_arrow( world_view[3], world_view[0], 1.0f, 0xff0000ff ); + vg_line_arrow( world_view[3], world_view[1], 1.0f, 0xff00ff00 ); + vg_line_arrow( world_view[3], world_view[2], 1.0f, 0xffff0000 ); + + m4x3f invworld; + m4x3_invert_affine( world, invworld ); + m4x3_mul( mmdl, invworld, world_view ); + + v3_copy( world_view[3], localplayer.rb.co ); + m3x3_q( world_view, localplayer.rb.q ); + + /* new * old^-1 = transfer function */ + m4x3f transfer; + m4x3_invert_affine( mmdl, transfer ); + m4x3_mul( world_view, transfer, transfer ); + + m3x3_mulv( transfer, state->air_init_v, localplayer.rb.v ); + m3x3_mulv( transfer, state->store_cog_v, state->cog_v ); + m4x3_mulv( transfer, state->store_cog, state->cog ); + v3_muladds( state->cog, localplayer.rb.to_world[1], + -state->handplant_t*0.5f, state->cog ); + + v4f qtransfer; + m3x3_q( transfer, qtransfer ); + q_mul( qtransfer, state->store_smoothed, state->smoothed_rotation ); + q_normalize( state->smoothed_rotation ); + rb_update_transform( &localplayer.rb ); + + if( end ){ + state->activity = k_skate_activity_air; + } + else return; + } + if( button_down( k_srbind_use ) ){ localplayer.subsystem = k_player_subsystem_walk; @@ -2073,6 +2161,10 @@ static void player__skate_update(void){ struct player_skate_state *state = &player_skate.state; world_instance *world = world_current_instance(); + if( state->activity == k_skate_activity_handplant ){ + return; + } + if( world->water.enabled ){ if( localplayer.rb.co[1]+0.25f < world->water.height ){ player__networked_sfx( k_player_subsystem_walk, 32, @@ -2239,6 +2331,7 @@ grinding:; skate_adjust_up_direction(); skate_apply_cog_model(); skate_apply_jump_model(); + skate_apply_handplant_model(); skate_apply_grab_model(); skate_apply_trick_model(); skate_apply_pump_model(); @@ -2656,6 +2749,7 @@ static void player__skate_im_gui(void){ "air", "air_to_grind", "ground", + "handplant", "undefined (INVALID)", "grind_any (INVALID)", "grind_boardslide", @@ -2958,8 +3052,18 @@ static void player__skate_animate(void){ vg_line_arrow( localplayer.rb.co, p2, 0.5f, VG__PINK ); } else q_identity( animator->qfixuptotal ); - rb_extrapolate( &localplayer.rb, animator->root_co, animator->root_q ); - v3_copy( localplayer.rb.v, animator->root_v ); + + if( state->activity == k_skate_activity_handplant ){ + v3_copy( state->store_co, animator->root_co ); + v4_copy( state->store_q, animator->root_q ); + v3_zero( animator->root_v ); + } + else { + rb_extrapolate( &localplayer.rb, animator->root_co, animator->root_q ); + v3_copy( localplayer.rb.v, animator->root_v ); + } + + animator->handplant_t = state->handplant_t; } static void player__skate_pose( void *_animator, player_pose *pose ){ @@ -3010,24 +3114,8 @@ static void player__skate_pose( void *_animator, player_pose *pose ){ skeleton_sample_anim( sk, player_skate.anim_slide, slide_frame, bpose ); mdl_keyframe mirrored[32]; - for( u32 i=1; ibone_count; i ++ ){ - - mdl_keyframe *dest = &mirrored[i-1]; - u8 mapping = localplayer.skeleton_mirror[i]; - - if( mapping ) *dest = bpose[mapping-1]; /* R */ - else *dest = bpose[i-1]; /* L */ - - dest->co[2] *= -1.0f; - dest->q[0] *= -1.0f; - dest->q[1] *= -1.0f; - } + player_mirror_pose( bpose, mirrored ); skeleton_lerp_pose( sk, bpose, mirrored, animator->z, bpose ); - - - - - skeleton_lerp_pose( sk, apose, bpose, animator->slide, apose ); if( animator->reverse > 0.0f ){ @@ -3105,6 +3193,7 @@ static void player__skate_pose( void *_animator, player_pose *pose ){ pose->keyframes[apply_to[i]-1].co[2] += animator->offset[2]*add_grab_mod; } +#if 1 /* angle 'correction' */ v3f origin; v3_add( sk->bones[localplayer.id_hip].co, kf_hip->co, origin ); @@ -3114,6 +3203,48 @@ static void player__skate_pose( void *_animator, player_pose *pose ){ keyframe_rotate_around( kf, origin, sk->bones[apply_to[i]].co, animator->qfixuptotal ); } +#endif + + if( animator->activity == k_skate_activity_handplant ){ + mdl_keyframe hpose[32]; + skeleton_sample_anim_clamped( sk, player_skate.anim_handplant, + animator->handplant_t, hpose ); + if( animator->reverse < 0.0f ) + player_mirror_pose( hpose, hpose ); + + mdl_keyframe *kf_world = &hpose[ localplayer.id_world -1 ]; + m4x3f world, mmdl, world_view; + q_m3x3( kf_world->q, world ); + v3_copy( kf_world->co, world[3] ); + + q_m3x3( pose->root_q, mmdl ); + v3_copy( pose->root_co, mmdl[3] ); + + m4x3_mul( mmdl, world, world_view ); + + vg_line_arrow( world_view[3], world_view[0], 1.0f, 0xff0000ff ); + vg_line_arrow( world_view[3], world_view[1], 1.0f, 0xff00ff00 ); + vg_line_arrow( world_view[3], world_view[2], 1.0f, 0xffff0000 ); + + m4x3f invworld; + m4x3_invert_affine( world, invworld ); + m4x3_mul( mmdl, invworld, world_view ); + + m3x3_q( world_view, pose->root_q ); + v3_copy( world_view[3], pose->root_co ); + + f32 t = animator->handplant_t, + frames = player_skate.anim_handplant->length-1, + length = frames / player_skate.anim_handplant->rate, + end_dist = vg_minf( t, length - t )/k_anim_transition, + blend = vg_smoothstepf( vg_minf(1,end_dist) ); + + skeleton_lerp_pose( sk, pose->keyframes, hpose, blend, pose->keyframes ); + } + + + + /* trick rotation */ v4f qtrick, qyaw, qpitch, qroll; @@ -3175,7 +3306,8 @@ static void player__skate_pose( void *_animator, player_pose *pose ){ q_mul( q, kf_wheels[i]->q, kf_wheels[i]->q ); q_normalize( kf_wheels[i]->q ); } - + +#if 1 { mdl_keyframe *kf_head = &pose->keyframes[localplayer.id_head-1], @@ -3253,6 +3385,7 @@ static void player__skate_pose( void *_animator, player_pose *pose ){ sk->bones[skidders[i]].co, qskid ); } } +#endif } static void player__skate_effects( void *_animator, m4x3f *final_mtx, diff --git a/player_skate.h b/player_skate.h index 04978ae..269e552 100644 --- a/player_skate.h +++ b/player_skate.h @@ -12,6 +12,7 @@ struct player_skate{ k_skate_activity_air, k_skate_activity_air_to_grind, k_skate_activity_ground, + k_skate_activity_handplant, k_skate_activity_undefined, k_skate_activity_grind_any, k_skate_activity_grind_boardslide, @@ -80,6 +81,10 @@ struct player_skate{ v4f smoothed_rotation; f32 velocity_limit, grind_y_start, skid; + f32 handplant_t; + + v3f store_cog_v, store_cog, store_co; + v4f store_smoothed, store_q; } state; @@ -122,8 +127,9 @@ struct player_skate{ f32 jump_charge; - /* linear anims */ - f32 push_time, jump_time; + /* linear anims. TODO: we can union a bunch of variables here depending + * on activity. */ + f32 push_time, jump_time, handplant_t; u8 jump_dir; u8 trick_type; u8 activity; @@ -136,7 +142,8 @@ struct player_skate{ *anim_air, *anim_grind, *anim_grind_jump, *anim_push, *anim_push_reverse, *anim_ollie, *anim_ollie_reverse, - *anim_grabs, *anim_stop; + *anim_grabs, *anim_stop, + *anim_handplant; /* vectors representing the direction of the axels in localspace */ v3f truckv0[2]; @@ -262,7 +269,8 @@ static float k_board_end_radius = 0.1f, k_board_radius = 0.14f, /* 0.07 */ - k_grind_balance = -40.0f; + k_grind_balance = -40.0f, + k_anim_transition = 0.12f; static void player__skate_register(void){ VG_VAR_F32( k_grind_dampener, flags=VG_VAR_CHEAT ); @@ -291,6 +299,7 @@ static void player__skate_register(void){ VG_VAR_F32( k_mmcollect_vert, flags=VG_VAR_CHEAT ); VG_VAR_F32( k_mmdecay, flags=VG_VAR_CHEAT ); VG_VAR_F32( k_mmthrow_steer, flags=VG_VAR_CHEAT ); + VG_VAR_F32( k_anim_transition, flags=VG_VAR_CHEAT ); } static void player__skate_bind (void);