Пример #1
0
        private static int EncodeEntry(int index, AnimDataFormat format, KeyframeCollection kf, VoidPtr addr)
        {
            int           numFrames = kf.FrameLimit;
            KeyframeEntry frame, root = kf._keyArrays[index]._keyRoot;
            bfloat *      pVal = (bfloat *)addr;
            float         val, frameScale = numFrames <= 1 ? 1 : 1.0f / (numFrames - 1);
            float         min, max, stride, step;
            int           span, i;
            int           keyCount = kf._keyArrays[index]._keyCount;

            if (format == AnimDataFormat.L4)
            {
                //Use all frames, just in case not all frames are key.
                for (i = 0; i < numFrames; i++)
                {
                    *pVal++ = kf[i, index];
                }

                return(numFrames * 4);
            }

            if (format == AnimDataFormat.I12)
            {
                I12Header *header = (I12Header *)addr;
                *          header = new I12Header(keyCount, frameScale);

                I12Entry *entry = header->Data;
                for (frame = root._next; frame._index != -1; frame = frame._next)
                {
                    *entry++ = new I12Entry(frame._index, frame._value, frame._tangent);
                }

                return(keyCount * 12 + 8);
            }

            //Get floor/ceil/stride
            min = float.MaxValue;
            max = float.MinValue;
            for (frame = root._next; frame != root; frame = frame._next)
            {
                val = frame._value;

                if (val > max)
                {
                    max = val;
                }

                if (val < min)
                {
                    min = val;
                }
            }

            stride = max - min;

            if (format == AnimDataFormat.L1)
            {
                //Find best span
                span = EvalSpan(255, 32, min, stride, root, true);
                step = stride / span;

                L1Header *header = (L1Header *)addr;
                *         header = new L1Header(step, min);

                byte *dPtr = header->Data;
                for (i = 0; i < numFrames; i++)
                {
                    *dPtr++ = (byte)((kf[i, index] - min) / step + 0.5f);
                }

                //Fill remaining bytes
                while ((i++ & 3) != 0)
                {
                    *dPtr++ = 0;
                }

                return((8 + numFrames).Align(4));
            }

            if (format == AnimDataFormat.I4)
            {
                //Find best span
                span = EvalSpan(4095, 32, min, stride, root, false);
                step = stride / span;

                I4Header *header = (I4Header *)addr;
                *         header = new I4Header(keyCount, frameScale, step, min);

                I4Entry *entry = header->Data;

                for (frame = root._next; frame._index != -1; frame = frame._next)
                {
                    val  = (frame._value - min) / step;
                    val += val < 0 ? -0.5f : 0.5f;

                    *entry++ = new I4Entry(frame._index, (int)val, frame._tangent);
                }

                return(keyCount * 4 + 16);
            }

            if (format == AnimDataFormat.I6)
            {
                //Find best span
                span = EvalSpan(65535, 32, min, stride, root, false);
                step = stride / span;

                I6Header *header = (I6Header *)addr;
                *         header = new I6Header(keyCount, frameScale, step, min);

                I6Entry *entry = header->Data;

                for (frame = root._next; frame._index != -1; frame = frame._next)
                {
                    val  = (frame._value - min) / step;
                    val += val < 0 ? -0.5f : 0.5f;

                    *entry++ = new I6Entry(frame._index, (int)val, frame._tangent);
                }

                //Fill remaining bytes
                if ((keyCount & 1) != 0)
                {
                    entry->_data = 0;
                }

                return((keyCount * 6 + 16).Align(4));
            }

            return(0);
        }
        private static int EncodeEntry(int index, AnimDataFormat format, KeyframeCollection kf, VoidPtr addr)
        {
            int numFrames = kf._frameCount;
            KeyframeEntry frame, root = kf._keyRoots[index];
            bfloat* pVal = (bfloat*)addr;
            float val, frameScale = numFrames <= 1 ? 1 : 1.0f / (numFrames - 1);
            float min, max, stride, step;
            int span, i;
            int keyCount = kf._keyCounts[index];
            KeyFrameMode mode = KeyFrameMode.ScaleX + index;

            if (format == AnimDataFormat.L4)
            {
                //Use all frames, just in case not all frames are key.
                for (i = 0; i < numFrames; i++)
                    *pVal++ = kf[mode, i];
                return numFrames * 4;
            }

            if (format == AnimDataFormat.I12)
            {
                I12Header* header = (I12Header*)addr;
                *header = new I12Header(keyCount, frameScale);

                I12Entry* entry = header->Data;
                for (frame = root._next; frame._index != -1; frame = frame._next)
                    *entry++ = new I12Entry(frame._index, frame._value, frame._tangent);

                return keyCount * 12 + 8;
            }

            //Get floor/ceil/stride
            min = float.MaxValue; max = float.MinValue;
            for (frame = root._next; frame != root; frame = frame._next)
            {
                val = frame._value;

                if (val > max) max = val;
                if (val < min) min = val;
            }
            stride = max - min;

            if (format == AnimDataFormat.L1)
            {
                //Find best span
                span = EvalSpan(255, 32, min, stride, root, true, kf._linearRot);
                step = stride / span;

                L1Header* header = (L1Header*)addr;
                *header = new L1Header(step, min);

                byte* dPtr = header->Data;
                for (i = 0; i < numFrames; i++)
                    *dPtr++ = (byte)((kf[mode, i] - min) / step + 0.5f);

                //Fill remaining bytes
                while ((i++ & 3) != 0)
                    *dPtr++ = 0;

                return (8 + numFrames).Align(4);
            }

            if (format == AnimDataFormat.I4)
            {
                //Find best span
                span = EvalSpan(4095, 32, min, stride, root, false, false);
                step = stride / span;

                I4Header* header = (I4Header*)addr;
                *header = new I4Header(keyCount, frameScale, step, min);

                I4Entry* entry = header->Data;

                for (frame = root._next; frame._index != -1; frame = frame._next)
                {
                    val = (frame._value - min) / step;
                    val += (val < 0 ? -0.5f : 0.5f);

                    *entry++ = new I4Entry(frame._index, (int)val, frame._tangent);
                }

                return keyCount * 4 + 16;
            }

            if (format == AnimDataFormat.I6)
            {
                //Find best span
                span = EvalSpan(65535, 32, min, stride, root, false, false);
                step = stride / span;

                I6Header* header = (I6Header*)addr;
                *header = new I6Header(keyCount, frameScale, step, min);

                I6Entry* entry = header->Data;

                for (frame = root._next; frame._index != -1; frame = frame._next)
                {
                    val = ((frame._value - min) / step);
                    val += (val < 0 ? -0.5f : 0.5f);

                    *entry++ = new I6Entry(frame._index, (int)val, frame._tangent);
                }

                //Fill remaining bytes
                if ((keyCount & 1) != 0)
                    entry->_data = 0;

                return ((keyCount * 6) + 16).Align(4);
            }

            return 0;
        }