X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;ds=sidebyside;f=player.h;h=bd7304dc614550c8978345c08cce9fb893a363ae;hb=9c85e110fa8b965195438d96625ff9753af362a6;hp=984d4e3fe3c62e943c9d10bf6f8b3fbd5d96560a;hpb=1656d58a7bd17df4a1edcc9677ade4dbafc82229;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player.h b/player.h index 984d4e3..bd7304d 100644 --- a/player.h +++ b/player.h @@ -1,8 +1,10 @@ #ifndef PLAYER_H #define PLAYER_H +#include "audio.h" #include "common.h" #include "character.h" +#include "bvh.h" static int freecam = 0; static float k_walkspeed = 2.0f; @@ -19,9 +21,6 @@ static struct gplayer float iY; /* Yaw inertia */ int in_air, is_dead, on_board; - /* Input */ - v2f joy_l; - v2f board_xy; float grab; float pitch; @@ -30,7 +29,7 @@ static struct gplayer v3f land_target_log[22]; u32 land_target_colours[22]; int land_log_count; - m3x3f vr; + m3x3f vr,vr_pstep; m4x3f to_world, to_local; @@ -51,6 +50,11 @@ player = .on_board = 1 }; +static float *player_cam_pos(void) +{ + return player.camera_pos; +} + static void player_transform_update(void) { q_normalize( player.rot ); @@ -62,16 +66,49 @@ static void player_transform_update(void) static int reset_player( int argc, char const *argv[] ) { - v3_copy( (v3f){ 0.0f, -2.0f, 0.0f }, player.co ); + struct respawn_point *rp = NULL, *r; + + if( argc > 1 ) + { + for( int i=0; iname, argv[0] ) ) + { + rp = r; + break; + } + } + + if( !rp ) + vg_warn( "No spawn named '%s'\n", argv[0] ); + } + + if( !rp ) + { + float min_dist = INFINITY; + for( int i=0; ico, player.co ); + + if( d < min_dist ) + { + min_dist = d; + rp = r; + } + } + } - if( argc == 1 ) + if( !rp ) { - if( !strcmp( argv[0], "tutorial" )) - v3_copy( world.tutorial, player.co ); + vg_error( "No spawn found\n" ); + return 0; } - v3_copy( (v3f){ 0.0f, 0.0f, -0.2f }, player.v ); - q_identity( player.rot ); + v4_copy( r->q, player.rot ); + v3_copy( r->co, player.co ); + player.vswitch = 1.0f; player.slip_last = 0.0f; player.is_dead = 0; @@ -82,16 +119,21 @@ static int reset_player( int argc, char const *argv[] ) player.mdl.shoes[1] = 1; player_transform_update(); - return 0; + m3x3_mulv( player.to_world, (v3f){ 0.0f, 0.0f, -0.2f }, player.v ); + return 1; } static void player_mouseview(void) { + if( gui_want_mouse() ) + return; + static v2f mouse_last, view_vel = { 0.0f, 0.0f }; if( vg_get_button_down( "primary" ) ) v2_copy( vg_mouse, mouse_last ); + else if( vg_get_button( "primary" ) ) { v2f delta; @@ -101,10 +143,12 @@ static void player_mouseview(void) v2_muladds( view_vel, delta, 0.005f, 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_add( view_vel, player.angles, player.angles ); player.angles[1] = vg_clampf( player.angles[1], -VG_PIf*0.5f, VG_PIf*0.5f ); - } static void player_freecam(void) @@ -218,7 +262,8 @@ static void player_start_air(void) best_velocity_mod = vmod; v3_copy( contact.pos, player.land_target ); - + + m3x3_copy( vr, player.vr_pstep ); q_axis_angle( vr_q, axis, vmod*0.1f ); q_m3x3( vr_q, player.vr ); } @@ -363,7 +408,9 @@ static void player_physics_ground(void) for( int i=0; i<5; i++ ) { vel[2] = stable_force( vel[2], vg_signf( vel[2] ) * fwd_resistance ); - vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -7.0f *substep ); + + /* This used to be -7.0, then -10.0 */ + vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -8.5f *substep ); } static double start_push = 0.0; @@ -391,7 +438,7 @@ static void player_physics_ground(void) player.iY -= 3.6f * ktimestep; float steer = vg_get_axis( "horizontal" ); - player.iY -= vg_signf(steer)*powf(steer,2.0f) * 1.5f * ktimestep; + player.iY -= vg_signf(steer)*powf(steer,2.0f) * 2.5f * ktimestep; /* Too much lean and it starts to look like a snowboard here */ v2_lerp( player.board_xy, (v2f){ slip*0.25f, 0.0f }, @@ -453,6 +500,7 @@ static void player_physics_air(void) for( int i=0; i<50; i++ ) { v3_copy( pco, pco1 ); + m3x3_mulv( player.vr_pstep, pv, pv ); apply_gravity( pv, pstep ); v3_muladds( pco, pv, pstep, pco ); @@ -497,7 +545,8 @@ static void player_physics_air(void) player.iY -= vg_get_axis( "horizontal" ) * 3.6f * ktimestep; { - float iX = vg_get_axis( "vertical" ) * 3.6f * limiter * ktimestep; + float iX = vg_get_axis( "vertical" ) * + player.reverse * 3.6f * limiter * ktimestep; static float siX = 0.0f; siX = vg_lerpf( siX, iX, 0.3f ); @@ -521,9 +570,6 @@ static void player_do_motion(void) float horizontal = vg_get_axis("horizontal"), vertical = vg_get_axis("vertical"); - player.joy_l[0] = vg_signf(horizontal) * powf( horizontal, 2.0f ); - player.joy_l[1] = vg_signf(vertical) * powf( vertical, 2.0f ); - if( player.in_air ) player_physics_air(); @@ -581,12 +627,12 @@ static void player_do_motion(void) player.angles[0] = atan2f( player.vl[0], -player.vl[2] ); player.angles[1] = atan2f( -player.vl[1], sqrtf(player.vl[0]*player.vl[0]+ - player.vl[2]*player.vl[2]) ) * 0.3f; + player.vl[2]*player.vl[2]) ) * 0.7f; } static int player_walkgrid_tri_walkable( u32 tri[3] ) { - return tri[0] < world.sm_road.vertex_count; + return tri[0] < world.sm_surface.vertex_count; } #define WALKGRID_SIZE 16 @@ -616,10 +662,6 @@ struct walkgrid } samples[WALKGRID_SIZE][WALKGRID_SIZE]; -#if 0 - u32 geo[256]; -#endif - boxf region; float move; /* Current amount of movement we have left to apply */ @@ -638,13 +680,9 @@ static void player_walkgrid_samplepole( struct grid_sample *s ) boxf region = {{ s->pos[0] -0.01f, s->pos[1] - 4.0f, s->pos[2] -0.01f}, { s->pos[0] +0.01f, s->pos[1] + 4.0f, s->pos[2] +0.01f}}; -#if 0 - vg_line( region[0],region[1], 0x20ffffff ); -#endif - u32 geo[256]; v3f tri[3]; - int len = bvh_select_triangles( &world.geo, region, geo, 256 ); + int len = bh_select( &world.geo.bhtris, region, geo, 256 ); const float k_minworld_y = -2000.0f; @@ -655,7 +693,7 @@ static void player_walkgrid_samplepole( struct grid_sample *s ) for( int i=0; i block_height ) block_height = p0[1]; -#if 0 - draw_cross( p0, 0xff0000ff, 0.05f ); -#endif } } } @@ -702,39 +733,6 @@ static void player_walkgrid_samplepole( struct grid_sample *s ) s->type = k_sample_type_valid; else s->type = k_sample_type_air; - -#if 0 - if( s->type == k_sample_type_valid ) - { - vg_line_pt3( s->pos, 0.01f, 0xff00ff00 ); - } -#endif - -#if 0 - int count = 0; - - ray_hit hit; - hit.dist = 10.0f; - count = bvh_raycast( &world.geo, sample_pos, vdir, &hit ); - - if( count ) - { - v3_copy( hit.pos, s->pos ); - - if( !player_walkgrid_tri_walkable( hit.tri ) ) - { - draw_cross( pos, 0xff0000ff, 0.05f ); - return 0; - } - else - { - draw_cross( pos, 0xff00ff00, 0.05f ); - return count; - } - } - else - return 0; -#endif } float const k_gridscale = 0.5f; @@ -764,8 +762,7 @@ static void player_walkgrid_clip_blocker( struct grid_sample *sa, u32 geo[256]; v3f tri[3]; - int len = bvh_select_triangles( &world.geo, cell_region, geo, 256 ); - + int len = bh_select( &world.geo.bhtris, cell_region, geo, 256 ); float start_time = v3_length( clipdir ), min_time = start_time; @@ -774,7 +771,7 @@ static void player_walkgrid_clip_blocker( struct grid_sample *sa, for( int i=0; itype, sb->type ), - maxtype = VG_MAX( sa->type, sb->type ); - - if( maxtype == k_sample_type_valid ) - { - if( mintype == k_sample_type_air || mintype == k_sample_type_invalid ) - { - player_walkgrid_clip_edge( sa, sb, sa, dir ); - } - -#if 0 - else if( mintype == k_sample_type_invalid ) - { - player_walkgrid_clip_blocker( sa, sb, dir ); - } -#endif - } -} - static const struct conf { struct confedge @@ -1032,19 +1006,6 @@ static void player_walkgrid_iter(struct walkgrid *wg, int iter) * the intersections with the grid, and any edges that are present */ -#if 0 - if( wg->cell_id[0] < 0 || wg->cell_id[0] >= WALKGRID_SIZE-1 || - wg->cell_id[1] < 0 || wg->cell_id[1] >= WALKGRID_SIZE-1 ) - { - /* - * This condition should never be reached if the grid size is big - * enough - */ - wg->move = -1.0f; - return; - } -#endif - u32 icolours[] = { 0xffff00ff, 0xff00ffff, 0xffffff00 }; v3f pa, pb, pc, pd, pl0, pl1; @@ -1061,6 +1022,7 @@ static void player_walkgrid_iter(struct walkgrid *wg, int iter) 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 ); vg_line( pc, pd, 0xff00ffff ); @@ -1419,6 +1381,11 @@ static void player_walkgrid_getsurface(void) v3_muladds( delta, side, -ktimestep*k_walkspeed, delta ); if( glfwGetKey( vg_window, GLFW_KEY_D ) ) v3_muladds( delta, side, ktimestep*k_walkspeed, delta ); + + v3_muladds( delta, fwd, + vg_get_axis("vertical")*-ktimestep*k_walkspeed, delta ); + v3_muladds( delta, side, + vg_get_axis("horizontal")*ktimestep*k_walkspeed, delta ); } /* @@ -1440,73 +1407,6 @@ static void player_walkgrid_getsurface(void) wg.cell_id[0] = region_cell_pos[0]; wg.cell_id[1] = region_cell_pos[1]; - -#if 0 - /* Get surface samples - * - * TODO: Replace this with a spiral starting from the player position - */ - for( int y=0; ypos ); - s->pos[1] = cell[1]; - player_walkgrid_samplepole( s ); - } - } - - /* - * Calculate h+v clipping distances. - * Distances are stored in A always, so you know that if the sample is - * invalid, this signifies the start of the manifold as opposed to the - * extent or bounds of it. - */ - for( int i=0; i<2; i++ ) - { - for( int x=0; xtype == k_sample_type_valid && - sb->type == k_sample_type_valid ) - vg_line( sa->pos, sb->pos, 0xffffffff ); -#if 0 - if( sa->valid != sb->valid ) - { - clipdir[i*2] = (float)(sa->valid - sb->valid) * k_gridscale; - - player_walkgrid_clip( sa->valid? sa->pos: sb->pos, - clipdir, sa->clip[i] ); - } - else - { - if( sa->valid ) - { - vg_line( sa->pos, sb->pos, 0xffffffff ); - } - } -#endif - } - } - } -#endif - for(int y=0; yend, localv, -0.01f, arm_l->end ); v3_muladds( arm_r->end, localv, -0.01f, arm_r->end ); +#endif /* New board transformation */ v4f board_rotation; v3f board_location; @@ -1885,8 +1782,9 @@ static void player_animate(void) /* 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] ),-1.0f,1.0f), 0.04f ); + vg_clampf( atan2f(localv[2],-localv[0]),-klook_max,klook_max), 0.04f ); player.mdl.rhead = rhead; } @@ -2079,7 +1977,7 @@ static void player_do_collision( rigidbody *rb ) int collide = 1; float min_dist = 99999.9f; - v2f normal; + v2f normal = {0.0f,0.0f}; for( int i=0; i0.0f) reset_player(0,NULL); + if( vg_get_button_down( "switchmode" ) ) + { + player.on_board ^= 0x1; + } + if( freecam ) { player_freecam(); @@ -2177,8 +2125,41 @@ static void player_update(void) { if( player.is_dead ) { + /* + * Follow camera + */ character_ragdoll_iter( &player.mdl ); character_debug_ragdoll( &player.mdl ); + + v3f delta; + v3f head_pos; + v3_copy( player.mdl.ragdoll[k_chpart_head].co, head_pos ); + + v3_sub( head_pos, player.camera_pos, delta ); + v3_normalize( delta ); + + v3f follow_pos; + v3_muladds( head_pos, delta, -2.5f, follow_pos ); + v3_lerp( player.camera_pos, follow_pos, 0.1f, player.camera_pos ); + + /* + * Make sure the camera stays above the ground + */ + v3f min_height = {0.0f,1.0f,0.0f}; + + v3f sample; + v3_add( player.camera_pos, min_height, sample ); + ray_hit hit; + hit.dist = min_height[1]*2.0f; + + if( ray_world( sample, (v3f){0.0f,-1.0f,0.0f}, &hit )) + v3_add( hit.pos, min_height, player.camera_pos ); + + player.camera_pos[1] = + vg_maxf( wrender.height + 2.0f, player.camera_pos[1] ); + + player.angles[0] = atan2f( delta[0], -delta[2] ); + player.angles[1] = -asinf( delta[1] ); } else { @@ -2198,6 +2179,13 @@ static void player_update(void) player_do_motion(); player_animate(); + + v3f offs = { -0.29f, 0.08f, 0.0f }; + m3x3_mulv( player.to_world, offs, offs ); + m4x3_mulv( player.to_world, player.mdl.ik_body.end, player.camera_pos ); + //m4x3_mulv( player.mdl.matrices[k_chpart_head], offs, player.camera_pos ); + // v3_copy( player.mdl.matrices[k_chpart_head][3], player.camera_pos ); + v3_add( offs, player.camera_pos, player.camera_pos ); } else { @@ -2206,10 +2194,12 @@ static void player_update(void) } } + player_audio(); + /* Update camera matrices */ m4x3_identity( player.camera ); m4x3_rotate_y( player.camera, -player.angles[0] ); - m4x3_rotate_x( player.camera, -0.33f -player.angles[1] ); + m4x3_rotate_x( player.camera, -0.30f -player.angles[1] ); v3_copy( player.camera_pos, player.camera[3] ); m4x3_invert_affine( player.camera, player.camera_inverse ); } @@ -2224,7 +2214,11 @@ static void draw_player(void) else character_eval( &player.mdl ); - character_draw( &player.mdl, (player.is_dead|player.in_air)? 0.0f: 1.0f ); + float opacity = 1.0f-player.air_blend; + if( player.is_dead ) + opacity = 0.0f; + + character_draw( &player.mdl, opacity ); } #endif /* PLAYER_H */