X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_interface.h;h=dc23776500b58bfd163a8770b29f354c8a507a58;hb=0de25596501d8aba67b08c92bdab417d6947cd13;hp=c890166d93cbe30ca5b03146852e953af96c023a;hpb=2ab1c45f664daf5a452fd212c89dcfd918f7dd81;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_interface.h b/player_interface.h index c890166..dc23776 100644 --- a/player_interface.h +++ b/player_interface.h @@ -1,28 +1,48 @@ +#if 0 #ifndef PLAYER_INTERFACE_H #define PLAYER_INTERFACE_H #include "model.h" #include "camera.h" #include "rigidbody.h" +#include "player_ragdoll.h" +#include "player_model.h" #include "world.h" 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, @@ -34,29 +54,50 @@ struct player_interface *input_walkv, *input_use, *input_reset, - *input_grab; + *input_grab, + *input_camera; + + /* + * Animation + * -------------------------------------------------- + */ + + struct player_avatar *playeravatar; + glmesh *playermesh; + struct player_ragdoll ragdoll; }; -struct player_device +enum player_device_event_type { - 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 ); + 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, +}; - void (* get_camera) ( player_interface *player, player_attachment *at, - camera *cam ); +/* FIXME: yo */ +vg_tex2d tex_characters = { .path = "textures/ch_gradient.qoi" }; - void (* attatch ) ( player_interface *player, player_attachment *at, - void *storage ); +struct player_device +{ + const char *name; + int (* event ) ( player_device *dev, player_interface *player, + enum player_device_event_type ev, void *data ); - void (* reset ) ( player_interface *player, player_attachment *at, - struct respawn_point *spawn ); + void *storage; - 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 ); + /* 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 ) @@ -77,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[] = { @@ -114,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 ); } -VG_STATIC void player_use_device( player_interface *player, player_device *dev, - void *storage ) +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 ) +{ + player->playeravatar = av; + player_setup_ragdoll_from_avatar( &player->ragdoll, av ); +} + +VG_STATIC void player_use_mesh( player_interface *player, glmesh *mesh ) +{ + player->playermesh = mesh; +} + +/* FIXME: Seperate concepts for binding and equip. + */ +VG_STATIC void player_add_device( player_interface *player, player_device *dev ) +{ + if( player->device_count == vg_list_size( player->devices ) ) + vg_fatal_exit_loop( "Too many devices added\n" ); + + player->devices[ player->device_count ++ ] = dev; + + assert( dev->event ); + assert( dev->storage ); + + vg_success( "Added player device '%s'\n", dev->name ); +} + +VG_STATIC void player_bind( player_interface *player ) { - player->dev.device = dev; - player->dev.storage = storage; + for( int i=0; idevice_count; i++ ) + { + player_device *dev = player->devices[i]; + dev->event( dev, player, k_player_device_event_bind, NULL ); + } +} + +PLAYER_DEVICE_API void player_transition_to_device( player_interface *player, + u32 id, void *data ) +{ + assert( id < player->device_count ); + + player->active_device = id; + player_device *dev = player->devices[ player->active_device ]; + + dev->event( dev, player, k_player_device_event_custom_transition, data ); + //dev->event( dev, player, k_player_device_event_pre_update, NULL ); } VG_STATIC void player_pre_update( player_interface *player ) { - assert( player->dev.device ); + if( vg_input_button_down( player->input_camera ) ) + { + 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 + if( vg_input_button_down( player->input_use ) ) + player->active_device ^= 0x1; +#endif - if( player->dev.device->pre_update ) - player->dev.device->pre_update( player, &player->dev ); +#if 0 + 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 ); +} + +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 ); +} - if( player->dev.device->update ) - player->dev.device->update( player, &player->dev ); +/* + * 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 ) { - assert( player->dev.device ); + player_device *dev = player->devices[ player->active_device ]; + dev->event( dev, player, k_player_device_event_post_update, NULL ); +} + +VG_STATIC void player_pre_render( player_interface *player ) +{ + player_device *dev = player->devices[ player->active_device ]; + dev->event( dev, player, k_player_device_event_animate, NULL ); + + /* TODO: eventually, blending code goes here */ + + 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, dev->pose, k_anim_apply_defer_ik ); + skeleton_apply_ik_pass( sk ); + skeleton_apply_pose( sk, dev->pose, k_anim_apply_deffered_only ); + skeleton_apply_inverses( sk ); + skeleton_apply_transform( sk, transform ); + skeleton_debug( sk ); - if( player->dev.device->post_update ) - player->dev.device->post_update( player, &player->dev ); - - if( player->dev.device->get_camera ) - player->dev.device->get_camera( player, &player->dev, &player->cam ); #if 0 - camera_update_transform( &player->cam ); - camera_update_view( &player->cam ); - camera_update_projection( &player->cam ); - camera_finalize( &player->cam ); + 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; + v3_copy( player->gate_waiting->recv_to_world[2], plane ); + plane[3] = v3_dot( plane, player->gate_waiting->recv_to_world[3] ); + + /* 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 -VG_STATIC void player_pre_render( player_interface *player ) -{ - assert( player->dev.device ); + 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 +} - if( player->dev.device->pre_render ) - player->dev.device->pre_render( player ); +VG_STATIC void player_render( camera *cam, player_interface *player ) +{ + shader_viewchar_use(); + vg_tex2d_bind( &tex_characters, 0 ); + shader_viewchar_uTexMain( 0 ); + shader_viewchar_uCamera( cam->transform[3] ); + shader_viewchar_uPv( cam->mtx.pv ); + shader_link_standard_ub( _shader_viewchar.id, 2 ); + glUniformMatrix4x3fv( _uniform_viewchar_uTransforms, + player->playeravatar->sk.bone_count, + 0, + (float *)player->playeravatar->sk.final_mtx ); + + mesh_bind( player->playermesh ); + mesh_draw( player->playermesh ); } -#endif VG_STATIC void player_debugtext( int size, const char *fmt, ... ) { @@ -193,36 +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] = 0; - 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 ); - 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 ); + + 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 ); @@ -261,3 +495,4 @@ VG_STATIC void player_look( player_interface *player, v3f angles ) } #endif /* PLAYER_INTERFACE_H */ +#endif