Пример #1
0
        public static KeyframeCollection DecodeKeyframes(VoidPtr entry, NW4RAnimationNode node, int arrayCount,
                                                         params float[] defaults)
        {
            //If the node is null, assume the programmer has created a new entry and accessed
            //the keyframe collection for the first time before assigning the parent and will
            //set the frame count later manually.
            int numFrames = node == null ? 1 : node.FrameCount + (node.Loop ? 1 : 0);

            KeyframeCollection kf;

            if (node is CHR0Node && entry)
            {
                kf = DecodeCHR0Keyframes((CHR0Entry *)entry, numFrames);
            }
            else if (node is SRT0Node && entry)
            {
                kf = DecodeSRT0Keyframes((SRT0TextureEntry *)entry, numFrames);
            }
            else
            {
                kf = new KeyframeCollection(arrayCount, numFrames, defaults);
            }

            kf.Loop = node.Loop;

            return(kf);
        }
Пример #2
0
        public static int CalculateCHR0Size(KeyframeCollection kf, out int entrySize, out AnimationCode code)
        {
            int dataSize = 0;

            entrySize = 8;

            code = AnimationCode.Default;

            for (int i = 0; i < 3; i++)
            {
                dataSize += EvaluateCHR0Group(ref code, kf, i, ref entrySize);
            }

            if (!code.HasRotation && !code.HasTranslation)
            {
                code.IgnoreRotAndTrans = true;
                code.Identity          = !code.HasScale;
            }
            else
            {
                code.IgnoreRotAndTrans = false;
                code.Identity          = false;
            }

            return(dataSize);
        }
Пример #3
0
        public static void EncodeSRT0Keyframes(KeyframeCollection kf, VoidPtr entryAddress, VoidPtr dataAddress, SRT0Code code)
        {
            SRT0TextureEntry *header = (SRT0TextureEntry *)entryAddress;

            header->Code = code;

            bint *pOffset = (bint *)entryAddress + 1;

            int index = 0;

            //Write values/offset and encode groups
            for (int type = 0; type < 3; type++)
            {
                bool has = false;
                switch (type)
                {
                case 0: has = !code.NoScale; break;

                case 1: has = !code.NoRotation; break;

                case 2: has = !code.NoTranslation; break;
                }
                for (int axis = 0; axis < (type == 1 ? 1 : 2); axis++, index++)
                {
                    if (has)
                    {
                        if (code.ScaleIsotropic && type == 0)
                        {
                            if (axis == 0)
                            {
                                if (code.FixedScaleX)
                                {
                                    *(bfloat *)pOffset++ = kf._keyArrays[0]._keyRoot._next._value;
                                }
                                else
                                {
                                    *pOffset = (int)dataAddress - (int)pOffset; pOffset++;
                                    dataAddress += EncodeEntry(index, AnimDataFormat.I12, kf, dataAddress);
                                }
                            }
                        }
                        else
                        {
                            //This gets the fixed bit. Same order, so it can be indexed
                            if (code._data[5 + index])
                            {
                                *(bfloat *)pOffset++ = kf._keyArrays[index]._keyRoot._next._value;
                            }
                            else
                            {
                                *pOffset = (int)dataAddress - (int)pOffset; pOffset++;
                                dataAddress += EncodeEntry(index, AnimDataFormat.I12, kf, dataAddress);
                            }
                        }
                    }
                }
            }
        }
        public static int CalculateSRT0Size(KeyframeCollection kf, out int entrySize)
        {
            int dataSize = 0;
            entrySize = 4;

            kf._texEvalCode = SRT0Code.Default;

            for (int i = 0; i < 3; i++)
                dataSize += EvaluateSRT0Group(ref kf._texEvalCode, kf, i, ref entrySize);

            return dataSize;
        }
Пример #5
0
        public static void Serialize(CHR0Node node, bool bake, string output)
        {
            using (StreamWriter file = new StreamWriter(output))
            {
                file.WriteLine("animVersion 1.1;");
                file.WriteLine("mayaVersion 2014 x64;");
                file.WriteLine("timeUnit ntsc;");
                file.WriteLine("linearUnit cm;");
                file.WriteLine("angularUnit deg;");
                file.WriteLine("startTime 1;");
                file.WriteLine(String.Format("endTime {0};", node.FrameCount));
                foreach (CHR0EntryNode e in node.Children)
                {
                    KeyframeCollection c = e.Keyframes;
                    for (int index = 0; index < 9; index++)
                    {
                        KeyFrameMode m = (KeyFrameMode)(index + 0x10);

                        if (c[m] <= 0)
                        {
                            continue;
                        }

                        file.WriteLine(String.Format("anim {0}.{0}{1} {0}{1} {2} {3} {4} {5}", types[index / 3], axes[index % 3], e.Name, e.Index, index / 3, index % 3));
                        file.WriteLine("animData {");
                        file.WriteLine(" input time;");
                        file.WriteLine(String.Format(" output {0};", index > 2 && index < 6 ? "angular" : "linear"));
                        file.WriteLine(" weighted 1;");
                        file.WriteLine(" preInfinity constant;");
                        file.WriteLine(" postInfinity constant;");
                        file.WriteLine(" keys {");
                        for (KeyframeEntry entry = c._keyRoots[index]._next; (entry != c._keyRoots[index]); entry = entry._next)
                        {
                            float angle = (float)Math.Atan(entry._tangent) * Maths._rad2degf;
                            file.WriteLine(String.Format(" {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10};",
                                                         entry._index + 1,
                                                         entry._value.ToString(CultureInfo.InvariantCulture.NumberFormat),
                                                         "fixed",
                                                         "fixed",
                                                         "1",
                                                         "1",
                                                         "0",
                                                         angle.ToString(CultureInfo.InvariantCulture.NumberFormat),
                                                         (Math.Abs(entry._tangent) + 1).ToString(CultureInfo.InvariantCulture.NumberFormat),
                                                         angle.ToString(CultureInfo.InvariantCulture.NumberFormat),
                                                         (Math.Abs(entry._tangent) + 1).ToString(CultureInfo.InvariantCulture.NumberFormat)));
                        }
                        file.WriteLine(" }");
                        file.WriteLine("}");
                    }
                }
            }
        }
Пример #6
0
        public static void EncodeCHR0Keyframes(KeyframeCollection kf, VoidPtr entryAddress, VoidPtr dataAddress)
        {
            AnimationCode code = kf._evalCode;
            //VoidPtr dataAddr = addr + 8;

            CHR0Entry *header = (CHR0Entry *)entryAddress;

            header->_code         = (uint)code._data;
            header->_stringOffset = 0;

            //entryAddress += 8;
            bint *pOffset = (bint *)entryAddress + 2;

            //Write values/offset and encode groups
            for (int i = 0, x = 0; i < 3; i++, x += 3)
            {
                if (code.GetExists(i))
                {
                    AnimDataFormat format = code.GetFormat(i);
                    if ((i == 0) && (code.GetIsIsotropic(i)))
                    {
                        if (code.GetIsFixed(2))
                        {
                            *(bfloat *)pOffset++ = kf._keyRoots[2]._next._value;
                        }
                        else
                        {
                            *pOffset++ = (int)(dataAddress - entryAddress);
                            dataAddress += EncodeEntry(x, format, kf, dataAddress);
                        }
                    }
                    else
                    {
                        for (int y = 0, z = x; y < 3; y++, z++)
                        {
                            if (code.GetIsFixed(z))
                            {
                                *(bfloat *)pOffset++ = kf._keyRoots[z]._next._value;
                            }
                            else
                            {
                                *pOffset++ = (int)(dataAddress - entryAddress);
                                dataAddress += EncodeEntry(z, format, kf, dataAddress);
                            }
                        }
                    }
                }
            }
        }
Пример #7
0
        public static int CalculateSRT0Size(KeyframeCollection kf, out int entrySize, out SRT0Code code)
        {
            int dataSize = 0;

            entrySize = 4;

            code = SRT0Code.Default;

            for (int i = 0; i < 3; i++)
            {
                dataSize += EvaluateSRT0Group(ref code, kf, i, ref entrySize);
            }

            return(dataSize);
        }
Пример #8
0
        private static void DecodeSRT0Frames(KeyframeCollection kf, void *dataAddr, KeyFrameMode mode)
        {
            int fCount;

            I12Header *header = (I12Header *)dataAddr;

            fCount = header->_numFrames;

            I12Entry *entry = header->Data;

            for (int i = 0; i < fCount; i++, entry++)
            {
                kf.SetFrameValue(mode, (int)entry->_index, entry->_value)._tangent = entry->_tangent;
            }
        }
