6 VG_STATIC
void player_walk_transfer_to_skate( player_instance
*player
,
7 enum skate_activity init
)
9 struct player_walk
*w
= &player
->_walk
;
13 v3_copy( player
->rb
.v
, xy_speed
);
16 if( v3_length2( xy_speed
) < 0.1f
* 0.1f
)
18 q_mulv( player
->rb
.q
, (v3f
){0.0f
,0.0f
,-1.6f
}, v
);
21 v3_copy( player
->rb
.v
, v
);
23 player
->subsystem
= k_player_subsystem_skate
;
24 player__skate_transition( player
, v
, init
);
28 VG_STATIC
void temp_drop_in_finish( player_instance
*player
)
30 player
->subsystem
= k_player_subsystem_skate
;
32 struct player_walk
*w
= &player
->_walk
;
33 struct player_skate
*s
= &player
->_skate
;
34 s
->state
.activity_prev
= k_skate_activity_air
;
35 s
->state
.activity
= k_skate_activity_air
;
38 s
->blend_slide
= 0.0f
;
41 s
->blend_stand
= 0.0f
;
44 s
->blend_airdir
= 0.0f
;
46 v3f axis
, init_dir
, init_velocity
;
47 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, w
->state
.drop_in_normal
, axis
);
48 v3_cross( axis
, w
->state
.drop_in_normal
, init_dir
);
49 v3_normalize( init_dir
);
50 v3_muls( init_dir
, 7.0f
, init_velocity
);
52 rb_update_transform( &player
->rb
);
54 v3_muladds( player
->rb
.co
, player
->rb
.to_world
[1], 1.0f
, s
->state
.cog
);
55 v3_copy( init_velocity
, s
->state
.cog_v
);
56 v3_copy( init_velocity
, s
->state
.vl
);
57 v3_copy( init_velocity
, player
->rb
.v
);
58 v3_copy( init_velocity
, player
->cam_velocity_smooth
);
61 VG_STATIC
int player_walk_scan_for_drop_in( player_instance
*player
)
63 struct player_walk
*w
= &player
->_walk
;
66 q_mulv( player
->rb
.q
, (v3f
){0.0f
,0.0f
,1.0f
}, dir
);
67 v3_muladds( player
->rb
.co
, player
->rb
.to_world
[1], -1.0f
, center
);
72 for( int i
=0; i
<20; i
++ )
74 float t
= (float)i
* (1.0f
/19.0f
),
75 s
= sinf( t
* VG_PIf
* 0.25f
),
76 c
= cosf( t
* VG_PIf
* 0.25f
);
79 v3_muls ( player
->rb
.to_world
[1], -c
, ray_dir
);
80 v3_muladds( ray_dir
, dir
, -s
, ray_dir
);
81 v3_muladds( center
, ray_dir
, -2.0f
, pos
);
83 ray_hit
*ray
= &samples
[ sample_count
];
86 if( ray_world( pos
, ray_dir
, ray
) )
88 vg_line( pos
, ray
->pos
, VG__RED
);
89 vg_line_pt3( ray
->pos
, 0.025f
, VG__BLACK
);
95 float min_a
= 0.70710678118654752f
;
96 ray_hit
*candidate
= NULL
;
98 if( sample_count
>= 2 )
100 for( int i
=0; i
<sample_count
-1; i
++ )
102 ray_hit
*s0
= &samples
[i
],
105 float a
= v3_dot( s0
->normal
, s1
->normal
);
107 if( (a
< min_a
) && (a
>= -0.1f
) && (s0
->normal
[1]>s1
->normal
[1]) )
119 ray_hit
*s0
= candidate
,
122 vg_line( s0
->pos
, s1
->pos
, VG__WHITE
);
124 v3_copy( s0
->normal
, pa
);
125 v3_copy( s1
->normal
, pb
);
126 v3_cross( player
->rb
.to_world
[1], dir
, pc
);
129 pa
[3] = v3_dot( pa
, s0
->pos
);
130 pb
[3] = v3_dot( pb
, s1
->pos
);
131 pc
[3] = v3_dot( pc
, player
->rb
.co
);
134 if( plane_intersect3( pa
, pb
, pc
, edge
) )
136 v3_copy( edge
, w
->state
.drop_in_target
);
137 v3_copy( s1
->normal
, w
->state
.drop_in_normal
);
140 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, w
->state
.drop_in_normal
, axis
);
141 v3_cross( axis
, w
->state
.drop_in_normal
, init_dir
);
142 v3_normalize( init_dir
);
143 v3_muls( init_dir
, 7.0f
, player
->rb
.v
);
148 v3_muladds( w
->state
.drop_in_target
, s0
->normal
, 0.3f
,
151 player
->subsystem
= k_player_subsystem_skate
;
152 player__skate_transition( player
, s1
->normal
, k_skate_activity_air
);
157 vg_error( "failed to find intersection of drop in\n" );
164 VG_STATIC
void player__walk_pre_update( player_instance
*player
)
166 struct player_walk
*w
= &player
->_walk
;
168 if( w
->state
.activity
!= k_walk_activity_immobile
)
169 player_look( player
, player
->angles
);
171 if( w
->state
.outro_anim
)
173 float outro_length
= (float)w
->state
.outro_anim
->length
/
174 w
->state
.outro_anim
->rate
,
175 outro_time
= vg
.time
- w
->state
.outro_start_time
;
177 if( outro_time
>= outro_length
)
179 w
->state
.outro_anim
= NULL
;
180 if( w
->state
.outro_type
== k_walk_outro_drop_in
)
182 temp_drop_in_finish( player
);
186 player_walk_transfer_to_skate( player
, k_skate_activity_air
);
191 else if( vg_input_button_down( player
->input_use
) )
193 if( w
->state
.activity
== k_walk_activity_ground
)
195 //player_walk_transfer_to_skate( player, k_skate_activity_ground );
196 if( player_walk_scan_for_drop_in( player
) )
198 w
->state
.outro_type
= k_walk_outro_drop_in
;
199 w
->state
.outro_anim
= w
->anim_drop_in
;
200 w
->state
.outro_start_time
= vg
.time
;
202 v3_copy( player
->cam
.pos
, player
->follow_pos
);
203 v3_copy( player
->cam
.angles
, player
->follow_angles
);
205 w
->state
.activity
= k_walk_activity_immobile
;
206 //v3_zero( player->rb.v );
207 v3_copy( player
->rb
.co
, w
->state
.drop_in_start
);
209 w
->state
.drop_in_start_angle
= player_get_heading_yaw( player
);
210 w
->state
.drop_in_angle
= atan2f( w
->state
.drop_in_normal
[0],
211 w
->state
.drop_in_normal
[2] );
213 struct player_avatar
*av
= player
->playeravatar
;
214 m4x3_mulv( av
->sk
.final_mtx
[ av
->id_ik_foot_r
],
215 av
->sk
.bones
[ av
->id_ik_foot_r
].co
,
216 w
->state
.drop_in_foot_anchor
);
222 w
->state
.outro_type
= k_walk_outro_jump_to_air
;
223 w
->state
.outro_anim
= w
->anim_jump_to_air
;
224 w
->state
.outro_start_time
= vg
.time
;
226 v3_copy( player
->cam
.pos
, player
->follow_pos
);
227 v3_copy( player
->cam
.angles
, player
->follow_angles
);
234 VG_STATIC
int player_walk_normal_standable( v3f n
)
236 return n
[1] > 0.70710678118f
;
239 VG_STATIC
void player_accelerate( v3f v
, v3f movedir
, float speed
, float accel
)
241 float currentspeed
= v3_dot( v
, movedir
),
242 addspeed
= speed
- currentspeed
;
247 float accelspeed
= accel
* k_rb_delta
* speed
;
249 if( accelspeed
> addspeed
)
250 accelspeed
= addspeed
;
252 v3_muladds( v
, movedir
, accelspeed
, v
);
255 VG_STATIC
void player_friction( v3f v
)
257 float speed
= v3_length( v
),
259 control
= vg_maxf( speed
, k_stopspeed
);
264 drop
+= control
* k_walk_friction
* k_rb_delta
;
266 float newspeed
= vg_maxf( 0.0f
, speed
- drop
);
269 v3_muls( v
, newspeed
, v
);
272 VG_STATIC
void player__walk_update( player_instance
*player
)
274 struct player_walk
*w
= &player
->_walk
;
275 v3_copy( player
->rb
.co
, w
->state
.prev_pos
);
277 if( w
->state
.activity
== k_walk_activity_immobile
)
280 w
->collider
.height
= 2.0f
;
281 w
->collider
.radius
= 0.3f
;
284 m3x3_identity( mtx
);
285 v3_add( player
->rb
.co
, (v3f
){0.0f
, 1.0f
, 0.0f
}, mtx
[3] );
287 debug_capsule( mtx
, w
->collider
.radius
, w
->collider
.height
, VG__WHITE
);
292 float yaw
= player
->angles
[0];
294 v3f forward_dir
= { sinf(yaw
), 0.0f
, -cosf(yaw
) };
295 v3f right_dir
= { -forward_dir
[2], 0.0f
, forward_dir
[0] };
297 v2f walk
= { player
->input_walkh
->axis
.value
,
298 player
->input_walkv
->axis
.value
};
300 if( v2_length2(walk
) > 0.001f
)
301 v2_normalize_clamp( walk
);
303 w
->move_speed
= v2_length( walk
);
306 * Collision detection
308 len
= rb_capsule__scene( mtx
, &w
->collider
, NULL
,
309 &world
.rb_geo
.inf
.scene
, manifold
);
310 rb_manifold_filter_coplanar( manifold
, len
, 0.01f
);
311 len
= rb_manifold_apply_filtered( manifold
, len
);
313 v3f surface_avg
= { 0.0f
, 0.0f
, 0.0f
};
314 w
->state
.activity
= k_walk_activity_air
;
316 for( int i
=0; i
<len
; i
++ )
318 struct contact
*ct
= &manifold
[i
];
319 rb_debug_contact( ct
);
321 if( player_walk_normal_standable( ct
->n
) )
323 w
->state
.activity
= k_walk_activity_ground
;
324 v3_add( surface_avg
, ct
->n
, surface_avg
);
327 rb_prepare_contact( ct
);
333 float accel_speed
= 0.0f
, nominal_speed
= 0.0f
;
335 v3_muls( right_dir
, walk
[0], movedir
);
336 v3_muladds( movedir
, forward_dir
, walk
[1], movedir
);
338 if( w
->state
.activity
== k_walk_activity_ground
)
340 v3_normalize( surface_avg
);
343 rb_tangent_basis( surface_avg
, tx
, ty
);
345 if( v2_length2(walk
) > 0.001f
)
347 /* clip movement to the surface */
348 float d
= v3_dot(surface_avg
,movedir
);
349 v3_muladds( movedir
, surface_avg
, -d
, movedir
);
352 accel_speed
= k_walk_accel
;
353 nominal_speed
= k_walkspeed
;
356 if( player
->input_jump
->button
.value
)
358 player
->rb
.v
[1] = 5.0f
;
359 w
->state
.activity
= k_walk_activity_air
;
360 accel_speed
= k_walk_air_accel
;
361 nominal_speed
= k_airspeed
;
365 player_friction( player
->rb
.v
);
367 struct world_material
*surface_mat
= world_contact_material(manifold
);
368 w
->surface
= surface_mat
->info
.surface_prop
;
373 accel_speed
= k_walk_air_accel
;
374 nominal_speed
= k_airspeed
;
377 if( v2_length2(walk
) > 0.001f
)
379 player_accelerate( player
->rb
.v
, movedir
, nominal_speed
, accel_speed
);
380 v3_normalize( movedir
);
384 * Resolve velocity constraints
386 for( int j
=0; j
<5; j
++ )
388 for( int i
=0; i
<len
; i
++ )
390 struct contact
*ct
= &manifold
[i
];
393 float vn
= -v3_dot( player
->rb
.v
, ct
->n
);
395 float temp
= ct
->norm_impulse
;
396 ct
->norm_impulse
= vg_maxf( temp
+ vn
, 0.0f
);
397 vn
= ct
->norm_impulse
- temp
;
399 v3_muladds( player
->rb
.v
, ct
->n
, vn
, player
->rb
.v
);
408 for( int j
=0; j
<8; j
++ )
410 for( int i
=0; i
<len
; i
++ )
412 struct contact
*ct
= &manifold
[i
];
414 float resolved_amt
= v3_dot( ct
->n
, dt
),
415 remaining
= (ct
->p
-k_penetration_slop
) - resolved_amt
,
416 apply
= vg_maxf( remaining
, 0.0f
) * 0.3f
;
418 v3_muladds( dt
, ct
->n
, apply
, dt
);
421 v3_add( dt
, player
->rb
.co
, player
->rb
.co
);
423 /* TODO: Stepping......
425 * ideas; walkgrid style steps
428 if( w
->state
.activity
== k_walk_activity_ground
)
431 float max_dist
= 0.4f
;
434 v3_copy( player
->rb
.co
, pa
);
435 pa
[1] += w
->collider
.radius
+ max_dist
;
437 v3_muladds( pa
, (v3f
){0.0f
,1.0f
,0.0f
}, -max_dist
* 2.0f
, pb
);
438 vg_line( pa
, pb
, 0xff000000 );
442 if( spherecast_world( pa
, pb
, w
->collider
.radius
, &t
, n
) != -1 )
444 if( player_walk_normal_standable( n
) )
446 v3_lerp( pa
, pb
, t
, player
->rb
.co
);
447 player
->rb
.co
[1] -= w
->collider
.radius
;
455 if( w
->state
.activity
== k_walk_activity_air
)
456 player
->rb
.v
[1] += -k_gravity
* k_rb_delta
;
458 v3_muladds( player
->rb
.co
, player
->rb
.v
, k_rb_delta
, player
->rb
.co
);
461 v3_add( player
->rb
.co
, (v3f
){0.0f
, 1.0f
, 0.0f
}, mtx
[3] );
462 debug_capsule( mtx
, w
->collider
.radius
, w
->collider
.height
, VG__GREEN
);
466 * ---------------------------------------------------
471 lwr_offs
= { 0.0f
, w
->collider
.radius
, 0.0f
};
473 v3_add( lwr_offs
, w
->state
.prev_pos
, lwr_prev
);
474 v3_add( lwr_offs
, player
->rb
.co
, lwr_now
);
477 v3_sub( player
->rb
.co
, w
->state
.prev_pos
, movedelta
);
479 float movedist
= v3_length( movedelta
);
481 if( movedist
> 0.3f
)
483 float t
, sr
= w
->collider
.radius
-0.04f
;
486 if( spherecast_world( lwr_prev
, lwr_now
, sr
, &t
, n
) != -1 )
488 v3_lerp( lwr_prev
, lwr_now
, vg_maxf(0.01f
,t
), player
->rb
.co
);
489 player
->rb
.co
[1] -= w
->collider
.radius
;
490 rb_update_transform( &player
->rb
);
492 v3_add( player
->rb
.co
, (v3f
){0.0f
, 1.0f
, 0.0f
}, mtx
[3] );
493 debug_capsule( mtx
, w
->collider
.radius
, w
->collider
.height
, VG__RED
);
498 if( (gate
= world_intersect_gates( player
->rb
.co
, w
->state
.prev_pos
)) )
500 m4x3_mulv( gate
->transport
, player
->rb
.co
, player
->rb
.co
);
501 m3x3_mulv( gate
->transport
, player
->rb
.v
, player
->rb
.v
);
502 rb_update_transform( &player
->rb
);
504 /* analytical rotation of yaw */
505 float a
= player_get_heading_yaw( player
);
506 v3f fwd_dir
= { cosf(a
),
509 m3x3_mulv( gate
->transport
, fwd_dir
, fwd_dir
);
510 player
->angles
[0] = atan2f( fwd_dir
[2], fwd_dir
[0] );
512 w
->state_gate_storage
= w
->state
;
513 player__pass_gate( player
, gate
);
517 VG_STATIC
void player__walk_post_update( player_instance
*player
)
519 struct player_walk
*w
= &player
->_walk
;
522 m3x3_identity( mtx
);
523 v3_add( player
->rb
.co
, (v3f
){0.0f
, 1.0f
, 0.0f
}, mtx
[3] );
525 float substep
= vg_clampf( vg
.accumulator
/ k_rb_delta
, 0.0f
, 1.0f
);
526 v3_muladds( mtx
[3], player
->rb
.v
, k_rb_delta
*substep
, mtx
[3] );
527 debug_capsule( mtx
, w
->collider
.radius
, w
->collider
.height
, VG__YELOW
);
530 /* Calculate header */
533 v3_copy( player
->rb
.v
, xy_speed
);
536 if( v3_length2( xy_speed
) > 0.1f
* 0.1f
)
538 float a
= atan2f( player
->rb
.v
[0], player
->rb
.v
[2] );
539 q_axis_angle( player
->rb
.q
, (v3f
){0.0f
,1.0f
,0.0f
}, a
);
542 vg_line_pt3( w
->state
.drop_in_target
, 0.1f
, VG__GREEN
);
544 v3_muladds( w
->state
.drop_in_target
, w
->state
.drop_in_normal
, 0.3f
, p1
);
545 vg_line( w
->state
.drop_in_target
, p1
, VG__GREEN
);
546 v3_muladds( w
->state
.drop_in_target
, player
->rb
.to_world
[1], 0.3f
, p1
);
547 vg_line( w
->state
.drop_in_target
, p1
, VG__GREEN
);
549 vg_line( w
->state
.drop_in_target
, w
->state
.drop_in_foot_anchor
, VG__WHITE
);
550 vg_line_pt3( w
->state
.drop_in_foot_anchor
, 0.08f
, VG__PINK
);
553 float a
= player_get_heading_yaw( player
);
558 v3_add( player
->rb
.co
, p1
, p1
);
559 vg_line( player
->rb
.co
, p1
, VG__PINK
);
562 VG_STATIC
void player__walk_animate( player_instance
*player
,
563 player_animation
*dest
)
565 struct player_walk
*w
= &player
->_walk
;
566 struct skeleton
*sk
= &player
->playeravatar
->sk
;
569 float fly
= (w
->state
.activity
== k_walk_activity_air
)? 1.0f
: 0.0f
,
572 if( w
->state
.activity
== k_walk_activity_air
)
577 w
->blend_fly
= vg_lerpf( w
->blend_fly
, fly
, rate
*vg
.time_delta
);
578 w
->blend_run
= vg_lerpf( w
->blend_run
,
580 (1.0f
+ player
->input_walk
->button
.value
*0.5f
),
581 2.0f
*vg
.time_delta
);
584 player_pose apose
, bpose
;
586 if( w
->move_speed
> 0.025f
)
589 float walk_norm
= 30.0f
/(float)w
->anim_walk
->length
,
590 run_norm
= 30.0f
/(float)w
->anim_run
->length
,
591 walk_adv
= vg_lerpf( walk_norm
, run_norm
, w
->move_speed
);
593 w
->walk_timer
+= walk_adv
* vg
.time_delta
;
597 w
->walk_timer
= 0.0f
;
600 float walk_norm
= (float)w
->anim_walk
->length
/30.0f
,
601 run_norm
= (float)w
->anim_run
->length
/30.0f
,
603 l
= vg_clampf( w
->blend_run
*15.0f
, 0.0f
, 1.0f
),
604 idle_walk
= vg_clampf( (w
->blend_run
-0.1f
)/(1.0f
-0.1f
), 0.0f
, 1.0f
);
607 skeleton_sample_anim( sk
, w
->anim_walk
, t
*walk_norm
, apose
);
608 skeleton_sample_anim( sk
, w
->anim_run
, t
*run_norm
, bpose
);
610 skeleton_lerp_pose( sk
, apose
, bpose
, l
, apose
);
613 skeleton_sample_anim( sk
, w
->anim_idle
, vg
.time
*0.1f
, bpose
);
614 skeleton_lerp_pose( sk
, apose
, bpose
, 1.0f
-idle_walk
, apose
);
617 skeleton_sample_anim( sk
, w
->anim_jump
, vg
.time
*0.6f
, bpose
);
618 skeleton_lerp_pose( sk
, apose
, bpose
, w
->blend_fly
, apose
);
620 /* Create transform */
621 rb_extrapolate( &player
->rb
, dest
->root_co
, dest
->root_q
);
623 float walk_yaw
= player_get_heading_yaw( player
);
625 if( w
->state
.outro_anim
)
627 struct player_avatar
*av
= player
->playeravatar
;
628 float outro_length
= (float)w
->state
.outro_anim
->length
/
629 w
->state
.outro_anim
->rate
,
630 outro_time
= vg
.time
- w
->state
.outro_start_time
,
631 outro_t
= outro_time
/ outro_length
;
633 /* TODO: Compression */
634 skeleton_sample_anim_clamped( sk
, w
->state
.outro_anim
,
636 skeleton_lerp_pose( sk
, apose
, bpose
, outro_t
* 10.0f
, dest
->pose
);
638 if( w
->state
.outro_type
== k_walk_outro_drop_in
)
640 float inv_rate
= 1.0f
/ w
->state
.outro_anim
->rate
,
641 anim_frames
= w
->state
.outro_anim
->length
* inv_rate
,
642 step_frames
= 12.0f
* inv_rate
,
643 commit_frames
= 6.0f
* inv_rate
,
644 drop_frames
= anim_frames
- step_frames
,
645 step_t
= vg_minf( 1.0f
, outro_time
/ step_frames
),
646 remaind_time
= vg_maxf( 0.0f
, outro_time
- step_frames
),
647 dop_t
= vg_minf( 1.0f
, remaind_time
/ drop_frames
),
648 commit_t
= vg_minf( 1.0f
, remaind_time
/ commit_frames
);
650 walk_yaw
= vg_alerpf( w
->state
.drop_in_start_angle
,
651 w
->state
.drop_in_angle
, step_t
);
653 w
->state
.heading_angle
= walk_yaw
;
656 v3_lerp( w
->state
.drop_in_start
, w
->state
.drop_in_target
,
657 step_t
, player
->rb
.co
);
658 q_axis_angle( dest
->root_q
, (v3f
){0.0f
,1.0f
,0.0f
}, walk_yaw
+ VG_PIf
);
660 m4x3f transform
, inverse
;
661 q_m3x3( dest
->root_q
, transform
);
662 v3_copy( dest
->root_co
, transform
[3] );
663 m4x3_invert_affine( transform
, inverse
);
666 m4x3_mulv( inverse
, w
->state
.drop_in_foot_anchor
, anchored_pos
);
668 v3_lerp( dest
->pose
[ av
->id_ik_foot_r
-1 ].co
, anchored_pos
,
670 dest
->pose
[ av
->id_ik_foot_r
-1 ].co
);
673 /* the drop in bit */
676 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, w
->state
.drop_in_normal
, axis
);
677 v3_normalize( axis
);
679 float a
= acosf( w
->state
.drop_in_normal
[1] ) * dop_t
;
681 q_axis_angle( final_q
, axis
, a
);
682 q_mul( final_q
, dest
->root_q
, dest
->root_q
);
684 float l
= dop_t
* 0.5f
,
685 heading_angle
= player_get_heading_yaw( player
);
688 overhang
[0] = sinf( heading_angle
) * l
;
689 overhang
[1] = 0.28f
* l
;
690 overhang
[2] = cosf( heading_angle
) * l
;
692 q_mulv( final_q
, overhang
, overhang
);
694 v3_add( player
->rb
.co
, overhang
, player
->rb
.co
);
695 v3_copy( player
->rb
.co
, dest
->root_co
);
696 v4_copy( dest
->root_q
, player
->rb
.q
);
698 v3_muladds( dest
->root_co
, player
->rb
.to_world
[1],
699 -0.28f
* dop_t
, dest
->root_co
);
704 v3_muladds( dest
->root_co
, player
->rb
.to_world
[1],
705 -0.28f
* outro_t
, dest
->root_co
);
710 skeleton_copy_pose( sk
, apose
, dest
->pose
);
713 q_axis_angle( dest
->root_q
, (v3f
){0.0f
,1.0f
,0.0f
}, walk_yaw
+ VG_PIf
);
716 VG_STATIC
void player__walk_post_animate( player_instance
*player
)
721 struct player_walk
*w
= &player
->_walk
;
722 struct player_avatar
*av
= player
->playeravatar
;
724 if( w
->state
.outro_anim
)
726 float outro_length
= (float)w
->state
.outro_anim
->length
/
727 w
->state
.outro_anim
->rate
,
728 outro_time
= vg
.time
- w
->state
.outro_start_time
,
729 outro_t
= outro_time
/ outro_length
;
731 player
->cam_velocity_influence
= outro_t
;
734 player
->cam_velocity_influence
= 0.0f
;
740 v3_copy( w
->state
.angles
, view_angles
);
743 euler_m3x3( view_angles
, angles
);
745 v3f cast_dir
, origin
;
747 v3_add( player
->rb
.co
, (v3f
){0.0f
,2.0f
,0.0f
}, origin
);
749 v3_muladds( origin
, angles
[2], 2.0f
, player
->override_pos
);
750 v3_muladds( player
->override_pos
, angles
[0], 0.5f
, player
->override_pos
);
752 if( w
->state
.outro_anim
&& (w
->state
.outro_type
== k_walk_outro_drop_in
))
754 float outro_length
= (float)w
->state
.outro_anim
->length
/
755 w
->state
.outro_anim
->rate
,
756 outro_time
= vg
.time
- w
->state
.outro_start_time
,
757 outro_t
= outro_time
/ outro_length
;
759 player
->override_pos
[1] += outro_t
* 3.0f
;
764 if( spherecast_world( origin
, player
->override_pos
, 0.1f
, &t
, n
) != -1 )
765 v3_lerp( origin
, player
->override_pos
, t
, player
->override_pos
);
766 v3_copy( w
->state
.angles
, player
->override_angles
);
769 /* FIXME: viewpoint entity */
770 v3f vp
= {-0.1f
,1.8f
,0.0f
};
771 m4x3_mulv( av
->sk
.final_mtx
[ av
->id_head
-1 ], vp
, player
->fpv_pos
);
772 v3_copy( w
->state
.angles
, player
->fpv_angles
);
774 if( w
->state
.outro_anim
)
776 float outro_length
= (float)w
->state
.outro_anim
->length
/
777 w
->state
.outro_anim
->rate
,
778 outro_time
= vg
.time
- w
->state
.outro_start_time
,
779 outro_t
= outro_time
/ outro_length
;
781 /* FIXME: Compression */
782 v3_add( player
->rb
.co
, (v3f
){0.0f
,1.35f
,0.0f
}, origin
);
783 player_set_follower_subject( player
, origin
);
785 player
->cam_angles_override_strength
= 1.0f
-outro_t
;
786 player
->cam_position_override_strength
= 1.0f
-outro_t
;
790 if( w
->state
.outro_anim
)
792 if( w
->state
.outro_type
== k_walk_outro_drop_in
)
795 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, w
->state
.drop_in_normal
, axis
);
796 v3_cross( axis
, w
->state
.drop_in_normal
, init_dir
);
798 player_vector_angles( fpv_angles
, init_dir
, 1.0f
, 0.25f
);
802 player_vector_angles( fpv_angles
, player
->rb
.v
, 1.0f
, 0.25f
);
806 player_vector_angles( fpv_angles
, player
->rb
.v
, 1.0f
, 0.25f
);
808 camera_lerp_angles( player
->fpv_angles
, fpv_angles
, outro_t
,
809 player
->fpv_angles
);
813 player
->cam_angles_override_strength
= 1.0f
;
814 player
->cam_position_override_strength
= 1.0f
;
818 /* FIXME: Organize this. Its int wrong fucking place */
819 v3f vp0
= {0.0f
,0.1f
, 0.6f
},
820 vp1
= {0.0f
,0.1f
,-0.6f
};
821 m4x3_mulv( av
->sk
.final_mtx
[ av
->id_board
], vp0
, TEMP_BOARD_0
);
822 m4x3_mulv( av
->sk
.final_mtx
[ av
->id_board
], vp1
, TEMP_BOARD_1
);
826 VG_STATIC
void player__walk_im_gui( player_instance
*player
)
828 struct player_walk
*w
= &player
->_walk
;
829 player__debugtext( 1, "V: %5.2f %5.2f %5.2f",player
->rb
.v
[0],
832 player__debugtext( 1, "CO: %5.2f %5.2f %5.2f",player
->rb
.co
[0],
835 player__debugtext( 1, "activity: %s\n",
836 (const char *[]){ "k_walk_activity_air",
837 "k_walk_activity_ground",
838 "k_walk_activity_sleep",
839 "k_walk_activity_immobile" }
840 [w
->state
.activity
] );
842 if( w
->state
.outro_anim
)
844 float outro_length
= (float)w
->state
.outro_anim
->length
/
845 w
->state
.outro_anim
->rate
,
846 outro_time
= vg
.time
- w
->state
.outro_start_time
;
847 player__debugtext( 1, "outro time: %f / %f", outro_time
, outro_length
);
851 VG_STATIC
void player__walk_bind( player_instance
*player
)
853 struct player_walk
*w
= &player
->_walk
;
854 struct player_avatar
*av
= player
->playeravatar
;
855 struct skeleton
*sk
= &av
->sk
;
857 w
->anim_idle
= skeleton_get_anim( sk
, "idle_cycle+y" );
858 w
->anim_walk
= skeleton_get_anim( sk
, "walk+y" );
859 w
->anim_run
= skeleton_get_anim( sk
, "run+y" );
860 w
->anim_jump
= skeleton_get_anim( sk
, "jump+y" );
861 w
->anim_jump_to_air
= skeleton_get_anim( sk
, "jump_to_air" );
862 w
->anim_drop_in
= skeleton_get_anim( sk
, "drop_in" );
865 VG_STATIC
void player__walk_transition( player_instance
*player
, v3f angles
)
867 struct player_walk
*w
= &player
->_walk
;
869 v3_copy( angles
, w
->state
.angles
);
871 w
->state
.activity
= k_walk_activity_air
;
874 #endif /* PLAYER_DEVICE_WALK_H */