From 5388f705086600105358d9880e8895673ac0e247 Mon Sep 17 00:00:00 2001 From: hgn Date: Tue, 3 Oct 2023 19:17:15 +0100 Subject: [PATCH] network compression test --- network_compression.h | 115 ++++++++++++++++++++++++++++++++++++++++++ player.h | 2 + player_remote.c | 35 ++++++++++++- player_skate.c | 49 ++++++++++++++++++ player_skate.h | 2 + 5 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 network_compression.h diff --git a/network_compression.h b/network_compression.h new file mode 100644 index 0000000..6ef08f9 --- /dev/null +++ b/network_compression.h @@ -0,0 +1,115 @@ +#ifndef NETWORK_COMPRESSION_H +#define NETWORK_COMPRESSION_H + +#include "vg/vg_stdint.h" +#include "vg/vg_m.h" + +typedef struct bitpack_ctx bitpack_ctx; +struct bitpack_ctx { + enum bitpack_mode { + k_bitpack_compress, + k_bitpack_decompress + } + mode; + + u8 *buffer; + u32 bytes, buffer_len; +}; + +static void bitpack_bytes( bitpack_ctx *ctx, u32 bytes, void *data ){ + u8 *ext = data; + for( u32 i=0; ibytes+i; + if( ctx->mode == k_bitpack_compress ){ + if( index < ctx->buffer_len ) + ctx->buffer[index] = ext[i]; + } + else{ + if( index < ctx->buffer_len ) + ext[i] = ctx->buffer[index]; + else + ext[i] = 0x00; + } + } + ctx->bytes += bytes; +} + +static void bitpack_qf32( bitpack_ctx *ctx, u32 bits, + f32 min, f32 max, f32 *v ){ + u32 mask = (0x1 << bits) - 1; + + if( ctx->mode == k_bitpack_compress ){ + u32 a = vg_quantf( *v, bits, min, max ); + bitpack_bytes( ctx, bits/8, &a ); + } + else { + u32 a = 0; + bitpack_bytes( ctx, bits/8, &a ); + *v = vg_dequantf( a, bits, min, max ); + } +} + +static void bitpack_qv2f( bitpack_ctx *ctx, u32 bits, + f32 min, f32 max, v2f v ){ + for( u32 i=0; i<2; i ++ ) + bitpack_qf32( ctx, bits, min, max, v+i ); +} + +static void bitpack_qv3f( bitpack_ctx *ctx, u32 bits, + f32 min, f32 max, v3f v ){ + for( u32 i=0; i<3; i ++ ) + bitpack_qf32( ctx, bits, min, max, v+i ); +} + +static void bitpack_qv4f( bitpack_ctx *ctx, u32 bits, + f32 min, f32 max, v4f v ){ + for( u32 i=0; i<4; i ++ ) + bitpack_qf32( ctx, bits, min, max, v+i ); +} + +static void bitpack_qquat( bitpack_ctx *ctx, v4f quat ){ + const f32 k_domain = 0.70710678118f; + + if( ctx->mode == k_bitpack_compress ){ + v4f qabs; + for( u32 i=0; i<4; i++ ) + qabs[i] = fabsf(quat[i]); + + u32 lxy = qabs[1]>qabs[0], + lzw = (qabs[3]>qabs[2])+2, + l = qabs[lzw]>qabs[lxy]? lzw: lxy; + + f32 sign = vg_signf(quat[l]); + + u32 smallest[3]; + for( u32 i=0, j=0; i<4; i ++ ) + if( i != l ) + smallest[j ++] = vg_quantf( quat[i]*sign, 10, -k_domain, k_domain ); + + u32 comp = (smallest[0]<<2) | (smallest[1]<<12) | (smallest[2]<<22) | l; + bitpack_bytes( ctx, 4, &comp ); + } + else { + u32 comp; + bitpack_bytes( ctx, 4, &comp ); + + u32 smallest[3] = {(comp>>2 )&0x3ff, + (comp>>12)&0x3ff, + (comp>>22)&0x3ff}, + l = comp & 0x3; + + f32 m = 1.0f; + + for( u32 i=0, j=0; i<4; i ++ ){ + if( i != l ){ + quat[i] = vg_dequantf( smallest[j ++], 10, -k_domain, k_domain ); + m -= quat[i]*quat[i]; + } + } + + quat[l] = sqrtf(m); + q_normalize( quat ); + } +} + +#endif /* NETWORK_COMPRESSION_H */ diff --git a/player.h b/player.h index 63e3028..bb87028 100644 --- a/player.h +++ b/player.h @@ -3,6 +3,7 @@ #include "skaterift.h" #include "player_common.h" +#include "network_compression.h" enum player_subsystem{ k_player_subsystem_walk = 0, @@ -43,6 +44,7 @@ struct player_subsystem_interface{ void(*animate)(void); void(*pose)( void *animator, player_pose *pose ); void(*post_animate)(void); + void(*network_animator_exchange)( bitpack_ctx *ctx, void *data ); void *animator_data; u32 animator_size; diff --git a/player_remote.c b/player_remote.c index 73ed42c..cfad5e9 100644 --- a/player_remote.c +++ b/player_remote.c @@ -157,7 +157,25 @@ static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){ dest->boundary_hash = frame->boundary_hash; struct network_player *player = &netplayers.list[ frame->client ]; - memcpy( &dest->data, frame->animdata, datasize ); + + struct player_subsystem_interface *sys = + player_subsystems[ frame->subsystem ]; + + if( sys->network_animator_exchange ){ + bitpack_ctx ctx = { + .mode = k_bitpack_decompress, + .buffer = frame->animdata, + .buffer_len = datasize, + .bytes = 0, + }; + + memset( &dest->data, 0, sys->animator_size ); + sys->network_animator_exchange( &ctx, &dest->data ); + } + else { + memcpy( &dest->data, frame->animdata, datasize ); + } + player->subsystem = frame->subsystem; player->down_bytes += msg->m_cbSize; } @@ -227,7 +245,20 @@ static void remote_player_send_playerframe(void){ frame->boundary_hash = localplayer.boundary_hash; frame->instance_id = world_static.active_instance; - memcpy( frame->animdata, sys->animator_data, sys->animator_size ); + if( sys->network_animator_exchange ){ + bitpack_ctx ctx = { + .mode = k_bitpack_compress, + .buffer = frame->animdata, + .buffer_len = size, + .bytes = 0, + }; + + sys->network_animator_exchange( &ctx, sys->animator_data ); + size = ctx.bytes; + } + else{ + memcpy( frame->animdata, sys->animator_data, sys->animator_size ); + } netplayers.up_bytes += size; diff --git a/player_skate.c b/player_skate.c index f8b4166..7acc9f5 100644 --- a/player_skate.c +++ b/player_skate.c @@ -3185,4 +3185,53 @@ static void player__skate_reset( ent_spawn *rp ){ state->head_position[1] = 1.8f; } +#include "network_compression.h" + +static void player__skate_animator_exchange( bitpack_ctx *ctx, void *data ){ + struct player_skate_animator *animator = data; + + bitpack_bytes( ctx, sizeof(animator->root_co), animator->root_co ); + bitpack_qquat( ctx, animator->root_q ); + bitpack_qv3f( ctx, 8, -1.0f, 1.0f, animator->offset ); + bitpack_qv3f( ctx, 8, -1.0f, 1.0f, animator->local_cog ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->slide ); + bitpack_qf32( ctx, 8, -1.0f, 1.0f, &animator->z ); + bitpack_qf32( ctx, 8, -1.0f, 1.0f, &animator->x ); + + /* these could likely be pressed down into single bits if needed */ + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->fly ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->grind ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->stand ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->push ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->jump ); /*??*/ + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->jump_charge ); /*??*/ + + /* just the sign bit? */ + bitpack_qf32( ctx, 8, -1.0f, 1.0f, &animator->reverse ); + bitpack_qf32( ctx, 8, -1.0f, 1.0f, &animator->delayed_slip_dir ); + bitpack_bytes( ctx, 1, &animator->jump_dir ); + bitpack_bytes( ctx, 1, &animator->trick_type ); + + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->grind_balance ); + bitpack_qf32( ctx, 8, -1.0f, 1.0f, &animator->airdir ); + bitpack_qf32( ctx, 8, -1.0f, 1.0f, &animator->weight ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->trick_foot ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->slap ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->subslap ); + bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->grabbing ); + + /* animator->wobble is ommited */ + + bitpack_qv2f( ctx, 8, -1.0f, 1.0f, animator->foot_offset ); + bitpack_qquat( ctx, animator->qfixuptotal ); + bitpack_qquat( ctx, animator->qflip ); + + bitpack_qv3f( ctx, 16, -100.0f, 100.0f, animator->board_euler ); + bitpack_qf32( ctx, 8, -1.0f, 1.0f, &animator->board_lean ); + bitpack_qv2f( ctx, 8, -1.0f, 1.0f, animator->steer ); + bitpack_qv2f( ctx, 8, -1.0f, 1.0f, animator->grab ); + + bitpack_qf32( ctx, 16, 0.0f, 120.0f, &animator->push_time ); +} + #endif /* PLAYER_SKATE_C */ diff --git a/player_skate.h b/player_skate.h index 68f2dcb..e5cc42f 100644 --- a/player_skate.h +++ b/player_skate.h @@ -287,6 +287,7 @@ static void player__skate_animate (void); static void player__skate_pose (void *animator, player_pose *pose); static void player__skate_post_animate (void); static void player__skate_reset (ent_spawn *rp); +static void player__skate_animator_exchange( bitpack_ctx *ctx, void *data ); static void player__skate_clear_mechanics(void); static void player__skate_reset_animator(void); @@ -303,6 +304,7 @@ struct player_subsystem_interface static player_subsystem_skate = { .animate = player__skate_animate, .pose = player__skate_pose, .post_animate = player__skate_post_animate, + .network_animator_exchange = player__skate_animator_exchange, .animator_data = &player_skate.animator, .animator_size = sizeof(player_skate.animator), -- 2.25.1