Пример #9
0
        public static int CalculateSRT0Size(KeyframeCollection kf, out int entrySize)
        {
            int dataSize = 0;

            entrySize = 4;

#if DEBUG
            //kf.Clean();
#endif
            kf._texEvalCode = SRT0Code.Default;

            for (int i = 0; i < 3; i++)
            {
                dataSize += EvaluateSRT0Group(ref kf._texEvalCode, kf, i, ref entrySize);
            }

            return(dataSize);
        }
        public static int CalculateSize(KeyframeCollection kf, out int entrySize)
        {
            int dataSize = 0;

            entrySize = 8;
            //int count = kf.FrameLimit;

#if DEBUG
            //kf.Clean();
#endif
            kf._evalCode = AnimationCode.Default;

            for (int i = 0; i < 3; i++)
            {
                dataSize += EvaluateGroup(ref kf._evalCode, kf, i, ref entrySize);
            }

            return(dataSize);
        }
        public static int CalculateCHR0Size(KeyframeCollection kf, out int entrySize)
        {
            int dataSize = 0;
            entrySize = 8;

            kf._evalCode = AnimationCode.Default;

            for (int i = 0; i < 3; i++)
                dataSize += EvaluateCHR0Group(ref kf._evalCode, kf, i, ref entrySize);

            if (!kf._evalCode.HasRotation && !kf._evalCode.HasTranslation)
            {
                kf._evalCode.IgnoreRotAndTrans = true;
                kf._evalCode.Identity = !kf._evalCode.HasScale;
            }
            else
            {
                kf._evalCode.IgnoreRotAndTrans = false;
                kf._evalCode.Identity = false;
            }

            return dataSize;
        }
Пример #12
0
        public override bool OnInitialize()
        {
            if (_name == null)
                _name = (_indirect ? "Ind" : "") + "Texture" + _textureIndex;

            _flags = Header->Code;

            _keyframes = null;

            if (Parent is SRT0EntryNode && Parent.Parent is SRT0Node)
                _numFrames = ((SRT0Node)Parent.Parent).FrameCount;

            return false;
        }
Пример #13
0
        public static void EncodeSRT0Keyframes(KeyframeCollection kf, VoidPtr entryAddress, VoidPtr dataAddress)
        {
            SRT0Code code = kf._texEvalCode;

            SRT0TextureEntry *header = (SRT0TextureEntry *)entryAddress;

            header->_code = code.data._data;

            bint *pOffset = (bint *)entryAddress + 1;

            int r = 0;

            //Write values/offset and encode groups
            for (int type = 0; type < 3; type++)
            {
                r = type * 3; //Increment to next
                bool has = false;
                switch (type)
                {
                case 0: has = !code.NoScale; break;

                case 1: has = !code.NoRotation; break;

                case 2: has = !code.NoTranslation; break;
                }
                for (int axis = 0; axis < (type == 1 ? 1 : 2); axis++)
                {
                    if (has)
                    {
                        if (code.ScaleIsotropic && type == 0)
                        {
                            if (axis == 0)
                            {
                                if (code.FixedScaleX)
                                {
                                    *(bfloat *)pOffset++ = kf._keyRoots[0]._next._value;
                                }
                                else
                                {
                                    *pOffset = (int)(dataAddress - pOffset); pOffset++;
                                    dataAddress += EncodeEntry(r + axis, AnimDataFormat.I12, kf, dataAddress);
                                }
                            }
                        }
                        else
                        {
                            bool fix = false;
                            switch (type)
                            {
                            case 0:
                                switch (axis)
                                {
                                case 0:
                                    fix = code.FixedScaleX;
                                    break;

                                case 1:
                                    fix = code.FixedScaleY;
                                    break;
                                }
                                break;

                            case 1:
                                fix = code.FixedRotation;
                                break;

                            case 2:
                                switch (axis)
                                {
                                case 0:
                                    fix = code.FixedX;
                                    break;

                                case 1:
                                    fix = code.FixedY;
                                    break;
                                }
                                break;
                            }

                            if (fix)
                            {
                                *(bfloat *)pOffset++ = kf._keyRoots[r + axis]._next._value;
                            }
                            else
                            {
                                *pOffset = (int)(dataAddress - pOffset); pOffset++;
                                dataAddress += EncodeEntry(r + axis, AnimDataFormat.I12, kf, dataAddress);
                            }
                        }
                    }
                }
            }
        }
        private static int EvaluateCHR0Group(ref AnimationCode code, KeyframeCollection kf, int group, ref int entrySize)
        {
            int index = group * 3;
            int numFrames = kf.FrameCount;
            int dataLen = 0;
            int maxEntries;
            int evalCount;
            int scaleSpan;
            //bool useLinear = group == 1;

            bool exist = false;
            bool isotropic = group == 0;
            AnimDataFormat format = AnimDataFormat.None;

            KeyframeEntry[] roots = new KeyframeEntry[3];

            KeyframeEntry[][] arr = new KeyframeEntry[3][];
            int* count = stackalloc int[3];
            bool* isExist = stackalloc bool[3];
            bool* isFixed = stackalloc bool[3];
            bool* isScalable = stackalloc bool[3];
            float* floor = stackalloc float[3];
            float* ceil = stackalloc float[3];

            KeyframeEntry entry;
            int eCount = 0;

            float min;
            float max;
            int maxIndex = 0;

            //Initialize values
            for (int i = 0; i < 3; i++)
            {
                entry = roots[i] = kf._keyRoots[index + i];
                count[i] = kf._keyCounts[index + i];
                isExist[i] = count[i] > 0;
                isFixed[i] = count[i] <= 1;

                if (!isFixed[i])
                {
                    min = float.MaxValue;
                    max = float.MinValue;

                    for (entry = entry._next; entry._index != -1; entry = entry._next)
                    {
                        min = Math.Min(entry._value, min);
                        max = Math.Max(entry._value, max);
                    }

                    floor[i] = min;
                    ceil[i] = max;

                    maxIndex = Math.Max(entry._prev._index, maxIndex);
                }
            }

            if (exist = isExist[0] || isExist[1] || isExist[2])
            {
                if (group == 0)
                {
                    if ((isFixed[0] != isFixed[1]) || (isFixed[0] != isFixed[2]))
                        isotropic = false;
                    else if ((count[0] != count[1]) || (count[0] != count[2]))
                        isotropic = false;
                    else
                    {
                        KeyframeEntry e1 = roots[0], e2 = roots[1], e3 = roots[2];
                        for (int i = count[0]; i-- > 0; )
                        {
                            e1 = e1._next; e2 = e2._next; e3 = e3._next;
                            if ((e1._index != e2._index) || (e1._index != e3._index) ||
                                (e1._value != e2._value) || (e1._value != e3._value))
                            {
                                isotropic = false;
                                break;
                            }
                        }
                    }
                }

                if (isotropic)
                {
                    evalCount = 1;
                    maxEntries = count[0];
                }
                else
                {
                    evalCount = 3;
                    maxEntries = Math.Max(Math.Max(count[0], count[1]), count[2]);
                    //useLinear &= (count[0] == numFrames) && (count[1] == numFrames) && (count[2] == numFrames);
                }

                scaleSpan = (group == 1) ? 255 : (maxIndex <= 255) ? 4095 : (maxIndex <= 2047) ? 65535 : -1;
                //scaleSpan = useLinear ? 255 : 4095;

                //Determine if values are scalable
                for (int i = 0; i < evalCount; i++)
                {
                    isScalable[i] = true;
                    if ((isFixed[i]) || (scaleSpan == -1))
                        continue;

                    //float* pValue = value[i];
                    eCount = count[i];

                    float basev, range, step, distance, val;

                    basev = floor[i];
                    range = ceil[i] - basev;

                //Evaluate spans until we reach a success.
                //A success means that compression using that span is possible.
                //No further evaluation necessary.
                SpanBegin:
                    int span = scaleSpan;
                    int spanEval = scaleSpan - 32;

                    float tanScale = scaleSpan == 4095 ? 32.0f : 256.0f;
                    if (scaleSpan != 255)
                    {
                        for (entry = roots[i]._next; entry._index != -1; entry = entry._next)
                        {
                            //Ignore entries that don't need interp.
                            if (((entry._index - entry._prev._index >= 1) && (entry._prev._index != -1)) ||
                                ((entry._next._index - entry._index >= 1) && (entry._next._index != -1)))
                            {
                                val = entry._tangent * tanScale;
                                val += val < 0 ? -0.5f : 0.5f;
                                if (Math.Abs(((int)val / tanScale) - entry._tangent) > tanError)
                                {
                                    span = spanEval;
                                    break;
                                }
                            }
                        }
                    }

                    if ((span > spanEval) && (range == 0.0f))
                        continue;

                SpanStep:
                    if (span > spanEval)
                    {
                        step = range / span;

                        //if span <= 255, check every frame instead!
                        if (span <= 255)
                        {
                            for (int x = 0; x < numFrames; x++)
                            {
                                val = kf[KeyFrameMode.ScaleX + index + i, x];
                                distance = ((val - basev) / step) + 0.5f;
                                distance = Math.Abs(val - (basev + ((int)distance * step)));

                                //If distance is too large change span and retry
                                if (distance > scaleError)
                                {
                                    span--;
                                    goto SpanStep;
                                }
                            }
                        }
                        else
                        {
                            for (entry = roots[i]._next; entry._index != -1; entry = entry._next)
                            {
                                val = entry._value;
                                distance = ((val - basev) / step) + 0.5f;
                                distance = Math.Abs(val - (basev + ((int)distance * step)));

                                //If distance is too large change span and retry
                                if (distance > scaleError)
                                {
                                    span--;
                                    goto SpanStep;
                                }
                            }
                        }
                    }
                    else
                    {
                        if ((scaleSpan <= 255) && (maxIndex <= 255))
                            scaleSpan = 4095;
                        else if ((scaleSpan <= 4095) && (maxIndex <= 2047))
                            scaleSpan = 65535;
                        else
                        {
                            scaleSpan = -1;
                            isScalable[i] = false;
                            continue;
                        }
                        goto SpanBegin;
                    }
                }

                //Determine format only if there are unfixed entries
                if (!isFixed[0] || !isFixed[1] || !isFixed[2])
                {
                    bool scale = (isotropic) ? isScalable[0] : (isScalable[0] && isScalable[1] && isScalable[2]);
                    float frameSpan = (float)numFrames / maxEntries;

                    if (scale)
                    {
                        if ((group == 1) && (scaleSpan <= 255) && (frameSpan < 4.0f))
                            format = AnimDataFormat.L1;
                        else if ((scaleSpan <= 4095) && (maxIndex <= 255))
                            format = AnimDataFormat.I4;
                        else if ((frameSpan > 1.5f) && (maxIndex <= 2047))
                            format = AnimDataFormat.I6;
                        else if ((group == 1) && (frameSpan <= 3.0f))
                            format = AnimDataFormat.L4;
                        else
                            format = AnimDataFormat.I12;
                    }
                    else if ((group == 1) && (frameSpan <= 3.0f))
                        format = AnimDataFormat.L4;
                    else
                        format = AnimDataFormat.I12;
                }

                //calculate size
                for (int i = 0; i < evalCount; i++)
                {
                    entrySize += 4;

                    if (!isFixed[i])
                    {
                        switch (format)
                        {
                            case AnimDataFormat.I12:
                                dataLen += 8 + (count[i] * 12);
                                break;

                            case AnimDataFormat.I4:
                                dataLen += 16 + (count[i] * 4);
                                break;

                            case AnimDataFormat.I6:
                                dataLen += (16 + (count[i] * 6)).Align(4);
                                break;

                            case AnimDataFormat.L1:
                                dataLen += (8 + numFrames).Align(4);
                                break;

                            case AnimDataFormat.L4:
                                dataLen += numFrames * 4;
                                break;
                        }
                    }
                }
                //Should we compress here?
            }
            else //Set isotropic to true, so it sets the default value.
                isotropic = true;

            if (group == 0)
                code.IgnoreScale = !exist;

            code.SetExists(group, exist);
            code.SetIsIsotropic(group, isotropic);
            for (int i = 0; i < 3; i++)
                code.SetIsFixed(index + i, isFixed[i]);
            code.SetFormat(group, format);

            return dataLen;
        }
        public static void EncodeCHR0Keyframes(KeyframeCollection kf, VoidPtr entryAddress, VoidPtr dataAddress)
        {
            AnimationCode code = kf._evalCode;
            //VoidPtr dataAddr = addr + 8;

            CHR0Entry* header = (CHR0Entry*)entryAddress;
            header->_code = (uint)code._data;
            header->_stringOffset = 0;

            //entryAddress += 8;
            bint* pOffset = (bint*)entryAddress + 2;

            //Write values/offset and encode groups
            for (int i = 0, x = 0; i < 3; i++, x += 3)
                if (code.GetExists(i))
                {
                    AnimDataFormat format = code.GetFormat(i);
                    if ((i == 0) && (code.GetIsIsotropic(i)))
                    {
                        if (code.GetIsFixed(2))
                            *(bfloat*)pOffset++ = kf._keyRoots[2]._next._value;
                        else
                        {
                            *pOffset++ = (int)(dataAddress - entryAddress);
                            dataAddress += EncodeEntry(x, format, kf, dataAddress);
                        }
                    }
                    else
                        for (int y = 0, z = x; y < 3; y++, z++)
                            if (code.GetIsFixed(z))
                                *(bfloat*)pOffset++ = kf._keyRoots[z]._next._value;
                            else
                            {
                                *pOffset++ = (int)(dataAddress - entryAddress);
                                dataAddress += EncodeEntry(z, format, kf, dataAddress);
                            }
                }
        }
