UE4 数据压缩方法(三)

导语
之前我们压缩了整数(压缩方法一),Angle角度浮点数(压缩方法二),那么用来同步位置的FVector是否也可以压缩呢?
整数压缩部分是用编码解压实现的,属于无损压缩,Angle角度浮点数是用一个小范围的数据集来表示一个大范围的数据集,属于有损压缩。那么我们可能会问,如果同步的数据不一致,对于不同客户端的计算或者显示结果是否会有影响呢?比如一个游戏中,一个玩家在不同的客户端上的位置和方向存在较大的差异,那肯定是不行的。

实现思路

本次我的思路是对于特定情况下的一些数据压缩提供一种思路。比如我们的一个多人在线应用,用户的活动范围被限制在一定的范围内,也就是玩家的位置坐标的最大值能用更短的整数来存储。那么我们就有压缩的空间了。

上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 用短整形表示的坐标
struct FShortLoc
{
int16 X;
int16 Y;
int16 Z;
};

// 压缩位置信息 -3275 -> +3275
static FORCEINLINE FShortLoc LocDataCom(FVector Loc)
{
FShortLoc a;
a.X = CompFloatTo16Bit_(Loc.X);
a.Y = CompFloatTo16Bit_(Loc.Y);
a.Z = CompFloatTo16Bit_(Loc.Z);
return a;
};

// 解压缩位置信息 -3275 -> +3275
static FORCEINLINE FVector LocDataDec(FShortLoc source)
{
FVector a;
a.X = DecomFloatTo16Bit_(source.X);
a.Y = DecomFloatTo16Bit_(source.Y);
a.Z = DecomFloatTo16Bit_(source.Z);
return a;
};

static FORCEINLINE int16 CompFloatTo16Bit_(float value)
{
// -3276.7 -> +3276.7
int16 a = value * 10;
return a;
}

static FORCEINLINE float DecomFloatTo16Bit_(int16 value)
{
// -3276.7 -> +3276.7
return (value / 10.f);
}

总结

以上代码我们把坐标的范围控制在了 -3275.0 -> +3275.0 ,并且保留了一位小数点。对于位置精度不高,玩家获得范围不超过半径为32.75米的圆形区域(约3,367.8㎡)内的情况下,这种数据压缩节约了1/2的带宽。

------------- 感谢您的阅读-------------
作者dreamingpoet
有问题请发邮箱 Dreamingoet@126.com
您的鼓励将成为创作者的动力