X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_interface.h;h=a304fbb5b752e56865d7b52eb51a75b3a48e0cc8;hb=919d1227839218c57430fe9cab8f74d594c7bd14;hp=a4be40ed5177fe1a0fde9048a7c18d25740c9490;hpb=c5b57b50f0a67361fa4c49feb05750d1cd0ae2ba;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_interface.h b/player_interface.h index a4be40e..a304fbb 100644 --- a/player_interface.h +++ b/player_interface.h @@ -1,3 +1,4 @@ +#if 0 #ifndef PLAYER_INTERFACE_H #define PLAYER_INTERFACE_H @@ -10,21 +11,38 @@ typedef struct player_device player_device; typedef struct player_interface player_interface; -typedef struct player_attachment player_attachment; +typedef struct player_device_transition player_device_transition; typedef mdl_keyframe player_pose[32]; +#define PLAYER_DEVICE_API VG_STATIC + struct player_interface { rigidbody rb; camera cam; - - struct player_attachment + + player_device *devices[ 8 ]; + u32 active_device, + device_count; + + /* + * Camera management + * --------------------------- + */ + enum camera_mode { - player_device *device; - void *storage; + k_camera_mode_firstperson, + k_camera_mode_thirdperson } - dev; + camera_mode; + float camera_type_blend; + + teleport_gate *gate_waiting; + /* + * Input + * -------------------------------- + */ struct input_binding *input_js1h, *input_js1v, *input_js2h, @@ -36,41 +54,50 @@ struct player_interface *input_walkv, *input_use, *input_reset, - *input_grab; + *input_grab, + *input_camera; - v3f prev_position; + /* + * Animation + * -------------------------------------------------- + */ struct player_avatar *playeravatar; glmesh *playermesh; struct player_ragdoll ragdoll; }; +enum player_device_event_type +{ + k_player_device_event_bind, + k_player_device_event_respawn, + k_player_device_event_custom_transition, + + k_player_device_event_pre_update, + k_player_device_event_update, + k_player_device_event_post_update, + k_player_device_event_animate, + k_player_device_event_post_animate, + k_player_device_event_debug_ui, + k_player_device_event_restore_state, +}; + /* FIXME: yo */ vg_tex2d tex_characters = { .path = "textures/ch_gradient.qoi" }; struct player_device { - void (* bind ) ( player_interface *player, player_attachment *at ); - void (* pre_update) ( player_interface *player, player_attachment *at ); - void (* update) ( player_interface *player, player_attachment *at ); - void (* post_update)( player_interface *player, player_attachment *at ); - void (* pose) ( player_interface *player, player_attachment *at, - player_pose pose, m4x3f transform ); - - void (* get_camera) ( player_interface *player, player_attachment *at, - camera *cam ); - - void (* attatch ) ( player_interface *player, player_attachment *at, - void *storage ); - - void (* reset ) ( player_interface *player, player_attachment *at, - struct respawn_point *spawn ); - - void (* store_state)( player_interface *player, player_attachment *at ); - void (* load_state) ( player_interface *player, player_attachment *at ); - void (* debug_ui) ( player_interface *player, player_attachment *at ); - void (* gate_transport)( player_interface *player, player_attachment *at, - teleport_gate *gate ); + const char *name; + int (* event ) ( player_device *dev, player_interface *player, + enum player_device_event_type ev, void *data ); + + void *storage; + + /* animation driven */ + player_pose pose; + v3f pose_root_co; + v4f pose_root_q; + camera cam_1st, cam_3rd; }; VG_STATIC void player_interface_create_player( player_interface *inst ) @@ -91,6 +118,7 @@ VG_STATIC void player_interface_create_player( player_interface *inst ) inst->input_walkv= vg_create_named_input( "walk-v", k_input_type_axis ); inst->input_use = vg_create_named_input( "use", k_input_type_button ); inst->input_reset= vg_create_named_input( "reset", k_input_type_button ); + inst->input_camera=vg_create_named_input( "camera", k_input_type_button ); const char *default_cfg[] = { @@ -128,6 +156,7 @@ VG_STATIC void player_interface_create_player( player_interface *inst ) "bind use gp-y", "bind use e", + "bind camera c" }; for( int i=0; irb.to_local ); } +PLAYER_DEVICE_API u32 player_get_device( player_interface *player, + const char *name ) +{ + for( u32 i=0; idevice_count; i++ ) + { + player_device *dev = player->devices[i]; + if( !strcmp( name, dev->name ) ) + return i; + } + + vg_fatal_exit_loop( "Invalid device name\n" ); + return -1; +} + VG_STATIC void player_use_avatar( player_interface *player, struct player_avatar *av ) { @@ -153,101 +196,189 @@ VG_STATIC void player_use_mesh( player_interface *player, glmesh *mesh ) player->playermesh = mesh; } -VG_STATIC void player_use_device( player_interface *player, player_device *dev, - void *storage ) +/* FIXME: Seperate concepts for binding and equip. + */ +VG_STATIC void player_add_device( player_interface *player, player_device *dev ) { - player->dev.device = dev; - player->dev.storage = storage; + if( player->device_count == vg_list_size( player->devices ) ) + vg_fatal_exit_loop( "Too many devices added\n" ); - player->dev.device->bind( player, &player->dev ); -} + player->devices[ player->device_count ++ ] = dev; -VG_STATIC void player_pre_update( player_interface *player ) -{ - assert( player->dev.device ); - - v3_copy( player->rb.co, player->prev_position ); + assert( dev->event ); + assert( dev->storage ); - if( player->dev.device->pre_update ) - player->dev.device->pre_update( player, &player->dev ); + vg_success( "Added player device '%s'\n", dev->name ); } -VG_STATIC void player_update( player_interface *player ) +VG_STATIC void player_bind( player_interface *player ) { - assert( player->dev.device ); - - if( player->dev.device->update ) - player->dev.device->update( player, &player->dev ); + for( int i=0; idevice_count; i++ ) + { + player_device *dev = player->devices[i]; + dev->event( dev, player, k_player_device_event_bind, NULL ); + } } -VG_STATIC void player_post_update( player_interface *player, - camera *main_camera ) +PLAYER_DEVICE_API void player_transition_to_device( player_interface *player, + u32 id, void *data ) { - assert( player->dev.device ); + assert( id < player->device_count ); - if( player->dev.device->post_update ) - player->dev.device->post_update( player, &player->dev ); + player->active_device = id; + player_device *dev = player->devices[ player->active_device ]; - /* FIXME: only need to test against the visible gate.... - * OR... bvh */ + dev->event( dev, player, k_player_device_event_custom_transition, data ); + //dev->event( dev, player, k_player_device_event_pre_update, NULL ); +} - for( int i=0; iinput_camera ) ) { - struct route_gate *rg = &world.gates[i]; - teleport_gate *gate = &rg->gate; - - if( gate_intersect( gate, player->rb.co, player->prev_position ) ) - { - player->dev.device->gate_transport( player, &player->dev, gate ); - v3_copy( player->rb.co, player->prev_position ); - - /* Pre-emptively edit the camera matrices so that the motion vectors - * are correct */ - m4x3f transport_i; - m4x4f transport_4; - m4x3_invert_affine( gate->transport, transport_i ); - m4x3_expand( transport_i, transport_4 ); - m4x4_mul( main_camera->mtx.pv, transport_4, main_camera->mtx.pv ); - m4x4_mul( main_camera->mtx.v, transport_4, main_camera->mtx.v ); - } + if( player->camera_mode == k_camera_mode_firstperson ) + player->camera_mode = k_camera_mode_thirdperson; + else + player->camera_mode = k_camera_mode_firstperson; } - + #if 0 - camera_update_transform( &player->cam ); - camera_update_view( &player->cam ); - camera_update_projection( &player->cam ); - camera_finalize( &player->cam ); + if( vg_input_button_down( player->input_use ) ) + player->active_device ^= 0x1; #endif -} #if 0 -VG_STATIC void player_pre_render( player_interface *player ) + v3_copy( player->rb.co, player->prev_position ); +#endif + + player_device *dev = player->devices[ player->active_device ]; + dev->event( dev, player, k_player_device_event_pre_update, NULL ); +} + +VG_STATIC void player_update( player_interface *player ) { - assert( player->dev.device ); + player_device *dev = player->devices[ player->active_device ]; + dev->event( dev, player, k_player_device_event_update, NULL ); +} - if( player->dev.device->pre_render ) - player->dev.device->pre_render( player ); +VG_STATIC void player_apply_transport_to_cam( m4x3f transport ) +{ + /* FIXME: Applies to main_camera directly! */ + + /* Pre-emptively edit the camera matrices so that the motion vectors + * are correct */ + m4x3f transport_i; + m4x4f transport_4; + m4x3_invert_affine( transport, transport_i ); + m4x3_expand( transport_i, transport_4 ); + m4x4_mul( main_camera.mtx.pv, transport_4, main_camera.mtx.pv ); + m4x4_mul( main_camera.mtx.v, transport_4, main_camera.mtx.v ); +} + +/* + * Applies gate transport to a player_interface + */ +PLAYER_DEVICE_API +void player_pass_gate( player_interface *player, teleport_gate *gate ) +{ + player->gate_waiting = gate; +} + +VG_STATIC void player_post_update( player_interface *player ) +{ + player_device *dev = player->devices[ player->active_device ]; + dev->event( dev, player, k_player_device_event_post_update, NULL ); } -#endif VG_STATIC void player_pre_render( player_interface *player ) { - player_pose pose; - m4x3f transform; + player_device *dev = player->devices[ player->active_device ]; + dev->event( dev, player, k_player_device_event_animate, NULL ); + + /* TODO: eventually, blending code goes here */ - player->dev.device->pose( player, &player->dev, pose, transform ); + m4x3f transform; + q_m3x3( dev->pose_root_q, transform ); + v3_copy( dev->pose_root_co, transform[3] ); struct skeleton *sk = &player->playeravatar->sk; - skeleton_apply_pose( sk, pose, k_anim_apply_defer_ik ); + skeleton_apply_pose( sk, dev->pose, k_anim_apply_defer_ik ); skeleton_apply_ik_pass( sk ); - skeleton_apply_pose( sk, pose, k_anim_apply_deffered_only ); + skeleton_apply_pose( sk, dev->pose, k_anim_apply_deffered_only ); skeleton_apply_inverses( sk ); skeleton_apply_transform( sk, transform ); skeleton_debug( sk ); - player->dev.device->get_camera( player, &player->dev, &player->cam ); - /* TODO: if dead copy ragdoll.. . */ +#if 0 + if( player->dev.device->pose ) + { + player->dev.device->pose( player, &player->dev, pose, transform ); + + struct skeleton *sk = &player->playeravatar->sk; + + skeleton_apply_pose( sk, pose, k_anim_apply_defer_ik ); + skeleton_apply_ik_pass( sk ); + skeleton_apply_pose( sk, pose, k_anim_apply_deffered_only ); + skeleton_apply_inverses( sk ); + skeleton_apply_transform( sk, transform ); + skeleton_debug( sk ); + } +#endif + + dev->event( dev, player, k_player_device_event_post_animate, NULL ); + + /* TODO: eventually, blending code goes here */ + + float camera_blend_target = 1.0f; + if( player->camera_mode == k_camera_mode_firstperson ) + camera_blend_target = 0.0f; + + player->camera_type_blend = vg_lerpf( player->camera_type_blend, + camera_blend_target, + 5.0f * vg.frame_delta ); + + float t = player->camera_type_blend; + camera_lerp( &dev->cam_1st, &dev->cam_3rd, t, &player->cam ); + player->cam.fov = vg_lerpf( 118.0f, 90.0f, t ); + + if( player->gate_waiting ) + { + /* construct plane equation for reciever gate */ + v4f plane; + q_mulv( player->gate_waiting->q[1], (v3f){0.0f,0.0f,1.0f}, plane ); + plane[3] = v3_dot( plane, player->gate_waiting->co[1] ); + + /* check camera polarity */ + if( v3_dot( player->cam.pos, plane ) < plane[3] ) + { + vg_success( "Plane cleared\n" ); + player_apply_transport_to_cam( player->gate_waiting->transport ); + player->gate_waiting = NULL; + } + else + { + /* de-transform camera and player back */ + m4x3f inverse; + m4x3_invert_affine( player->gate_waiting->transport, inverse ); + m4x3_mulv( inverse, player->cam.pos, player->cam.pos ); + + /* TODO: Find robust method for this */ + v3f fwd_dir = { cosf(player->cam.angles[0]), + 0.0f, + sinf(player->cam.angles[0])}; + m3x3_mulv( inverse, fwd_dir, fwd_dir ); + player->cam.angles[0] = atan2f( fwd_dir[2], fwd_dir[0] ); + + skeleton_apply_transform( sk, inverse ); + } + } + +#if 0 + v3_copy( player->dev.cam_1st.pos, player->cam.pos ); + v3_copy( player->dev.cam_1st.angles, player->cam.angles ); + player->cam.fov = player->dev.cam_1st.fov; +#endif } VG_STATIC void player_render( camera *cam, player_interface *player ) @@ -283,42 +414,49 @@ VG_STATIC void player_debugtext( int size, const char *fmt, ... ) VG_STATIC void player_ui( player_interface *player ) { /* TODO: if debugger enabled */ + player_device *dev = player->devices[ player->active_device ]; - if( player->dev.device->debug_ui ) - { - vg_uictx.cursor[0] = vg.window_x - 200; - vg_uictx.cursor[1] = 0; - vg_uictx.cursor[2] = 200; - vg_uictx.cursor[3] = 200; + vg_uictx.cursor[0] = vg.window_x - 200; + vg_uictx.cursor[1] = 0; + vg_uictx.cursor[2] = 200; + vg_uictx.cursor[3] = 200; - struct ui_vert *b = ui_fill_rect( vg_uictx.cursor, 0x70000000 ); + struct ui_vert *b = ui_fill_rect( vg_uictx.cursor, 0x70000000 ); - vg_uictx.cursor[0] = vg.window_x; - player->dev.device->debug_ui( player, &player->dev ); + vg_uictx.cursor[0] = vg.window_x; + dev->event( dev, player, k_player_device_event_debug_ui, NULL ); - b[2].co[1] = vg_uictx.cursor[1]; - b[3].co[1] = vg_uictx.cursor[1]; - } + b[2].co[1] = vg_uictx.cursor[1]; + b[3].co[1] = vg_uictx.cursor[1]; } VG_STATIC void player_spawn( player_interface *player, struct respawn_point *rp ) { + player_device *dev = player->devices[ player->active_device ]; v3_copy( rp->co, player->rb.co ); +#if 0 v3_copy( rp->co, player->prev_position ); +#endif v3_zero( player->rb.v ); v3_zero( player->rb.w ); q_identity( player->rb.q ); rb_update_transform( &player->rb ); - if( player->dev.device->reset ) - player->dev.device->reset( player, &player->dev, rp ); + dev->event( dev, player, k_player_device_event_respawn, rp ); +} + + +VG_STATIC void player_kill( player_interface *player ) +{ + } /* * Apply per render-frame mouse look from player to angles */ -VG_STATIC void player_look( player_interface *player, v3f angles ) +PLAYER_DEVICE_API +void player_look( player_interface *player, v3f angles ) { angles[2] = 0.0f; v2_muladds( angles, vg.mouse_delta, 0.0025f, angles ); @@ -357,3 +495,4 @@ VG_STATIC void player_look( player_interface *player, v3f angles ) } #endif /* PLAYER_INTERFACE_H */ +#endif