四元数压缩

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);
        }

  

posted @ 2020-07-13 21:57  00000000O  阅读(311)  评论(0编辑  收藏  举报