0b84ef16220140b2c72e7bd7eef64bb2b34260b1
6 VG_STATIC
void player_walk_drop_in_vector( player_instance
*player
, v3f vec
)
8 struct player_walk
*w
= &player
->_walk
;
11 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, w
->state
.drop_in_normal
, axis
);
12 v3_cross( axis
, w
->state
.drop_in_normal
, init_dir
);
13 v3_normalize( init_dir
);
14 v3_muls( init_dir
, 7.0f
, vec
);
17 VG_STATIC
void player_walk_generic_to_skate( player_instance
*player
,
18 enum skate_activity init
)
20 player
->subsystem
= k_player_subsystem_skate
;
22 struct player_walk
*w
= &player
->_walk
;
23 struct player_skate
*s
= &player
->_skate
;
27 v3_copy( player
->rb
.v
, xy_speed
);
30 if( v3_length2( xy_speed
) < 0.1f
* 0.1f
)
31 q_mulv( player
->rb
.q
, (v3f
){0.0f
,0.0f
,-1.6f
}, v
);
33 v3_copy( player
->rb
.v
, v
);
35 s
->state
.activity_prev
= k_skate_activity_ground
;
36 s
->state
.activity
= init
;
42 q_axis_angle( player
->rb
.q
, (v3f
){0.0f
,1.0f
,0.0f
},
43 atan2f( -dir
[0], -dir
[2] ) );
45 v3_muladds( player
->rb
.co
, player
->rb
.to_world
[1], 1.0f
, s
->state
.cog
);
46 v3_copy( v
, s
->state
.cog_v
);
47 v3_copy( v
, player
->rb
.v
);
49 player__skate_reset_animator( player
);
50 player__skate_clear_mechanics( player
);
51 rb_update_transform( &player
->rb
);
52 v3_copy( (v3f
){0.0f
,0.0f
,0.0f
}, s
->state
.trick_euler
);
54 if( init
== k_skate_activity_air
)
55 player__approximate_best_trajectory( player
);
58 VG_STATIC
void player_walk_drop_in_to_skate( player_instance
*player
)
60 player
->subsystem
= k_player_subsystem_skate
;
62 struct player_walk
*w
= &player
->_walk
;
63 struct player_skate
*s
= &player
->_skate
;
64 s
->state
.activity_prev
= k_skate_activity_ground
;
65 s
->state
.activity
= k_skate_activity_ground
;
67 player__skate_clear_mechanics( player
);
68 player__skate_reset_animator( player
);
71 player_walk_drop_in_vector( player
, init_velocity
);
73 rb_update_transform( &player
->rb
);
74 v3_muladds( player
->rb
.co
, player
->rb
.to_world
[1], 1.0f
, s
->state
.cog
);
75 v3_copy( init_velocity
, s
->state
.cog_v
);
76 v3_copy( init_velocity
, player
->rb
.v
);
77 v3_copy( init_velocity
, player
->cam_velocity_smooth
);
78 v3_copy( (v3f
){1.0f
,0.0f
,0.0f
}, s
->state
.trick_euler
);
81 VG_STATIC
void player_walk_drop_in_overhang_transform( player_instance
*player
,
85 struct player_walk
*w
= &player
->_walk
;
88 v3_cross( (v3f
){0.0f
,1.0f
,0.0f
}, w
->state
.drop_in_normal
, axis
);
91 float a
= acosf( w
->state
.drop_in_normal
[1] ) * t
;
93 q_axis_angle( q
, axis
, a
);
96 heading_angle
= w
->state
.drop_in_angle
;
99 overhang
[0] = sinf( heading_angle
) * l
;
100 overhang
[1] = 0.28f
* l
;
101 overhang
[2] = cosf( heading_angle
) * l
;
103 q_mulv( q
, overhang
, overhang
);
104 v3_add( w
->state
.drop_in_target
, overhang
, co
);
107 VG_STATIC
int player_walk_scan_for_drop_in( player_instance
*player
)
109 struct player_walk
*w
= &player
->_walk
;
112 q_mulv( player
->rb
.q
, (v3f
){0.0f
,0.0f
,1.0f
}, dir
);
113 v3_muladds( player
->rb
.co
, player
->rb
.to_world
[1], -1.0f
, center
);
116 int sample_count
= 0;
118 for( int i
=0; i
<20; i
++ )
120 float t
= (float)i
* (1.0f
/19.0f
),
121 s
= sinf( t
* VG_PIf
* 0.25f
),
122 c
= cosf( t
* VG_PIf
* 0.25f
);
125 v3_muls ( player
->rb
.to_world
[1], -c
, ray_dir
);
126 v3_muladds( ray_dir
, dir
, -s
, ray_dir
);
127 v3_muladds( center
, ray_dir
, -2.0f
, pos
);
129 ray_hit
*ray
= &samples
[ sample_count
];
132 if( ray_world( pos
, ray_dir
, ray
) )
134 vg_line( pos
, ray
->pos
, VG__RED
);
135 vg_line_pt3( ray
->pos
, 0.025f
, VG__BLACK
);
141 float min_a
= 0.70710678118654752f
;
142 ray_hit
*candidate
= NULL
;
144 if( sample_count
>= 2 )
146 for( int i
=0; i
<sample_count
-1; i
++ )
148 ray_hit
*s0
= &samples
[i
],
151 float a
= v3_dot( s0
->normal
, s1
->normal
);
153 if( (a
< min_a
) && (a
>= -0.1f
) && (s0
->normal
[1]>s1
->normal
[1]) )
165 ray_hit
*s0
= candidate
,
168 vg_line( s0
->pos
, s1
->pos
, VG__WHITE
);
170 v3_copy( s0
->normal
, pa
);
171 v3_copy( s1
->normal
, pb
);
172 v3_cross( player
->rb
.to_world
[1], dir
, pc
);
175 pa
[3] = v3_dot( pa
, s0
->pos
);
176 pb
[3] = v3_dot( pb
, s1
->pos
);
177 pc
[3] = v3_dot( pc
, player
->rb
.co
);
180 if( plane_intersect3( pa
, pb
, pc
, edge
) )
182 v3_copy( edge
, w
->state
.drop_in_target
);
183 v3_copy( s1
->normal
, w
->state
.drop_in_normal
);
184 v3_copy( player
->rb
.co
, w
->state
.drop_in_start
);
186 w
->state
.drop_in_start_angle
= player_get_heading_yaw( player
);
187 w
->state
.drop_in_angle
= atan2f( w
->state
.drop_in_normal
[0],
188 w
->state
.drop_in_normal
[2] );
190 /* TODO: scan multiple of these? */
193 player_walk_drop_in_overhang_transform( player
, 1.0f
, oco
, oq
);
195 v3f va
= {0.0f
,0.0f
,-k_board_length
- 0.3f
},
196 vb
= {0.0f
,0.0f
, k_board_length
+ 0.3f
};
198 q_mulv( oq
, va
, va
);
199 q_mulv( oq
, vb
, vb
);
200 v3_add( oco
, va
, va
);
201 v3_add( oco
, vb
, vb
);
204 v3_sub( vb
, va
, v0
);
208 ray
.dist
= k_board_length
*2.0f
+ 0.6f
;
210 if( ray_world( va
, v0
, &ray
) )
212 vg_line( va
, vb
, VG__RED
);
213 vg_line_pt3( ray
.pos
, 0.1f
, VG__RED
);
214 vg_error( "invalidated\n" );
218 v3_muls( v0
, -1.0f
, v0
);
219 if( ray_world( vb
, v0
, &ray
) )
221 vg_line( va
, vb
, VG__RED
);
222 vg_line_pt3( ray
.pos
, 0.1f
, VG__RED
);
223 vg_error( "invalidated\n" );
227 player_walk_drop_in_vector( player
, player
->rb
.v
);
232 vg_error( "failed to find intersection of drop in\n" );
239 VG_STATIC
void player__walk_pre_update( player_instance
*player
)
241 struct player_walk
*w
= &player
->_walk
;
243 if( w
->state
.activity
!= k_walk_activity_immobile
)
244 player_look( player
, player
->angles
);
246 if( w
->state
.outro_anim
)
248 float outro_length
= (float)w
->state
.outro_anim
->length
/
249 w
->state
.outro_anim
->rate
,
250 outro_time
= vg
.time
- w
->state
.outro_start_time
;
252 if( outro_time
>= outro_length
)
254 w
->state
.outro_anim
= NULL
;
255 if( w
->state
.outro_type
== k_walk_outro_drop_in
)
257 player_walk_drop_in_to_skate( player
);
261 player_walk_generic_to_skate( player
, k_skate_activity_air
);
266 else if( vg_input_button_down( player
->input_use
) )
268 if( w
->state
.activity
== k_walk_activity_ground
)
270 if( player_walk_scan_for_drop_in( player
) )
272 w
->state
.outro_type
= k_walk_outro_drop_in
;
273 w
->state
.outro_anim
= w
->anim_drop_in
;
274 w
->state
.outro_start_time
= vg
.time
;
275 w
->state
.activity
= k_walk_activity_immobile
;
277 struct player_avatar
*av
= player
->playeravatar
;
278 m4x3_mulv( av
->sk
.final_mtx
[ av
->id_ik_foot_r
],
279 av
->sk
.bones
[ av
->id_ik_foot_r
].co
,
280 w
->state
.drop_in_foot_anchor
);
286 w
->state
.outro_type
= k_walk_outro_jump_to_air
;
287 w
->state
.outro_anim
= w
->anim_jump_to_air
;
288 w
->state
.outro_start_time
= vg
.time
;
294 VG_STATIC
int player_walk_normal_standable( v3f n
)
296 return n
[1] > 0.70710678118f
;
299 VG_STATIC
void player_accelerate( v3f v
, v3f movedir
, float speed
, float accel
)
301 float currentspeed
= v3_dot( v
, movedir
),
302 addspeed
= speed
- currentspeed
;
307 float accelspeed
= accel
* k_rb_delta
* speed
;
309 if( accelspeed
> addspeed
)
310 accelspeed
= addspeed
;
312 v3_muladds( v
, movedir
, accelspeed
, v
);
315 VG_STATIC
void player_friction( v3f v
)
317 float speed
= v3_length( v
),
319 control
= vg_maxf( speed
, k_stopspeed
);
324 drop
+= control
* k_walk_friction
* k_rb_delta
;
326 float newspeed
= vg_maxf( 0.0f
, speed
- drop
);
329 v3_muls( v
, newspeed
, v
);
332 VG_STATIC
void player__walk_update( player_instance
*player
)
334 struct player_walk
*w
= &player
->_walk
;
335 v3_copy( player
->rb
.co
, w
->state
.prev_pos
);
337 if( w
->state
.activity
== k_walk_activity_immobile
)
340 w
->collider
.height
= 2.0f
;
341 w
->collider
.radius
= 0.3f
;
344 m3x3_identity( mtx
);
345 v3_add( player
->rb
.co
, (v3f
){0.0f
, 1.0f
, 0.0f
}, mtx
[3] );
347 debug_capsule( mtx
, w
->collider
.radius
, w
->collider
.height
, VG__WHITE
);
352 float yaw
= player
->angles
[0];
354 v3f forward_dir
= { sinf(yaw
), 0.0f
, -cosf(yaw
) };
355 v3f right_dir
= { -forward_dir
[2], 0.0f
, forward_dir
[0] };
357 v2f walk
= { player
->input_walkh
->axis
.value
,
358 player
->input_walkv
->axis
.value
};
360 if( v2_length2(walk
) > 0.001f
)
361 v2_normalize_clamp( walk
);
363 w
->move_speed
= v2_length( walk
);
366 * Collision detection
368 len
= rb_capsule__scene( mtx
, &w
->collider
, NULL
,
369 &world
.rb_geo
.inf
.scene
, manifold
);
370 rb_manifold_filter_coplanar( manifold
, len
, 0.01f
);
371 len
= rb_manifold_apply_filtered( manifold
, len
);
373 v3f surface_avg
= { 0.0f
, 0.0f
, 0.0f
};
374 w
->state
.activity
= k_walk_activity_air
;
376 for( int i
=0; i
<len
; i
++ )
378 struct contact
*ct
= &manifold
[i
];
379 rb_debug_contact( ct
);
381 if( player_walk_normal_standable( ct
->n
) )
383 w
->state
.activity
= k_walk_activity_ground
;
384 v3_add( surface_avg
, ct
->n
, surface_avg
);
387 rb_prepare_contact( ct
);
393 float accel_speed
= 0.0f
, nominal_speed
= 0.0f
;
395 v3_muls( right_dir
, walk
[0], movedir
);
396 v3_muladds( movedir
, forward_dir
, walk
[1], movedir
);
398 if( w
->state
.activity
== k_walk_activity_ground
)
400 v3_normalize( surface_avg
);
403 rb_tangent_basis( surface_avg
, tx
, ty
);
405 if( v2_length2(walk
) > 0.001f
)
407 /* clip movement to the surface */
408 float d
= v3_dot(surface_avg
,movedir
);
409 v3_muladds( movedir
, surface_avg
, -d
, movedir
);
412 accel_speed
= k_walk_accel
;
413 nominal_speed
= k_walkspeed
;
416 if( player
->input_jump
->button
.value
)
418 player
->rb
.v
[1] = 5.0f
;
419 w
->state
.activity
= k_walk_activity_air
;
420 accel_speed
= k_walk_air_accel
;
421 nominal_speed
= k_airspeed
;
425 player_friction( player
->rb
.v
);
427 struct world_material
*surface_mat
= world_contact_material(manifold
);
428 w
->surface
= surface_mat
->info
.surface_prop
;
433 accel_speed
= k_walk_air_accel
;
434 nominal_speed
= k_airspeed
;
437 if( v2_length2(walk
) > 0.001f
)
439 player_accelerate( player
->rb
.v
, movedir
, nominal_speed
, accel_speed
);
440 v3_normalize( movedir
);
444 * Resolve velocity constraints
446 for( int j
=0; j
<5; j
++ )
448 for( int i
=0; i
<len
; i
++ )
450 struct contact
*ct
= &manifold
[i
];
453 float vn
= -v3_dot( player
->rb
.v
, ct
->n
);
455 float temp
= ct
->norm_impulse
;
456 ct
->norm_impulse
= vg_maxf( temp
+ vn
, 0.0f
);
457 vn
= ct
->norm_impulse
- temp
;
459 v3_muladds( player
->rb
.v
, ct
->n
, vn
, player
->rb
.v
);
468 for( int j
=0; j
<8; j
++ )
470 for( int i
=0; i
<len
; i
++ )
472 struct contact
*ct
= &manifold
[i
];
474 float resolved_amt
= v3_dot( ct
->n
, dt
),
475 remaining
= (ct
->p
-k_penetration_slop
) - resolved_amt
,
476 apply
= vg_maxf( remaining
, 0.0f
) * 0.3f
;
478 v3_muladds( dt
, ct
->n
, apply
, dt
);
481 v3_add( dt
, player
->rb
.co
, player
->rb
.co
);
483 /* TODO: Stepping......
485 * ideas; walkgrid style steps
488 if( w
->state
.activity
== k_walk_activity_ground
)
491 float max_dist
= 0.4f
;
494 v3_copy( player
->rb
.co
, pa
);
495 pa
[1] += w
->collider
.radius
+ max_dist
;
497 v3_muladds( pa
, (v3f
){0.0f
,1.0f
,0.0f
}, -max_dist
* 2.0f
, pb
);
498 vg_line( pa
, pb
, 0xff000000 );
502 if( spherecast_world( pa
, pb
, w
->collider
.radius
, &t
, n
) != -1 )
504 if( player_walk_normal_standable( n
) )
506 v3_lerp( pa
, pb
, t
, player
->rb
.co
);
507 player
->rb
.co
[1] -= w
->collider
.radius
;
515 if( w
->state
.activity
== k_walk_activity_air
)
516 player
->rb
.v
[1] += -k_gravity
* k_rb_delta
;
518 v3_muladds( player
->rb
.co
, player
->rb
.v
, k_rb_delta
, player
->rb
.co
);
521 v3_add( player
->rb
.co
, (v3f
){0.0f
, 1.0f
, 0.0f
}, mtx
[3] );
522 debug_capsule( mtx
, w
->collider
.radius
, w
->collider
.height
, VG__GREEN
);
526 * ---------------------------------------------------
531 lwr_offs
= { 0.0f
, w
->collider
.radius
, 0.0f
};
533 v3_add( lwr_offs
, w
->state
.prev_pos
, lwr_prev
);
534 v3_add( lwr_offs
, player
->rb
.co
, lwr_now
);
537 v3_sub( player
->rb
.co
, w
->state
.prev_pos
, movedelta
);
539 float movedist
= v3_length( movedelta
);
541 if( movedist
> 0.3f
)
543 float t
, sr
= w
->collider
.radius
-0.04f
;
546 if( spherecast_world( lwr_prev
, lwr_now
, sr
, &t
, n
) != -1 )
548 v3_lerp( lwr_prev
, lwr_now
, vg_maxf(0.01f
,t
), player
->rb
.co
);
549 player
->rb
.co
[1] -= w
->collider
.radius
;
550 rb_update_transform( &player
->rb
);
552 v3_add( player
->rb
.co
, (v3f
){0.0f
, 1.0f
, 0.0f
}, mtx
[3] );
553 debug_capsule( mtx
, w
->collider
.radius
, w
->collider
.height
, VG__RED
);
558 if( (gate
= world_intersect_gates( player
->rb
.co
, w
->state
.prev_pos
)) )
560 m4x3_mulv( gate
->transport
, player
->rb
.co
, player
->rb
.co
);
561 m3x3_mulv( gate
->transport
, player
->rb
.v
, player
->rb
.v
);
562 rb_update_transform( &player
->rb
);
564 w
->state_gate_storage
= w
->state
;
565 player__pass_gate( player
, gate
);
569 VG_STATIC
void player__walk_post_update( player_instance
*player
)
571 struct player_walk
*w
= &player
->_walk
;
574 m3x3_copy( player
->rb
.to_world
, mtx
);
575 v3_add( player
->rb
.co
, (v3f
){0.0f
, 1.0f
, 0.0f
}, mtx
[3] );
577 float substep
= vg_clampf( vg
.accumulator
/ k_rb_delta
, 0.0f
, 1.0f
);
578 v3_muladds( mtx
[3], player
->rb
.v
, k_rb_delta
*substep
, mtx
[3] );
579 debug_capsule( mtx
, w
->collider
.radius
, w
->collider
.height
, VG__YELOW
);
582 /* Calculate header */
585 v3_copy( player
->rb
.v
, xy_speed
);
588 if( v3_length2( xy_speed
) > 0.1f
* 0.1f
)
590 float a
= atan2f( player
->rb
.v
[0], player
->rb
.v
[2] );
591 q_axis_angle( player
->rb
.q
, (v3f
){0.0f
,1.0f
,0.0f
}, a
);
594 vg_line_pt3( w
->state
.drop_in_target
, 0.1f
, VG__GREEN
);
596 v3_muladds( w
->state
.drop_in_target
, w
->state
.drop_in_normal
, 0.3f
, p1
);
597 vg_line( w
->state
.drop_in_target
, p1
, VG__GREEN
);
598 v3_muladds( w
->state
.drop_in_target
, player
->rb
.to_world
[1], 0.3f
, p1
);
599 vg_line( w
->state
.drop_in_target
, p1
, VG__GREEN
);
601 vg_line( w
->state
.drop_in_target
, w
->state
.drop_in_foot_anchor
, VG__WHITE
);
602 vg_line_pt3( w
->state
.drop_in_foot_anchor
, 0.08f
, VG__PINK
);
605 float a
= player_get_heading_yaw( player
);
610 v3_add( player
->rb
.co
, p1
, p1
);
611 vg_line( player
->rb
.co
, p1
, VG__PINK
);
614 VG_STATIC
void player__walk_animate( player_instance
*player
,
615 player_animation
*dest
)
617 struct player_walk
*w
= &player
->_walk
;
618 struct skeleton
*sk
= &player
->playeravatar
->sk
;
621 float fly
= (w
->state
.activity
== k_walk_activity_air
)? 1.0f
: 0.0f
,
624 if( w
->state
.activity
== k_walk_activity_air
)
629 w
->blend_fly
= vg_lerpf( w
->blend_fly
, fly
, rate
*vg
.time_delta
);
630 w
->blend_run
= vg_lerpf( w
->blend_run
,
632 (1.0f
+ player
->input_walk
->button
.value
*0.5f
),
633 2.0f
*vg
.time_delta
);
636 player_pose apose
, bpose
;
638 if( w
->move_speed
> 0.025f
)
641 float walk_norm
= 30.0f
/(float)w
->anim_walk
->length
,
642 run_norm
= 30.0f
/(float)w
->anim_run
->length
,
643 walk_adv
= vg_lerpf( walk_norm
, run_norm
, w
->move_speed
);
645 w
->walk_timer
+= walk_adv
* vg
.time_delta
;
649 w
->walk_timer
= 0.0f
;
652 float walk_norm
= (float)w
->anim_walk
->length
/30.0f
,
653 run_norm
= (float)w
->anim_run
->length
/30.0f
,
655 l
= vg_clampf( w
->blend_run
*15.0f
, 0.0f
, 1.0f
),
656 idle_walk
= vg_clampf( (w
->blend_run
-0.1f
)/(1.0f
-0.1f
), 0.0f
, 1.0f
);
659 skeleton_sample_anim( sk
, w
->anim_walk
, t
*walk_norm
, apose
);
660 skeleton_sample_anim( sk
, w
->anim_run
, t
*run_norm
, bpose
);
662 skeleton_lerp_pose( sk
, apose
, bpose
, l
, apose
);
665 skeleton_sample_anim( sk
, w
->anim_idle
, vg
.time
*0.1f
, bpose
);
666 skeleton_lerp_pose( sk
, apose
, bpose
, 1.0f
-idle_walk
, apose
);
669 skeleton_sample_anim( sk
, w
->anim_jump
, vg
.time
*0.6f
, bpose
);
670 skeleton_lerp_pose( sk
, apose
, bpose
, w
->blend_fly
, apose
);
672 /* Create transform */
673 rb_extrapolate( &player
->rb
, dest
->root_co
, dest
->root_q
);
675 float walk_yaw
= player_get_heading_yaw( player
);
677 if( w
->state
.outro_anim
)
679 struct player_avatar
*av
= player
->playeravatar
;
680 float outro_length
= (float)w
->state
.outro_anim
->length
/
681 w
->state
.outro_anim
->rate
,
682 outro_time
= vg
.time
- w
->state
.outro_start_time
,
683 outro_t
= outro_time
/ outro_length
;
685 /* TODO: Compression */
686 skeleton_sample_anim_clamped( sk
, w
->state
.outro_anim
,
688 skeleton_lerp_pose( sk
, apose
, bpose
, outro_t
* 10.0f
, dest
->pose
);
690 if( w
->state
.outro_type
== k_walk_outro_drop_in
)
692 float inv_rate
= 1.0f
/ w
->state
.outro_anim
->rate
,
693 anim_frames
= w
->state
.outro_anim
->length
* inv_rate
,
694 step_frames
= 12.0f
* inv_rate
,
695 commit_frames
= 6.0f
* inv_rate
,
696 drop_frames
= anim_frames
- step_frames
,
697 step_t
= vg_minf( 1.0f
, outro_time
/ step_frames
),
698 remaind_time
= vg_maxf( 0.0f
, outro_time
- step_frames
),
699 dop_t
= vg_minf( 1.0f
, remaind_time
/ drop_frames
),
700 commit_t
= vg_minf( 1.0f
, remaind_time
/ commit_frames
);
702 walk_yaw
= vg_alerpf( w
->state
.drop_in_start_angle
,
703 w
->state
.drop_in_angle
, step_t
);
705 v3_lerp( w
->state
.drop_in_start
, w
->state
.drop_in_target
,
706 step_t
, player
->rb
.co
);
707 q_axis_angle( dest
->root_q
, (v3f
){0.0f
,1.0f
,0.0f
}, walk_yaw
+ VG_PIf
);
709 m4x3f transform
, inverse
;
710 q_m3x3( dest
->root_q
, transform
);
711 v3_copy( dest
->root_co
, transform
[3] );
712 m4x3_invert_affine( transform
, inverse
);
715 m4x3_mulv( inverse
, w
->state
.drop_in_foot_anchor
, anchored_pos
);
717 v3_lerp( dest
->pose
[ av
->id_ik_foot_r
-1 ].co
, anchored_pos
,
719 dest
->pose
[ av
->id_ik_foot_r
-1 ].co
);
722 /* the drop in bit */
726 player_walk_drop_in_overhang_transform( player
, dop_t
,
727 player
->rb
.co
, final_q
);
728 q_mul( final_q
, dest
->root_q
, dest
->root_q
);
730 v4_copy( dest
->root_q
, player
->rb
.q
);
731 v3_muladds( dest
->root_co
, player
->rb
.to_world
[1],
732 -0.1f
* dop_t
, dest
->root_co
);
734 skeleton_copy_pose( sk
, dest
->pose
, player
->holdout_pose
);
735 player
->holdout_time
= 1.0f
;
741 v3_muladds( dest
->root_co
, player
->rb
.to_world
[1],
742 -0.1f
* outro_t
, dest
->root_co
);
744 skeleton_copy_pose( sk
, dest
->pose
, player
->holdout_pose
);
745 player
->holdout_time
= 1.0f
;
750 skeleton_copy_pose( sk
, apose
, dest
->pose
);
753 q_axis_angle( dest
->root_q
, (v3f
){0.0f
,1.0f
,0.0f
}, walk_yaw
+ VG_PIf
);
756 VG_STATIC
void player__walk_post_animate( player_instance
*player
)
761 struct player_walk
*w
= &player
->_walk
;
762 struct player_avatar
*av
= player
->playeravatar
;
764 if( w
->state
.outro_anim
)
766 float outro_length
= (float)w
->state
.outro_anim
->length
/
767 w
->state
.outro_anim
->rate
,
768 outro_time
= vg
.time
- w
->state
.outro_start_time
,
769 outro_t
= outro_time
/ outro_length
;
771 player
->cam_velocity_influence
= outro_t
;
774 player
->cam_velocity_influence
= 0.0f
;
778 VG_STATIC
void player__walk_im_gui( player_instance
*player
)
780 struct player_walk
*w
= &player
->_walk
;
781 player__debugtext( 1, "V: %5.2f %5.2f %5.2f",player
->rb
.v
[0],
784 player__debugtext( 1, "CO: %5.2f %5.2f %5.2f",player
->rb
.co
[0],
787 player__debugtext( 1, "activity: %s\n",
788 (const char *[]){ "k_walk_activity_air",
789 "k_walk_activity_ground",
790 "k_walk_activity_sleep",
791 "k_walk_activity_immobile" }
792 [w
->state
.activity
] );
794 if( w
->state
.outro_anim
)
796 float outro_length
= (float)w
->state
.outro_anim
->length
/
797 w
->state
.outro_anim
->rate
,
798 outro_time
= vg
.time
- w
->state
.outro_start_time
;
799 player__debugtext( 1, "outro time: %f / %f", outro_time
, outro_length
);
803 VG_STATIC
void player__walk_bind( player_instance
*player
)
805 struct player_walk
*w
= &player
->_walk
;
806 struct player_avatar
*av
= player
->playeravatar
;
807 struct skeleton
*sk
= &av
->sk
;
809 w
->anim_idle
= skeleton_get_anim( sk
, "idle_cycle+y" );
810 w
->anim_walk
= skeleton_get_anim( sk
, "walk+y" );
811 w
->anim_run
= skeleton_get_anim( sk
, "run+y" );
812 w
->anim_jump
= skeleton_get_anim( sk
, "jump+y" );
813 w
->anim_jump_to_air
= skeleton_get_anim( sk
, "jump_to_air" );
814 w
->anim_drop_in
= skeleton_get_anim( sk
, "drop_in" );
817 VG_STATIC
void player__walk_transition( player_instance
*player
, v3f angles
)
819 struct player_walk
*w
= &player
->_walk
;
820 w
->state
.activity
= k_walk_activity_air
;
822 v3f fwd
= { 0.0f
, 0.0f
, 1.0f
};
823 q_mulv( player
->rb
.q
, fwd
, fwd
);
825 q_axis_angle( player
->rb
.q
, (v3f
){0.0f
,1.0f
,0.0f
},
826 atan2f( fwd
[0], fwd
[2] ) );
827 rb_update_transform( &player
->rb
);
830 #endif /* PLAYER_DEVICE_WALK_H */