Пример #16
0
        public static KeyframeCollection DecodeCHR0Keyframes(CHR0Entry *entry, int numFrames)
        {
            KeyframeCollection kf = new KeyframeCollection(9, numFrames, 1, 1, 1);

            if (entry == null)
            {
                return(kf);
            }

            bfloat *       sPtr = (bfloat *)entry->Data;
            AnimationCode  code = entry->Code;
            AnimDataFormat format;

            if (code.HasScale)
            {
                format = code.ScaleDataFormat;
                if (code.IsScaleIsotropic)
                {
                    if (code.IsScaleZFixed)
                    {
                        kf[0, 0, 1, 2] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 0, 1, 2);
                    }
                }
                else
                {
                    if (code.IsScaleXFixed)
                    {
                        kf[0, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 0);
                    }

                    if (code.IsScaleYFixed)
                    {
                        kf[0, 1] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 1);
                    }

                    if (code.IsScaleZFixed)
                    {
                        kf[0, 2] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 2);
                    }
                }
            }

            if (code.HasRotation)
            {
                format = code.RotationDataFormat;
                if (code.IsRotationIsotropic)
                {
                    if (code.IsRotationZFixed)
                    {
                        kf[0, 3, 4, 5] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 3, 4, 5);
                    }
                }
                else
                {
                    if (code.IsRotationXFixed)
                    {
                        kf[0, 3] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 3);
                    }

                    if (code.IsRotationYFixed)
                    {
                        kf[0, 4] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 4);
                    }

                    if (code.IsRotationZFixed)
                    {
                        kf[0, 5] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 5);
                    }
                }
            }

            if (code.HasTranslation)
            {
                format = code.TranslationDataFormat;
                if (code.IsTranslationIsotropic)
                {
                    if (code.IsTranslationZFixed)
                    {
                        kf[0, 6, 7, 8] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 6, 7, 8);
                    }
                }
                else
                {
                    if (code.IsTranslationXFixed)
                    {
                        kf[0, 6] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 6);
                    }

                    if (code.IsTranslationYFixed)
                    {
                        kf[0, 7] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 7);
                    }

                    if (code.IsTranslationZFixed)
                    {
                        kf[0, 8] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, 8);
                    }
                }
            }

            return(kf);
        }
        public static void EncodeSRT0Keyframes(KeyframeCollection kf, VoidPtr entryAddress, VoidPtr dataAddress)
        {
            SRT0Code code = kf._texEvalCode;

            SRT0TextureEntry* header = (SRT0TextureEntry*)entryAddress;
            header->_code = code.data._data;

            bint* pOffset = (bint*)entryAddress + 1;

            int r = 0;

            //Write values/offset and encode groups
            for (int type = 0; type < 3; type++)
            {
                r = type * 3; //Increment to next
                bool has = false;
                switch (type)
                {
                    case 0: has = !code.NoScale; break;
                    case 1: has = !code.NoRotation; break;
                    case 2: has = !code.NoTranslation; break;
                }
                for (int axis = 0; axis < (type == 1 ? 1 : 2); axis++)
                {
                    if (has)
                    {
                        if (code.ScaleIsotropic && type == 0)
                        {
                            if (axis == 0)
                            {
                                if (code.FixedScaleX)
                                    *(bfloat*)pOffset++ = kf._keyRoots[0]._next._value;
                                else
                                {
                                    *pOffset = (int)(dataAddress - pOffset); pOffset++;
                                    dataAddress += EncodeEntry(r + axis, AnimDataFormat.I12, kf, dataAddress);
                                }
                            }
                        }
                        else
                        {
                            bool fix = false;
                            switch (type)
                            {
                                case 0:
                                    switch (axis)
                                    {
                                        case 0:
                                            fix = code.FixedScaleX;
                                            break;
                                        case 1:
                                            fix = code.FixedScaleY;
                                            break;
                                    }
                                    break;
                                case 1:
                                    fix = code.FixedRotation;
                                    break;
                                case 2:
                                    switch (axis)
                                    {
                                        case 0:
                                            fix = code.FixedX;
                                            break;
                                        case 1:
                                            fix = code.FixedY;
                                            break;
                                    }
                                    break;
                            }

                            if (fix)
                                *(bfloat*)pOffset++ = kf._keyRoots[r + axis]._next._value;
                            else
                            {
                                *pOffset = (int)(dataAddress - pOffset); pOffset++;
                                dataAddress += EncodeEntry(r + axis, AnimDataFormat.I12, kf, dataAddress);
                            }
                        }
                    }
                }
            }
        }
