double start_push,
cur_push;
- v3f vl;
+ v3f vl, follow_cam_pos;
+ struct teleport_gate *follow_cam_gate;
}
state,
state_gate_storage;
}
predictions[22];
u32 prediction_count;
+ float land_dist;
+ v3f land_normal;
/* animation */
struct skeleton_anim *anim_stand, *anim_highg, *anim_slide,
{
v4f correction;
q_axis_angle( correction, axis,
- acosf(angle)*(1.0f-limiter)*3.0f*VG_TIMESTEP_FIXED );
+ acosf(angle)*(1.0f-limiter)*2.0f*VG_TIMESTEP_FIXED );
q_mul( correction, player->rb.q, player->rb.q );
}
}
s->state.steery -= steer[0] * k_steer_air * VG_TIMESTEP_FIXED;
s->state.steerx += steer[1] * s->state.reverse * k_steer_air
* limiter * k_rb_delta;
+ s->land_dist = time_to_impact;
+ v3_copy( target_normal, s->land_normal );
}
VG_STATIC void skate_get_board_points( player_interface *player,
float angle = -atan2f( dy, dx );
q_axis_angle( s->board_rotation, (v3f){1.0f,0.0f,0.0f}, angle );
+ int lift_frames_limit = 1;
+
/* Surface connection */
if( len == 0 && !(spring_hit0 && spring_hit1) )
{
s->state.lift_frames ++;
- if( s->state.lift_frames >= 8 )
+ if( s->state.lift_frames >= lift_frames_limit )
s->state.activity = k_skate_activity_air;
}
else
{
s->state.lift_frames ++;
- if( s->state.lift_frames >= 8 )
+ if( s->state.lift_frames >= lift_frames_limit )
s->state.activity = k_skate_activity_air;
}
else
s->state.jump_charge = 0.0f;
s->state.jump_time = vg.time;
+
+ v2f steer = { player->input_js1h->axis.value,
+ player->input_js1v->axis.value };
+ v2_normalize_clamp( steer );
+
+ float maxspin = k_steer_air * k_rb_delta * k_spin_boost;
+ s->state.steery_s = -steer[0] * maxspin;
+ s->state.steerx_s = steer[1] * s->state.reverse * maxspin;
+ s->state.steerx = s->state.steerx_s;
+ s->state.steery = s->state.steery_s;
/* FIXME audio events */
#if 0
skate_apply_air_model( player, s );
skate_integrate( player, s );
+
+ vg_line_pt3( s->state.cog, 0.1f, VG__WHITE );
+ vg_line_pt3( s->state.cog, 0.11f, VG__WHITE );
+ vg_line_pt3( s->state.cog, 0.12f, VG__WHITE );
+ vg_line_pt3( s->state.cog, 0.13f, VG__WHITE );
+ vg_line_pt3( s->state.cog, 0.14f, VG__WHITE );
+
+ vg_line( player->rb.co, s->state.cog, VG__RED );
}
VG_STATIC void player_skate_post_update( player_interface *player,
"k_skate_activity_ground",
"k_skate_activity_grind }" }
[s->state.activity] );
+ player_debugtext( 1, "steer_s: %5.2f %5.2f [%.2f %.2f]\n",
+ s->state.steerx_s, s->state.steery_s,
+ 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 )
v3f offset;
v3_zero( offset );
+ m4x3_mulv( player->rb.to_local, s->state.cog, offset );
+ v3_muls( offset, -4.0f, offset );
+
#if 0
m3x3_mulv( player.inv_visual_transform, phys->bob, offset );
#endif
/* 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_zero( cam->angles );
cam->fov = 119.0f;
- /* TODO: smooth clamp lerp rate of change */
+ v3f flat_dir,
+ vel_dir,
+ look_dir;
- v3_lerp( s->state.vl, player->rb.v, 5.0f*vg.time_delta, s->state.vl );
+ v3_copy( player->rb.v, vel_dir );
+ //v3_normalize( vel_dir );
- 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;
+ float tti = s->land_dist;
+ v3f norm;
+ v3_copy( s->land_normal, norm );
- cam->angles[0] = yaw;
- cam->angles[1] = pitch;
+ if( s->state.activity == k_skate_activity_ground )
+ {
+ tti = 0.0f;
+ v3_copy( player->rb.to_world[1], norm );
+ }
+
+ v3_muladds( vel_dir, norm, -v3_dot(vel_dir,norm), flat_dir );
+ //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
+ */
+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 );
+
+ /* FIXME: Organize this. Its int wrong fucking place */
+ v3f vp0 = {0.0f,0.1f, 0.6f},
+ vp1 = {0.0f,0.1f,-0.6f};
+
+ m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp0, TEMP_BOARD_0 );
+ m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp1, TEMP_BOARD_1 );
}
VG_STATIC void player_skate_transport( player_interface *player,
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, player->rb.v, player->rb.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,
+ player_attachment *at,
+ struct respawn_point *rp )
+{
+ 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 =
.debug_ui = player_skate_ui,
.bind = player_skate_bind,
.pose = player_skate_pose,
- .gate_transport= player_skate_transport
+ .gate_transport= player_skate_transport,
+ .reset = player_skate_reset
};
#endif /* PLAYER_DEVICE_SKATE_H */