From ff8fcac9582d07bc1ccbf08421d6ffec1758a755 Mon Sep 17 00:00:00 2001 From: hgn Date: Sun, 29 Jan 2023 10:58:02 +0000 Subject: [PATCH] another api change --- camera.h | 9 ++ common.h | 2 +- maps_src/mp_gridmap.mdl | Bin 1400144 -> 1415664 bytes player_device_common.h | 131 ++++++++++++++++++++++++++ player_device_dead.h | 39 +++++--- player_device_skate.h | 188 ++++++++++++++++-------------------- player_device_walk.h | 170 +++++++++++++++++++-------------- player_interface.h | 204 ++++++++++++++++++++++++++++++---------- rigidbody.h | 25 +++++ skaterift.c | 2 +- world_gate.h | 17 ++++ 11 files changed, 544 insertions(+), 243 deletions(-) create mode 100644 player_device_common.h diff --git a/camera.h b/camera.h index e818e8f..dbacc26 100644 --- a/camera.h +++ b/camera.h @@ -27,6 +27,15 @@ struct camera } VG_STATIC main_camera; +VG_STATIC void camera_lerp( camera *a, camera *b, float t, camera *d ) +{ + v3_lerp( a->pos, b->pos, t, d->pos ); + d->angles[0] = vg_alerpf( a->angles[0], b->angles[0], t ); + d->angles[1] = vg_lerpf( a->angles[1], b->angles[1], t ); + d->angles[2] = vg_lerpf( a->angles[2], b->angles[2], t ); + d->fov = vg_lerpf( a->fov, b->fov, t ); +} + /* * 1) [angles, pos] -> transform */ diff --git a/common.h b/common.h index ff52267..6b10d8b 100644 --- a/common.h +++ b/common.h @@ -136,7 +136,7 @@ VG_STATIC float VG_STATIC float k_walkspeed = 10.0f, - k_airspeed = 2.0f, + k_airspeed = 1.2f, k_stopspeed = 4.0f, k_walk_accel = 10.0f, k_walk_air_accel = 7.0f, diff --git a/maps_src/mp_gridmap.mdl b/maps_src/mp_gridmap.mdl index a742af31f9ff6de515d73f404c53dd7609f06af3..7efdc8a2322305c47ddc4001be9ac5a397e9354d 100644 GIT binary patch delta 18481 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 SbLU>P2db}{d(q)k{{I1pQD;{G delta 4600 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 diff --git a/player_device_common.h b/player_device_common.h new file mode 100644 index 0000000..6e468eb --- /dev/null +++ b/player_device_common.h @@ -0,0 +1,131 @@ +#ifndef PLAYER_DEVICE_COMMON_H +#define PLAYER_DEVICE_COMMON_H + +#define VG_GAME +#include "vg/vg.h" +#include "common.h" +#include "player_interface.h" + +struct mixedcam_state +{ + v3f vl, vt, pos, post, dir; + struct teleport_gate *gate; +}; + +/* + * 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 followcam_nextpos( player_interface *player, + struct mixedcam_state *mc, + v3f next_pos, v3f d ) +{ +} + + +VG_STATIC int followcam_will_hit_gate( player_interface *player, + struct mixedcam_state *mc ) +{ + if( mc->gate ) + { + v3f next_pos, d, _; + followcam_nextpos( player, mc, next_pos, d ); + + return gate_intersect_plane( mc->gate, next_pos, mc->pos, _ ); + } + + return 0; +} + +VG_STATIC void mixedcam_transport( struct mixedcam_state *mc, + teleport_gate *gate ) +{ + m3x3_mulv( gate->transport, mc->vl, mc->vl ); + mc->gate = gate; + +#if 0 + if( !cl_thirdperson ) + player_apply_transport_to_cam( gate->transport ); +#endif +} + +VG_STATIC void mixedcam_reset( player_interface *player, + struct mixedcam_state *mc ) +{ + mc->gate = NULL; +} + + +VG_STATIC void mixedcam_set_targets( struct mixedcam_state *mc, v3f v, v3f co ) +{ + v3_copy( v, mc->vt ); + v3_copy( co, mc->post ); +} + + +VG_STATIC void mixedcam_iterate_firstperson_frame( player_interface *player, + struct mixedcam_state *mc ) +{ + v3_lerp( mc->vl, mc->vt, 4.0f*vg.time_delta, mc->vl ); +} + +VG_STATIC void mixedcam_iterate_thirdperson_frame( player_interface *player, + struct mixedcam_state *mc ) +{ + v3f prev_pos, origin, target, dir; + + v3_copy( mc->pos, prev_pos ); + + if( mc->gate ) + { + m4x3f inverse; + m4x3_invert_affine( mc->gate->transport, inverse ); + m4x3_mulv( inverse, mc->post, origin ); + } + else + { + v3_copy( mc->post, origin ); + } + + /* TODO: Remove? */ + v3_add( origin, (v3f){0.0f,1.35f,0.0f}, origin ); + v3_sub( origin, mc->pos, dir ); + + if( v3_length2( dir ) < 0.1f*0.1f ) + v3_copy( (v3f){ 0.0f, 0.0f, 1.0f }, dir ); /* FIXME */ + else + v3_normalize( dir ); + + v3_muladds( origin, dir, -2.0f, target ); + v3_lerp( mc->pos, target, vg.frame_delta * 12.0f, mc->pos ); + v3_copy( dir, mc->dir ); + + if( mc->gate ) + { + v2f _; + if( gate_intersect_plane( mc->gate, mc->pos, prev_pos, _ ) ) + { + m4x3_mulv( mc->gate->transport, mc->pos, mc->pos ); + m3x3_mulv( mc->gate->transport, mc->dir, mc->dir ); + //player_apply_transport_to_cam( mc->gate->transport ); + + mc->gate = NULL; + } + } +} + +VG_STATIC void mixedcam_iterate_frame( player_interface *player, + struct mixedcam_state *mc ) +{ + if( cl_thirdperson ) + mixedcam_iterate_thirdperson_frame( player, mc ); + else + mixedcam_iterate_firstperson_frame( player, mc ); +} + +VG_STATIC void mixedcam_get_camera( struct mixedcam_state *mc ) +{ + +} + +#endif /* PLAYER_DEVICE_COMMON_H */ diff --git a/player_device_dead.h b/player_device_dead.h index 848e8ec..9a0ed20 100644 --- a/player_device_dead.h +++ b/player_device_dead.h @@ -23,7 +23,6 @@ VG_STATIC void player_dead_update( player_interface *player, VG_STATIC void player_dead_post_update( player_interface *player, player_attachment *at ) { - copy_ragdoll_pose_to_avatar( &player->ragdoll, player->playeravatar ); } VG_STATIC void player_dead_ui( player_interface *player, @@ -38,22 +37,35 @@ VG_STATIC void player_dead_bind( player_interface *player, player->rb.v ); } -VG_STATIC void player_dead_pose( player_interface *player, - player_attachment *at, - player_pose pose, m4x3f transform ) +/* FIXME: This should be an optional function */ +VG_STATIC void player_dead_animate( player_interface *player, + player_attachment *at ) { + v3_zero( at->pose_root_co ); + q_identity( at->pose_root_q ); + + for( int i=0; ipose ); i ++ ) + { + v3_zero( at->pose[i].co ); + v3_fill( at->pose[i].s, 1.0f ); + q_identity( at->pose[i].q ); + } } -/* FIXME: player_device_common */ -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 ); - -VG_STATIC void player_dead_get_camera( player_interface *player, - player_attachment *at, camera *cam ) +VG_STATIC void player_dead_post_animate( player_interface *player, + player_attachment *at ) { struct player_avatar *av = player->playeravatar; + v3_zero( at->cam_1st.pos ); + v3_zero( at->cam_1st.angles ); + at->cam_1st.fov = 90.0f; + + /* FIXME: This overwrites pose blending, however, do we need to blend with + * this device, anyway? */ + copy_ragdoll_pose_to_avatar( &player->ragdoll, player->playeravatar ); + +#if 0 v3f vp = {-0.1f,1.8f,0.0f}, vd = {-1.0f,0.0f,0.0f}; @@ -64,6 +76,7 @@ VG_STATIC void player_dead_get_camera( player_interface *player, cam->fov = 119.0f; skate_camera_vector_look( cam, vd, 1.0f, 0.0f ); +#endif } VG_STATIC void player_dead_transport( player_interface *player, @@ -77,12 +90,12 @@ VG_STATIC player_device player_device_dead = .pre_update = player_dead_pre_update, .update = player_dead_update, .post_update = player_dead_post_update, - .get_camera = player_dead_get_camera, + .animate = player_dead_animate, + .post_animate = player_dead_post_animate, .debug_ui = player_dead_ui, .bind = player_dead_bind, #if 0 .pose = player_dead_pose, #endif - .gate_transport= player_dead_transport }; #endif /* PLAYER_DEVICE_DEAD_H */ diff --git a/player_device_skate.h b/player_device_skate.h index 3d5b079..04a2da1 100644 --- a/player_device_skate.h +++ b/player_device_skate.h @@ -4,6 +4,7 @@ #include "player_interface.h" #include "skeleton.h" #include "player_model.h" +#include "player_device_common.h" struct player_device_skate { @@ -43,8 +44,9 @@ struct player_device_skate double start_push, cur_push; - v3f vl, follow_cam_pos; - struct teleport_gate *follow_cam_gate; + struct mixedcam_state cam; + + v3f prev_pos; } state, state_gate_storage; @@ -1101,6 +1103,7 @@ VG_STATIC void player_skate_update( player_interface *player, player_attachment *at ) { struct player_device_skate *s = at->storage; + v3_copy( player->rb.co, s->state.prev_pos ); s->state.activity_prev = s->state.activity; /* Setup colliders */ @@ -1158,6 +1161,27 @@ VG_STATIC void player_skate_update( player_interface *player, vg_line_pt3( s->state.cog, 0.14f, VG__WHITE ); vg_line( player->rb.co, s->state.cog, VG__RED ); + + + teleport_gate *gate; + if( (gate = world_intersect_gates( player->rb.co, s->state.prev_pos )) ) + { + m4x3_mulv( gate->transport, player->rb.co, player->rb.co ); + m3x3_mulv( gate->transport, player->rb.v, player->rb.v ); + m4x3_mulv( gate->transport, s->state.cog, s->state.cog ); + m3x3_mulv( gate->transport, s->state.cog_v, s->state.cog_v ); + m3x3_mulv( gate->transport, s->state.throw_v, s->state.throw_v ); + + mixedcam_transport( &s->state.cam, gate ); + + v4f transport_rotation; + m3x3_q( gate->transport, transport_rotation ); + q_mul( transport_rotation, player->rb.q, player->rb.q ); + rb_update_transform( &player->rb ); + + s->state_gate_storage = s->state; + player_pass_gate( player, gate ); + } } VG_STATIC void player_skate_post_update( player_interface *player, @@ -1191,14 +1215,8 @@ 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 ) +VG_STATIC void player_skate_animate( player_interface *player, + player_attachment *at ) { struct player_device_skate *s = at->storage; struct player_avatar *av = player->playeravatar; @@ -1363,7 +1381,7 @@ VG_STATIC void player_skate_pose( player_interface *player, skeleton_lerp_pose( sk, apose, bpose, s->state.grabbing, air_pose ); } - skeleton_lerp_pose( sk, ground_pose, air_pose, s->blend_fly, pose ); + skeleton_lerp_pose( sk, ground_pose, air_pose, s->blend_fly, at->pose ); float add_grab_mod = 1.0f - s->blend_fly; @@ -1377,13 +1395,13 @@ VG_STATIC void player_skate_pose( player_interface *player, for( int i=0; ipose[apply_to[i]-1].co[0] += offset[0]*add_grab_mod; + at->pose[apply_to[i]-1].co[2] += offset[2]*add_grab_mod; } - mdl_keyframe *kf_board = &pose[av->id_board-1], - *kf_foot_l = &pose[av->id_ik_foot_l-1], - *kf_foot_r = &pose[av->id_ik_foot_r-1]; + mdl_keyframe *kf_board = &at->pose[av->id_board-1], + *kf_foot_l = &at->pose[av->id_ik_foot_l-1], + *kf_foot_r = &at->pose[av->id_ik_foot_r-1]; v3f bo; v3_muls( s->board_offset, add_grab_mod, bo ); @@ -1409,9 +1427,10 @@ VG_STATIC void player_skate_pose( player_interface *player, } /* transform */ - rb_extrapolate_transform( &player->rb, transform ); + rb_extrapolate( &player->rb, at->pose_root_co, at->pose_root_q ); - v3_muladds( transform[3], player->rb.to_world[1], -0.28f, transform[3] ); + v3_muladds( at->pose_root_co, player->rb.to_world[1], -0.28f, + at->pose_root_co ); v4f qresy, qresx, qresidual; m3x3f mtx_residual; @@ -1420,22 +1439,21 @@ VG_STATIC void player_skate_pose( player_interface *player, q_axis_angle( qresx, player->rb.to_world[0], s->state.steerx_s*substep ); q_mul( qresy, qresx, qresidual ); - q_m3x3( qresidual, mtx_residual ); - m3x3_mul( transform, mtx_residual, transform ); + q_normalize( qresidual ); + q_mul( at->pose_root_q, qresidual, at->pose_root_q ); + q_normalize( at->pose_root_q ); - if( cl_thirdperson && s->state.follow_cam_gate ) +#if 0 + if( cl_thirdperson ) { - 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, _ ) ) + if( !followcam_will_hit_gate( player, &s->state.cam ) ) { m4x3f inverse; - m4x3_invert_affine( s->state.follow_cam_gate->transport, inverse ); + m4x3_invert_affine( s->state.cam.gate->transport, inverse ); m4x3_mul( inverse, transform, transform ); } } +#endif } VG_STATIC void skate_camera_vector_look( camera *cam, v3f v, float C, float k ) @@ -1455,15 +1473,17 @@ VG_STATIC void skate_camera_vector_look( camera *cam, v3f v, float C, float k ) } VG_STATIC void skate_camera_firstperson( player_interface *player, - struct player_device_skate *s, - struct player_avatar *av, camera *cam ) + player_attachment *at ) { + struct player_device_skate *s = at->storage; + struct player_avatar *av = player->playeravatar; + /* FIXME: viewpoint entity */ v3f vp = {-0.1f,1.8f,0.0f}; - m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, cam->pos ); + m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, at->cam_1st.pos ); - v3_zero( cam->angles ); - cam->fov = 119.0f; + v3_zero( at->cam_1st.angles ); + at->cam_1st.fov = 119.0f; v3f flat_dir, vel_dir, @@ -1486,84 +1506,57 @@ VG_STATIC void skate_camera_firstperson( player_interface *player, //v3_normalize( flat_dir ); 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 ); - - skate_camera_vector_look( cam, s->state.vl, 0.7f, 0.5f ); -} - -/* this is a little yucky but needs to be done so we can use this 'prediction' - * in the pose function. its unfortunate. too bad - * - * FIXME: Can do better with FREEDOM MODE + api ordering. - */ -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_lerp( s->state.cam.vl, look_dir, 4.0f*vg.time_delta, s->state.cam.vl ); - v3_muladds( origin, d, -2.0f, target ); - v3_lerp( s->state.follow_cam_pos, target, vg.frame_delta * 12.0f, next_pos ); + skate_camera_vector_look( &at->cam_1st, s->state.cam.vl, 0.7f, 0.5f ); } +#if 0 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); + v3_copy( s->state.cam.pos, prev_pos ); + skate_camera_thirdperson_nextpos( player, s, av, s->state.cam.pos, d); - if( s->state.follow_cam_gate ) + if( s->state.cam.gate ) { v2f _; - if( gate_intersect_plane( s->state.follow_cam_gate, - s->state.follow_cam_pos, prev_pos, _ ) ) + if( gate_intersect_plane( s->state.cam.gate, + s->state.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 ); + m4x3_mulv( s->state.cam.gate->transport, + s->state.cam.pos, s->state.cam.pos ); + m3x3_mulv( s->state.cam.gate->transport, d, d ); + player_apply_transport_to_cam( s->state.cam.gate->transport ); - s->state.follow_cam_gate = NULL; + s->state.cam.gate = NULL; } } skate_camera_vector_look( cam, d, 1.0f, 0.0f ); - v3_copy( s->state.follow_cam_pos, cam->pos ); + v3_copy( s->state.cam.pos, cam->pos ); } +#endif -VG_STATIC void player_skate_get_camera( player_interface *player, - player_attachment *at, camera *cam ) +VG_STATIC void player_skate_post_animate( player_interface *player, + player_attachment *at ) { struct player_device_skate *s = at->storage; struct player_avatar *av = player->playeravatar; + v3_zero( at->cam_1st.pos ); + v3_zero( at->cam_1st.angles ); + at->cam_1st.fov = 90.0f; + +#if 0 if( cl_thirdperson ) skate_camera_thirdperson( player, s, av, cam ); else - skate_camera_firstperson( player, s, av, cam ); +#endif + skate_camera_firstperson( player, at ); /* FIXME: Organize this. Its int wrong fucking place */ v3f vp0 = {0.0f,0.1f, 0.6f}, @@ -1577,27 +1570,6 @@ VG_STATIC void player_skate_transport( player_interface *player, player_attachment *at, teleport_gate *gate ) { - struct player_device_skate *s = at->storage; - - m4x3_mulv( gate->transport, player->rb.co, player->rb.co ); - m3x3_mulv( gate->transport, player->rb.v, player->rb.v ); - m4x3_mulv( gate->transport, s->state.cog, s->state.cog ); - m3x3_mulv( gate->transport, s->state.cog_v, s->state.cog_v ); - m3x3_mulv( gate->transport, s->state.vl, s->state.vl ); - m3x3_mulv( gate->transport, s->state.throw_v, s->state.throw_v ); - - v4f transport_rotation; - m3x3_q( gate->transport, transport_rotation ); - 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, @@ -1606,7 +1578,8 @@ 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; + + mixedcam_reset( player, &s->state.cam ); } VG_STATIC player_device player_device_skate = @@ -1614,11 +1587,10 @@ VG_STATIC player_device player_device_skate = .pre_update = player_skate_pre_update, .update = player_skate_update, .post_update = player_skate_post_update, - .get_camera = player_skate_get_camera, + .animate = player_skate_animate, + .post_animate = player_skate_post_animate, .debug_ui = player_skate_ui, .bind = player_skate_bind, - .pose = player_skate_pose, - .gate_transport= player_skate_transport, .reset = player_skate_reset }; diff --git a/player_device_walk.h b/player_device_walk.h index 94f4368..3b30d06 100644 --- a/player_device_walk.h +++ b/player_device_walk.h @@ -12,6 +12,7 @@ struct player_device_walk struct { v3f angles; + v3f prev_pos; enum walk_activity { @@ -99,6 +100,8 @@ VG_STATIC void player_walk_update( player_interface *player, player_attachment *at ) { struct player_device_walk *w = at->storage; + v3_copy( player->rb.co, w->state.prev_pos ); + w->collider.height = 2.0f; w->collider.radius = 0.3f; @@ -283,31 +286,21 @@ VG_STATIC void player_walk_update( player_interface *player, v3_add( player->rb.co, (v3f){0.0f, 1.0f, 0.0f}, mtx[3] ); debug_capsule( mtx, w->collider.radius, w->collider.height, VG__GREEN ); -} - -VG_STATIC void player_walk_post_update( player_interface *player, - player_attachment *at ) -{ - struct player_device_walk *w = at->storage; - - m4x3f mtx; - m3x3_identity( mtx ); - v3_add( player->rb.co, (v3f){0.0f, 1.0f, 0.0f}, mtx[3] ); - - float substep = vg_clampf( vg.accumulator / k_rb_delta, 0.0f, 1.0f ); - v3_muladds( mtx[3], player->rb.v, k_rb_delta*substep, mtx[3] ); - debug_capsule( mtx, w->collider.radius, w->collider.height, VG__YELOW ); - + /* + * CCD routine + * --------------------------------------------------- + * + */ v3f lwr_prev, lwr_now, lwr_offs = { 0.0f, w->collider.radius, 0.0f }; - v3_add( lwr_offs, player->prev_position, lwr_prev ); + v3_add( lwr_offs, w->state.prev_pos, lwr_prev ); v3_add( lwr_offs, player->rb.co, lwr_now ); v3f movedelta; - v3_sub( player->rb.co, player->prev_position, movedelta ); + v3_sub( player->rb.co, w->state.prev_pos, movedelta ); float movedist = v3_length( movedelta ); @@ -326,35 +319,49 @@ VG_STATIC void player_walk_post_update( player_interface *player, debug_capsule( mtx, w->collider.radius, w->collider.height, VG__RED ); } } -} -VG_STATIC void player_walk_ui( player_interface *player, - player_attachment *at ) -{ - player_debugtext( 1, "V: %5.2f %5.2f %5.2f",player->rb.v[0], - player->rb.v[1], - player->rb.v[2] ); - player_debugtext( 1, "CO: %5.2f %5.2f %5.2f",player->rb.co[0], - player->rb.co[1], - player->rb.co[2] ); + teleport_gate *gate; + if( (gate = world_intersect_gates( player->rb.co, w->state.prev_pos )) ) + { + struct player_device_walk *w = at->storage; + + m4x3_mulv( gate->transport, player->rb.co, player->rb.co ); + m3x3_mulv( gate->transport, player->rb.v, player->rb.v ); + rb_update_transform( &player->rb ); + + /* analytical rotation of yaw */ + v3f fwd_dir = { cosf(w->state.angles[0]), + 0.0f, + sinf(w->state.angles[0])}; + m3x3_mulv( gate->transport, fwd_dir, fwd_dir ); + w->state.angles[0] = atan2f( fwd_dir[2], fwd_dir[0] ); + + w->state_gate_storage = w->state; + player_pass_gate( player, gate ); + } } -VG_STATIC void player_walk_bind( player_interface *player, - player_attachment *at ) +VG_STATIC void player_walk_post_update( player_interface *player, + player_attachment *at ) { struct player_device_walk *w = at->storage; - struct player_avatar *av = player->playeravatar; - struct skeleton *sk = &av->sk; - w->anim_idle = skeleton_get_anim( sk, "idle_cycle" ); - w->anim_walk = skeleton_get_anim( sk, "walk" ); - w->anim_run = skeleton_get_anim( sk, "run" ); - w->anim_jump = skeleton_get_anim( sk, "jump" ); + m4x3f mtx; + m3x3_identity( mtx ); + v3_add( player->rb.co, (v3f){0.0f, 1.0f, 0.0f}, mtx[3] ); + + float substep = vg_clampf( vg.accumulator / k_rb_delta, 0.0f, 1.0f ); + v3_muladds( mtx[3], player->rb.v, k_rb_delta*substep, mtx[3] ); + debug_capsule( mtx, w->collider.radius, w->collider.height, VG__YELOW ); + +#if 0 + player_apply_transport_to_cam( gate->transport ); +#endif + } -VG_STATIC void player_walk_pose( player_interface *player, - player_attachment *at, - player_pose pose, m4x3f transform ) +VG_STATIC void player_walk_animate( player_interface *player, + player_attachment *at ) { struct player_device_walk *w = at->storage; struct skeleton *sk = &player->playeravatar->sk; @@ -409,49 +416,73 @@ VG_STATIC void player_walk_pose( player_interface *player, /* air */ skeleton_sample_anim( sk, w->anim_jump, vg.time*0.6f, bpose ); - skeleton_lerp_pose( sk, apose, bpose, w->blend_fly, pose ); - - /* Create transform matrix */ - m3x3f rotation_mtx; - v4f rot; - q_axis_angle( rot, (v3f){0.0f,1.0f,0.0f}, -w->state.angles[0]-VG_PIf*0.5f ); - q_m3x3( rot, rotation_mtx ); + skeleton_lerp_pose( sk, apose, bpose, w->blend_fly, at->pose ); - rb_extrapolate_transform( &player->rb, transform ); - m3x3_copy( rotation_mtx, transform ); + /* Create transform */ + rb_extrapolate( &player->rb, at->pose_root_co, at->pose_root_q ); + q_axis_angle( at->pose_root_q, (v3f){0.0f,1.0f,0.0f}, + -w->state.angles[0]-VG_PIf*0.5f ); } -VG_STATIC void player_walk_get_camera( player_interface *player, - player_attachment *at, camera *cam ) +VG_STATIC void player_walk_post_animate( player_interface *player, + player_attachment *at ) { + /* + * Camera + */ struct player_device_walk *w = at->storage; struct player_avatar *av = player->playeravatar; + /* 3RD */ + m3x3f angles; + euler_m3x3( w->state.angles, angles ); + + v3f cast_dir, origin; + + v3_add( player->rb.co, (v3f){0.0f,2.0f,0.0f}, origin ); + + v3_muladds( origin, angles[2], 2.0f, at->cam_3rd.pos ); + v3_muladds( at->cam_3rd.pos, angles[0], 0.5f, at->cam_3rd.pos ); + + float t; + v3f n; + if( spherecast_world( origin, at->cam_3rd.pos, 0.1f, &t, n ) != -1 ) + v3_lerp( origin, at->cam_3rd.pos, t, at->cam_3rd.pos ); + v3_copy( w->state.angles, at->cam_3rd.angles ); + at->cam_3rd.fov = 90.0f; + + + /* 1ST */ /* FIXME: viewpoint entity */ v3f vp = {-0.1f,1.8f,0.0f}; - m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, cam->pos ); - v3_copy( w->state.angles, cam->angles ); - cam->fov = 90.0f; + m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], vp, at->cam_1st.pos ); + v3_copy( w->state.angles, at->cam_1st.angles ); + at->cam_1st.fov = 90.0f; } -VG_STATIC void player_walk_transport( player_interface *player, - player_attachment *at, - teleport_gate *gate ) -{ - struct player_device_walk *w = at->storage; - m4x3_mulv( gate->transport, player->rb.co, player->rb.co ); - m3x3_mulv( gate->transport, player->rb.v, player->rb.v ); +VG_STATIC void player_walk_ui( player_interface *player, + player_attachment *at ) +{ + player_debugtext( 1, "V: %5.2f %5.2f %5.2f",player->rb.v[0], + player->rb.v[1], + player->rb.v[2] ); + player_debugtext( 1, "CO: %5.2f %5.2f %5.2f",player->rb.co[0], + player->rb.co[1], + player->rb.co[2] ); +} - /* analytical rotation of yaw */ - v3f fwd_dir = { cosf(w->state.angles[0]), - 0.0f, - sinf(w->state.angles[0])}; - m3x3_mulv( gate->transport, fwd_dir, fwd_dir ); - w->state.angles[0] = atan2f( fwd_dir[2], fwd_dir[0] ); +VG_STATIC void player_walk_bind( player_interface *player, + player_attachment *at ) +{ + struct player_device_walk *w = at->storage; + struct player_avatar *av = player->playeravatar; + struct skeleton *sk = &av->sk; - w->state_gate_storage = w->state; - player_apply_transport_to_cam( gate->transport ); + w->anim_idle = skeleton_get_anim( sk, "idle_cycle" ); + w->anim_walk = skeleton_get_anim( sk, "walk" ); + w->anim_run = skeleton_get_anim( sk, "run" ); + w->anim_jump = skeleton_get_anim( sk, "jump" ); } VG_STATIC player_device player_device_walk = @@ -459,11 +490,10 @@ VG_STATIC player_device player_device_walk = .pre_update = player_walk_pre_update, .update = player_walk_update, .post_update = player_walk_post_update, - .get_camera = player_walk_get_camera, .debug_ui = player_walk_ui, .bind = player_walk_bind, - .pose = player_walk_pose, - .gate_transport= player_walk_transport + .animate = player_walk_animate, + .post_animate = player_walk_post_animate }; #endif /* PLAYER_DEVICE_WALK_H */ diff --git a/player_interface.h b/player_interface.h index acd9e1e..e0830c1 100644 --- a/player_interface.h +++ b/player_interface.h @@ -13,6 +13,8 @@ typedef struct player_interface player_interface; typedef struct player_attachment player_attachment; typedef mdl_keyframe player_pose[32]; +#define PLAYER_DEVICE_API VG_STATIC + struct player_interface { rigidbody rb; @@ -22,8 +24,33 @@ struct player_interface { player_device *device; void *storage; + + /* animation driven */ + player_pose pose; + v3f pose_root_co; + v4f pose_root_q; + camera cam_1st, cam_3rd; + } + dev, + dev_previous; + + enum camera_mode + { + k_camera_mode_firstperson, + k_camera_mode_thirdperson } - dev; + camera_mode; + + float camera_type_blend; + + /* TODO: have an automated system for crossing the thirdperson camera + * across portal boundaries. if it fails the check with the gate plane, then + * transform root_co and root_q, as well as final camera, BACK across the + * division, using the inverse of the transport matrix + */ + + int device_blend; + float device_blend_time; struct input_binding *input_js1h, *input_js1v, @@ -36,13 +63,23 @@ struct player_interface *input_walkv, *input_use, *input_reset, - *input_grab; + *input_grab, + *input_camera; +#if 0 v3f prev_position; +#endif struct player_avatar *playeravatar; glmesh *playermesh; struct player_ragdoll ragdoll; + + + /* FIXME: eventually store animation state here when we have more than 1 + * player. since currently its written into the avatar + * + * struct avatar_anim_state anim_state; + */ }; /* FIXME: yo */ @@ -51,26 +88,71 @@ vg_tex2d tex_characters = { .path = "textures/ch_gradient.qoi" }; struct player_device { void (* bind ) ( player_interface *player, player_attachment *at ); + + /* + * Regular updates + */ void (* pre_update) ( player_interface *player, player_attachment *at ); void (* update) ( player_interface *player, player_attachment *at ); void (* post_update)( player_interface *player, player_attachment *at ); - void (* pose) ( player_interface *player, player_attachment *at, - player_pose pose, m4x3f transform ); - void (* get_camera) ( player_interface *player, player_attachment *at, - camera *cam ); - - void (* attatch ) ( player_interface *player, player_attachment *at, - void *storage ); +#if 0 + /* + * Get current pose, and root transform + */ + void (* pose) ( player_interface *player, player_attachment *at, + player_pose pose, v3f root_co, v4f root_q ); +#endif + /* + * Use this to fill out animation state + */ + void (* animate) ( player_interface *player, player_attachment *at ); + + /* Get current camera, required fields to be filled are: + * fov + * pos + * angles + * + * They may be blended with other systems + */ + void (* post_animate) ( player_interface *player, player_attachment *at ); + + /* + This is called when a player is forced back to a spawnpoint. + */ void (* reset ) ( player_interface *player, player_attachment *at, struct respawn_point *spawn ); - void (* store_state)( player_interface *player, player_attachment *at ); - void (* load_state) ( player_interface *player, player_attachment *at ); + /* + * make calls into player_debugtext( .. ) in this function + */ void (* debug_ui) ( player_interface *player, player_attachment *at ); + +#if 0 + /* + * Called when going through a gate, it should modify any direction and + * position sensitive things, as well as store context here. it may be + * restored later. + */ void (* gate_transport)( player_interface *player, player_attachment *at, teleport_gate *gate ); +#endif + + /* + * Load the state previously saved when gate_transport was called + */ + void (* load_state) ( player_interface *player, player_attachment *at ); + + + + +#if 0 + void (* store_state)( player_interface *player, player_attachment *at ); + void (* attatch ) ( player_interface *player, player_attachment *at, + void *storage ); +#endif + }; VG_STATIC void player_interface_create_player( player_interface *inst ) @@ -91,6 +173,7 @@ VG_STATIC void player_interface_create_player( player_interface *inst ) inst->input_walkv= vg_create_named_input( "walk-v", k_input_type_axis ); inst->input_use = vg_create_named_input( "use", k_input_type_button ); inst->input_reset= vg_create_named_input( "reset", k_input_type_button ); + inst->input_camera=vg_create_named_input( "camera", k_input_type_button ); const char *default_cfg[] = { @@ -128,6 +211,7 @@ VG_STATIC void player_interface_create_player( player_interface *inst ) "bind use gp-y", "bind use e", + "bind camera c" }; for( int i=0; idev.device ); + if( vg_input_button_down( player->input_camera ) ) + { + if( player->camera_mode == k_camera_mode_firstperson ) + player->camera_mode = k_camera_mode_thirdperson; + else + player->camera_mode = k_camera_mode_firstperson; + } + +#if 0 v3_copy( player->rb.co, player->prev_position ); +#endif if( player->dev.device->pre_update ) player->dev.device->pre_update( player, &player->dev ); @@ -196,57 +290,43 @@ VG_STATIC void player_apply_transport_to_cam( m4x3f transport ) m4x4_mul( main_camera.mtx.v, transport_4, main_camera.mtx.v ); } -VG_STATIC void player_post_update( player_interface *player ) +/* + * Applies gate transport to a player_interface + */ +PLAYER_DEVICE_API +void player_pass_gate( player_interface *player, teleport_gate *gate ) { - /* FIXME: Applies to main_camera directly! */ +} + +VG_STATIC void player_post_update( player_interface *player ) +{ assert( player->dev.device ); if( player->dev.device->post_update ) player->dev.device->post_update( player, &player->dev ); - - /* FIXME: only need to test against the visible gate.... - * OR... bvh */ - - for( int i=0; igate; - - if( gate_intersect( gate, player->rb.co, player->prev_position ) ) - { - player->dev.device->gate_transport( player, &player->dev, gate ); - v3_copy( player->rb.co, player->prev_position ); - } - } - -#if 0 - camera_update_transform( &player->cam ); - camera_update_view( &player->cam ); - camera_update_projection( &player->cam ); - camera_finalize( &player->cam ); -#endif } -#if 0 VG_STATIC void player_pre_render( player_interface *player ) { - assert( player->dev.device ); + player->dev.device->animate( player, &player->dev ); - if( player->dev.device->pre_render ) - player->dev.device->pre_render( player ); -} -#endif + /* TODO: eventually, blending code goes here */ -VG_STATIC void player_pre_render( player_interface *player ) -{ - player_pose pose; m4x3f transform; + q_m3x3( player->dev.pose_root_q, transform ); + v3_copy( player->dev.pose_root_co, transform[3] ); + + struct skeleton *sk = &player->playeravatar->sk; - /* FIXME: Give devices more control over these render stages, and have - * 'API calls' - * for this kindof crap instead of it dictating order... */ + skeleton_apply_pose( sk, player->dev.pose, k_anim_apply_defer_ik ); + skeleton_apply_ik_pass( sk ); + skeleton_apply_pose( sk, player->dev.pose, k_anim_apply_deffered_only ); + skeleton_apply_inverses( sk ); + skeleton_apply_transform( sk, transform ); + skeleton_debug( sk ); +#if 0 if( player->dev.device->pose ) { player->dev.device->pose( player, &player->dev, pose, transform ); @@ -260,9 +340,29 @@ VG_STATIC void player_pre_render( player_interface *player ) skeleton_apply_transform( sk, transform ); skeleton_debug( sk ); } +#endif + + player->dev.device->post_animate( player, &player->dev ); - player->dev.device->get_camera( player, &player->dev, &player->cam ); - /* TODO: if dead copy ragdoll.. . */ + /* TODO: eventually, blending code goes here */ + + float camera_blend_target = 1.0f; + if( player->camera_mode == k_camera_mode_firstperson ) + camera_blend_target = 0.0f; + + player->camera_type_blend = vg_lerpf( player->camera_type_blend, + camera_blend_target, + 5.0f * vg.frame_delta ); + + float t = player->camera_type_blend; + camera_lerp( &player->dev.cam_1st, &player->dev.cam_3rd, t, &player->cam ); + + +#if 0 + v3_copy( player->dev.cam_1st.pos, player->cam.pos ); + v3_copy( player->dev.cam_1st.angles, player->cam.angles ); + player->cam.fov = player->dev.cam_1st.fov; +#endif } VG_STATIC void player_render( camera *cam, player_interface *player ) @@ -320,7 +420,9 @@ VG_STATIC void player_spawn( player_interface *player, struct respawn_point *rp ) { v3_copy( rp->co, player->rb.co ); +#if 0 v3_copy( rp->co, player->prev_position ); +#endif v3_zero( player->rb.v ); v3_zero( player->rb.w ); q_identity( player->rb.q ); @@ -330,6 +432,7 @@ VG_STATIC void player_spawn( player_interface *player, player->dev.device->reset( player, &player->dev, rp ); } + VG_STATIC void player_kill( player_interface *player ) { @@ -338,7 +441,8 @@ VG_STATIC void player_kill( player_interface *player ) /* * Apply per render-frame mouse look from player to angles */ -VG_STATIC void player_look( player_interface *player, v3f angles ) +PLAYER_DEVICE_API +void player_look( player_interface *player, v3f angles ) { angles[2] = 0.0f; v2_muladds( angles, vg.mouse_delta, 0.0025f, angles ); diff --git a/rigidbody.h b/rigidbody.h index d2ce949..ad4b600 100644 --- a/rigidbody.h +++ b/rigidbody.h @@ -404,6 +404,7 @@ VG_STATIC void rb_update_transform( rigidbody *rb ) * Extrapolate rigidbody into a transform based on vg accumulator. * Useful for rendering */ +__attribute__ ((deprecated)) VG_STATIC void rb_extrapolate_transform( rigidbody *rb, m4x3f transform ) { float substep = vg_clampf( vg.accumulator / k_rb_delta, 0.0f, 1.0f ); @@ -434,6 +435,30 @@ VG_STATIC void rb_extrapolate_transform( rigidbody *rb, m4x3f transform ) v3_copy( co, transform[3] ); } +VG_STATIC void rb_extrapolate( rigidbody *rb, v3f co, v4f q ) +{ + float substep = vg_clampf( vg.accumulator / k_rb_delta, 0.0f, 1.0f ); + + v3_muladds( rb->co, rb->v, k_rb_delta*substep, co ); + + if( v3_length2( rb->w ) > 0.0f ) + { + v4f rotation; + v3f axis; + v3_copy( rb->w, axis ); + + float mag = v3_length( axis ); + v3_divs( axis, mag, axis ); + q_axis_angle( rotation, axis, mag*k_rb_delta*substep ); + q_mul( rotation, rb->q, q ); + q_normalize( q ); + } + else + { + v4_copy( rb->q, q ); + } +} + /* * Initialize rigidbody and calculate masses, inertia */ diff --git a/skaterift.c b/skaterift.c index 0d3ff70..3923ca0 100644 --- a/skaterift.c +++ b/skaterift.c @@ -251,7 +251,7 @@ VG_STATIC void vg_load(void) player_use_avatar( &localplayer, &localplayer_avatar ); player_use_mesh( &localplayer, &localplayer_meshes[0] ); player_use_device( &localplayer, &player_device_walk, &localplayer_walk ); - player_use_device( &localplayer, &player_device_skate, &localplayer_skate ); + //player_use_device( &localplayer, &player_device_skate, &localplayer_skate ); /* --------------------- */ diff --git a/world_gate.h b/world_gate.h index f83cd87..1bf8afe 100644 --- a/world_gate.h +++ b/world_gate.h @@ -211,4 +211,21 @@ VG_STATIC int gate_intersect( teleport_gate *gate, v3f pos, v3f last ) return 0; } +/* + * Intersect all gates in the world + */ +VG_STATIC teleport_gate *world_intersect_gates( v3f pos, v3f last ) +{ + for( int i=0; igate; + + if( gate_intersect( gate, pos, last ) ) + return gate; + } + + return NULL; +} + #endif /* WORLD_GATE_H */ -- 2.25.1