Пример #18
0
 /// <summary>
 /// Stretches or compresses all frames of the animation to fit a new frame count.
 /// </summary>
 public void Resize(int newFrameCount)
 {
     KeyframeEntry kfe = null;
     float ratio = (float)newFrameCount / (float)FrameCount;
     foreach (CHR0EntryNode e in Children)
     {
         KeyframeCollection newCollection = new KeyframeCollection(newFrameCount);
         for (int x = 0; x < FrameCount; x++)
         {
             int newFrame = (int)((float)x * ratio + 0.5f);
             float frameRatio = newFrame == 0 ? 0 : (float)x / (float)newFrame;
             for (int i = 0x10; i < 0x19; i++)
                 if ((kfe = e.GetKeyframe((KeyFrameMode)i, x)) != null)
                     newCollection.SetFrameValue((KeyFrameMode)i, newFrame, kfe._value)._tangent = kfe._tangent * (float.IsNaN(frameRatio) ? 1 : frameRatio);
         }
         e._keyframes = newCollection;
     }
     FrameCount = newFrameCount;
 }
Пример #19
0
        public static void EncodeSRT0Keyframes(KeyframeCollection kf, VoidPtr entryAddress, VoidPtr dataAddress)
        {
            SRT0Code code = kf._texEvalCode;

            SRT0TextureEntry *header = (SRT0TextureEntry *)entryAddress;

            header->_code = code.data;

            bint *pOffset = (bint *)entryAddress + 1;

            int r = 0;

            //Write values/offset and encode groups
            for (int type = 0; type < 3; type++)
            {
                r = type * 3; //Increment to next
                for (int axis = 0; axis < (type == 1 ? 1 : 2); axis++)
                {
                    int loc = 0;
                    if (type == 2)
                    {
                        loc = 2;
                    }
                    else if (type == 1)
                    {
                        loc = 1;
                    }
                    else if (type == 0 && axis == 0)
                    {
                        loc = 3;
                    }
                    else
                    {
                        loc = 0;
                    }

                    int fix = 0;
                    if (type == 0)
                    {
                        fix = axis;
                    }
                    else if (type == 1)
                    {
                        fix = 2;
                    }
                    else if (type == 2)
                    {
                        fix = 3 + axis;
                    }

                    if (code.GetHas(loc))
                    {
                        if (code.GetFixed(fix))
                        {
                            *(bfloat *)pOffset++ = kf._keyRoots[r + axis]._next._value;
                        }
                        else
                        {
                            *pOffset = (int)(dataAddress - pOffset); pOffset++;
                            dataAddress += EncodeEntry(r + axis, AnimDataFormat.I12, kf, dataAddress);
                        }
                    }
                }
            }
        }
Пример #20
0
        private static int EvaluateSRT0Group(ref SRT0Code code, KeyframeCollection kf, int group, ref int entrySize)
        {
            //SRT0s always use I12

            //group
            //0 = scale
            //1 = rot
            //2 = trans

            int index     = group * 3;
            int numFrames = kf.FrameLimit;
            int dataLen   = 0;

            bool exist = false;

            int * count   = stackalloc int[2];
            bool *isExist = stackalloc bool[2];
            bool *isFixed = stackalloc bool[2];

            for (int i = 0; i < (group == 1 ? 1 : 2); i++)
            {
                count[i]   = kf._keyCounts[index + i];
                isExist[i] = count[i] > 0;
                isFixed[i] = count[i] <= 1;
            }

            exist = isExist[0] || isExist[1];
            for (int i = 0; i < (group == 1 ? 1 : 2); i++)
            {
                int loc = 0;
                if (group == 2)
                {
                    loc = 2;
                }
                else if (group == 1)
                {
                    loc = 1;
                }
                else if (group == 0 && i == 0)
                {
                    loc = 3;
                }
                else
                {
                    loc = 0;
                }

                int fix = 0;
                if (group == 0)
                {
                    fix = i;
                }
                else if (group == 1)
                {
                    fix = 2;
                }
                else if (group == 2)
                {
                    fix = 3 + i;
                }

                if (exist)
                {
                    entrySize += 4;
                    if (!isFixed[i])
                    {
                        dataLen += 8 + (count[i] * 12);
                    }
                }
                code.SetFixed(fix, isFixed[i]);
                code.SetHas(loc, exist);
            }
            return(dataLen);
        }
        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;
        }
        private static int EvaluateSRT0Group(ref SRT0Code code, KeyframeCollection kf, int group, ref int entrySize)
        {
            //SRT0s always use I12

            //group
            //0 = scale
            //1 = rot
            //2 = trans

            int index = group * 3;
            int numFrames = kf.FrameCount;
            int dataLen = 0;
            KeyframeEntry[] roots = new KeyframeEntry[2];
            bool exist = false;
            bool isotropic = group == 0;
            int* count = stackalloc int[2];
            bool* isExist = stackalloc bool[2];
            bool* isFixed = stackalloc bool[2];

            for (int i = 0; i < (group == 1 ? 1 : 2); i++)
            {
                roots[i] = kf._keyRoots[index + i];
                count[i] = kf._keyCounts[index + i];
                isExist[i] = count[i] > 0;
                isFixed[i] = count[i] <= 1;
            }

            if (exist = isExist[0] || isExist[1])
            {
                if (group == 0)
                {
                    if (isFixed[0] != isFixed[1])
                        isotropic = false;
                    else if (count[0] != count[1])
                        isotropic = false;
                    else
                    {
                        KeyframeEntry e1 = roots[0], e2 = roots[1];
                        for (int i = count[0]; i-- > 0; )
                        {
                            e1 = e1._next; e2 = e2._next;
                            if ((e1._index != e2._index) ||
                                (e1._value != e2._value))
                            {
                                isotropic = false;
                                break;
                            }
                        }
                    }
                }
            }
            if (group == 0 && !isotropic)
                code.ScaleIsotropic = false;
            for (int i = 0; i < (group == 1 ? 1 : 2); i++)
            {
                if (exist)
                {
                    switch (group)
                    {
                        case 0: code.NoScale = false; break;
                        case 1: code.NoRotation = false; break;
                        case 2: code.NoTranslation = false; break;
                    }
                    if (!(group == 0 && i == 1 && code.ScaleIsotropic))
                        entrySize += 4;
                    if (!isFixed[i])
                    {
                        switch (group)
                        {
                            case 0:
                                switch (i)
                                {
                                    case 0: code.FixedScaleX = false; break;
                                    case 1: code.FixedScaleY = false; break;
                                }
                                break;
                            case 1: code.FixedRotation = false; break;
                            case 2: switch (i)
                                {
                                    case 0: code.FixedX = false; break;
                                    case 1: code.FixedY = false; break;
                                }
                                break;
                        }
                        if (!(group == 0 && i == 1 && code.ScaleIsotropic))
                            dataLen += 8 + (count[i] * 12);
                    }
                }
            }
            return dataLen;
        }
        private static void DecodeCHR0Frames(KeyframeCollection kf, void* dataAddr, AnimDataFormat format, KeyFrameMode mode)
        {
            int fCount;
            float vStep, vBase;
            switch (format)
            {
                case AnimDataFormat.I4:
                    {
                        I4Header* header = (I4Header*)dataAddr;
                        fCount = header->_entries;
                        vStep = header->_step;
                        vBase = header->_base;

                        I4Entry* entry = header->Data;
                        for (int i = 0; i < fCount; i++, entry++)
                            kf.SetFrameValue(mode, entry->FrameIndex, vBase + (entry->Step * vStep))._tangent = entry->Tangent;
                        break;
                    }
                case AnimDataFormat.I6:
                    {
                        I6Header* header = (I6Header*)dataAddr;
                        fCount = header->_numFrames;
                        vStep = header->_step;
                        vBase = header->_base;

                        I6Entry* entry = header->Data;
                        for (int i = 0; i < fCount; i++, entry++)
                            kf.SetFrameValue(mode, entry->FrameIndex, vBase + (entry->_step * vStep))._tangent = entry->Tangent;
                        break;
                    }
                case AnimDataFormat.I12:
                    {
                        I12Header* header = (I12Header*)dataAddr;
                        fCount = header->_numFrames;

                        I12Entry* entry = header->Data;
                        for (int i = 0; i < fCount; i++, entry++)
                            kf.SetFrameValue(mode, (int)entry->_index, entry->_value)._tangent = entry->_tangent;
                        break;
                    }
                case AnimDataFormat.L1:
                    {
                        L1Header* header = (L1Header*)dataAddr;
                        vStep = header->_step;
                        vBase = header->_base;

                        byte* sPtr = header->Data;
                        for (int i = 0; i < kf.FrameCount; i++)
                            kf[mode, i] = vBase + (*sPtr++ * vStep);

                        KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                        for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                            entry.GenerateTangent();

                        break;
                    }
                case AnimDataFormat.L2:
                    {
                        L1Header* header = (L1Header*)dataAddr;
                        vStep = header->_step;
                        vBase = header->_base;

                        bushort* sPtr = (bushort*)header->Data;
                        for (int i = 0; i < kf.FrameCount; i++)
                            kf[mode, i] = vBase + (*sPtr++ * vStep);

                        KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                        for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                            entry.GenerateTangent();

                        break;
                    }
                case AnimDataFormat.L4:
                    {
                        bfloat* sPtr = (bfloat*)dataAddr;

                        for (int i = 0; i < kf.FrameCount; i++)
                            kf[mode, i] = *sPtr++;

                        KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                        for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                            entry.GenerateTangent();

                        break;
                    }
            }
        }
