#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;
*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 );
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 )
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 );
}
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 );
}
#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 ];
{
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];
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 );
}
/*