third person better camera
[carveJwlIkooP6JGAAIwe30JlM.git] / player_interface.h
index c890166d93cbe30ca5b03146852e953af96c023a..54173455e9be62569a9b68cb23037761a41bc2ae 100644 (file)
@@ -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; i<world.gate_count; i++ )
+   {
+      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 );
+      }
+   }
    
-   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 );
 }
 
 /*