Пример #24
0
        public override bool OnInitialize()
        {
            _keyframes = null;

            if (_parent is CHR0Node)
                _numFrames = ((CHR0Node)_parent).FrameCount;

            if ((_name == null) && (Header->_stringOffset != 0))
                _name = Header->ResourceString;

            _useModelScale = Header->Code.UseModelScale;
            _useModelRotate = Header->Code.UseModelRot;
            _useModelTranslate = Header->Code.UseModelTrans;

            _scaleCompApply = Header->Code.ScaleCompApply;
            _scaleCompParent = Header->Code.ScaleCompParent;
            _classicScaleOff = Header->Code.ClassicScaleOff;

            return false;
        }
Пример #25
0
        private static int EvaluateCHR0Group(ref AnimationCode code, KeyframeCollection kf, int group,
                                             ref int entrySize)
        {
            int index     = group * 3;
            int numFrames = kf.FrameLimit;
            int dataLen   = 0;
            int maxEntries;
            int evalCount;
            int scaleSpan;
            //bool useLinear = group == 1;

            bool           exist     = false;
            bool           isotropic = group == 0;
            AnimDataFormat format    = AnimDataFormat.None;

            KeyframeEntry[] roots = new KeyframeEntry[3];

            KeyframeEntry[][] arr        = new KeyframeEntry[3][];
            int[]             count      = new int[3];
            bool[]            isExist    = new bool[3];
            bool[]            isFixed    = new bool[3];
            bool[]            isScalable = new bool[3];
            float[]           floor      = new float[3];
            float[]           ceil       = new float[3];

            KeyframeEntry entry;
            int           eCount = 0;

            float min;
            float max;
            int   maxIndex = 0;

            //Initialize values
            for (int i = 0; i < 3; i++)
            {
                entry      = roots[i] = kf._keyArrays[index + i]._keyRoot;
                count[i]   = kf._keyArrays[index + i]._keyCount;
                isExist[i] = count[i] > 0;
                isFixed[i] = count[i] <= 1;

                if (!isFixed[i])
                {
                    min = float.MaxValue;
                    max = float.MinValue;

                    for (entry = entry._next; entry._index != -1; entry = entry._next)
                    {
                        min = Math.Min(entry._value, min);
                        max = Math.Max(entry._value, max);
                    }

                    floor[i] = min;
                    ceil[i]  = max;

                    maxIndex = Math.Max(entry._prev._index, maxIndex);
                }
            }

            if (exist = isExist[0] || isExist[1] || isExist[2])
            {
                if (group == 0)
                {
                    if (isFixed[0] != isFixed[1] || isFixed[0] != isFixed[2])
                    {
                        isotropic = false;
                    }
                    else if (count[0] != count[1] || count[0] != count[2])
                    {
                        isotropic = false;
                    }
                    else
                    {
                        KeyframeEntry e1 = roots[0], e2 = roots[1], e3 = roots[2];
                        for (int i = count[0]; i-- > 0;)
                        {
                            e1 = e1._next;
                            e2 = e2._next;
                            e3 = e3._next;
                            if (e1._index != e2._index || e1._index != e3._index ||
                                e1._value != e2._value || e1._value != e3._value)
                            {
                                isotropic = false;
                                break;
                            }
                        }
                    }
                }

                if (isotropic)
                {
                    evalCount  = 1;
                    maxEntries = count[0];
                }
                else
                {
                    evalCount  = 3;
                    maxEntries = Math.Max(Math.Max(count[0], count[1]), count[2]);
                    //useLinear &= (count[0] == numFrames) && (count[1] == numFrames) && (count[2] == numFrames);
                }

                scaleSpan = @group == 1 ? 255 : maxIndex <= 255 ? 4095 : maxIndex <= 2047 ? 65535 : -1;
                //scaleSpan = useLinear ? 255 : 4095;

                //Determine if values are scalable
                for (int i = 0; i < evalCount; i++)
                {
                    isScalable[i] = true;
                    if (isFixed[i] || scaleSpan == -1)
                    {
                        continue;
                    }

                    //float* pValue = value[i];
                    eCount = count[i];

                    float basev, range, step, distance, val;

                    basev = floor[i];
                    range = ceil[i] - basev;


                    //Evaluate spans until we reach a success.
                    //A success means that compression using that span is possible.
                    //No further evaluation necessary.
SpanBegin:
                    int span = scaleSpan;
                    int spanEval = scaleSpan - 32;

                    float tanScale = scaleSpan == 4095 ? 32.0f : 256.0f;
                    if (scaleSpan != 255)
                    {
                        for (entry = roots[i]._next; entry._index != -1; entry = entry._next)
                        {
                            //Ignore entries that don't need interp.
                            if (entry._index - entry._prev._index >= 1 && entry._prev._index != -1 ||
                                entry._next._index - entry._index >= 1 && entry._next._index != -1)
                            {
                                val  = entry._tangent * tanScale;
                                val += val < 0 ? -0.5f : 0.5f;
                                if (Math.Abs((int)val / tanScale - entry._tangent) > tanError)
                                {
                                    span = spanEval;
                                    break;
                                }
                            }
                        }
                    }

                    if (span > spanEval && range == 0.0f)
                    {
                        continue;
                    }

SpanStep:
                    if (span > spanEval)
                    {
                        step = range / span;

                        //if span <= 255, check every frame instead!
                        if (span <= 255)
                        {
                            for (int x = 0; x < numFrames; x++)
                            {
                                val      = kf[x, index + i];
                                distance = (val - basev) / step + 0.5f;
                                distance = Math.Abs(val - (basev + (int)distance * step));

                                //If distance is too large change span and retry
                                if (distance > scaleError)
                                {
                                    span--;
                                    goto SpanStep;
                                }
                            }
                        }
                        else
                        {
                            for (entry = roots[i]._next; entry._index != -1; entry = entry._next)
                            {
                                val      = entry._value;
                                distance = (val - basev) / step + 0.5f;
                                distance = Math.Abs(val - (basev + (int)distance * step));

                                //If distance is too large change span and retry
                                if (distance > scaleError)
                                {
                                    span--;
                                    goto SpanStep;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (scaleSpan <= 255 && maxIndex <= 255)
                        {
                            scaleSpan = 4095;
                        }
                        else if (scaleSpan <= 4095 && maxIndex <= 2047)
                        {
                            scaleSpan = 65535;
                        }
                        else
                        {
                            scaleSpan     = -1;
                            isScalable[i] = false;
                            continue;
                        }

                        goto SpanBegin;
                    }
                }

                //Determine format only if there are unfixed entries
                if (!isFixed[0] || !isFixed[1] || !isFixed[2])
                {
                    bool  scale     = isotropic ? isScalable[0] : isScalable[0] && isScalable[1] && isScalable[2];
                    float frameSpan = (float)numFrames / maxEntries;

                    if (scale)
                    {
                        if (@group == 1 && scaleSpan <= 255 && frameSpan < 4.0f)
                        {
                            format = AnimDataFormat.L1;
                        }
                        else if (scaleSpan <= 4095 && maxIndex <= 255)
                        {
                            format = AnimDataFormat.I4;
                        }
                        else if (frameSpan > 1.5f && maxIndex <= 2047)
                        {
                            format = AnimDataFormat.I6;
                        }
                        else if (@group == 1 && frameSpan <= 3.0f)
                        {
                            format = AnimDataFormat.L4;
                        }
                        else
                        {
                            format = AnimDataFormat.I12;
                        }
                    }
                    else if (@group == 1 && frameSpan <= 3.0f)
                    {
                        format = AnimDataFormat.L4;
                    }
                    else
                    {
                        format = AnimDataFormat.I12;
                    }
                }

                //calculate size
                for (int i = 0; i < evalCount; i++)
                {
                    entrySize += 4;

                    if (!isFixed[i])
                    {
                        switch (format)
                        {
                        case AnimDataFormat.I12:
                            dataLen += 8 + count[i] * 12;
                            break;

                        case AnimDataFormat.I4:
                            dataLen += 16 + count[i] * 4;
                            break;

                        case AnimDataFormat.I6:
                            dataLen += (16 + count[i] * 6).Align(4);
                            break;

                        case AnimDataFormat.L1:
                            dataLen += (8 + numFrames).Align(4);
                            break;

                        case AnimDataFormat.L4:
                            dataLen += numFrames * 4;
                            break;
                        }
                    }
                }

                //Should we compress here?
            }
            else //Set isotropic to true, so it sets the default value.
            {
                isotropic = true;
            }

            if (group == 0)
            {
                code.IgnoreScale = !exist;
            }

            code.SetExists(group, exist);
            code.SetIsIsotropic(group, isotropic);
            for (int i = 0; i < 3; i++)
            {
                code.SetIsFixed(index + i, isFixed[i]);
            }

            code.SetFormat(group, format);

            return(dataLen);
        }
        public static void Serialize(CHR0Node node, bool bake, string output)
        {
            MDL0Node model;

            OpenFileDialog dlgOpen = new OpenFileDialog();

            dlgOpen.Filter = "MDL0 Model (*.mdl0)|*.mdl0";
            dlgOpen.Title  = "Select the model this animation is for...";

            if (dlgOpen.ShowDialog() != DialogResult.OK || (model = (MDL0Node)NodeFactory.FromFile(null, dlgOpen.FileName)) == null)
            {
                return;
            }

            using (StreamWriter file = new StreamWriter(output))
            {
                file.WriteLine("animVersion 1.1;");
                file.WriteLine("mayaVersion 2015;");
                file.WriteLine("timeUnit ntsc;");
                file.WriteLine("linearUnit cm;");
                file.WriteLine("angularUnit deg;");
                file.WriteLine("startTime 1;");
                file.WriteLine(String.Format("endTime {0};", node.FrameCount));
                foreach (CHR0EntryNode e in node.Children)
                {
                    MDL0BoneNode bone = model.FindChild("Bones/" + e.Name, true) as MDL0BoneNode;
                    if (bone == null)
                    {
                        continue;
                    }

                    KeyframeCollection c = e.Keyframes;
                    for (int index = 0; index < 9; index++)
                    {
                        KeyframeArray array = c._keyArrays[index];

                        if (array._keyCount <= 0)
                        {
                            continue;
                        }

                        file.WriteLine(String.Format("anim {0}.{0}{1} {0}{1} {2} {3} {4} {5}", types[index / 3], axes[index % 3], e.Name, 0, bone.Children.Count, index < 6 ? (index + 3) : index - 6));
                        file.WriteLine("animData {");
                        file.WriteLine("  input time;");
                        file.WriteLine(String.Format("  output {0};", index > 2 && index < 6 ? "angular" : "linear"));
                        file.WriteLine("  weighted 0;");
                        file.WriteLine("  preInfinity constant;");
                        file.WriteLine("  postInfinity constant;");
                        file.WriteLine("  keys {");
                        for (KeyframeEntry entry = array._keyRoot._next; (entry != array._keyRoot); entry = entry._next)
                        {
                            bool single = entry._next._index < 0 && entry._prev._index < 0;
                            //float angle = (float)Math.Atan(entry._tangent) * Maths._rad2degf;
                            //if (single)
                            {
                                file.WriteLine(String.Format("    {0} {1} {2} {2} {3} {4} {5};",
                                                             entry._index + 1,
                                                             entry._value.ToString(CultureInfo.InvariantCulture.NumberFormat),
                                                             "auto",//single ? "auto" : "fixed",
                                                             "1",
                                                             "1",
                                                             "0"));
                            }
                        }
                        file.WriteLine("  }");
                        file.WriteLine("}");
                    }
                }
            }
        }
Пример #27
0
        private static int EvaluateSRT0Group(ref SRT0Code code, KeyframeCollection kf, int group, ref int entrySize)
        {
            //SRT0s always use I12

            //group
            //0 = scale
            //1 = rot
            //2 = trans

            int index     = group == 0 ? 0 : group == 1 ? 2 : 3;
            int numFrames = kf.FrameLimit;
            int dataLen   = 0;

            KeyframeEntry[] roots     = new KeyframeEntry[2];
            bool            exist     = false;
            bool            isotropic = group == 0;

            int[]  count   = new int[2];
            bool[] isExist = new bool[2];
            bool[] isFixed = new bool[2];

            for (int i = 0; i < (group == 1 ? 1 : 2); i++)
            {
                roots[i]   = kf._keyArrays[index + i]._keyRoot;
                count[i]   = kf._keyArrays[index + i]._keyCount;
                isExist[i] = count[i] > 0;
                isFixed[i] = count[i] <= 1;
            }

            if (exist = isExist[0] || isExist[1])
            {
                if (group == 0)
                {
                    if (isFixed[0] != isFixed[1])
                    {
                        isotropic = false;
                    }
                    else if (count[0] != count[1])
                    {
                        isotropic = false;
                    }
                    else
                    {
                        KeyframeEntry e1 = roots[0], e2 = roots[1];
                        for (int i = count[0]; i-- > 0;)
                        {
                            e1 = e1._next;
                            e2 = e2._next;
                            if (e1._index != e2._index ||
                                e1._value != e2._value)
                            {
                                isotropic = false;
                                break;
                            }
                        }
                    }
                }
            }

            if (group == 0 && !isotropic)
            {
                code.ScaleIsotropic = false;
            }

            for (int i = 0; i < (group == 1 ? 1 : 2); i++)
            {
                if (exist)
                {
                    switch (group)
                    {
                    case 0:
                        code.NoScale = false;
                        break;

                    case 1:
                        code.NoRotation = false;
                        break;

                    case 2:
                        code.NoTranslation = false;
                        break;
                    }

                    if (!(group == 0 && i == 1 && code.ScaleIsotropic))
                    {
                        entrySize += 4;
                    }

                    if (!isFixed[i])
                    {
                        switch (group)
                        {
                        case 0:
                            switch (i)
                            {
                            case 0:
                                code.FixedScaleX = false;
                                break;

                            case 1:
                                code.FixedScaleY = false;
                                break;
                            }

                            break;

                        case 1:
                            code.FixedRotation = false;
                            break;

                        case 2:
                            switch (i)
                            {
                            case 0:
                                code.FixedX = false;
                                break;

                            case 1:
                                code.FixedY = false;
                                break;
                            }

                            break;
                        }

                        if (!(group == 0 && i == 1 && code.ScaleIsotropic))
                        {
                            dataLen += 8 + count[i] * 12;
                        }
                    }
                }
            }

            return(dataLen);
        }
Пример #28
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 void DecodeSRT0Frames(KeyframeCollection kf, void* dataAddr, KeyFrameMode mode)
        {
            int fCount;

            I12Header* header = (I12Header*)dataAddr;
            fCount = header->_numFrames;

            I12Entry* entry = header->Data;
            for (int i = 0; i < fCount; i++, entry++)
                kf.SetFrameValue(mode, (int)entry->_index, entry->_value)._tangent = entry->_tangent;
        }
Пример #30
0
        private static void DecodeFrames(KeyframeCollection kf, void *dataAddr, AnimDataFormat format,
                                         params int[] arrays)
        {
            int   fCount;
            float vStep, vBase;

            switch (format)
            {
            case AnimDataFormat.I4:
            {
                I4Header *header = (I4Header *)dataAddr;
                fCount = header->_entries;
                vStep  = header->_step;
                vBase  = header->_base;

                foreach (int x in arrays)
                {
                    I4Entry *entry = header->Data;
                    for (int i = 0; i < fCount; i++, entry++)
                    {
                        kf.SetFrameValue(x, entry->FrameIndex, vBase + entry->Step * vStep, true)._tangent =
                            entry->Tangent;
                    }
                }

                break;
            }

            case AnimDataFormat.I6:
            {
                I6Header *header = (I6Header *)dataAddr;
                fCount = header->_numFrames;
                vStep  = header->_step;
                vBase  = header->_base;

                foreach (int x in arrays)
                {
                    I6Entry *entry = header->Data;
                    for (int i = 0; i < fCount; i++, entry++)
                    {
                        kf.SetFrameValue(x, entry->FrameIndex, vBase + entry->_step * vStep, true)._tangent =
                            entry->Tangent;
                    }
                }

                break;
            }

            case AnimDataFormat.I12:
            {
                I12Header *header = (I12Header *)dataAddr;
                fCount = header->_numFrames;

                foreach (int x in arrays)
                {
                    I12Entry *entry = header->Data;
                    for (int i = 0; i < fCount; i++, entry++)
                    {
                        kf.SetFrameValue(x, (int)entry->_index, entry->_value, true)._tangent = entry->_tangent;
                    }
                }

                break;
            }

            case AnimDataFormat.L1:
            {
                L1Header *header = (L1Header *)dataAddr;
                vStep = header->_step;
                vBase = header->_base;

                foreach (int x in arrays)
                {
                    byte *sPtr = header->Data;
                    for (int i = 0; i < kf.FrameLimit; i++)
                    {
                        kf.SetFrameValue(x, i, vBase + *sPtr++ *vStep, true).GenerateTangent();
                    }
                }

                break;
            }

            case AnimDataFormat.L2:
            {
                L1Header *header = (L1Header *)dataAddr;
                vStep = header->_step;
                vBase = header->_base;

                foreach (int x in arrays)
                {
                    bushort *sPtr = (bushort *)header->Data;
                    for (int i = 0; i < kf.FrameLimit; i++)
                    {
                        kf.SetFrameValue(x, i, vBase + *sPtr++ *vStep, true).GenerateTangent();
                    }
                }

                break;
            }

            case AnimDataFormat.L4:
            {
                foreach (int x in arrays)
                {
                    bfloat *sPtr = (bfloat *)dataAddr;
                    for (int i = 0; i < kf.FrameLimit; i++)
                    {
                        kf.SetFrameValue(x, i, *sPtr++, true).GenerateTangent();
                    }
                }

                break;
            }
            }
        }
Пример #31
0
        public static KeyframeCollection DecodeCHR0Keyframes(CHR0Entry *entry, int numFrames)
        {
            KeyframeCollection kf   = new KeyframeCollection(numFrames);
            bfloat *           sPtr = (bfloat *)entry->Data;
            AnimationCode      code = entry->Code;
            AnimDataFormat     format;

            if (code.HasScale)
            {
                format = code.ScaleDataFormat;
                if (code.IsScaleIsotropic)
                {
                    if (code.IsScaleZFixed)
                    {
                        kf[KeyFrameMode.ScaleXYZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.ScaleXYZ);
                    }
                }
                else
                {
                    if (code.IsScaleXFixed)
                    {
                        kf[KeyFrameMode.ScaleX, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.ScaleX);
                    }

                    if (code.IsScaleYFixed)
                    {
                        kf[KeyFrameMode.ScaleY, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.ScaleY);
                    }

                    if (code.IsScaleZFixed)
                    {
                        kf[KeyFrameMode.ScaleZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.ScaleZ);
                    }
                }
            }

            if (code.HasRotation)
            {
                format = code.RotationDataFormat;
                if (code.IsRotationIsotropic)
                {
                    if (code.IsRotationZFixed)
                    {
                        kf[KeyFrameMode.RotXYZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.RotXYZ);
                    }
                }
                else
                {
                    if (code.IsRotationXFixed)
                    {
                        kf[KeyFrameMode.RotX, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.RotX);
                    }

                    if (code.IsRotationYFixed)
                    {
                        kf[KeyFrameMode.RotY, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.RotY);
                    }

                    if (code.IsRotationZFixed)
                    {
                        kf[KeyFrameMode.RotZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.RotZ);
                    }
                }
            }

            if (code.HasTranslation)
            {
                format = code.TranslationDataFormat;
                if (code.IsTranslationIsotropic)
                {
                    if (code.IsTranslationZFixed)
                    {
                        kf[KeyFrameMode.TransXYZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.TransXYZ);
                    }
                }
                else
                {
                    if (code.IsTranslationXFixed)
                    {
                        kf[KeyFrameMode.TransX, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.TransX);
                    }

                    if (code.IsTranslationYFixed)
                    {
                        kf[KeyFrameMode.TransY, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.TransY);
                    }

                    if (code.IsTranslationZFixed)
                    {
                        kf[KeyFrameMode.TransZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint *)sPtr++, format, KeyFrameMode.TransZ);
                    }
                }
            }

            return(kf);
        }
Пример #32
0
        private static void DecodeCHR0Frames(KeyframeCollection kf, void *dataAddr, AnimDataFormat format, KeyFrameMode mode)
        {
            int   fCount;
            float vStep, vBase;

            switch (format)
            {
            case AnimDataFormat.I4:
            {
                I4Header *header = (I4Header *)dataAddr;
                fCount = header->_entries;
                vStep  = header->_step;
                vBase  = header->_base;

                I4Entry *entry = header->Data;
                for (int i = 0; i < fCount; i++, entry++)
                {
                    kf.SetFrameValue(mode, entry->FrameIndex, vBase + (entry->Step * vStep))._tangent = entry->Tangent;
                }
                break;
            }

            case AnimDataFormat.I6:
            {
                I6Header *header = (I6Header *)dataAddr;
                fCount = header->_numFrames;
                vStep  = header->_step;
                vBase  = header->_base;

                I6Entry *entry = header->Data;
                for (int i = 0; i < fCount; i++, entry++)
                {
                    kf.SetFrameValue(mode, entry->FrameIndex, vBase + (entry->_step * vStep))._tangent = entry->Tangent;
                }
                break;
            }

            case AnimDataFormat.I12:
            {
                I12Header *header = (I12Header *)dataAddr;
                fCount = header->_numFrames;

                I12Entry *entry = header->Data;
                for (int i = 0; i < fCount; i++, entry++)
                {
                    kf.SetFrameValue(mode, (int)entry->_index, entry->_value)._tangent = entry->_tangent;
                }
                break;
            }

            case AnimDataFormat.L1:
            {
                L1Header *header = (L1Header *)dataAddr;
                vStep = header->_step;
                vBase = header->_base;

                byte *sPtr = header->Data;
                for (int i = 0; i < kf.FrameCount; i++)
                {
                    kf[mode, i] = vBase + (*sPtr++ *vStep);
                }

                KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                {
                    entry.GenerateTangent();
                }

                break;
            }

            case AnimDataFormat.L2:
            {
                L1Header *header = (L1Header *)dataAddr;
                vStep = header->_step;
                vBase = header->_base;

                bushort *sPtr = (bushort *)header->Data;
                for (int i = 0; i < kf.FrameCount; i++)
                {
                    kf[mode, i] = vBase + (*sPtr++ *vStep);
                }

                KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                {
                    entry.GenerateTangent();
                }

                break;
            }

            case AnimDataFormat.L4:
            {
                bfloat *sPtr = (bfloat *)dataAddr;

                for (int i = 0; i < kf.FrameCount; i++)
                {
                    kf[mode, i] = *sPtr++;
                }

                KeyframeEntry root = kf._keyRoots[(int)mode & 0xF];
                for (KeyframeEntry entry = root._next; entry != root; entry = entry._next)
                {
                    entry.GenerateTangent();
                }

                break;
            }
            }
        }
        public static KeyframeCollection DecodeCHR0Keyframes(CHR0Entry* entry, int numFrames)
        {
            KeyframeCollection kf = new KeyframeCollection(numFrames);
            bfloat* sPtr = (bfloat*)entry->Data;
            AnimationCode code = entry->Code;
            AnimDataFormat format;

            if (code.HasScale)
            {
                format = code.ScaleDataFormat;
                if (code.IsScaleIsotropic)
                {
                    if (code.IsScaleZFixed)
                        kf[KeyFrameMode.ScaleXYZ, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.ScaleXYZ);
                }
                else
                {
                    if (code.IsScaleXFixed)
                        kf[KeyFrameMode.ScaleX, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.ScaleX);

                    if (code.IsScaleYFixed)
                        kf[KeyFrameMode.ScaleY, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.ScaleY);

                    if (code.IsScaleZFixed)
                        kf[KeyFrameMode.ScaleZ, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.ScaleZ);
                }
            }

            if (code.HasRotation)
            {
                format = code.RotationDataFormat;
                if (code.IsRotationIsotropic)
                {
                    if (code.IsRotationZFixed)
                        kf[KeyFrameMode.RotXYZ, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.RotXYZ);
                }
                else
                {
                    if (code.IsRotationXFixed)
                        kf[KeyFrameMode.RotX, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.RotX);

                    if (code.IsRotationYFixed)
                        kf[KeyFrameMode.RotY, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.RotY);

                    if (code.IsRotationZFixed)
                        kf[KeyFrameMode.RotZ, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.RotZ);
                }
            }

            if (code.HasTranslation)
            {
                format = code.TranslationDataFormat;
                if (code.IsTranslationIsotropic)
                {
                    if (code.IsTranslationZFixed)
                        kf[KeyFrameMode.TransXYZ, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.TransXYZ);
                }
                else
                {
                    if (code.IsTranslationXFixed)
                        kf[KeyFrameMode.TransX, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.TransX);

                    if (code.IsTranslationYFixed)
                        kf[KeyFrameMode.TransY, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.TransY);

                    if (code.IsTranslationZFixed)
                        kf[KeyFrameMode.TransZ, 0] = *sPtr++;
                    else
                        DecodeCHR0Frames(kf, (VoidPtr)entry + *(buint*)sPtr++, format, KeyFrameMode.TransZ);
                }
            }

            return kf;
        }
Пример #34
0
        public static KeyframeCollection DecodeSRT0Keyframes(SRT0TextureEntry *entry, int numFrames)
        {
            KeyframeCollection kf = new KeyframeCollection(5, numFrames, 1, 1);

            if (entry == null)
            {
                return(kf);
            }

            bfloat * sPtr = (bfloat *)entry->Data;
            SRT0Code code = entry->Code;

            if (!code.NoScale)
            {
                if (code.ScaleIsotropic)
                {
                    if (code.FixedScaleX)
                    {
                        kf[0, 0, 1] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 0, 1);
                    }
                }
                else
                {
                    if (code.FixedScaleX)
                    {
                        kf[0, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 0);
                    }

                    if (code.FixedScaleY)
                    {
                        kf[0, 1] = *sPtr++;
                    }
                    else
                    {
                        DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 1);
                    }
                }
            }

            if (!code.NoRotation)
            {
                if (code.FixedRotation)
                {
                    kf[0, 2] = *sPtr++;
                }
                else
                {
                    DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 2);
                }
            }

            if (!code.NoTranslation)
            {
                if (code.FixedX)
                {
                    kf[0, 3] = *sPtr++;
                }
                else
                {
                    DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 3);
                }

                if (code.FixedY)
                {
                    kf[0, 4] = *sPtr++;
                }
                else
                {
                    DecodeFrames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, AnimDataFormat.I12, 4);
                }
            }

            return(kf);
        }
