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 */
double start_push,
cur_push;
- v3f vl;
+ v3f vl, follow_cam_pos;
+ struct teleport_gate *follow_cam_gate;
}
state,
state_gate_storage;
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 )
/* 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;
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 );
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,
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,
{
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 =
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 )
{
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 );
}
}