https://blog.codingnow.com/2017/11/quaternion_compress.html
https://bitbucket.org/Nabril/unitynetworking/commits/702a387656c6ee54311345a1c29f286767b59a22?at=5.4
public void Write(Quaternion value)
{
//nafio info index,用来标识绝对值最大的那个分量的index
int largest = 0;
float a, b, c;
float abs_w = Mathf.Abs(value.w);
float abs_x = Mathf.Abs(value.x);
float abs_y = Mathf.Abs(value.y);
float abs_z = Mathf.Abs(value.z);
float largest_value = abs_x;
if (abs_y > largest_value)
{
largest = 1;
largest_value = abs_y;
}
if (abs_z > largest_value)
{
largest = 2;
largest_value = abs_z;
}
if (abs_w > largest_value)
{
largest = 3;
largest_value = abs_w;
}
//nafio info 最终要将4个分量存到uint中,这里应该决定了哪个分量存哪个位置
//假设largest=3
//a = value[4%4] = value[0] = x
//b = value[5%4] = value[1] = y
//c = value[6%4] = value[2] = z
//假设largest=2
//a = value[3%4] = value[3] = w
//b = value[4%4] = value[0] = x
//c = value[5%4] = value[1] = y
if (value[largest] >= 0f)
{
a = value[(largest + 1) % 4];
b = value[(largest + 2) % 4];
c = value[(largest + 3) % 4];
}
else
{
a = -value[(largest + 1) % 4];
b = -value[(largest + 2) % 4];
c = -value[(largest + 3) % 4];
}
//nafio 这里 1/根号2 有什么玄机还不清楚
//这里实际是个精度,但为什么精度是这个需要考虑
// serialize
const float minimum = -1.0f / 1.414214f; // note: 1.0f / sqrt(2)
const float maximum = +1.0f / 1.414214f;
const float delta = maximum - minimum;
const uint maxIntegerValue = (1 << 10) - 1; // 10 bits
const float maxIntegerValueF = (float)maxIntegerValue;
float normalizedValue;
uint integerValue;
uint sentData = ((uint)largest) << 30;
// a
normalizedValue = Mathf.Clamp01((a - minimum) / delta);
integerValue = (uint)Mathf.Floor(normalizedValue * maxIntegerValueF + 0.5f);
sentData = sentData | ((integerValue & maxIntegerValue) << 20);
// b
normalizedValue = Mathf.Clamp01((b - minimum) / delta);
integerValue = (uint)Mathf.Floor(normalizedValue * maxIntegerValueF + 0.5f);
sentData = sentData | ((integerValue & maxIntegerValue) << 10);
// c
normalizedValue = Mathf.Clamp01((c - minimum) / delta);
integerValue = (uint)Mathf.Floor(normalizedValue * maxIntegerValueF + 0.5f);
sentData = sentData | (integerValue & maxIntegerValue);
Write(sentData);
}
原文:https://www.cnblogs.com/nafio/p/13296136.html