Пример #35
0
        public static KeyframeCollection DecodeSRT0Keyframes(SRT0TextureEntry *entry, int numFrames)
        {
            KeyframeCollection kf   = new KeyframeCollection(numFrames);
            bfloat *           sPtr = (bfloat *)entry->Data;
            SRT0Code           code = entry->Code;

            if (!code.NoScale)
            {
                if (code.ScaleIsotropic)
                {
                    if (code.FixedScaleX)
                    {
                        kf[KeyFrameMode.ScaleXYZ, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.ScaleXYZ);
                    }
                }
                else
                {
                    if (code.FixedScaleX)
                    {
                        kf[KeyFrameMode.ScaleX, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.ScaleX);
                    }
                    if (code.FixedScaleY)
                    {
                        kf[KeyFrameMode.ScaleY, 0] = *sPtr++;
                    }
                    else
                    {
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.ScaleY);
                    }
                }
            }
            if (!code.NoRotation)
            {
                if (code.FixedRotation)
                {
                    kf[KeyFrameMode.RotX, 0] = *sPtr++;
                }
                else
                {
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.RotX);
                }
            }

            if (!code.NoTranslation)
            {
                if (code.FixedX)
                {
                    kf[KeyFrameMode.TransX, 0] = *sPtr++;
                }
                else
                {
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.TransX);
                }
                if (code.FixedY)
                {
                    kf[KeyFrameMode.TransY, 0] = *sPtr++;
                }
                else
                {
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint *)sPtr++, KeyFrameMode.TransY);
                }
            }

            return(kf);
        }
