X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=network_compression.h;fp=network_compression.h;h=6ef08f93f69cb7c9de0bc3b9825a0472a4b5ff50;hb=5388f705086600105358d9880e8895673ac0e247;hp=0000000000000000000000000000000000000000;hpb=88f8273a9ab7b0644813625c43c70c5af34cd4f5;p=carveJwlIkooP6JGAAIwe30JlM.git 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 */