1 #include "ent_skateshop.h"
5 #include "vg/vg_perlin.h"
7 float player_get_heading_yaw(void)
10 q_mulv( localplayer
.rb
.q
, (v3f
){ 0.0f
,0.0f
,1.0f
}, xz
);
11 return atan2f( xz
[0], xz
[2] );
14 static void player_camera_portal_correction(void)
16 if( localplayer
.gate_waiting
){
17 /* construct plane equation for reciever gate */
19 q_mulv( localplayer
.gate_waiting
->q
[1], (v3f
){0.0f
,0.0f
,1.0f
}, plane
);
20 plane
[3] = v3_dot( plane
, localplayer
.gate_waiting
->co
[1] );
22 f32 pol
= v3_dot( localplayer
.cam
.pos
, plane
) - plane
[3];
24 int cleared
= (pol
< 0.0f
) || (pol
> 5.0f
);
27 vg_success( "Plane cleared\n" );
31 m4x3_invert_affine( localplayer
.gate_waiting
->transport
, inverse
);
33 /* de-transform camera and player back */
35 m4x3_mulv( inverse
, localplayer
.cam
.pos
, localplayer
.cam
.pos
);
36 v3_angles_vector( localplayer
.cam
.angles
, v0
);
37 m3x3_mulv( inverse
, v0
, v0
);
38 v3_angles( v0
, localplayer
.cam
.angles
);
40 skeleton_apply_transform( &localplayer
.skeleton
, inverse
,
41 localplayer
.final_mtx
);
43 /* record and re-put things again */
46 skaterift_record_frame( &player_replay
.local
, 1 );
47 localplayer
.deferred_frame_record
= 1;
49 skeleton_apply_transform( &localplayer
.skeleton
,
50 localplayer
.gate_waiting
->transport
,
51 localplayer
.final_mtx
);
53 m4x3_mulv( localplayer
.gate_waiting
->transport
,
54 localplayer
.cam
.pos
, localplayer
.cam
.pos
);
55 v3_angles_vector( localplayer
.cam
.angles
, v0
);
56 m3x3_mulv( localplayer
.gate_waiting
->transport
, v0
, v0
);
57 v3_angles( v0
, localplayer
.cam
.angles
);
58 player_apply_transport_to_cam( localplayer
.gate_waiting
->transport
);
59 localplayer
.gate_waiting
= NULL
;
64 void player__cam_iterate(void)
66 struct player_cam_controller
*cc
= &localplayer
.cam_control
;
68 if( localplayer
.subsystem
== k_player_subsystem_walk
){
69 v3_copy( (v3f
){-0.1f
,1.8f
,0.0f
}, cc
->fpv_viewpoint
);
70 v3_copy( (v3f
){0.0f
,0.0f
,0.0f
}, cc
->fpv_offset
);
71 v3_copy( (v3f
){0.0f
,1.8f
,0.0f
}, cc
->tpv_offset
);
73 else if( localplayer
.subsystem
== k_player_subsystem_glide
){
74 v3_copy( (v3f
){-0.15f
,1.75f
,0.0f
}, cc
->fpv_viewpoint
);
75 v3_copy( (v3f
){0.0f
,0.0f
,0.0f
}, cc
->fpv_offset
);
76 v3_copy( (v3f
){0.0f
,-1.0f
,0.0f
}, cc
->tpv_offset
);
77 v3_add( cc
->tpv_offset_extra
, cc
->tpv_offset
, cc
->tpv_offset
);
80 v3_copy( (v3f
){-0.15f
,1.75f
,0.0f
}, cc
->fpv_viewpoint
);
81 v3_copy( (v3f
){0.0f
,0.0f
,0.0f
}, cc
->fpv_offset
);
83 f32 h
= vg_lerpf( 0.4f
, 1.4f
, k_cam_height
);
84 v3_copy( (v3f
){0.0f
,h
,0.0f
}, cc
->tpv_offset
);
85 v3_add( cc
->tpv_offset_extra
, cc
->tpv_offset
, cc
->tpv_offset
);
88 localplayer
.cam_velocity_constant
= 0.25f
;
89 localplayer
.cam_velocity_coefficient
= 0.7f
;
93 if( localplayer
.cam_dist_smooth
== 0.0f
){
94 localplayer
.cam_dist_smooth
= localplayer
.cam_dist
;
97 localplayer
.cam_dist_smooth
= vg_lerpf(
98 localplayer
.cam_dist_smooth
,
100 vg
.time_frame_delta
* 8.0f
);
103 localplayer
.cam_velocity_influence_smooth
= vg_lerpf(
104 localplayer
.cam_velocity_influence_smooth
,
105 localplayer
.cam_velocity_influence
,
106 vg
.time_frame_delta
* 8.0f
);
108 localplayer
.cam_velocity_coefficient_smooth
= vg_lerpf(
109 localplayer
.cam_velocity_coefficient_smooth
,
110 localplayer
.cam_velocity_coefficient
,
111 vg
.time_frame_delta
* 8.0f
);
113 localplayer
.cam_velocity_constant_smooth
= vg_lerpf(
114 localplayer
.cam_velocity_constant_smooth
,
115 localplayer
.cam_velocity_constant
,
116 vg
.time_frame_delta
* 8.0f
);
118 enum camera_mode target_mode
= cc
->camera_mode
;
120 if( localplayer
.subsystem
== k_player_subsystem_dead
)
121 target_mode
= k_cam_thirdperson
;
123 cc
->camera_type_blend
=
124 vg_lerpf( cc
->camera_type_blend
,
125 (target_mode
== k_cam_firstperson
)? 1.0f
: 0.0f
,
126 5.0f
* vg
.time_frame_delta
);
128 v3_lerp( cc
->fpv_viewpoint_smooth
, cc
->fpv_viewpoint
,
129 vg
.time_frame_delta
* 8.0f
, cc
->fpv_viewpoint_smooth
);
131 v3_lerp( cc
->fpv_offset_smooth
, cc
->fpv_offset
,
132 vg
.time_frame_delta
* 8.0f
, cc
->fpv_offset_smooth
);
134 v3_lerp( cc
->tpv_offset_smooth
, cc
->tpv_offset
,
135 vg
.time_frame_delta
* 8.0f
, cc
->tpv_offset_smooth
);
137 /* fov -- simple blend */
138 float fov_skate
= vg_lerpf( 97.0f
, 135.0f
, k_fov
),
139 fov_walk
= vg_lerpf( 90.0f
, 110.0f
, k_fov
);
141 localplayer
.cam
.fov
= vg_lerpf( fov_walk
, fov_skate
, cc
->camera_type_blend
);
144 * first person camera
148 v3f fpv_pos
, fpv_offset
;
149 m4x3_mulv( localplayer
.final_mtx
[ localplayer
.id_head
-1 ],
150 cc
->fpv_viewpoint_smooth
, fpv_pos
);
151 m3x3_mulv( localplayer
.rb
.to_world
, cc
->fpv_offset_smooth
, fpv_offset
);
152 v3_add( fpv_offset
, fpv_pos
, fpv_pos
);
156 v3_lerp( cc
->cam_velocity_smooth
, localplayer
.rb
.v
, 4.0f
*vg
.time_frame_delta
,
157 cc
->cam_velocity_smooth
);
159 v3_angles( cc
->cam_velocity_smooth
, velocity_angles
);
160 velocity_angles
[1] *= localplayer
.cam_velocity_coefficient_smooth
;
161 velocity_angles
[1] += localplayer
.cam_velocity_constant_smooth
;
163 float inf_fpv
= localplayer
.cam_velocity_influence_smooth
*
164 cc
->camera_type_blend
,
165 inf_tpv
= localplayer
.cam_velocity_influence_smooth
*
166 (1.0f
-cc
->camera_type_blend
);
168 vg_camera_lerp_angles( localplayer
.angles
, velocity_angles
,
170 localplayer
.angles
);
173 * Third person camera
176 /* no idea what this technique is called, it acts like clamped position based
177 * on some derivative of where the final camera would end up ....
179 * it is done in the local basis then transformed back */
182 v3_muls( localplayer
.rb
.v
, 0.4f
*vg
.time_frame_delta
, future
);
184 v3f camera_follow_dir
=
185 { -sinf( localplayer
.angles
[0] ) * cosf( localplayer
.angles
[1] ),
186 sinf( localplayer
.angles
[1] ),
187 cosf( localplayer
.angles
[0] ) * cosf( localplayer
.angles
[1] ) };
190 v3_sub( camera_follow_dir
, future
, v0
);
193 v3_copy( localplayer
.angles
, follow_angles
);
194 follow_angles
[0] = atan2f( -v0
[0], v0
[2] );
195 follow_angles
[1] = 0.3f
+ velocity_angles
[1] * 0.2f
;
197 float ya
= atan2f( -cc
->cam_velocity_smooth
[1], 30.0f
);
199 follow_angles
[1] = 0.3f
+ ya
;
200 vg_camera_lerp_angles( localplayer
.angles
, follow_angles
,
202 localplayer
.angles
);
206 rb_extrapolate( &localplayer
.rb
, pco
, pq
);
207 v3_muladds( pco
, localplayer
.holdout_pose
.root_co
,
208 localplayer
.holdout_time
, pco
);
209 v3_lerp( cc
->tpv_lpf
, pco
, 20.0f
*vg
.time_frame_delta
, cc
->tpv_lpf
);
211 /* now move into world */
212 v3f tpv_pos
, tpv_offset
, tpv_origin
;
214 /* TODO: whats up with CC and not CC but both sets of variables are doing
215 * the same ideas just saved in different places?
218 q_mulv( pq
, cc
->tpv_offset_smooth
, tpv_origin
);
219 v3_add( tpv_origin
, cc
->tpv_lpf
, tpv_origin
);
222 v3_muls( camera_follow_dir
, localplayer
.cam_dist_smooth
, tpv_offset
);
223 v3_muladds( tpv_offset
, cc
->cam_velocity_smooth
, -0.025f
, tpv_offset
);
225 v3_add( tpv_origin
, tpv_offset
, tpv_pos
);
228 if( localplayer
.subsystem
== k_player_subsystem_walk
)
231 v3_angles_vector( localplayer
.angles
, fwd
);
232 v3_cross( fwd
, (v3f
){0,1.001f
,0}, right
);
234 v3_normalize( right
);
235 v3_muladds( tpv_pos
, right
, 0.5f
, tpv_pos
);
242 v3_lerp( tpv_pos
, fpv_pos
, cc
->camera_type_blend
, localplayer
.cam
.pos
);
243 v3_copy( localplayer
.angles
, localplayer
.cam
.angles
);
246 f32 speed
= v3_length(localplayer
.rb
.v
),
247 strength
= k_cam_shake_strength
* speed
;
248 localplayer
.cam_trackshake
+=
249 speed
*k_cam_shake_trackspeed
*vg
.time_frame_delta
;
251 v2f rnd
= {vg_perlin_fract_1d( localplayer
.cam_trackshake
, 1.0f
, 4, 20 ),
252 vg_perlin_fract_1d( localplayer
.cam_trackshake
, 1.0f
, 4, 63 ) };
253 v2_muladds( localplayer
.cam
.angles
, rnd
, strength
, localplayer
.cam
.angles
);
256 v3_muls( localplayer
.cam_land_punch_v
, -k_cam_damp
, Fd
);
257 v3_muls( localplayer
.cam_land_punch
, -k_cam_spring
, Fs
);
258 v3_muladds( localplayer
.cam_land_punch
, localplayer
.cam_land_punch_v
,
259 vg
.time_frame_delta
, localplayer
.cam_land_punch
);
261 v3_muladds( localplayer
.cam_land_punch_v
, F
, vg
.time_frame_delta
,
262 localplayer
.cam_land_punch_v
);
263 v3_add( localplayer
.cam_land_punch
, localplayer
.cam
.pos
,
264 localplayer
.cam
.pos
);
266 /* portal transitions */
267 player_camera_portal_correction();
270 void player_look( v3f angles
, float speed
)
272 if( vg_ui
.wants_mouse
) return;
277 v2_copy( vg
.mouse_delta
, mouse_input
);
278 if( k_invert_y
) mouse_input
[1] *= -1.0f
;
279 v2_muladds( angles
, mouse_input
, 0.0025f
* speed
, angles
);
282 joystick_state( k_srjoystick_look
, jlook
);
284 angles
[0] += jlook
[0] * vg
.time_frame_delta
* 4.0f
* speed
;
285 float input_y
= jlook
[1] * vg
.time_frame_delta
* 4.0f
;
286 if( k_invert_y
) input_y
*= -1.0f
;
288 angles
[1] += input_y
* speed
;
289 angles
[1] = vg_clampf( angles
[1], -VG_PIf
*0.5f
, VG_PIf
*0.5f
);