#include "audio.h"
#include "common.h"
#include "world.h"
-#include "character.h"
+//#include "character.h"
+#include "player_model.h"
#include "bvh.h"
/*
k_friction_lat = 8.8f,
k_friction_resistance = 0.01f,
k_max_push_speed = 16.0f,
- k_push_accel = 5.0f,
+ k_push_accel = 10.0f,
k_push_cycle_rate = 8.0f,
k_steer_ground = 2.5f,
k_steer_air = 3.6f,
k_steer_air_lerp = 0.3f,
k_pump_force = 000.0f,
- k_downforce = 5.0f;
+ k_downforce = 5.0f,
+ k_jump_charge_speed = (1.0f/1.0f),
+ k_jump_force = 5.0f;
static int freecam = 0;
static int walk_grid_iterations = 1;
+static float fc_speed = 10.0f;
static struct gplayer
{
v2f board_xy;
float grab;
float pitch;
-
+ float pushing, push_time;
+ float jump;
+ int jump_charge;
+
v3f land_target;
v3f land_target_log[22];
u32 land_target_colours[22];
v3f camera_pos, smooth_localcam;
v2f angles;
m4x3f camera, camera_inverse;
+
+ /* animation */
+ double jump_time;
+ float fslide,
+ fdirz, fdirx,
+ fstand,
+ ffly,
+ fpush,
+ fairdir,
+ fsetup;
}
player =
{
v2_sub( vg_mouse, mouse_last, delta );
v2_copy( vg_mouse, mouse_last );
- v2_muladds( view_vel, delta, 0.005f, view_vel );
+ v2_muladds( view_vel, delta, 0.001f, view_vel );
}
v2_muladds( view_vel,
(v2f){ vg_get_axis("h1"), vg_get_axis("v1") },
0.05f, view_vel );
- v2_muls( view_vel, 0.7f, view_vel );
+ v2_muls( view_vel, 0.93f, view_vel );
v2_add( view_vel, player.angles, player.angles );
player.angles[1] = vg_clampf( player.angles[1], -VG_PIf*0.5f, VG_PIf*0.5f );
}
{
player_mouseview();
- float movespeed = 25.0f;
+ float movespeed = fc_speed;
v3f lookdir = { 0.0f, 0.0f, -1.0f },
sidedir = { 1.0f, 0.0f, 0.0f };
player.in_air = 1;
float pstep = ktimestep*10.0f;
-
- float best_velocity_mod = 0.0f,
- best_velocity_delta = -9999.9f;
-
+ float best_velocity_delta = -9999.9f;
float k_bias = 0.96f;
v3f axis;
if( (land_delta < 0.0f) && (land_delta > best_velocity_delta) )
{
best_velocity_delta = land_delta;
- best_velocity_mod = vmod;
v3_copy( contact.pos, player.land_target );
if( vg_get_button_down( "push" ) )
start_push = vg_time;
+ if( vg_get_button( "jump" ) )
+ {
+ player.jump += ktimestep * k_jump_charge_speed;
+ player.jump_charge = 1;
+ }
+
if( !vg_get_button("break") && vg_get_button( "push" ) )
{
- float cycle_time = (vg_time-start_push)*k_push_cycle_rate,
+ player.pushing = 1.0f;
+ player.push_time = vg_time-start_push;
+
+ float cycle_time = player.push_time*k_push_cycle_rate,
amt = k_push_accel * (sinf(cycle_time)*0.5f+0.5f)*ktimestep,
current = v3_length( vel ),
new_vel = vg_minf( current + amt, k_max_push_speed );
+
new_vel -= vg_minf(current, k_max_push_speed);
vel[2] -= new_vel * player.reverse;
}
float grabt = vg_get_axis( "grabr" )*0.5f+0.5f;
player.grab = vg_lerpf( player.grab, grabt, 0.14f );
+ player.pushing = 0.0f;
if( !player.in_air )
{
v3_muladds( player.rb.v, player.rb.up,
-k_downforce*ktimestep, player.rb.v );
+
player_physics_control();
+
+ if( !player.jump_charge && player.jump > 0.2f )
+ {
+ v3_muladds( player.rb.v, player.rb.up, k_jump_force*player.jump,
+ player.rb.v );
+
+ player.jump_time = vg_time;
+ }
}
else
{
player_physics_control_air();
}
+
+ if( !player.jump_charge )
+ {
+ player.jump -= k_jump_charge_speed * ktimestep;
+ }
+ player.jump_charge = 0;
+ player.jump = vg_clampf( player.jump, 0.0f, 1.0f );
}
static void player_do_motion(void)
pa[0] = wg->region[0][0] + (float)wg->cell_id[0] *k_gridscale;
pa[1] = (wg->region[0][1] + wg->region[1][1]) * 0.5f + k_gridscale;
pa[2] = wg->region[0][2] + (float)wg->cell_id[1] *k_gridscale;
+#if 0
pb[0] = pa[0];
pb[1] = pa[1];
pb[2] = pa[2] + k_gridscale;
pd[0] = pa[0] + k_gridscale;
pd[1] = pa[1];
pd[2] = pa[2];
-#if 0
/* if you want to draw the current cell */
vg_line( pa, pb, 0xff00ffff );
vg_line( pb, pc, 0xff00ffff );
offset[0] = vg_clampf( offset[0], -0.8f, 0.8f );
offset[1] = vg_clampf( offset[1], -0.5f, 0.0f );
-
- /*
- * Player rotation
- */
-#if 0
- float angle = v3_dot( player.rb.up, (v3f){0.0f,1.0f,0.0f} );
- v3f axis;
- v3_cross( player.rb.up, (v3f){0.0f,1.0f,0.0f}, axis );
-
- v4f correction;
- if( angle < 0.99f && 0 )
- {
- m3x3_mulv( player.rb.to_local, axis, axis );
- q_axis_angle( correction, axis, acosf(angle) );
- }
- else
- {
- q_identity( correction );
- }
+ offset[1] = 0.0f;
/*
* Animation blending
* ===========================================
*/
-#endif
-
- static float fslide = 0.0f;
- static float fdirz = 0.0f;
- static float fdirx = 0.0f;
- static float fstand = 0.0f;
- static float ffly = 0.0f;
+ /* scalar blending information */
float speed = v3_length( player.rb.v );
- fstand = vg_lerpf(fstand, 1.0f-vg_clampf(speed*0.03f,0.0f,1.0f),0.1f);
- fslide = vg_lerpf(fslide, vg_clampf(lslip,0.0f,1.0f), 0.04f);
- fdirz = vg_lerpf(fdirz, player.reverse > 0.0f? 1.0f: 0.0f, 0.04f );
- fdirx = vg_lerpf(fdirx, player.slip < 0.0f? 1.0f: 0.0f, 0.01f );
- ffly = vg_lerpf(ffly, player.in_air? 1.0f: 0.0f, 0.04f );
-
- character_pose_reset( &player.mdl );
-
- /* TODO */
- float fstand1 = 1.0f-(1.0f-fstand)*0.0f;
-
- float amt_air = ffly*ffly,
- amt_ground = 1.0f-amt_air,
- amt_std = (1.0f-fslide) * amt_ground,
- amt_stand = amt_std * fstand1,
- amt_aero = amt_std * (1.0f-fstand1),
- amt_slide = amt_ground * fslide;
-
- character_final_pose( &player.mdl, offset, &pose_stand, amt_stand*fdirz );
- character_final_pose( &player.mdl, offset,
- &pose_stand_reverse, amt_stand * (1.0f-fdirz) );
+ /* sliding */
+ {
+ float desired = vg_clampf( lslip, 0.0f, 1.0f );
+ player.fslide = vg_lerpf( player.fslide, desired, 0.04f );
+ }
+
+ /* movement information */
+ {
+ float dirz = player.reverse > 0.0f? 0.0f: 1.0f,
+ dirx = player.slip < 0.0f? 0.0f: 1.0f,
+ fly = player.in_air? 1.0f: 0.0f;
- character_final_pose( &player.mdl, offset, &pose_aero, amt_aero*fdirz );
- character_final_pose( &player.mdl, offset,
- &pose_aero_reverse, amt_aero * (1.0f-fdirz) );
+ player.fdirz = vg_lerpf( player.fdirz, dirz, 0.04f );
+ player.fdirx = vg_lerpf( player.fdirx, dirx, 0.01f );
+ player.ffly = vg_lerpf( player.ffly, fly, 0.04f );
+ }
+
+ struct skeleton *sk = &player.mdl.sk;
- character_final_pose( &player.mdl, offset, &pose_slide, amt_slide*fdirx );
- character_final_pose( &player.mdl, offset,
- &pose_slide1, amt_slide*(1.0f-fdirx) );
+ mdl_keyframe apose[32], bpose[32];
+ mdl_keyframe ground_pose[32];
+ {
+ /* when the player is moving fast he will crouch down a little bit */
+ float stand = 1.0f - vg_clampf( speed * 0.03f, 0.0f, 1.0f );
+ player.fstand = vg_lerpf( player.fstand, stand, 0.1f );
- character_final_pose( &player.mdl, (v4f){0.0f,0.0f,0.0f,1.0f},
- &pose_fly, amt_air );
+ /* stand/crouch */
+ float dir_frame = player.fdirz * (15.0f/30.0f),
+ stand_blend = offset[1]*-2.0f;
+
+ skeleton_sample_anim( sk, player.mdl.anim_stand, dir_frame, apose );
+ skeleton_sample_anim( sk, player.mdl.anim_highg, dir_frame, bpose );
+ skeleton_lerp_pose( sk, apose, bpose, stand_blend, apose );
- /*
- * Additive effects
- * ==========================
- */
- struct ik_basic *arm_l = &player.mdl.ik_arm_l,
- *arm_r = &player.mdl.ik_arm_r;
+ /* sliding */
+ float slide_frame = player.fdirx * (15.0f/30.0f);
+ skeleton_sample_anim( sk, player.mdl.anim_slide, slide_frame, bpose );
+ skeleton_lerp_pose( sk, apose, bpose, player.fslide, apose );
- v3f localv;
- m3x3_mulv( player.rb.to_local, player.rb.v, localv );
+ /* pushing */
+ player.fpush = vg_lerpf( player.fpush, player.pushing, 0.1f );
- /* New board transformation */
- v4f board_rotation; v3f board_location;
+ float pt = player.push_time;
+ if( player.reverse > 0.0f )
+ skeleton_sample_anim( sk, player.mdl.anim_push, pt, bpose );
+ else
+ skeleton_sample_anim( sk, player.mdl.anim_push_reverse, pt, bpose );
- v4f rz, rx;
- q_axis_angle( rz, (v3f){ 0.0f, 0.0f, 1.0f }, player.board_xy[0] );
- q_axis_angle( rx, (v3f){ 1.0f, 0.0f, 0.0f }, player.board_xy[1] );
- q_mul( rx, rz, board_rotation );
-
- v3f *mboard = player.mdl.matrices[k_chpart_board];// player.mboard;
- q_m3x3( board_rotation, mboard );
- m3x3_mulv( mboard, (v3f){ 0.0f, -0.5f, 0.0f }, board_location );
- v3_add( (v3f){0.0f,0.5f,0.0f}, board_location, board_location );
- v3_copy( board_location, mboard[3] );
+ skeleton_lerp_pose( sk, apose, bpose, player.fpush, apose );
+ /* trick setup */
+ float setup_frame = player.jump * (12.0f/30.0f),
+ setup_blend = vg_minf( player.jump*5.0f, 1.0f );
+
+ float jump_frame = (vg_time - player.jump_time) + (12.0f/30.0f);
+ if( jump_frame >= (12.0f/30.0f) && jump_frame <= (40.0f/30.0f) )
+ setup_frame = jump_frame;
- float wheel_r = offset[0]*-0.4f;
- v4f qwheel;
- q_axis_angle( qwheel, (v3f){0.0f,1.0f,0.0f}, wheel_r );
-
- q_m3x3( qwheel, player.mdl.matrices[k_chpart_wb] );
-
- m3x3_transpose( player.mdl.matrices[k_chpart_wb],
- player.mdl.matrices[k_chpart_wf] );
- v3_copy( player.mdl.offsets[k_chpart_wb],
- player.mdl.matrices[k_chpart_wb][3] );
- v3_copy( player.mdl.offsets[k_chpart_wf],
- player.mdl.matrices[k_chpart_wf][3] );
+ skeleton_sample_anim_clamped( sk, player.mdl.anim_ollie,
+ setup_frame, bpose );
+ skeleton_lerp_pose( sk, apose, bpose, setup_blend, ground_pose );
+ }
- m4x3_mul( mboard, player.mdl.matrices[k_chpart_wb],
- player.mdl.matrices[k_chpart_wb] );
- m4x3_mul( mboard, player.mdl.matrices[k_chpart_wf],
- player.mdl.matrices[k_chpart_wf] );
-
- m4x3_mulv( mboard, player.mdl.ik_leg_l.end, player.mdl.ik_leg_l.end );
- m4x3_mulv( mboard, player.mdl.ik_leg_r.end, player.mdl.ik_leg_r.end );
-
-
- v3_copy( player.mdl.ik_arm_l.end, player.handl_target );
- v3_copy( player.mdl.ik_arm_r.end, player.handr_target );
-
- if( 1||player.in_air )
+ mdl_keyframe air_pose[32];
{
- float tuck = player.board_xy[1],
- tuck_amt = fabsf( tuck ) * (1.0f-fabsf(player.board_xy[0]));
+ float target = -vg_get_axis("horizontal");
+ player.fairdir = vg_lerpf( player.fairdir, target, 0.04f );
- float crouch = player.grab*0.3f;
- v3_muladds( player.mdl.ik_body.base, (v3f){0.0f,-1.0f,0.0f},
- crouch, player.mdl.ik_body.base );
- v3_muladds( player.mdl.ik_body.end, (v3f){0.0f,-1.0f,0.0f},
- crouch*1.2f, player.mdl.ik_body.end );
-
- if( tuck < 0.0f )
- {
- //foot_l *= 1.0f-tuck_amt*1.5f;
-
- if( player.grab > 0.1f )
- {
- m4x3_mulv( mboard, (v3f){0.1f,0.14f,0.6f},
- player.handl_target );
- }
- }
- else
- {
- //foot_r *= 1.0f-tuck_amt*1.4f;
-
- if( player.grab > 0.1f )
- {
- m4x3_mulv( mboard, (v3f){0.1f,0.14f,-0.6f},
- player.handr_target );
- }
- }
+ float air_frame = (player.fairdir*0.5f+0.5f) * (15.0f/30.0f);
+
+ skeleton_sample_anim( sk, player.mdl.anim_air, air_frame, air_pose );
}
- v3_lerp( player.handl, player.handl_target, 1.0f, player.handl );
- v3_lerp( player.handr, player.handr_target, 1.0f, player.handr );
-
- v3_copy( player.handl, player.mdl.ik_arm_l.end );
- v3_copy( player.handr, player.mdl.ik_arm_r.end );
-
- /* Head rotation */
-
- static float rhead = 0.0f;
- static const float klook_max = 0.8f;
- rhead = vg_lerpf( rhead,
- vg_clampf( atan2f(localv[2],-localv[0]),-klook_max,klook_max), 0.04f );
- player.mdl.rhead = rhead;
+ skeleton_lerp_pose( sk, ground_pose, air_pose, player.ffly, apose );
+
+ /* additive effects */
+ apose[player.mdl.id_hip-1].co[0] += offset[0];
+ apose[player.mdl.id_hip-1].co[2] += offset[2];
+ apose[player.mdl.id_ik_hand_l-1].co[0] += offset[0];
+ apose[player.mdl.id_ik_hand_l-1].co[2] += offset[2];
+ apose[player.mdl.id_ik_hand_r-1].co[0] += offset[0];
+ apose[player.mdl.id_ik_hand_r-1].co[2] += offset[2];
+ apose[player.mdl.id_ik_elbow_l-1].co[0] += offset[0];
+ apose[player.mdl.id_ik_elbow_l-1].co[2] += offset[2];
+ apose[player.mdl.id_ik_elbow_r-1].co[0] += offset[0];
+ apose[player.mdl.id_ik_elbow_r-1].co[2] += offset[2];
+
+ skeleton_apply_pose( &player.mdl.sk, apose, k_anim_apply_defer_ik );
+ skeleton_apply_ik_pass( &player.mdl.sk );
+ skeleton_apply_pose( &player.mdl.sk, apose, k_anim_apply_deffered_only );
+
+ v3_copy( player.mdl.sk.final_mtx[player.mdl.id_head-1][3],
+ player.mdl.cam_pos );
+ skeleton_apply_inverses( &player.mdl.sk );
+ skeleton_apply_transform( &player.mdl.sk, player.rb.to_world );
+
+ skeleton_debug( &player.mdl.sk );
}
static void player_camera_update(void)
static void player_animate_death_cam(void)
{
+#if 0
v3f delta;
v3f head_pos;
v3_copy( player.mdl.ragdoll[k_chpart_head].co, head_pos );
player.angles[0] = atan2f( delta[0], -delta[2] );
player.angles[1] = -asinf( delta[1] );
+#endif
}
static void player_animate_camera(void)
{
- v3f offs = { -0.29f, 0.08f, 0.0f };
- m3x3_mulv( player.rb.to_world, offs, offs );
- m4x3_mulv( player.rb.to_world, player.mdl.ik_body.end, player.camera_pos );
- v3_add( offs, player.camera_pos, player.camera_pos );
+ static v3f lerp_cam = {0.0f,0.0f,0.0f};
+ v3f offs = { -0.4f, 0.15f, 0.0f };
+
+ v3_lerp( lerp_cam, player.mdl.cam_pos, 0.8f, lerp_cam );
+ v3_add( lerp_cam, offs, offs );
+ m4x3_mulv( player.rb.to_world, offs, player.camera_pos );
/* Look angles */
v3_lerp( player.vl, player.rb.v, 0.05f, player.vl );
player.mdl.shoes[0] = 1;
player.mdl.shoes[1] = 1;
+
+ world_routes_notify_reset();
}
if( vg_get_button_down( "switchmode" ) )
static void draw_player(void)
{
/* Draw */
+#if 0
m4x3_copy( player.rb.to_world, player.mdl.mroot );
if( player.is_dead )
opacity = 0.0f;
character_draw( &player.mdl, opacity, player.camera );
+#endif
+
+ shader_viewchar_use();
+ vg_tex2d_bind( &tex_characters, 0 );
+ shader_viewchar_uTexMain( 0 );
+ shader_viewchar_uCamera( player.camera[3] );
+ shader_viewchar_uPv( vg_pv );
+ shader_link_standard_ub( _shader_viewchar.id, 2 );
+ glUniformMatrix4x3fv( _uniform_viewchar_uTransforms,
+ player.mdl.sk.bone_count,
+ 0,
+ (float *)player.mdl.sk.final_mtx );
+
+ mesh_bind( &player.mdl.mesh );
+ mesh_draw( &player.mdl.mesh );
}
#endif /* PLAYER_H */