1 #ifndef PLAYER_COMMON_C
2 #define PLAYER_COMMON_C
4 #include "ent_skateshop.h"
13 VG_STATIC
void player_vector_angles( v3f angles
, v3f v
, float C
, float k
)
15 float yaw
= atan2f( v
[0], -v
[2] ),
30 VG_STATIC
float player_get_heading_yaw( player_instance
*player
)
33 q_mulv( player
->rb
.q
, (v3f
){ 0.0f
,0.0f
,1.0f
}, xz
);
34 m3x3_mulv( player
->invbasis
, xz
, xz
);
35 return atan2f( xz
[0], xz
[2] );
38 VG_STATIC
void player_camera_portal_correction( player_instance
*player
)
40 if( player
->gate_waiting
){
41 /* construct plane equation for reciever gate */
43 q_mulv( player
->gate_waiting
->q
[1], (v3f
){0.0f
,0.0f
,1.0f
}, plane
);
44 plane
[3] = v3_dot( plane
, player
->gate_waiting
->co
[1] );
46 /* check camera polarity */
47 if( v3_dot( player
->cam
.pos
, plane
) < plane
[3] ) {
48 vg_success( "Plane cleared\n" );
49 player_apply_transport_to_cam( player
->gate_waiting
->transport
);
50 player
->gate_waiting
= NULL
;
51 player
->viewable_world
= get_active_world();
54 /* de-transform camera and player back */
56 m4x3_invert_affine( player
->gate_waiting
->transport
, inverse
);
57 m4x3_mulv( inverse
, player
->cam
.pos
, player
->cam
.pos
);
59 struct skeleton
*sk
= &player
->playeravatar
->sk
;
60 skeleton_apply_transform( sk
, inverse
);
65 static v3f TEMP_TPV_EXTRA
;
67 VG_STATIC
void player__cam_iterate( player_instance
*player
)
69 struct player_avatar
*av
= player
->playeravatar
;
71 if( player
->subsystem
== k_player_subsystem_walk
){
72 v3_copy( (v3f
){-0.1f
,1.8f
,0.0f
}, player
->fpv_viewpoint
);
73 v3_copy( (v3f
){0.0f
,0.0f
,0.0f
}, player
->fpv_offset
);
74 v3_copy( (v3f
){0.0f
,1.4f
,0.0f
}, player
->tpv_offset
);
77 v3_copy( (v3f
){-0.15f
,1.75f
,0.0f
}, player
->fpv_viewpoint
);
79 v3_copy( (v3f
){-0.35f
,0.0f
,0.0f
}, player
->fpv_offset
);
81 v3_copy( (v3f
){0.0f
,0.0f
,0.0f
}, player
->fpv_offset
);
82 v3_copy( (v3f
){0.0f
,1.4f
,0.0f
}, player
->tpv_offset
);
83 v3_add( TEMP_TPV_EXTRA
, player
->tpv_offset
, player
->tpv_offset
);
86 player
->cam_velocity_constant
= 0.25f
;
87 player
->cam_velocity_coefficient
= 0.7f
;
91 player
->cam_velocity_influence_smooth
= vg_lerpf(
92 player
->cam_velocity_influence_smooth
,
93 player
->cam_velocity_influence
,
94 vg
.time_frame_delta
* 8.0f
);
96 player
->cam_velocity_coefficient_smooth
= vg_lerpf(
97 player
->cam_velocity_coefficient_smooth
,
98 player
->cam_velocity_coefficient
,
99 vg
.time_frame_delta
* 8.0f
);
101 player
->cam_velocity_constant_smooth
= vg_lerpf(
102 player
->cam_velocity_constant_smooth
,
103 player
->cam_velocity_constant
,
104 vg
.time_frame_delta
* 8.0f
);
106 enum camera_mode target_mode
= player
->camera_mode
;
108 if( player
->subsystem
== k_player_subsystem_dead
)
109 target_mode
= k_cam_thirdperson
;
111 player
->camera_type_blend
=
112 vg_lerpf( player
->camera_type_blend
,
113 (target_mode
== k_cam_firstperson
)? 1.0f
: 0.0f
,
114 5.0f
* vg
.time_frame_delta
);
116 v3_lerp( player
->fpv_viewpoint_smooth
, player
->fpv_viewpoint
,
117 vg
.time_frame_delta
* 8.0f
, player
->fpv_viewpoint_smooth
);
119 v3_lerp( player
->fpv_offset_smooth
, player
->fpv_offset
,
120 vg
.time_frame_delta
* 8.0f
, player
->fpv_offset_smooth
);
122 v3_lerp( player
->tpv_offset_smooth
, player
->tpv_offset
,
123 vg
.time_frame_delta
* 8.0f
, player
->tpv_offset_smooth
);
125 /* fov -- simple blend */
126 float fov_skate
= vg_lerpf( 97.0f
, 135.0f
, cl_fov
),
127 fov_walk
= vg_lerpf( 90.0f
, 110.0f
, cl_fov
);
129 player
->cam
.fov
= vg_lerpf( fov_walk
, fov_skate
, player
->camera_type_blend
);
132 * first person camera
136 v3f fpv_pos
, fpv_offset
;
137 m4x3_mulv( av
->sk
.final_mtx
[ av
->id_head
-1 ],
138 player
->fpv_viewpoint_smooth
, fpv_pos
);
139 m3x3_mulv( player
->rb
.to_world
, player
->fpv_offset_smooth
, fpv_offset
);
140 v3_add( fpv_offset
, fpv_pos
, fpv_pos
);
144 v3_lerp( player
->cam_velocity_smooth
, player
->rb
.v
, 4.0f
*vg
.time_frame_delta
,
145 player
->cam_velocity_smooth
);
148 m3x3_mulv( player
->invbasis
, player
->cam_velocity_smooth
, velocity_local
);
149 player_vector_angles( velocity_angles
, velocity_local
,
150 player
->cam_velocity_coefficient_smooth
,
151 player
->cam_velocity_constant_smooth
);
153 float inf_fpv
= player
->cam_velocity_influence_smooth
*
154 player
->camera_type_blend
,
155 inf_tpv
= player
->cam_velocity_influence_smooth
*
156 (1.0f
-player
->camera_type_blend
);
158 camera_lerp_angles( player
->angles
, velocity_angles
,
163 * Third person camera
166 /* no idea what this technique is called, it acts like clamped position based
167 * on some derivative of where the final camera would end up ....
169 * it is done in the local basis then transformed back */
172 v3_muls( player
->rb
.v
, 0.4f
*vg
.time_frame_delta
, future
);
173 m3x3_mulv( player
->invbasis
, future
, future
);
175 v3f camera_follow_dir
=
176 { -sinf( player
->angles
[0] ) * cosf( player
->angles
[1] ),
177 sinf( player
->angles
[1] ),
178 cosf( player
->angles
[0] ) * cosf( player
->angles
[1] ) };
181 v3_sub( camera_follow_dir
, future
, v0
);
184 v3_copy( player
->angles
, follow_angles
);
185 follow_angles
[0] = atan2f( -v0
[0], v0
[2] );
186 follow_angles
[1] = 0.3f
+ velocity_angles
[1] * 0.2f
;
188 float ya
= atan2f( -velocity_local
[1], 30.0f
);
190 follow_angles
[1] = 0.3f
+ ya
;
191 camera_lerp_angles( player
->angles
, follow_angles
,
197 rb_extrapolate( &player
->rb
, pco
, pq
);
198 v3_lerp( player
->tpv_lpf
, pco
, 20.0f
*vg
.time_frame_delta
, player
->tpv_lpf
);
200 /* now move into world */
202 m3x3_mulv( player
->basis
, camera_follow_dir
, camera_follow_dir
);
203 v3f tpv_pos
, tpv_offset
;
205 v3_muladds( player
->tpv_lpf
, camera_follow_dir
, 1.8f
, tpv_pos
);
206 q_mulv( pq
, player
->tpv_offset_smooth
, tpv_offset
);
207 v3_add( tpv_offset
, tpv_pos
, tpv_pos
);
208 v3_muladds( tpv_pos
, player
->cam_velocity_smooth
, -0.025f
, tpv_pos
);
213 v3_lerp( tpv_pos
, fpv_pos
, player
->camera_type_blend
, player
->cam
.pos
);
214 v3_copy( player
->angles
, player
->cam
.angles
);
216 float Fd
= -player
->cam_land_punch_v
* k_cam_damp
,
217 Fs
= -player
->cam_land_punch
* k_cam_spring
;
218 player
->cam_land_punch
+= player
->cam_land_punch_v
* vg
.time_frame_delta
;
219 player
->cam_land_punch_v
+= ( Fd
+ Fs
) * vg
.time_frame_delta
;
220 player
->cam
.angles
[1] += player
->cam_land_punch
;
222 /* override camera */
223 player
->cam
.angles
[0] =
224 vg_alerpf( player
->cam
.angles
[0], player
->cam_override_angles
[0],
225 player
->cam_override_strength
);
226 player
->cam
.angles
[1] =
227 vg_lerpf ( player
->cam
.angles
[1], player
->cam_override_angles
[1],
228 player
->cam_override_strength
);
229 v3_lerp( player
->cam
.pos
, player
->cam_override_pos
,
230 player
->cam_override_strength
, player
->cam
.pos
);
231 player
->cam
.fov
= vg_lerpf( player
->cam
.fov
, player
->cam_override_fov
,
232 player
->cam_override_strength
);
234 /* portal transitions */
235 player_camera_portal_correction( player
);
238 VG_STATIC
void player_look( player_instance
*player
, v3f angles
)
243 v2_copy( vg
.mouse_delta
, mouse_input
);
245 mouse_input
[1] *= -1.0f
;
246 v2_muladds( angles
, mouse_input
, 0.0025f
, angles
);
249 joystick_state( k_srjoystick_look
, jlook
);
251 angles
[0] += jlook
[0] * vg
.time_delta
* 4.0f
;
252 float input_y
= jlook
[1] * vg
.time_delta
* 4.0f
;
256 angles
[1] += input_y
;
258 angles
[1] = vg_clampf( angles
[1], -VG_PIf
*0.5f
, VG_PIf
*0.5f
);
261 struct player_board
*player_get_player_board( struct player_instance
*player
)
263 struct player_board
*board
= NULL
;
265 if( localplayer
.board_view_slot
){
266 struct dynamic_board
*vs
= localplayer
.board_view_slot
;
267 if( vs
->state
== k_dynamic_board_state_loaded
){
275 #endif /* PLAYER_COMMON_C */