From: hgn Date: Sat, 28 Jan 2023 06:57:31 +0000 (+0000) Subject: third person better camera X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=9edcce70acf6cf8fbb2449bf54d797e212ebb2c2;p=carveJwlIkooP6JGAAIwe30JlM.git third person better camera --- diff --git a/common.h b/common.h index a8d0e86..556834d 100644 --- a/common.h +++ b/common.h @@ -133,4 +133,66 @@ VG_STATIC float k_spring_dampener = 5.0f; +VG_STATIC float + k_walkspeed = 10.0f, + k_airspeed = 2.0f, + k_stopspeed = 4.0f, + k_walk_accel = 10.0f, + k_walk_air_accel = 7.0f, + k_walk_friction = 10.0f, + k_walk_step_height = 0.2f; + +VG_STATIC float k_ragdoll_floatyiness = 20.0f, + k_ragdoll_floatydrag = 1.0f, + k_ragdoll_limit_scale = 1.0f; + +VG_STATIC int k_ragdoll_div = 1, + ragdoll_frame = 0, + k_ragdoll_debug_collider = 1, + k_ragdoll_debug_constraints = 0; + + +VG_STATIC int freecam = 0; +VG_STATIC int walk_grid_iterations = 1; +VG_STATIC float fc_speed = 10.0f; +VG_STATIC int cl_thirdperson = 0; + +VG_STATIC void common_var_temp(void) +{ + VG_VAR_F32( k_walkspeed ); + VG_VAR_F32( k_stopspeed ); + VG_VAR_F32( k_airspeed ); + VG_VAR_F32( k_walk_friction ); + VG_VAR_F32( k_walk_air_accel ); + VG_VAR_F32( k_runspeed ); + VG_VAR_F32( k_walk_accel ); + + VG_VAR_I32( freecam ); + VG_VAR_I32( cl_thirdperson ); + VG_VAR_F32_PERSISTENT( fc_speed ); + + /* TODO: NOT PERSISTENT */ + VG_VAR_F32( k_ragdoll_limit_scale ); + VG_VAR_I32( k_ragdoll_div ); + VG_VAR_I32( k_ragdoll_debug_collider ); + VG_VAR_I32( k_ragdoll_debug_constraints ); + + VG_VAR_F32( k_friction_lat ); + + VG_VAR_F32( k_cog_spring ); + VG_VAR_F32( k_cog_damp ); + + VG_VAR_F32( k_cog_mass_ratio ); + VG_VAR_F32( k_downforce ); + + VG_VAR_F32( k_spring_force ); + VG_VAR_F32( k_spring_dampener ); + VG_VAR_F32( k_spring_angular ); + + VG_VAR_F32( k_mmthrow_scale ); + VG_VAR_F32( k_mmcollect_lat ); + VG_VAR_F32( k_mmcollect_vert ); + VG_VAR_F32( k_mmdecay ); +} + #endif /* COMMON_H */ diff --git a/player.h b/player.h index e625b0b..1a97e1a 100644 --- a/player.h +++ b/player.h @@ -16,11 +16,6 @@ #include "bvh.h" -VG_STATIC int freecam = 0; -VG_STATIC int walk_grid_iterations = 1; -VG_STATIC float fc_speed = 10.0f; -VG_STATIC int cl_thirdperson = 0; - /* * ----------------------------------------------------------------------------- * Memory diff --git a/player_device_skate.h b/player_device_skate.h index 5370c29..168e8ee 100644 --- a/player_device_skate.h +++ b/player_device_skate.h @@ -43,7 +43,8 @@ struct player_device_skate double start_push, cur_push; - v3f vl; + v3f vl, follow_cam_pos; + struct teleport_gate *follow_cam_gate; } state, state_gate_storage; @@ -1190,6 +1191,11 @@ VG_STATIC void player_skate_ui( player_interface *player, k_steer_ground, k_steer_air ); } +VG_STATIC void skate_camera_thirdperson_nextpos( player_interface *player, + struct player_device_skate *s, + struct player_avatar *av, + v3f next_pos, v3f d ); + VG_STATIC void player_skate_pose( player_interface *player, player_attachment *at, player_pose pose, m4x3f transform ) @@ -1405,10 +1411,7 @@ VG_STATIC void player_skate_pose( player_interface *player, /* transform */ rb_extrapolate_transform( &player->rb, transform ); -#if 0 - v3_muladds( player.visual_transform[3], phys->rb.up, -0.2f, - player.visual_transform[3] ); -#endif + v3_muladds( transform[3], player->rb.to_world[1], -0.28f, transform[3] ); v4f qresy, qresx, qresidual; m3x3f mtx_residual; @@ -1419,14 +1422,42 @@ VG_STATIC void player_skate_pose( player_interface *player, q_mul( qresy, qresx, qresidual ); q_m3x3( qresidual, mtx_residual ); m3x3_mul( transform, mtx_residual, transform ); + + if( cl_thirdperson && s->state.follow_cam_gate ) + { + v3f next_pos, d, _; + skate_camera_thirdperson_nextpos( player, s, av, next_pos, d ); + + if( !gate_intersect_plane( s->state.follow_cam_gate, + next_pos, s->state.follow_cam_pos, _ ) ) + { + m4x3f inverse; + m4x3_invert_affine( s->state.follow_cam_gate->transport, inverse ); + m4x3_mul( inverse, transform, transform ); + } + } } -VG_STATIC void player_skate_get_camera( player_interface *player, - player_attachment *at, camera *cam ) +VG_STATIC void skate_camera_vector_look( camera *cam, v3f v, float C, float k ) { - struct player_device_skate *s = at->storage; - struct player_avatar *av = player->playeravatar; + float yaw = atan2f( v[0], -v[2] ), + pitch = atan2f + ( + -v[1], + sqrtf + ( + v[0]*v[0] + v[2]*v[2] + ) + ) * C + k; + cam->angles[0] = yaw; + cam->angles[1] = pitch; +} + +VG_STATIC void skate_camera_firstperson( player_interface *player, + struct player_device_skate *s, + struct player_avatar *av, camera *cam ) +{ /* FIXME: viewpoint entity */ v3f vp = {-0.1f,1.8f,0.0f}; m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, cam->pos ); @@ -1457,20 +1488,80 @@ VG_STATIC void player_skate_get_camera( player_interface *player, v3_lerp( flat_dir, vel_dir, vg_clampf( tti / 2.0f, 0.4f, 1.0f ), look_dir ); v3_lerp( s->state.vl, look_dir, 4.0f*vg.time_delta, s->state.vl ); - float *v = s->state.vl, - yaw = atan2f( v[0], -v[2] ), - pitch = atan2f - ( - -v[1], - sqrtf - ( - v[0]*v[0] + v[2]*v[2] - ) - ) - * 0.7f + 0.5f; + skate_camera_vector_look( cam, s->state.vl, 0.7f, 0.5f ); +} - cam->angles[0] = yaw; - cam->angles[1] = pitch; +/* this is a little yucky but needs to be done so we can use this 'prediction' + * in the pose function. its unfortunate. too bad + */ +VG_STATIC void skate_camera_thirdperson_nextpos( player_interface *player, + struct player_device_skate *s, + struct player_avatar *av, + v3f next_pos, v3f d ) +{ + v3f origin, target; + + if( s->state.follow_cam_gate ) + { + m4x3f inverse; + m4x3_invert_affine( s->state.follow_cam_gate->transport, inverse ); + m4x3_mulv( inverse, player->rb.co, origin ); + } + else + { + v3_copy( player->rb.co, origin ); + } + + v3_add( origin, (v3f){0.0f,1.35f,0.0f}, origin ); + v3_sub( origin, s->state.follow_cam_pos, d ); + + if( v3_length2( d ) < 0.1f*0.1f ) + v3_copy( (v3f){ 0.0f, 0.0f, 1.0f }, d ); + else + v3_normalize( d ); + + v3_muladds( origin, d, -2.0f, target ); + v3_lerp( s->state.follow_cam_pos, target, vg.frame_delta * 12.0f, next_pos ); +} + +VG_STATIC void skate_camera_thirdperson( player_interface *player, + struct player_device_skate *s, + struct player_avatar *av, camera *cam ) +{ + v3f prev_pos, cam_look_dir, d; + + v3_copy( s->state.follow_cam_pos, prev_pos ); + skate_camera_thirdperson_nextpos( player, s, av, s->state.follow_cam_pos, d); + + if( s->state.follow_cam_gate ) + { + v2f _; + if( gate_intersect_plane( s->state.follow_cam_gate, + s->state.follow_cam_pos, prev_pos, _ ) ) + { + m4x3_mulv( s->state.follow_cam_gate->transport, + s->state.follow_cam_pos, s->state.follow_cam_pos ); + m3x3_mulv( s->state.follow_cam_gate->transport, d, d ); + player_apply_transport_to_cam( s->state.follow_cam_gate->transport ); + + s->state.follow_cam_gate = NULL; + } + } + + skate_camera_vector_look( cam, d, 1.0f, 0.0f ); + v3_copy( s->state.follow_cam_pos, cam->pos ); +} + +VG_STATIC void player_skate_get_camera( player_interface *player, + player_attachment *at, camera *cam ) +{ + struct player_device_skate *s = at->storage; + struct player_avatar *av = player->playeravatar; + + if( cl_thirdperson ) + skate_camera_thirdperson( player, s, av, cam ); + else + skate_camera_firstperson( player, s, av, cam ); } VG_STATIC void player_skate_transport( player_interface *player, @@ -1491,7 +1582,13 @@ VG_STATIC void player_skate_transport( player_interface *player, q_mul( transport_rotation, player->rb.q, player->rb.q ); rb_update_transform( &player->rb ); + s->state.follow_cam_gate = gate; s->state_gate_storage = s->state; + + if( !cl_thirdperson ) + { + player_apply_transport_to_cam( gate->transport ); + } } VG_STATIC void player_skate_reset( player_interface *player, @@ -1500,6 +1597,7 @@ VG_STATIC void player_skate_reset( player_interface *player, { struct player_device_skate *s = at->storage; v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog ); + s->state.follow_cam_gate = NULL; } VG_STATIC player_device player_device_skate = diff --git a/player_device_walk.h b/player_device_walk.h index 508feef..fbbe895 100644 --- a/player_device_walk.h +++ b/player_device_walk.h @@ -5,15 +5,6 @@ #include "skeleton.h" #include "player_model.h" -VG_STATIC float - k_walkspeed = 10.0f, - k_airspeed = 2.0f, - k_stopspeed = 4.0f, - k_walk_accel = 10.0f, - k_walk_air_accel = 7.0f, - k_walk_friction = 10.0f, - k_walk_step_height = 0.2f; - struct player_device_walk { rb_capsule collider; @@ -432,6 +423,7 @@ VG_STATIC void player_walk_transport( player_interface *player, w->state.angles[0] = atan2f( fwd_dir[2], fwd_dir[0] ); w->state_gate_storage = w->state; + player_apply_transport_to_cam( gate->transport ); } VG_STATIC player_device player_device_walk = diff --git a/player_interface.h b/player_interface.h index a4be40e..5417345 100644 --- a/player_interface.h +++ b/player_interface.h @@ -180,9 +180,24 @@ VG_STATIC void player_update( player_interface *player ) player->dev.device->update( player, &player->dev ); } -VG_STATIC void player_post_update( player_interface *player, - camera *main_camera ) +VG_STATIC void player_apply_transport_to_cam( m4x3f transport ) { + /* FIXME: Applies to main_camera directly! */ + + /* Pre-emptively edit the camera matrices so that the motion vectors + * are correct */ + m4x3f transport_i; + m4x4f transport_4; + m4x3_invert_affine( transport, transport_i ); + m4x3_expand( transport_i, transport_4 ); + m4x4_mul( main_camera.mtx.pv, transport_4, main_camera.mtx.pv ); + m4x4_mul( main_camera.mtx.v, transport_4, main_camera.mtx.v ); +} + +VG_STATIC void player_post_update( player_interface *player ) +{ + /* FIXME: Applies to main_camera directly! */ + assert( player->dev.device ); if( player->dev.device->post_update ) @@ -200,15 +215,6 @@ VG_STATIC void player_post_update( player_interface *player, { player->dev.device->gate_transport( player, &player->dev, gate ); v3_copy( player->rb.co, player->prev_position ); - - /* Pre-emptively edit the camera matrices so that the motion vectors - * are correct */ - m4x3f transport_i; - m4x4f transport_4; - m4x3_invert_affine( gate->transport, transport_i ); - m4x3_expand( transport_i, transport_4 ); - m4x4_mul( main_camera->mtx.pv, transport_4, main_camera->mtx.pv ); - m4x4_mul( main_camera->mtx.v, transport_4, main_camera->mtx.v ); } } diff --git a/player_ragdoll.h b/player_ragdoll.h index db01ece..f1f6221 100644 --- a/player_ragdoll.h +++ b/player_ragdoll.h @@ -8,15 +8,6 @@ #include "player_model.h" #include "world.h" -VG_STATIC float k_ragdoll_floatyiness = 20.0f, - k_ragdoll_floatydrag = 1.0f, - k_ragdoll_limit_scale = 1.0f; - -VG_STATIC int k_ragdoll_div = 1, - ragdoll_frame = 0, - k_ragdoll_debug_collider = 1, - k_ragdoll_debug_constraints = 0; - struct player_ragdoll { struct ragdoll_part diff --git a/skaterift.c b/skaterift.c index 7420fbd..0ad5bba 100644 --- a/skaterift.c +++ b/skaterift.c @@ -122,6 +122,8 @@ VG_STATIC void vg_preload(void) { g_conf_init(); + common_var_temp(); + vg_var_push( (struct vg_var){ .name = "cl_ui", .data = &cl_ui, @@ -311,7 +313,7 @@ VG_STATIC void vg_update_post(void) } #endif - player_post_update( &localplayer, &main_camera ); + player_post_update( &localplayer ); #if 0 menu_update(); diff --git a/world_gate.h b/world_gate.h index 9d12877..f83cd87 100644 --- a/world_gate.h +++ b/world_gate.h @@ -152,7 +152,8 @@ VG_STATIC int render_gate( teleport_gate *gate, camera *cam ) return 1; } -VG_STATIC int gate_intersect( teleport_gate *gate, v3f pos, v3f last ) +VG_STATIC int gate_intersect_plane( teleport_gate *gate, v3f pos, v3f last, + v2f where ) { v4f surface; m3x3_mulv( gate->to_world, (v3f){0.0f,0.0f,-1.0f}, surface ); @@ -185,12 +186,25 @@ VG_STATIC int gate_intersect( teleport_gate *gate, v3f pos, v3f last ) m3x3_mulv( gate->to_world, (v3f){0.0f,1.0f,0.0f}, vup ); m3x3_mulv( gate->to_world, (v3f){1.0f,0.0f,0.0f}, vside ); - v2f xy = { v3_dot( rel, vside ), v3_dot( rel, vup ) }; + where[0] = v3_dot( rel, vside ); + where[1] = v3_dot( rel, vup ); + + return 1; + } + } + + return 0; +} + +VG_STATIC int gate_intersect( teleport_gate *gate, v3f pos, v3f last ) +{ + v2f xy; - if( fabsf(xy[0]) <= gate->dims[0] && fabsf(xy[1]) <= gate->dims[1] ) - { - return 1; - } + if( gate_intersect_plane( gate, pos, last, xy ) ) + { + if( fabsf(xy[0]) <= gate->dims[0] && fabsf(xy[1]) <= gate->dims[1] ) + { + return 1; } }