X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_interface.h;h=dc23776500b58bfd163a8770b29f354c8a507a58;hb=0de25596501d8aba67b08c92bdab417d6947cd13;hp=54173455e9be62569a9b68cb23037761a41bc2ae;hpb=9edcce70acf6cf8fbb2449bf54d797e212ebb2c2;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_interface.h b/player_interface.h index 5417345..dc23776 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,31 +196,69 @@ 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 ) +{ + 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 ]; - player->dev.device->bind( player, &player->dev ); + 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 0 v3_copy( player->rb.co, player->prev_position ); +#endif - if( player->dev.device->pre_update ) - player->dev.device->pre_update( player, &player->dev ); + 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 ); - - if( player->dev.device->update ) - player->dev.device->update( player, &player->dev ); + 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 ) @@ -194,66 +275,110 @@ VG_STATIC void player_apply_transport_to_cam( m4x3f transport ) m4x4_mul( main_camera.mtx.v, transport_4, main_camera.mtx.v ); } -VG_STATIC void player_post_update( player_interface *player ) +/* + * Applies gate transport to a player_interface + */ +PLAYER_DEVICE_API +void player_pass_gate( player_interface *player, teleport_gate *gate ) { - /* FIXME: Applies to main_camera directly! */ - - assert( player->dev.device ); - - if( player->dev.device->post_update ) - player->dev.device->post_update( player, &player->dev ); - - /* FIXME: only need to test against the visible gate.... - * OR... bvh */ - - for( int i=0; igate; - - 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 ); - } - } - -#if 0 - camera_update_transform( &player->cam ); - camera_update_view( &player->cam ); - camera_update_projection( &player->cam ); - camera_finalize( &player->cam ); -#endif + player->gate_waiting = gate; } -#if 0 -VG_STATIC void player_pre_render( player_interface *player ) +VG_STATIC void player_post_update( player_interface *player ) { - assert( player->dev.device ); - - if( player->dev.device->pre_render ) - player->dev.device->pre_render( 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; + 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 + 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 ) @@ -289,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 ); @@ -363,3 +495,4 @@ VG_STATIC void player_look( player_interface *player, v3f angles ) } #endif /* PLAYER_INTERFACE_H */ +#endif