Пример #36
0
        public static void Serialize(CHR0Node node, string output, MDL0Node model)
        {
            model.Populate();
            using (StreamWriter file = new StreamWriter(output))
            {
                file.WriteLine("animVersion 1.1;");
                file.WriteLine("mayaVersion 2015;");
                file.WriteLine("timeUnit ntscf;");
                file.WriteLine("linearUnit cm;");
                file.WriteLine("angularUnit deg;");
                file.WriteLine("startTime 0;");
                file.WriteLine($"endTime {node.FrameCount - 1};");
                foreach (MDL0BoneNode b in model.AllBones)
                {
                    CHR0EntryNode e = node.FindChild(b.Name, true) as CHR0EntryNode;
                    if (e == null)
                    {
                        file.WriteLine($"anim {b.Name} 0 {b.Children.Count} 0;");
                        continue;
                    }

                    KeyframeCollection c = e.Keyframes;
                    int counter          = 0;
                    for (int index = 0; index < 9; index++)
                    {
                        KeyframeArray array = c._keyArrays[index];

                        if (array._keyCount <= 0)
                        {
                            continue;
                        }

                        file.WriteLine("anim {0}.{0}{1} {0}{1} {2} {3} {4} {5};", types[index / 3], axes[index % 3],
                                       e.Name, 0, b.Children.Count, counter);
                        file.WriteLine("animData {");
                        file.WriteLine("  input time;");
                        file.WriteLine($"  output {(index > 2 && index < 6 ? "angular" : "linear")};");
                        file.WriteLine("  weighted 1;");
                        file.WriteLine("  preInfinity constant;");
                        file.WriteLine("  postInfinity constant;");
                        file.WriteLine("  keys {");
                        for (KeyframeEntry entry = array._keyRoot._next; entry != array._keyRoot; entry = entry._next)
                        {
                            float angle = (float)Math.Atan(entry._tangent) * Maths._rad2degf;
                            file.WriteLine("    {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10};",
                                           entry._index,
                                           entry._value.ToString(CultureInfo.InvariantCulture.NumberFormat),
                                           "fixed",
                                           "fixed",
                                           "1",
                                           "1",
                                           "0",
                                           angle.ToString(CultureInfo.InvariantCulture.NumberFormat),
                                           "1",
                                           angle.ToString(CultureInfo.InvariantCulture.NumberFormat),
                                           "1");
                        }

                        file.WriteLine("  }");
                        file.WriteLine("}");
                        counter++;
                    }
                }
            }
        }
        public static KeyframeCollection DecodeSRT0Keyframes(SRT0TextureEntry* entry, int numFrames)
        {
            KeyframeCollection kf = new KeyframeCollection(numFrames);
            bfloat* sPtr = (bfloat*)entry->Data;
            SRT0Code code = entry->Code;

            if (!code.NoScale)
            {
                if (code.ScaleIsotropic)
                {
                    if (code.FixedScaleX)
                        kf[KeyFrameMode.ScaleXYZ, 0] = *sPtr++;
                    else
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint*)sPtr++, KeyFrameMode.ScaleXYZ);
                }
                else
                {
                    if (code.FixedScaleX)
                        kf[KeyFrameMode.ScaleX, 0] = *sPtr++;
                    else
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint*)sPtr++, KeyFrameMode.ScaleX);
                    if (code.FixedScaleY)
                        kf[KeyFrameMode.ScaleY, 0] = *sPtr++;
                    else
                        DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint*)sPtr++, KeyFrameMode.ScaleY);
                }
            }
            if (!code.NoRotation)
                if (code.FixedRotation)
                    kf[KeyFrameMode.RotX, 0] = *sPtr++;
                else
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint*)sPtr++, KeyFrameMode.RotX);

            if (!code.NoTranslation)
            {
                if (code.FixedX)
                    kf[KeyFrameMode.TransX, 0] = *sPtr++;
                else
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint*)sPtr++, KeyFrameMode.TransX);
                if (code.FixedY)
                    kf[KeyFrameMode.TransY, 0] = *sPtr++;
                else
                    DecodeSRT0Frames(kf, (VoidPtr)sPtr + *(buint*)sPtr++, KeyFrameMode.TransY);
            }

            return kf;
        }