X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_interface.h;h=54173455e9be62569a9b68cb23037761a41bc2ae;hb=9edcce70acf6cf8fbb2449bf54d797e212ebb2c2;hp=c890166d93cbe30ca5b03146852e953af96c023a;hpb=2ab1c45f664daf5a452fd212c89dcfd918f7dd81;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_interface.h b/player_interface.h index c890166..5417345 100644 --- a/player_interface.h +++ b/player_interface.h @@ -4,6 +4,8 @@ #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; @@ -35,15 +37,25 @@ struct player_interface *input_use, *input_reset, *input_grab; + + v3f prev_position; + + struct player_avatar *playeravatar; + glmesh *playermesh; + struct player_ragdoll ragdoll; }; +/* 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 ); + player_pose pose, m4x3f transform ); void (* get_camera) ( player_interface *player, player_attachment *at, camera *cam ); @@ -57,6 +69,8 @@ struct player_device 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 ); }; VG_STATIC void player_interface_create_player( player_interface *inst ) @@ -127,17 +141,33 @@ VG_STATIC void player_interface_create_player( player_interface *inst ) m4x3_identity( inst->rb.to_local ); } +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; +} + VG_STATIC void player_use_device( player_interface *player, player_device *dev, void *storage ) { player->dev.device = dev; player->dev.storage = storage; + + player->dev.device->bind( player, &player->dev ); } VG_STATIC void player_pre_update( player_interface *player ) { assert( player->dev.device ); + v3_copy( player->rb.co, player->prev_position ); + if( player->dev.device->pre_update ) player->dev.device->pre_update( player, &player->dev ); } @@ -150,15 +180,44 @@ VG_STATIC void player_update( player_interface *player ) player->dev.device->update( player, &player->dev ); } +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 ); +} + VG_STATIC void player_post_update( player_interface *player ) { + /* 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( 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 ); @@ -177,6 +236,43 @@ VG_STATIC void player_pre_render( player_interface *player ) } #endif +VG_STATIC void player_pre_render( player_interface *player ) +{ + player_pose pose; + m4x3f transform; + + 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 ); + + player->dev.device->get_camera( player, &player->dev, &player->cam ); + /* TODO: if dead copy ragdoll.. . */ +} + +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 ); +} + VG_STATIC void player_debugtext( int size, const char *fmt, ... ) { char buffer[ 1024 ]; @@ -198,11 +294,12 @@ VG_STATIC void player_ui( player_interface *player ) { vg_uictx.cursor[0] = vg.window_x - 200; vg_uictx.cursor[1] = 0; - vg_uictx.cursor[2] = 0; + vg_uictx.cursor[2] = 200; vg_uictx.cursor[3] = 200; 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 ); b[2].co[1] = vg_uictx.cursor[1]; @@ -214,9 +311,14 @@ VG_STATIC void player_spawn( player_interface *player, struct respawn_point *rp ) { v3_copy( rp->co, player->rb.co ); + v3_copy( rp->co, player->prev_position ); 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 ); } /*