1 #ifndef PLAYER_INTERFACE_H
2 #define PLAYER_INTERFACE_H
7 #include "player_ragdoll.h"
8 #include "player_model.h"
11 typedef struct player_device player_device
;
12 typedef struct player_interface player_interface
;
13 typedef struct player_attachment player_attachment
;
14 typedef mdl_keyframe player_pose
[32];
16 struct player_interface
21 struct player_attachment
23 player_device
*device
;
28 struct input_binding
*input_js1h
,
43 struct player_avatar
*playeravatar
;
45 struct player_ragdoll ragdoll
;
49 vg_tex2d tex_characters
= { .path
= "textures/ch_gradient.qoi" };
53 void (* bind
) ( player_interface
*player
, player_attachment
*at
);
54 void (* pre_update
) ( player_interface
*player
, player_attachment
*at
);
55 void (* update
) ( player_interface
*player
, player_attachment
*at
);
56 void (* post_update
)( player_interface
*player
, player_attachment
*at
);
57 void (* pose
) ( player_interface
*player
, player_attachment
*at
,
58 player_pose pose
, m4x3f transform
);
60 void (* get_camera
) ( player_interface
*player
, player_attachment
*at
,
63 void (* attatch
) ( player_interface
*player
, player_attachment
*at
,
66 void (* reset
) ( player_interface
*player
, player_attachment
*at
,
67 struct respawn_point
*spawn
);
69 void (* store_state
)( player_interface
*player
, player_attachment
*at
);
70 void (* load_state
) ( player_interface
*player
, player_attachment
*at
);
71 void (* debug_ui
) ( player_interface
*player
, player_attachment
*at
);
72 void (* gate_transport
)( player_interface
*player
, player_attachment
*at
,
73 teleport_gate
*gate
);
76 VG_STATIC
void player_interface_create_player( player_interface
*inst
)
78 static int only_once
= 0;
79 assert( only_once
== 0 );
82 inst
->input_js1h
= vg_create_named_input( "steer-h", k_input_type_axis
);
83 inst
->input_js1v
= vg_create_named_input( "steer-v", k_input_type_axis
);
84 inst
->input_grab
= vg_create_named_input( "grab", k_input_type_axis_norm
);
85 inst
->input_js2h
= vg_create_named_input( "grab-h", k_input_type_axis
);
86 inst
->input_js2v
= vg_create_named_input( "grab-v", k_input_type_axis
);
87 inst
->input_jump
= vg_create_named_input( "jump", k_input_type_button
);
88 inst
->input_push
= vg_create_named_input( "push", k_input_type_button
);
89 inst
->input_walk
= vg_create_named_input( "walk", k_input_type_button
);
90 inst
->input_walkh
= vg_create_named_input( "walk-h", k_input_type_axis
);
91 inst
->input_walkv
= vg_create_named_input( "walk-v", k_input_type_axis
);
92 inst
->input_use
= vg_create_named_input( "use", k_input_type_button
);
93 inst
->input_reset
= vg_create_named_input( "reset", k_input_type_button
);
95 const char *default_cfg
[] =
97 "bind steer-h gp-ls-h",
101 "bind steer-v gp-ls-v",
107 "bind grab-h gp-rs-h",
108 "bind grab-v gp-rs-v",
119 "bind walk-h gp-ls-h",
120 "bind walk-v -gp-ls-v",
133 for( int i
=0; i
<vg_list_size(default_cfg
); i
++ )
134 vg_execute_console_input(default_cfg
[i
]);
136 v3_zero( inst
->rb
.co
);
137 v3_zero( inst
->rb
.w
);
138 v3_zero( inst
->rb
.v
);
139 q_identity( inst
->rb
.q
);
140 m4x3_identity( inst
->rb
.to_world
);
141 m4x3_identity( inst
->rb
.to_local
);
144 VG_STATIC
void player_use_avatar( player_interface
*player
,
145 struct player_avatar
*av
)
147 player
->playeravatar
= av
;
148 player_setup_ragdoll_from_avatar( &player
->ragdoll
, av
);
151 VG_STATIC
void player_use_mesh( player_interface
*player
, glmesh
*mesh
)
153 player
->playermesh
= mesh
;
156 /* FIXME: Seperate concepts for binding and equip.
158 VG_STATIC
void player_use_device( player_interface
*player
, player_device
*dev
,
161 player
->dev
.device
= dev
;
162 player
->dev
.storage
= storage
;
164 player
->dev
.device
->bind( player
, &player
->dev
);
167 VG_STATIC
void player_pre_update( player_interface
*player
)
169 assert( player
->dev
.device
);
171 v3_copy( player
->rb
.co
, player
->prev_position
);
173 if( player
->dev
.device
->pre_update
)
174 player
->dev
.device
->pre_update( player
, &player
->dev
);
177 VG_STATIC
void player_update( player_interface
*player
)
179 assert( player
->dev
.device
);
181 if( player
->dev
.device
->update
)
182 player
->dev
.device
->update( player
, &player
->dev
);
185 VG_STATIC
void player_apply_transport_to_cam( m4x3f transport
)
187 /* FIXME: Applies to main_camera directly! */
189 /* Pre-emptively edit the camera matrices so that the motion vectors
193 m4x3_invert_affine( transport
, transport_i
);
194 m4x3_expand( transport_i
, transport_4
);
195 m4x4_mul( main_camera
.mtx
.pv
, transport_4
, main_camera
.mtx
.pv
);
196 m4x4_mul( main_camera
.mtx
.v
, transport_4
, main_camera
.mtx
.v
);
199 VG_STATIC
void player_post_update( player_interface
*player
)
201 /* FIXME: Applies to main_camera directly! */
203 assert( player
->dev
.device
);
205 if( player
->dev
.device
->post_update
)
206 player
->dev
.device
->post_update( player
, &player
->dev
);
208 /* FIXME: only need to test against the visible gate....
211 for( int i
=0; i
<world
.gate_count
; i
++ )
213 struct route_gate
*rg
= &world
.gates
[i
];
214 teleport_gate
*gate
= &rg
->gate
;
216 if( gate_intersect( gate
, player
->rb
.co
, player
->prev_position
) )
218 player
->dev
.device
->gate_transport( player
, &player
->dev
, gate
);
219 v3_copy( player
->rb
.co
, player
->prev_position
);
224 camera_update_transform( &player
->cam
);
225 camera_update_view( &player
->cam
);
226 camera_update_projection( &player
->cam
);
227 camera_finalize( &player
->cam
);
232 VG_STATIC
void player_pre_render( player_interface
*player
)
234 assert( player
->dev
.device
);
236 if( player
->dev
.device
->pre_render
)
237 player
->dev
.device
->pre_render( player
);
241 VG_STATIC
void player_pre_render( player_interface
*player
)
246 /* FIXME: Give devices more control over these render stages, and have
248 * for this kindof crap instead of it dictating order... */
250 if( player
->dev
.device
->pose
)
252 player
->dev
.device
->pose( player
, &player
->dev
, pose
, transform
);
254 struct skeleton
*sk
= &player
->playeravatar
->sk
;
256 skeleton_apply_pose( sk
, pose
, k_anim_apply_defer_ik
);
257 skeleton_apply_ik_pass( sk
);
258 skeleton_apply_pose( sk
, pose
, k_anim_apply_deffered_only
);
259 skeleton_apply_inverses( sk
);
260 skeleton_apply_transform( sk
, transform
);
261 skeleton_debug( sk
);
264 player
->dev
.device
->get_camera( player
, &player
->dev
, &player
->cam
);
265 /* TODO: if dead copy ragdoll.. . */
268 VG_STATIC
void player_render( camera
*cam
, player_interface
*player
)
270 shader_viewchar_use();
271 vg_tex2d_bind( &tex_characters
, 0 );
272 shader_viewchar_uTexMain( 0 );
273 shader_viewchar_uCamera( cam
->transform
[3] );
274 shader_viewchar_uPv( cam
->mtx
.pv
);
275 shader_link_standard_ub( _shader_viewchar
.id
, 2 );
276 glUniformMatrix4x3fv( _uniform_viewchar_uTransforms
,
277 player
->playeravatar
->sk
.bone_count
,
279 (float *)player
->playeravatar
->sk
.final_mtx
);
281 mesh_bind( player
->playermesh
);
282 mesh_draw( player
->playermesh
);
285 VG_STATIC
void player_debugtext( int size
, const char *fmt
, ... )
290 va_start( args
, fmt
);
291 vsnprintf( buffer
, 1024, fmt
, args
);
294 ui_text( vg_uictx
.cursor
, buffer
, size
, k_text_align_right
);
295 vg_uictx
.cursor
[1] += 14*size
;
298 VG_STATIC
void player_ui( player_interface
*player
)
300 /* TODO: if debugger enabled */
302 if( player
->dev
.device
->debug_ui
)
304 vg_uictx
.cursor
[0] = vg
.window_x
- 200;
305 vg_uictx
.cursor
[1] = 0;
306 vg_uictx
.cursor
[2] = 200;
307 vg_uictx
.cursor
[3] = 200;
309 struct ui_vert
*b
= ui_fill_rect( vg_uictx
.cursor
, 0x70000000 );
311 vg_uictx
.cursor
[0] = vg
.window_x
;
312 player
->dev
.device
->debug_ui( player
, &player
->dev
);
314 b
[2].co
[1] = vg_uictx
.cursor
[1];
315 b
[3].co
[1] = vg_uictx
.cursor
[1];
319 VG_STATIC
void player_spawn( player_interface
*player
,
320 struct respawn_point
*rp
)
322 v3_copy( rp
->co
, player
->rb
.co
);
323 v3_copy( rp
->co
, player
->prev_position
);
324 v3_zero( player
->rb
.v
);
325 v3_zero( player
->rb
.w
);
326 q_identity( player
->rb
.q
);
327 rb_update_transform( &player
->rb
);
329 if( player
->dev
.device
->reset
)
330 player
->dev
.device
->reset( player
, &player
->dev
, rp
);
333 VG_STATIC
void player_kill( player_interface
*player
)
339 * Apply per render-frame mouse look from player to angles
341 VG_STATIC
void player_look( player_interface
*player
, v3f angles
)
344 v2_muladds( angles
, vg
.mouse_delta
, 0.0025f
, angles
);
346 if( vg_input
.controller_should_use_trackpad_look
)
348 static v2f last_input
;
350 static v2f vel_smooth
;
352 v2f input
= { player
->input_js2h
->axis
.value
,
353 player
->input_js2v
->axis
.value
};
355 if( (v2_length2(last_input
) > 0.001f
) && (v2_length2(input
) > 0.001f
) )
357 v2_sub( input
, last_input
, vel
);
358 v2_muls( vel
, 1.0f
/vg
.time_delta
, vel
);
365 v2_lerp( vel_smooth
, vel
, vg
.time_delta
*8.0f
, vel_smooth
);
367 v2_muladds( angles
, vel_smooth
, vg
.time_delta
, angles
);
368 v2_copy( input
, last_input
);
372 angles
[0] += player
->input_js2h
->axis
.value
* vg
.time_delta
* 4.0f
;
373 angles
[1] += player
->input_js2v
->axis
.value
* vg
.time_delta
* 4.0f
;
376 angles
[1] = vg_clampf( angles
[1], -VG_PIf
*0.5f
, VG_PIf
*0.5f
);
379 #endif /* PLAYER_INTERFACE_H */