From 333430b27b5f9f73cbe9ad7921a4735aaff444f1 Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 30 Sep 2023 15:57:43 +0100 Subject: [PATCH] test network 5 --- gameserver.c | 50 ++++++++++++++++++------------ network.c | 21 +++++-------- network_msg.h | 3 +- player.h | 6 ++-- player_common.c | 4 +-- player_ragdoll.c | 17 +++++----- player_remote.c | 78 ++++++++++++++++++++++++++++++++++++++++++++-- player_remote.h | 13 ++++++-- player_render.c | 49 ++++++++++++++++------------- player_render.h | 3 +- player_skate.c | 3 +- player_walk.c | 2 +- skaterift.c | 38 +++++++++++++++++++++++ skeleton.h | 81 +++++++++++++++++++++++------------------------- workshop.c | 15 +++++---- 15 files changed, 259 insertions(+), 124 deletions(-) diff --git a/gameserver.c b/gameserver.c index 818b22d..ff8d635 100644 --- a/gameserver.c +++ b/gameserver.c @@ -296,29 +296,41 @@ static int packet_minsize( SteamNetworkingMessage_t *msg, u32 size ){ static void gameserver_rx_200_300( SteamNetworkingMessage_t *msg ){ netmsg_blank *tmp = msg->m_pData; + int client_id = gameserver_client_index( msg->m_conn ); + if( client_id == -1 ) return; + if( tmp->inetmsg_id == k_inetmsg_playerusername ){ if( !packet_minsize( msg, sizeof(netmsg_playerusername) )) return; - int client_id = gameserver_client_index( msg->m_conn ); - if( client_id != -1 ){ - struct gameserver_client *client = &gameserver.clients[ client_id ]; - netmsg_playerusername *src = msg->m_pData; - - vg_strncpy( src->username, client->username, sizeof(client->username), - k_strncpy_always_add_null ); - - /* update other users about this change */ - netmsg_playerusername msg; - memset( &msg, 0, sizeof(msg) ); - msg.inetmsg_id = k_inetmsg_playerusername; - msg.index = client_id; - vg_strncpy( client->username, msg.username, sizeof(msg.username), - k_strncpy_always_add_null ); - - gameserver_send_to_all( client_id, &msg, sizeof(msg), - k_nSteamNetworkingSend_Reliable ); - } + struct gameserver_client *client = &gameserver.clients[ client_id ]; + netmsg_playerusername *src = msg->m_pData; + + vg_info( "%d change name '%s' -> '%s'\n", + client_id, client->username, src->username ); + + vg_strncpy( src->username, client->username, sizeof(client->username), + k_strncpy_always_add_null ); + + /* update other users about this change */ + netmsg_playerusername msg; + memset( &msg, 0, sizeof(msg) ); + msg.inetmsg_id = k_inetmsg_playerusername; + msg.index = client_id; + vg_strncpy( client->username, msg.username, sizeof(msg.username), + k_strncpy_always_add_null ); + + gameserver_send_to_all( client_id, &msg, sizeof(msg), + k_nSteamNetworkingSend_Reliable ); + } + else if( tmp->inetmsg_id == k_inetmsg_playerframe ){ + /* propogate */ + + netmsg_playerframe *frame = alloca(msg->m_cbSize); + memcpy( frame, msg->m_pData, msg->m_cbSize ); + frame->client = client_id; + gameserver_send_to_all( client_id, frame, msg->m_cbSize, + k_nSteamNetworkingSend_Unreliable ); } } diff --git a/network.c b/network.c index a35ead4..3235c69 100644 --- a/network.c +++ b/network.c @@ -123,17 +123,6 @@ static void send_nickname(void){ } #endif -static void network_send_playerframe(void){ - netmsg_playerframe frame; - frame.inetmsg_id = k_inetmsg_playerframe; - v3_copy( localplayer.rb.co, frame.pos_temp ); - - SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( - hSteamNetworkingSockets, network_client.remote, - &frame, sizeof(frame), - k_nSteamNetworkingSend_Unreliable, NULL ); -} - #if 0 static void server_routine_update(void){ send_score_update(); @@ -220,8 +209,12 @@ static void on_persona_state_change( CallbackMsg_t *msg ){ PersonaStateChange_t *info = (void *)msg->m_pubParam; ISteamUser *hSteamUser = SteamAPI_SteamUser(); + + vg_info( "User: %llu, change: %u\n", info->m_ulSteamID, + info->m_nChangeFlags ); + if( info->m_ulSteamID == SteamAPI_ISteamUser_GetSteamID(hSteamUser) ){ - if( info->m_nChangeFlags == k_EPersonaChangeNickname ){ + if( info->m_nChangeFlags & k_EPersonaChangeName ){ network_send_username(); } } @@ -326,8 +319,10 @@ static void network_update(void){ if( frame_delta > 0.1 ){ network_client.last_frame = vg.time_real; - network_send_playerframe(); + remote_player_send_playerframe(); } + + remote_player_debug_update(); } else { if( (state == k_ESteamNetworkingConnectionState_Connecting) || diff --git a/network_msg.h b/network_msg.h index 0d585ba..b76e695 100644 --- a/network_msg.h +++ b/network_msg.h @@ -92,7 +92,8 @@ typedef struct netmsg_playerframe netmsg_playerframe; enum{ k_inetmsg_playerframe = 200 }; struct netmsg_playerframe{ u32 inetmsg_id; - v3f pos_temp; + u8 client, subsystem; + u8 animdata[]; }; /* remote -> client */ diff --git a/player.h b/player.h index 36b37a9..029a34e 100644 --- a/player.h +++ b/player.h @@ -5,12 +5,12 @@ #include "player_common.h" enum player_subsystem{ - k_player_subsystem_invalid = -1, k_player_subsystem_walk = 0, k_player_subsystem_skate = 1, k_player_subsystem_dead = 2, k_player_subsystem_drive = 3, - k_player_subsystem_max + k_player_subsystem_max, + k_player_subsystem_invalid = 255 }; struct player_cam_controller { @@ -110,6 +110,8 @@ struct { player_pose holdout_pose; float holdout_time; + m4x3f *final_mtx; + /* * Subsystems * ------------------------------------------------- diff --git a/player_common.c b/player_common.c index 7daa399..203f52b 100644 --- a/player_common.c +++ b/player_common.c @@ -53,7 +53,7 @@ static void player_camera_portal_correction(void){ m4x3_mulv( inverse, localplayer.cam.pos, localplayer.cam.pos ); struct skeleton *sk = &localplayer.playeravatar->sk; - skeleton_apply_transform( sk, inverse ); + skeleton_apply_transform( sk, inverse, localplayer.final_mtx ); } } } @@ -127,7 +127,7 @@ static void player__cam_iterate(void){ /* position */ v3f fpv_pos, fpv_offset; - m4x3_mulv( av->sk.final_mtx[ av->id_head-1 ], + m4x3_mulv( localplayer.final_mtx[ av->id_head-1 ], cc->fpv_viewpoint_smooth, fpv_pos ); m3x3_mulv( localplayer.rb.to_world, cc->fpv_offset_smooth, fpv_offset ); v3_add( fpv_offset, fpv_pos, fpv_pos ); diff --git a/player_ragdoll.c b/player_ragdoll.c index d36bec4..d5029dd 100644 --- a/player_ragdoll.c +++ b/player_ragdoll.c @@ -204,7 +204,8 @@ static void copy_ragdoll_pose_to_avatar( struct player_ragdoll *rd, q_m3x3( q_int, mtx ); v3_copy( co_int, mtx[3] ); - m4x3_mul( mtx, part->inv_collider_mtx, av->sk.final_mtx[part->bone_id] ); + m4x3_mul( mtx, part->inv_collider_mtx, + localplayer.final_mtx[part->bone_id] ); } for( u32 i=1; isk.bone_count; i++ ){ @@ -219,11 +220,12 @@ static void copy_ragdoll_pose_to_avatar( struct player_ragdoll *rd, v3_copy( delta, posemtx[3] ); /* final matrix */ - m4x3_mul( av->sk.final_mtx[sb->parent], posemtx, av->sk.final_mtx[i] ); + m4x3_mul( localplayer.final_mtx[sb->parent], posemtx, + localplayer.final_mtx[i] ); } } - skeleton_apply_inverses( &av->sk ); + skeleton_apply_inverses( &av->sk, localplayer.final_mtx ); } /* @@ -239,12 +241,12 @@ static void copy_avatar_pose_to_ragdoll( struct player_avatar *av, v3f pos, offset; u32 bone = part->bone_id; - m4x3_mulv( av->sk.final_mtx[bone], av->sk.bones[bone].co, pos ); - m3x3_mulv( av->sk.final_mtx[bone], part->collider_mtx[3], offset ); + m4x3_mulv( localplayer.final_mtx[bone], av->sk.bones[bone].co, pos ); + m3x3_mulv( localplayer.final_mtx[bone], part->collider_mtx[3], offset ); v3_add( pos, offset, part->obj.rb.co ); m3x3f r; - m3x3_mul( av->sk.final_mtx[bone], part->collider_mtx, r ); + m3x3_mul( localplayer.final_mtx[bone], part->collider_mtx, r ); m3x3_q( r, part->obj.rb.q ); v3_copy( velocity, part->obj.rb.v ); @@ -267,8 +269,7 @@ static void player_debug_ragdoll(void) /* * Ragdoll physics step */ -static void player_ragdoll_iter( struct player_ragdoll *rd ) -{ +static void player_ragdoll_iter( struct player_ragdoll *rd ){ world_instance *world = world_current_instance(); int run_sim = 0; diff --git a/player_remote.c b/player_remote.c index 69f148f..da0ee29 100644 --- a/player_remote.c +++ b/player_remote.c @@ -66,6 +66,73 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){ vg_error( "inetmsg_playerleave: player index out of range\n" ); } } + else if( tmp->inetmsg_id == k_inetmsg_playerframe ){ + u32 datasize = msg->m_cbSize - sizeof(netmsg_playerframe); + + if( datasize > sizeof(netplayers.list[0].animdata) ){ + vg_error( "Player frame data exceeds animdata size\n" ); + return; + } + + netmsg_playerframe *frame = msg->m_pData; + if( frame->client >= vg_list_size(netplayers.list) ){ + vg_error( "inetmsg_playerframe: player index out of range\n" ); + return; + } + + if( frame->subsystem >= k_player_subsystem_max ){ + vg_error( "inetmsg_playerframe: subsystem out of range\n" ); + return; + } + + struct network_player *player = &netplayers.list[ frame->client ]; + memcpy( &player->animdata, frame->animdata, datasize ); + player->subsystem = frame->subsystem; + player->down_bytes += msg->m_cbSize; + } +} + +static void remote_player_send_playerframe(void){ + u8 sysid = localplayer.subsystem; + if( sysid >= k_player_subsystem_max ) return; + + struct player_subsystem_interface *sys = player_subsystems[sysid]; + + if( sys->animator_size ){ + u32 size = sizeof(netmsg_playerframe)+sys->animator_size; + netmsg_playerframe *frame = alloca(size); + frame->inetmsg_id = k_inetmsg_playerframe; + frame->client = 0; + frame->subsystem = localplayer.subsystem; + memcpy( frame->animdata, sys->animator_data, sys->animator_size ); + + netplayers.up_bytes += size; + + SteamAPI_ISteamNetworkingSockets_SendMessageToConnection( + hSteamNetworkingSockets, network_client.remote, + frame, size, + k_nSteamNetworkingSend_Unreliable, NULL ); + } +} + +static void remote_player_debug_update(void){ + if( (vg.time_real - netplayers.last_data_measurement) > 1.0 ){ + netplayers.last_data_measurement = vg.time_real; + u32 total_down = 0; + + for( u32 i=0; iactive ){ + total_down += player->down_bytes; + player->down_kbs = ((f32)player->down_bytes)/1024.0f; + player->down_bytes = 0; + } + } + + netplayers.down_kbs = ((f32)total_down)/1024.0f; + netplayers.up_kbs = ((f32)netplayers.up_bytes)/1024.0f; + netplayers.up_bytes = 0; + } } static void remote_player_network_imgui(void){ @@ -108,16 +175,21 @@ static void remote_player_network_imgui(void){ if( network_client.state == k_ESteamNetworkingConnectionState_Connected ){ ui_info( panel, "#-1: localplayer" ); + + snprintf( buf, 512, "U%.1f/D%.1fkbs", + netplayers.up_kbs, netplayers.down_kbs ); + ui_info( panel, buf ); + for( u32 i=0; iactive ){ const char *sysname = "invalid"; - if( (player->subsystem >= 0) && - (player->subsystem < k_player_subsystem_max) ){ + if( player->subsystem < k_player_subsystem_max ){ sysname = player_subsystems[ player->subsystem ]->name; } - snprintf( buf, 512, "#%u: %s [%s]", i, player->username, sysname ); + snprintf( buf, 512, "#%u: %s [%s] D%.1fkbs", + i, player->username, sysname, player->down_kbs ); ui_info( panel, buf ); } } diff --git a/player_remote.h b/player_remote.h index e2d757c..1360e54 100644 --- a/player_remote.h +++ b/player_remote.h @@ -8,21 +8,30 @@ struct { struct network_player { int active; u16 board_view_slot, playermodel_view_slot; - player_pose pose; char username[32]; + u32 down_bytes; + f32 down_kbs; enum player_subsystem subsystem; union { struct player_skate_animator _skate; struct player_walk_animator _walk; struct player_dead_animator _dead; - }; + } animdata; } list[ 32 ]; + + m4x3f *final_mtx; + + u32 up_bytes; + f32 up_kbs, down_kbs; + f64 last_data_measurement; } static netplayers; static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ); +static void remote_player_debug_update(void); +static void remote_player_send_playerframe(void); #endif /* PLAYER_REMOTE_H */ diff --git a/player_render.c b/player_render.c index 93786b3..22938b5 100644 --- a/player_render.c +++ b/player_render.c @@ -136,25 +136,26 @@ static void player_model_unload( struct player_model *board ){ dynamic_model_unload( &board->mdl ); } -static void player_apply_pose_to_skeleton(void){ - struct skeleton *sk = &localplayer.playeravatar->sk; - player_pose *pose = &localplayer.pose; - +static void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose, + m4x3f *final_mtx ){ m4x3f transform; q_m3x3( pose->root_q, transform ); v3_copy( pose->root_co, transform[3] ); if( pose->type == k_player_pose_type_ik ){ - skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_defer_ik ); - skeleton_apply_ik_pass( sk ); - skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_deffered_only ); - skeleton_apply_inverses( sk ); - skeleton_apply_transform( sk, transform ); + skeleton_apply_pose( sk, pose->keyframes, + k_anim_apply_defer_ik, final_mtx ); + skeleton_apply_ik_pass( sk, final_mtx ); + skeleton_apply_pose( sk, pose->keyframes, + k_anim_apply_deffered_only, final_mtx ); + skeleton_apply_inverses( sk, final_mtx ); + skeleton_apply_transform( sk, transform, final_mtx ); } else if( pose->type == k_player_pose_type_fk_2 ){ - skeleton_apply_pose( sk, pose->keyframes, k_anim_apply_always ); - skeleton_apply_inverses( sk ); - skeleton_apply_transform( sk, transform ); + skeleton_apply_pose( sk, pose->keyframes, + k_anim_apply_always, final_mtx ); + skeleton_apply_inverses( sk, final_mtx ); + skeleton_apply_transform( sk, transform, final_mtx ); } } @@ -181,8 +182,9 @@ static void player__animate(void){ localplayer.holdout_time -= vg.time_frame_delta * 2.0f; } - player_apply_pose_to_skeleton(); - skeleton_debug( sk ); + apply_full_skeleton_pose( &localplayer.playeravatar->sk, &localplayer.pose, + localplayer.final_mtx ); + skeleton_debug( sk, localplayer.final_mtx ); if( sys->post_animate ) sys->post_animate(); @@ -247,7 +249,8 @@ static void player__animate_from_replay( replay_buffer *replay ){ } else return; - player_apply_pose_to_skeleton(); + apply_full_skeleton_pose( &localplayer.playeravatar->sk, &localplayer.pose, + localplayer.final_mtx ); } static void player__pre_render(void){ @@ -267,8 +270,8 @@ static void player__pre_render(void){ } struct ub_world_lighting *ubo = &world_current_instance()->ub_lighting; - m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp0, ubo->g_board_0 ); - m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp1, ubo->g_board_1 ); + m4x3_mulv( localplayer.final_mtx[ av->id_board ], vp0, ubo->g_board_0 ); + m4x3_mulv( localplayer.final_mtx[ av->id_board ], vp1, ubo->g_board_1 ); } static void render_board( camera *cam, world_instance *world, @@ -405,7 +408,8 @@ static void render_board( camera *cam, world_instance *world, static void render_playermodel( camera *cam, world_instance *world, int depth_compare, struct player_model *model, - struct skeleton *skeleton ){ + struct skeleton *skeleton, + m4x3f *final_mtx ){ if( !model ) return; shader_model_character_view_use(); @@ -441,7 +445,7 @@ static void render_playermodel( camera *cam, world_instance *world, glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms, skeleton->bone_count, 0, - (float *)skeleton->final_mtx ); + (f32 *)final_mtx ); mesh_bind( &model->mdl.mesh ); mesh_draw( &model->mdl.mesh ); @@ -456,14 +460,15 @@ static void player__render( camera *cam ){ localplayer.playermodel_view_slot ); if( !model ) model = &localplayer.fallback_model; - render_playermodel( cam, world, 1, model, &localplayer.playeravatar->sk ); + render_playermodel( cam, world, 1, model, &localplayer.playeravatar->sk, + localplayer.final_mtx ); struct player_board *board = addon_cache_item_if_loaded( k_addon_type_board, localplayer.board_view_slot ); - render_board( cam, world, board, localplayer.playeravatar->sk.final_mtx[ - localplayer.playeravatar->id_board], + render_board( cam, world, board, localplayer.final_mtx[ + localplayer.playeravatar->id_board], &localplayer.pose.board, k_board_shader_player ); diff --git a/player_render.h b/player_render.h index be12d68..44f26e1 100644 --- a/player_render.h +++ b/player_render.h @@ -85,6 +85,7 @@ static void render_board( camera *cam, world_instance *world, static void render_playermodel( camera *cam, world_instance *world, int depth_compare, struct player_model *model, - struct skeleton *skeleton ); + struct skeleton *skeleton, + m4x3f *final_mtx ); #endif /* PLAYER_RENDER_H */ diff --git a/player_skate.c b/player_skate.c index 1ea632a..dbf927b 100644 --- a/player_skate.c +++ b/player_skate.c @@ -3115,7 +3115,8 @@ static void player__skate_post_animate(void){ localplayer.cam_velocity_influence = 1.0f; v3f head = { 0.0f, 1.8f, 0.0f }; - m4x3_mulv( av->sk.final_mtx[ av->id_head ], head, state->head_position ); + m4x3_mulv( localplayer.final_mtx[ av->id_head ], + head, state->head_position ); m4x3_mulv( localplayer.rb.to_local, state->head_position, state->head_position ); } diff --git a/player_walk.c b/player_walk.c index ad58c73..c43e7bf 100644 --- a/player_walk.c +++ b/player_walk.c @@ -282,7 +282,7 @@ static void player__walk_pre_update(void){ localplayer.immobile = 1; struct player_avatar *av = localplayer.playeravatar; - m4x3_mulv( av->sk.final_mtx[ av->id_ik_foot_r ], + m4x3_mulv( localplayer.final_mtx[ av->id_ik_foot_r ], av->sk.bones[ av->id_ik_foot_r ].co, w->state.drop_in_foot_anchor ); } diff --git a/skaterift.c b/skaterift.c index 7f384f6..ce45885 100644 --- a/skaterift.c +++ b/skaterift.c @@ -201,6 +201,12 @@ static void vg_load(void){ player_avatar_load( &localplayer_avatar, "models/ch_none.mdl" ); player__use_avatar( &localplayer_avatar ); + + /* FIXME FIXME FIXME FIXME FIXME */ + u32 mtx_size = sizeof(m4x3f)*localplayer_avatar.sk.bone_count; + localplayer.final_mtx = vg_linear_alloc( vg_mem.rtmemory, mtx_size ); + netplayers.final_mtx = vg_linear_alloc( vg_mem.rtmemory, mtx_size*32 ); + player_model_load( &localplayer.fallback_model, "models/ch_none.mdl" ); player__bind(); @@ -449,6 +455,37 @@ static void render_player_transparent(void){ player__render( &small_cam ); } +static void animate_remote_players(void){ + for( u32 i=0; iactive ) continue; + if( player->subsystem > k_player_subsystem_max ) continue; + + struct player_subsystem_interface *sys = + player_subsystems[player->subsystem]; + + struct player_avatar *av = localplayer.playeravatar; + + player_pose pose; + sys->pose( &player->animdata, &pose ); + apply_full_skeleton_pose( &av->sk, &pose, + &netplayers.final_mtx[ av->sk.bone_count*i ] ); + } +} + +static void render_remote_players( world_instance *world, camera *cam ){ + for( u32 i=0; iactive ) continue; + + struct player_avatar *av = localplayer.playeravatar; + + struct player_model *model = &localplayer.fallback_model; + render_playermodel( cam, world, 0, model, &av->sk, + &netplayers.final_mtx[ av->sk.bone_count*i ] ); + } +} + static void render_scene(void){ /* Draw world */ glEnable( GL_DEPTH_TEST ); @@ -481,6 +518,7 @@ static void render_scene(void){ render_water_texture( view_world, &skaterift.cam, 0 ); render_fb_bind( gpipeline.fb_main, 1 ); render_water_surface( view_world, &skaterift.cam ); + render_remote_players( view_world, &skaterift.cam ); } } diff --git a/skeleton.h b/skeleton.h index 6791d1c..a07a33a 100644 --- a/skeleton.h +++ b/skeleton.h @@ -38,7 +38,9 @@ struct skeleton *anims; u32 anim_count; +#if 0 m4x3f *final_mtx; +#endif struct skeleton_ik { @@ -202,13 +204,12 @@ int should_apply_bone( struct skeleton *skele, u32 id, anim_apply type ) * Apply block of keyframes to skeletons final pose */ static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose, - anim_apply passtype ) -{ + anim_apply passtype, m4x3f *final_mtx ){ if( passtype == k_anim_apply_absolute ){ for( u32 i=1; ibone_count; i++ ){ mdl_keyframe *kf = &pose[i-1]; - v3f *posemtx = skele->final_mtx[i]; + v3f *posemtx = final_mtx[i]; q_m3x3( kf->q, posemtx ); v3_copy( kf->co, posemtx[3] ); @@ -216,7 +217,7 @@ static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose, return; } - m4x3_identity( skele->final_mtx[0] ); + m4x3_identity( final_mtx[0] ); skele->bones[0].defer = 0; skele->bones[0].flags &= ~k_bone_flag_ik; @@ -242,7 +243,7 @@ static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose, v3_add( temp_delta, posemtx[3], posemtx[3] ); /* final matrix */ - m4x3_mul( skele->final_mtx[ sb->parent ], posemtx, skele->final_mtx[i] ); + m4x3_mul( final_mtx[ sb->parent ], posemtx, final_mtx[i] ); } } @@ -250,11 +251,12 @@ static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose, * Take the final matrices and decompose it into an absolute positioned anim */ static void skeleton_decompose_mtx_absolute( struct skeleton *skele, - mdl_keyframe *anim ){ + mdl_keyframe *anim, + m4x3f *final_mtx ){ for( u32 i=1; ibone_count; i++ ){ struct skeleton_bone *sb = &skele->bones[i]; mdl_keyframe *kf = &anim[i-1]; - m4x3_decompose( skele->final_mtx[i], kf->co, kf->q, kf->s ); + m4x3_decompose( final_mtx[i], kf->co, kf->q, kf->s ); } } @@ -298,11 +300,12 @@ static void skeleton_create_inverses( struct skeleton *skele ) * Apply a model matrix to all bones, should be done last */ static -void skeleton_apply_transform( struct skeleton *skele, m4x3f transform ) +void skeleton_apply_transform( struct skeleton *skele, m4x3f transform, + m4x3f *final_mtx ) { for( u32 i=0; ibone_count; i++ ){ struct skeleton_bone *sb = &skele->bones[i]; - m4x3_mul( transform, skele->final_mtx[i], skele->final_mtx[i] ); + m4x3_mul( transform, final_mtx[i], final_mtx[i] ); } } @@ -310,23 +313,21 @@ void skeleton_apply_transform( struct skeleton *skele, m4x3f transform ) * Apply an inverse matrix to all bones which maps vertices from bind space into * bone relative positions */ -static void skeleton_apply_inverses( struct skeleton *skele ) -{ +static void skeleton_apply_inverses( struct skeleton *skele, m4x3f *final_mtx ){ for( u32 i=0; ibone_count; i++ ){ struct skeleton_bone *sb = &skele->bones[i]; m4x3f inverse; m3x3_identity( inverse ); v3_negate( sb->co, inverse[3] ); - m4x3_mul( skele->final_mtx[i], inverse, skele->final_mtx[i] ); + m4x3_mul( final_mtx[i], inverse, final_mtx[i] ); } } /* * Apply all IK modifiers (2 bone ik reference from blender is supported) */ -static void skeleton_apply_ik_pass( struct skeleton *skele ) -{ +static void skeleton_apply_ik_pass( struct skeleton *skele, m4x3f *final_mtx ){ for( u32 i=0; iik_count; i++ ){ struct skeleton_ik *ik = &skele->ik[i]; @@ -338,9 +339,9 @@ static void skeleton_apply_ik_pass( struct skeleton *skele ) co_target, co_pole; - v3_copy( skele->final_mtx[ik->lower][3], co_base ); - v3_copy( skele->final_mtx[ik->target][3], co_target ); - v3_copy( skele->final_mtx[ik->pole][3], co_pole ); + v3_copy( final_mtx[ik->lower][3], co_base ); + v3_copy( final_mtx[ik->target][3], co_target ); + v3_copy( final_mtx[ik->pole][3], co_pole ); v3_sub( co_target, co_base, v0 ); v3_sub( co_pole, co_base, v1 ); @@ -368,8 +369,8 @@ static void skeleton_apply_ik_pass( struct skeleton *skele ) knee[0] = sinf(-rot) * l1; knee[1] = cosf(-rot) * l1; - m4x3_identity( skele->final_mtx[ik->lower] ); - m4x3_identity( skele->final_mtx[ik->upper] ); + m4x3_identity( final_mtx[ik->lower] ); + m4x3_identity( final_mtx[ik->upper] ); /* create rotation matrix */ v3f co_knee; @@ -386,7 +387,7 @@ static void skeleton_apply_ik_pass( struct skeleton *skele ) v3_copy( co_base, transform[3] ); m3x3_mul( transform, ik->ia, transform ); - m4x3_copy( transform, skele->final_mtx[ik->lower] ); + m4x3_copy( transform, final_mtx[ik->lower] ); /* upper/knee bone */ v3_copy( vaxis, transform[0] ); @@ -396,7 +397,7 @@ static void skeleton_apply_ik_pass( struct skeleton *skele ) v3_copy( co_knee, transform[3] ); m3x3_mul( transform, ik->ib, transform ); - m4x3_copy( transform, skele->final_mtx[ik->upper] ); + m4x3_copy( transform, final_mtx[ik->upper] ); } } @@ -405,21 +406,19 @@ static void skeleton_apply_ik_pass( struct skeleton *skele ) * Pose, IK, Pose(deferred), Inverses, Transform */ static void skeleton_apply_standard( struct skeleton *skele, mdl_keyframe *pose, - m4x3f transform ) -{ - skeleton_apply_pose( skele, pose, k_anim_apply_defer_ik ); - skeleton_apply_ik_pass( skele ); - skeleton_apply_pose( skele, pose, k_anim_apply_deffered_only ); - skeleton_apply_inverses( skele ); - skeleton_apply_transform( skele, transform ); + m4x3f transform, m4x3f *final_mtx ){ + skeleton_apply_pose( skele, pose, k_anim_apply_defer_ik, final_mtx ); + skeleton_apply_ik_pass( skele, final_mtx ); + skeleton_apply_pose( skele, pose, k_anim_apply_deffered_only, final_mtx ); + skeleton_apply_inverses( skele, final_mtx ); + skeleton_apply_transform( skele, transform, final_mtx ); } /* * Get an animation by name */ static struct skeleton_anim *skeleton_get_anim( struct skeleton *skele, - const char *name ) -{ + const char *name ){ for( u32 i=0; ianim_count; i++ ){ struct skeleton_anim *anim = &skele->anims[i]; @@ -436,8 +435,7 @@ static struct skeleton_anim *skeleton_get_anim( struct skeleton *skele, static void skeleton_alloc_from( struct skeleton *skele, void *lin_alloc, mdl_context *mdl, - mdl_armature *armature ) -{ + mdl_armature *armature ){ skele->bone_count = armature->bone_count+1; skele->anim_count = armature->anim_count; skele->ik_count = 0; @@ -460,28 +458,26 @@ static void skeleton_alloc_from( struct skeleton *skele, skele->bones = vg_linear_alloc( lin_alloc, bone_size ); skele->ik = vg_linear_alloc( lin_alloc, ik_size ); - skele->final_mtx = vg_linear_alloc( lin_alloc, mtx_size ); + //skele->final_mtx = vg_linear_alloc( lin_alloc, mtx_size ); skele->anims = vg_linear_alloc( lin_alloc, anim_size ); memset( skele->bones, 0, bone_size ); memset( skele->ik, 0, ik_size ); - memset( skele->final_mtx, 0, mtx_size ); + //memset( skele->final_mtx, 0, mtx_size ); memset( skele->anims, 0, anim_size ); } -static void skeleton_fatal_err(void) -{ +static void skeleton_fatal_err(void){ vg_fatal_error( "Skeleton setup failed" ); } /* Setup an animated skeleton from model. mdl's metadata should stick around */ static void skeleton_setup( struct skeleton *skele, - void *lin_alloc, mdl_context *mdl ) -{ + void *lin_alloc, mdl_context *mdl ){ u32 ik_count = 0, collider_count = 0; skele->bone_count = 0; skele->bones = NULL; - skele->final_mtx = NULL; + //skele->final_mtx = NULL; skele->anims = NULL; if( !mdl->armatures.count ){ @@ -560,8 +556,7 @@ static void skeleton_setup( struct skeleton *skele, vg_success( " %u colliders\n", skele->collider_count ); } -static void skeleton_debug( struct skeleton *skele ) -{ +static void skeleton_debug( struct skeleton *skele, m4x3f *final_mtx ){ for( u32 i=1; ibone_count; i ++ ){ struct skeleton_bone *sb = &skele->bones[i]; @@ -569,8 +564,8 @@ static void skeleton_debug( struct skeleton *skele ) v3_copy( sb->co, p0 ); v3_add( p0, sb->end, p1 ); - m4x3_mulv( skele->final_mtx[i], p0, p0 ); - m4x3_mulv( skele->final_mtx[i], p1, p1 ); + m4x3_mulv( final_mtx[i], p0, p0 ); + m4x3_mulv( final_mtx[i], p1, p1 ); if( sb->flags & k_bone_flag_deform ){ if( sb->flags & k_bone_flag_ik ){ diff --git a/workshop.c b/workshop.c index ffe776c..6cb6b6f 100644 --- a/workshop.c +++ b/workshop.c @@ -894,11 +894,13 @@ static void workshop_render_player_preview(void){ v3_copy( res.root_co, transform[3] ); /* TODO: Function. */ - skeleton_apply_pose( sk, res.keyframes, k_anim_apply_defer_ik ); - skeleton_apply_ik_pass( sk ); - skeleton_apply_pose( sk, res.keyframes, k_anim_apply_deffered_only ); - skeleton_apply_inverses( sk ); - skeleton_apply_transform( sk, transform ); + skeleton_apply_pose( sk, res.keyframes, k_anim_apply_defer_ik, + localplayer.final_mtx ); + skeleton_apply_ik_pass( sk, localplayer.final_mtx ); + skeleton_apply_pose( sk, res.keyframes, k_anim_apply_deffered_only, + localplayer.final_mtx ); + skeleton_apply_inverses( sk, localplayer.final_mtx ); + skeleton_apply_transform( sk, transform, localplayer.final_mtx ); camera cam; v3_copy( (v3f){ 0.0f, 201.7f, 1.2f }, cam.pos ); @@ -914,7 +916,8 @@ static void workshop_render_player_preview(void){ camera_finalize( &cam ); world_instance *world = localplayer.viewable_world; - render_playermodel( &cam, world, 0, &workshop_form.player_model, sk ); + render_playermodel( &cam, world, 0, &workshop_form.player_model, sk, + localplayer.final_mtx ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glViewport( 0,0, vg.window_x, vg.window_y ); -- 2.25.1