예제 #1
0
        public static void AddRootMotion(ref Dictionary <UInt16, Dictionary <float, Vec3> > positions, ref Dictionary <UInt16, Dictionary <float, Quat> > rotations, animAnimation animAnimDes)
        {
            var          motionEx     = animAnimDes.MotionExtraction.GetReference().Data as animIMotionExtraction;
            var          duration     = animAnimDes.Duration.Value;
            var          numFrames    = 0;
            var          numPositions = 0;
            var          numRotations = 0;
            var          posTime      = new float[0];
            var          rotTime      = new float[0];
            var          rotBuffer    = new byte[0];
            var          posBuffer    = new byte[0];
            var          fps          = 0f;
            var          ft           = 0f;
            BinaryReader br;
            MemoryStream ms;

            switch (motionEx.REDType)
            {
            case "animLinearCompressedMotionExtraction":
            {
                var lc = motionEx as animLinearCompressedMotionExtraction;
                numPositions = lc.PosFrames.IsSerialized ? lc.PosFrames.Elements.Count : 0;
                numRotations = lc.RotFrames.IsSerialized ? lc.RotFrames.Elements.Count : 0;
                posTime      = lc.PosTime.IsSerialized ? lc.PosTime.Elements.Select(_ => _.Value).ToArray() : new float[numPositions];
                rotTime      = lc.RotTime.IsSerialized ? lc.RotTime.Elements.Select(_ => _.Value).ToArray() : new float[numRotations];

                if (numPositions > 0)
                {
                    if (!positions.ContainsKey(0))
                    {
                        positions.Add(0, new Dictionary <float, Vec3>());
                    }
                }
                if (numRotations > 0)
                {
                    if (!rotations.ContainsKey(0))
                    {
                        rotations.Add(0, new Dictionary <float, Quat>());
                    }
                }
                for (int i = 0; i < numPositions; i++)
                {
                    var v = lc.PosFrames[i];
                    positions[0].Add(posTime[i], new Vec3(v.X.Value, v.Z.Value, -v.Y.Value));
                }
                for (int i = 0; i < numRotations; i++)
                {
                    var q = lc.RotFrames[i];
                    rotations[0].Add(rotTime[i], new Quat(q.I.Value, q.K.Value, -q.J.Value, q.R.Value));
                }
                break;
            }

            case "animPlaneUncompressedMotionExtraction":
            {
                var pc = motionEx as animPlaneUncompressedMotionExtraction;
                duration     = pc.Duration.IsSerialized ? pc.Duration.Value : duration;
                numPositions = pc.Frames.IsSerialized ? pc.Frames.Elements.Count : 0;
                numFrames    = numPositions;
                fps          = (numFrames - 1f) / duration;
                ft           = 1f / fps;
                if (numPositions > 0)
                {
                    if (!positions.ContainsKey(0))
                    {
                        positions.Add(0, new Dictionary <float, Vec3>());
                    }
                }
                for (int i = 0; i < numFrames; i++)
                {
                    var v = pc.Frames.Elements[i];
                    positions[0].Add(ft * i, new Vec3(v.X.Value, v.Z.Value, -v.Y.Value));
                }
                break;
            }

            case "animSplineCompressedMotionExtraction":
            {
                var sc = motionEx as animSplineCompressedMotionExtraction;
                duration = sc.Duration.IsSerialized ? sc.Duration.Value : duration;

                #region rotations
                if (sc.RotKeysData.IsSerialized)
                {
                    rotBuffer    = sc.RotKeysData.Elements.Select(_ => _.Value).ToArray();
                    numRotations = rotBuffer.Length / 16;
                    if (numRotations > 0)
                    {
                        if (!rotations.ContainsKey(0))
                        {
                            rotations.Add(0, new Dictionary <float, Quat>());
                        }
                    }
                    using (ms = new MemoryStream(rotBuffer))
                        using (br = new BinaryReader(ms))
                        {
                            br.BaseStream.Seek(0, SeekOrigin.Begin);
                            for (int i = 0; i < numRotations; i++)
                            {
                                float  timeNormalized = br.ReadUInt16() / (float)UInt16.MaxValue;
                                UInt16 bitWiseData    = br.ReadUInt16();
                                UInt16 wSign          = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift);
                                UInt16 component      = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift);
                                UInt16 boneIdx        = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift);

                                float x = br.ReadSingle();
                                float y = br.ReadSingle();
                                float z = br.ReadSingle();

                                switch (component)
                                {
                                case 0:
                                    if (positions.ContainsKey(boneIdx))
                                    {
                                        positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y));
                                    }
                                    else
                                    {
                                        var dic = new Dictionary <float, Vec3>();
                                        dic.Add(timeNormalized * duration, new Vec3(x, z, -y));
                                        positions.Add(boneIdx, dic);
                                    }
                                    break;

                                case 1:
                                    float dotPr = (x * x + y * y + z * z);
                                    x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    float w = 1f - dotPr;
                                    if (wSign == 1)
                                    {
                                        w = -w;
                                    }
                                    Quat q = new Quat(x, z, -y, w);
                                    if (rotations.ContainsKey(boneIdx))
                                    {
                                        rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q));
                                    }
                                    else
                                    {
                                        var dic = new Dictionary <float, Quat>();
                                        dic.Add(timeNormalized * duration, Quat.Normalize(q));
                                        rotations.Add(boneIdx, dic);
                                    }
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                }
                #endregion
                if (sc.PosKeysData.IsSerialized)
                {
                    posBuffer    = sc.PosKeysData.Elements.Select(_ => _.Value).ToArray();
                    numPositions = posBuffer.Length / 16;
                    if (numPositions > 0)
                    {
                        if (!positions.ContainsKey(0))
                        {
                            positions.Add(0, new Dictionary <float, Vec3>());
                        }
                    }
                    using (ms = new MemoryStream(posBuffer))
                        using (br = new BinaryReader(ms))
                        {
                            br.BaseStream.Seek(0, SeekOrigin.Begin);
                            for (int i = 0; i < numPositions; i++)
                            {
                                float  timeNormalized = br.ReadUInt16() / (float)UInt16.MaxValue;
                                UInt16 bitWiseData    = br.ReadUInt16();
                                UInt16 wSign          = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift);
                                UInt16 component      = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift);
                                UInt16 boneIdx        = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift);

                                float x = br.ReadSingle();
                                float y = br.ReadSingle();
                                float z = br.ReadSingle();

                                switch (component)
                                {
                                case 0:
                                    if (positions.ContainsKey(boneIdx))
                                    {
                                        positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y));
                                    }
                                    else
                                    {
                                        var dic = new Dictionary <float, Vec3>();
                                        dic.Add(timeNormalized * duration, new Vec3(x, z, -y));
                                        positions.Add(boneIdx, dic);
                                    }
                                    break;

                                case 1:
                                    float dotPr = (x * x + y * y + z * z);
                                    x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    float w = 1f - dotPr;
                                    if (wSign == 1)
                                    {
                                        w = -w;
                                    }
                                    Quat q = new Quat(x, z, -y, w);
                                    if (rotations.ContainsKey(boneIdx))
                                    {
                                        rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q));
                                    }
                                    else
                                    {
                                        var dic = new Dictionary <float, Quat>();
                                        dic.Add(timeNormalized * duration, Quat.Normalize(q));
                                        rotations.Add(boneIdx, dic);
                                    }
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                }
                break;
            }

            case "animUncompressedAllAnglesMotionExtraction":
            {
                var aa = motionEx as animUncompressedAllAnglesMotionExtraction;
                duration  = aa.Duration.IsSerialized ? aa.Duration.Value : duration;
                numFrames = aa.Frames.IsSerialized ? aa.Frames.Elements.Count : 0;
                fps       = (numFrames - 1f) / duration;
                ft        = 1f / fps;
                if (numFrames > 0)
                {
                    if (!positions.ContainsKey(0))
                    {
                        positions.Add(0, new Dictionary <float, Vec3>());
                    }
                    if (!rotations.ContainsKey(0))
                    {
                        rotations.Add(0, new Dictionary <float, Quat>());
                    }
                }
                for (int i = 0; i < numFrames; i++)
                {
                    var v = aa.Frames.Elements[i].Position;
                    var q = aa.Frames.Elements[i].Orientation;
                    positions[0].Add(ft * i, new Vec3(v.X.Value, v.Z.Value, -v.Y.Value));
                    rotations[0].Add(ft * i, new Quat(q.I.Value, q.K.Value, -q.J.Value, q.R.Value));
                }
                break;
            }

            case "animUncompressedMotionExtraction":
            {
                var uc = motionEx as animUncompressedMotionExtraction;
                duration     = uc.Duration.IsSerialized ? uc.Duration.Value : duration;
                numFrames    = uc.Frames.IsSerialized ? uc.Frames.Elements.Count : 0;
                numPositions = numFrames;
                fps          = (numFrames - 1f) / duration;
                ft           = 1f / fps;
                if (numPositions > 0)
                {
                    if (!positions.ContainsKey(0))
                    {
                        positions.Add(0, new Dictionary <float, Vec3>());
                    }
                }
                for (int i = 0; i < numFrames; i++)
                {
                    var v = uc.Frames.Elements[i];
                    if (v.W.Value != 0f || v.W.Value != 1f)
                    {
                        throw new Exception("vec4 W unexpected value ???");
                    }
                    positions[0].Add(ft * i, new Vec3(v.X.Value, v.Z.Value, -v.Y.Value));
                }
                break;
            }

            default:
                break;
            }
        }
예제 #2
0
        public static void AddRootMotion(ref Dictionary <ushort, Dictionary <float, Vec3> > positions, ref Dictionary <ushort, Dictionary <float, Quat> > rotations, animAnimation animAnimDes)
        {
            var          motionEx     = animAnimDes.MotionExtraction.Chunk;
            var          duration     = animAnimDes.Duration;
            var          numFrames    = 0;
            var          numPositions = 0;
            var          numRotations = 0;
            var          posTime      = new float[0];
            var          rotTime      = new float[0];
            var          rotBuffer    = new byte[0];
            var          posBuffer    = new byte[0];
            var          fps          = 0f;
            var          ft           = 0f;
            BinaryReader br;
            MemoryStream ms;

            if (motionEx is animLinearCompressedMotionExtraction)
            {
                var lc = motionEx as animLinearCompressedMotionExtraction;
                numPositions = lc.PosFrames.Count;
                numRotations = lc.RotFrames.Count;
                posTime      = lc.PosTime.Cast <float>().ToArray();
                rotTime      = lc.RotTime.Cast <float>().ToArray();

                if (numPositions > 0)
                {
                    if (!positions.ContainsKey(0))
                    {
                        positions.Add(0, new Dictionary <float, Vec3>());
                    }
                }
                if (numRotations > 0)
                {
                    if (!rotations.ContainsKey(0))
                    {
                        rotations.Add(0, new Dictionary <float, Quat>());
                    }
                }
                for (var i = 0; i < numPositions; i++)
                {
                    var v = lc.PosFrames[i];
                    positions[0].Add(posTime[i], new Vec3(v.X, v.Z, -v.Y));
                }
                for (var i = 0; i < numRotations; i++)
                {
                    var q = lc.RotFrames[i];
                    rotations[0].Add(rotTime[i], new Quat(q.I, q.K, -q.J, q.R));
                }
            }
            else if (motionEx is animPlaneUncompressedMotionExtraction)
            {
                var pc = motionEx as animPlaneUncompressedMotionExtraction;
                duration     = pc.Duration;
                numPositions = pc.Frames.Count;
                numFrames    = numPositions;
                fps          = (numFrames - 1f) / duration;
                ft           = 1f / fps;
                if (numPositions > 0)
                {
                    if (!positions.ContainsKey(0))
                    {
                        positions.Add(0, new Dictionary <float, Vec3>());
                    }
                }
                for (var i = 0; i < numFrames; i++)
                {
                    var v = pc.Frames[i];
                    positions[0].Add(ft * i, new Vec3(v.X, v.Z, -v.Y));
                }
            }
            else if (motionEx is animSplineCompressedMotionExtraction)
            {
                var sc = motionEx as animSplineCompressedMotionExtraction;
                duration = sc.Duration;

                #region rotations
                if (sc.RotKeysData != null)
                {
                    rotBuffer    = sc.RotKeysData.Cast <byte>().ToArray();
                    numRotations = rotBuffer.Length / 16;
                    if (numRotations > 0)
                    {
                        if (!rotations.ContainsKey(0))
                        {
                            rotations.Add(0, new Dictionary <float, Quat>());
                        }
                    }
                    using (ms = new MemoryStream(rotBuffer))
                        using (br = new BinaryReader(ms))
                        {
                            br.BaseStream.Seek(0, SeekOrigin.Begin);
                            for (var i = 0; i < numRotations; i++)
                            {
                                var timeNormalized = br.ReadUInt16() / (float)ushort.MaxValue;
                                var bitWiseData    = br.ReadUInt16();
                                var wSign          = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift);
                                var component      = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift);
                                var boneIdx        = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift);

                                var x = br.ReadSingle();
                                var y = br.ReadSingle();
                                var z = br.ReadSingle();

                                switch (component)
                                {
                                case 0:
                                    if (positions.ContainsKey(boneIdx))
                                    {
                                        positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y));
                                    }
                                    else
                                    {
                                        var dic = new Dictionary <float, Vec3>
                                        {
                                            { timeNormalized *duration, new Vec3(x, z, -y) }
                                        };
                                        positions.Add(boneIdx, dic);
                                    }
                                    break;

                                case 1:
                                    var dotPr = (x * x + y * y + z * z);
                                    x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    var w = 1f - dotPr;
                                    if (wSign == 1)
                                    {
                                        w = -w;
                                    }

                                    var q = new Quat(x, z, -y, w);
                                    if (rotations.ContainsKey(boneIdx))
                                    {
                                        rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q));
                                    }
                                    else
                                    {
                                        var dic = new Dictionary <float, Quat>
                                        {
                                            { timeNormalized *duration, Quat.Normalize(q) }
                                        };
                                        rotations.Add(boneIdx, dic);
                                    }
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                }
                #endregion
                if (sc.PosKeysData != null)
                {
                    posBuffer    = sc.PosKeysData.Cast <byte>().ToArray();
                    numPositions = posBuffer.Length / 16;
                    if (numPositions > 0)
                    {
                        if (!positions.ContainsKey(0))
                        {
                            positions.Add(0, new Dictionary <float, Vec3>());
                        }
                    }
                    using (ms = new MemoryStream(posBuffer))
                        using (br = new BinaryReader(ms))
                        {
                            br.BaseStream.Seek(0, SeekOrigin.Begin);
                            for (var i = 0; i < numPositions; i++)
                            {
                                var timeNormalized = br.ReadUInt16() / (float)ushort.MaxValue;
                                var bitWiseData    = br.ReadUInt16();
                                var wSign          = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift);
                                var component      = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift);
                                var boneIdx        = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift);

                                var x = br.ReadSingle();
                                var y = br.ReadSingle();
                                var z = br.ReadSingle();

                                switch (component)
                                {
                                case 0:
                                    if (positions.ContainsKey(boneIdx))
                                    {
                                        positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y));
                                    }
                                    else
                                    {
                                        var dic = new Dictionary <float, Vec3>
                                        {
                                            { timeNormalized *duration, new Vec3(x, z, -y) }
                                        };
                                        positions.Add(boneIdx, dic);
                                    }
                                    break;

                                case 1:
                                    var dotPr = (x * x + y * y + z * z);
                                    x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                                    var w = 1f - dotPr;
                                    if (wSign == 1)
                                    {
                                        w = -w;
                                    }

                                    var q = new Quat(x, z, -y, w);
                                    if (rotations.ContainsKey(boneIdx))
                                    {
                                        rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q));
                                    }
                                    else
                                    {
                                        var dic = new Dictionary <float, Quat>
                                        {
                                            { timeNormalized *duration, Quat.Normalize(q) }
                                        };
                                        rotations.Add(boneIdx, dic);
                                    }
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                }
            }
            else if (motionEx is animUncompressedAllAnglesMotionExtraction)
            {
                var aa = motionEx as animUncompressedAllAnglesMotionExtraction;
                duration  = aa.Duration;
                numFrames = aa.Frames.Count;
                fps       = (numFrames - 1f) / duration;
                ft        = 1f / fps;
                if (numFrames > 0)
                {
                    if (!positions.ContainsKey(0))
                    {
                        positions.Add(0, new Dictionary <float, Vec3>());
                    }
                    if (!rotations.ContainsKey(0))
                    {
                        rotations.Add(0, new Dictionary <float, Quat>());
                    }
                }
                for (var i = 0; i < numFrames; i++)
                {
                    var v = aa.Frames[i].Position;
                    var q = aa.Frames[i].Orientation;
                    positions[0].Add(ft * i, new Vec3(v.X, v.Z, -v.Y));
                    rotations[0].Add(ft * i, new Quat(q.I, q.K, -q.J, q.R));
                }
            }
            else if (motionEx is animUncompressedMotionExtraction)
            {
                var uc = motionEx as animUncompressedMotionExtraction;
                duration     = uc.Duration;
                numFrames    = uc.Frames.Count;
                numPositions = numFrames;
                fps          = (numFrames - 1f) / duration;
                ft           = 1f / fps;
                if (numPositions > 0)
                {
                    if (!positions.ContainsKey(0))
                    {
                        positions.Add(0, new Dictionary <float, Vec3>());
                    }
                }
                for (var i = 0; i < numFrames; i++)
                {
                    var v = uc.Frames[i];
                    if (v.W != 0f || v.W != 1f)
                    {
                        throw new Exception("vec4 W unexpected value ???");
                    }
                    positions[0].Add(ft * i, new Vec3(v.X, v.Z, -v.Y));
                }
            }
        }
예제 #3
0
        public static void AddAnimationSpline(ref ModelRoot model, animAnimationBufferCompressed blob, string animName, Stream defferedBuffer, animAnimation animAnimDes)
        {
            //boneidx time value
            var positions = new Dictionary <ushort, Dictionary <float, Vec3> >();
            var rotations = new Dictionary <ushort, Dictionary <float, Quat> >();
            var scales    = new Dictionary <ushort, Dictionary <float, Vec3> >();

            var tracks = new Dictionary <ushort, float>();

            if (animAnimDes.MotionExtraction.Chunk != null)
            {
                ROOT_MOTION.AddRootMotion(ref positions, ref rotations, animAnimDes);
            }

            var   br                = new BinaryReader(defferedBuffer);
            float duration          = blob.Duration;
            uint  numFrames         = blob.NumFrames;
            uint  numJoints         = blob.NumJoints;
            uint  numTracks         = blob.NumTracks;
            uint  numExtraJoints    = blob.NumExtraJoints;
            uint  numAnimKeys       = blob.NumAnimKeys;
            uint  numAnimKeysRaw    = blob.NumAnimKeysRaw;
            uint  NumConstAnimKeys  = blob.NumConstAnimKeys;
            uint  numConstTrackKeys = blob.NumConstTrackKeys;

            defferedBuffer.Seek(0, SeekOrigin.Begin);
            for (uint i = 0; i < numAnimKeys; i++)
            {
                var timeNormalized = br.ReadUInt16() / (float)ushort.MaxValue;
                var bitWiseData    = br.ReadUInt16();
                var wSign          = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift);
                var component      = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift);
                var boneIdx        = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift);

                var x = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f;
                var y = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f;
                var z = ((1f / 65535f) * br.ReadUInt16() * 2) - 1f;

                switch (component)
                {
                case 0:
                    if (positions.ContainsKey(boneIdx))
                    {
                        positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Vec3>
                        {
                            { timeNormalized *duration, new Vec3(x, z, -y) }
                        };
                        positions.Add(boneIdx, dic);
                    }
                    break;

                case 1:
                    var dotPr = (x * x + y * y + z * z);
                    x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    var w = 1f - dotPr;
                    if (wSign == 1)
                    {
                        w = -w;
                    }

                    var q = new Quat(x, z, -y, w);
                    if (rotations.ContainsKey(boneIdx))
                    {
                        rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Quat>
                        {
                            { timeNormalized *duration, Quat.Normalize(q) }
                        };
                        rotations.Add(boneIdx, dic);
                    }
                    break;

                case 2:
                    if (scales.ContainsKey(boneIdx))
                    {
                        scales[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Vec3>
                        {
                            { timeNormalized *duration, new Vec3(x, z, -y) }
                        };
                        scales.Add(boneIdx, dic);
                    }
                    break;

                default:
                    break;
                }
            }
            for (uint i = 0; i < numAnimKeysRaw; i++)
            {
                var timeNormalized = br.ReadUInt16() / (float)ushort.MaxValue;
                var bitWiseData    = br.ReadUInt16();
                var wSign          = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift);
                var component      = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift);
                var boneIdx        = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift);

                var x = br.ReadSingle();
                var y = br.ReadSingle();
                var z = br.ReadSingle();

                switch (component)
                {
                case 0:
                    if (positions.ContainsKey(boneIdx))
                    {
                        positions[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Vec3>
                        {
                            { timeNormalized *duration, new Vec3(x, z, -y) }
                        };
                        positions.Add(boneIdx, dic);
                    }
                    break;

                case 1:
                    var dotPr = (x * x + y * y + z * z);
                    x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    var w = 1f - dotPr;
                    if (wSign == 1)
                    {
                        w = -w;
                    }

                    var q = new Quat(x, z, -y, w);
                    if (rotations.ContainsKey(boneIdx))
                    {
                        rotations[boneIdx].Add(timeNormalized * duration, Quat.Normalize(q));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Quat>
                        {
                            { timeNormalized *duration, Quat.Normalize(q) }
                        };
                        rotations.Add(boneIdx, dic);
                    }
                    break;

                case 2:
                    if (scales.ContainsKey(boneIdx))
                    {
                        scales[boneIdx].Add(timeNormalized * duration, new Vec3(x, z, -y));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Vec3>
                        {
                            { timeNormalized *duration, new Vec3(x, z, -y) }
                        };
                        scales.Add(boneIdx, dic);
                    }
                    break;

                default:
                    break;
                }
            }

            for (uint i = 0; i < NumConstAnimKeys; i++)
            {
                var bitWiseData    = br.ReadUInt16();
                var timeNormalized = br.ReadUInt16() / (float)ushort.MaxValue; // is it some time normalized or some padding garbage data i have no idea
                var wSign          = Convert.ToUInt16((bitWiseData & wSignMask) >> wSignRightShift);
                var component      = Convert.ToUInt16((bitWiseData & componentTypeMask) >> componentRightShift);
                var boneIdx        = Convert.ToUInt16((bitWiseData & boneIdxMask) >> boneIdxRightShift);

                var x = br.ReadSingle();
                var y = br.ReadSingle();
                var z = br.ReadSingle();

                switch (component)
                {
                case 0:
                    if (positions.ContainsKey(boneIdx))
                    {
                        positions[boneIdx].Add(0f, new Vec3(x, z, -y));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Vec3>
                        {
                            { 0f, new Vec3(x, z, -y) }
                        };
                        positions.Add(boneIdx, dic);
                    }
                    break;

                case 1:
                    var dotPr = (x * x + y * y + z * z);
                    x = x * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    y = y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    z = z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                    var w = 1f - dotPr;
                    if (wSign == 1)
                    {
                        w = -w;
                    }

                    var q = new Quat(x, z, -y, w);
                    if (rotations.ContainsKey(boneIdx))
                    {
                        rotations[boneIdx].Add(0f, Quat.Normalize(q));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Quat>
                        {
                            { 0f, Quat.Normalize(q) }
                        };
                        rotations.Add(boneIdx, dic);
                    }
                    break;

                case 2:
                    if (scales.ContainsKey(boneIdx))
                    {
                        scales[boneIdx].Add(0f, new Vec3(x, z, -y));
                    }
                    else
                    {
                        var dic = new Dictionary <float, Vec3>
                        {
                            { 0f, new Vec3(x, z, -y) }
                        };
                        scales.Add(boneIdx, dic);
                    }
                    break;

                default:
                    break;
                }
            }

            /*
             * for (UInt32 i = 0; i < numConstTrackKeys; i++)
             * {
             *  UInt16 idx = br.ReadUInt16();
             *  br.ReadUInt16(); //is it time or some garbage idk
             *  float value = br.ReadSingle();
             * }
             */
            var anim = model.CreateAnimation(animName);

            for (ushort i = 0; i < numJoints - numExtraJoints; i++)
            {
                if (positions.ContainsKey(i))
                {
                    anim.CreateTranslationChannel(model.LogicalNodes[i], positions[i]);
                }
                if (rotations.ContainsKey(i))
                {
                    anim.CreateRotationChannel(model.LogicalNodes[i], rotations[i]);
                }
                if (scales.ContainsKey(i))
                {
                    anim.CreateScaleChannel(model.LogicalNodes[i], scales[i]);
                }
            }
        }
예제 #4
0
        public static void AddAnimationSIMD(ref ModelRoot model, animAnimationBufferSimd blob, string animName, Stream defferedBuffer, animAnimation animAnimDes)
        {
            var rootPositions = new Dictionary <ushort, Dictionary <float, Vec3> >();
            var rootRotations = new Dictionary <ushort, Dictionary <float, Quat> >();
            var hasRootMotion = animAnimDes.MotionExtraction.Chunk is not null;

            if (hasRootMotion)
            {
                ROOT_MOTION.AddRootMotion(ref rootPositions, ref rootRotations, animAnimDes);
            }
            var br = new BinaryReader(defferedBuffer);

            var jointsCountAligned    = (blob.NumJoints + 3U) & (~3U);                          // simd 4 alignment
            var totalFloatCount       = (blob.NumFrames * jointsCountAligned * 3 + 3U) & (~3U); // simd 4 alignment
            var rotCompressedBuffSize = totalFloatCount * blob.QuantizationBits / 8U;

            rotCompressedBuffSize = (rotCompressedBuffSize + 15U) & (~15U); // 16byte padding aligment
            var mask = (1U << blob.QuantizationBits) - 1U;

            var floatsPacked = new ushort[totalFloatCount];

            for (uint i = 0; i < totalFloatCount; i++)
            {
                var bitOff  = i * blob.QuantizationBits;
                var byteOff = bitOff / 8;
                var shift   = (bitOff % 8);
                defferedBuffer.Position = byteOff;
                var val = br.ReadUInt32();
                val             = val >> (int)shift;
                floatsPacked[i] = Convert.ToUInt16(val & mask);
            }
            var floatsDecompressed = new float[totalFloatCount];

            for (uint i = 0; i < totalFloatCount; i++)
            {
                floatsDecompressed[i] = ((1f / mask) * floatsPacked[i] * 2) - 1f;
            }
            var Rotations = new Quat[blob.NumFrames, blob.NumJoints];

            for (uint i = 0; i < blob.NumFrames; i++)
            {
                for (uint e = 0; e < blob.NumJoints; e += 4)
                {
                    for (uint eye = 0; eye < 4; eye++)
                    {
                        var q = new Quat
                        {
                            X = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + eye],
                            Y = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + 4 + eye],
                            Z = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + 8 + eye]
                        };

                        var dotPr = (q.X * q.X + q.Y * q.Y + q.Z * q.Z);
                        q.X = q.X * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                        q.Y = q.Y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                        q.Z = q.Z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                        q.W = 1f - dotPr;
                        q   = Quat.Normalize(q);
                        if (e + eye < blob.NumJoints)
                        {
                            Rotations[i, e + eye] = new Quat(q.X, q.Z, -q.Y, q.W);
                        }
                    }
                }
            }
            var EvalAlignedPositions = new float[blob.NumFrames * blob.NumTranslationsToEvalAlignedToSimd * 3];

            defferedBuffer.Position = rotCompressedBuffSize;
            for (uint i = 0; i < blob.NumFrames * blob.NumTranslationsToEvalAlignedToSimd * 3; i++)
            {
                EvalAlignedPositions[i] = br.ReadSingle();
            }
            var Scales = new Vec3[blob.NumFrames, blob.NumJoints];

            if (blob.IsScaleConstant)
            {
                var scalesRaw = new float[4];
                for (uint i = 0; i < 4; i++)
                {
                    scalesRaw[i] = br.ReadSingle();
                }
                for (uint i = 0; i < blob.NumFrames; i++)
                {
                    for (uint e = 0; e < blob.NumJoints; e++)
                    {
                        var v = new Vec3
                        {
                            X = scalesRaw[0],
                            Y = scalesRaw[1],
                            Z = scalesRaw[2]
                        };
                        Scales[i, e] = v;
                    }
                }
            }
            else
            {
                var scalesRaw = new float[blob.NumFrames * jointsCountAligned * 3];
                for (uint i = 0; i < blob.NumFrames * jointsCountAligned * 3; i++)
                {
                    scalesRaw[i] = br.ReadSingle();
                }
                for (uint i = 0; i < blob.NumFrames; i++)
                {
                    for (uint e = 0; e < blob.NumJoints; e += 4)
                    {
                        for (uint eye = 0; eye < 4; eye++)
                        {
                            var v = new Vec3
                            {
                                X = scalesRaw[i * jointsCountAligned * 3 + e * 3 + eye],
                                Y = scalesRaw[i * jointsCountAligned * 3 + e * 3 + 4 + eye],
                                Z = scalesRaw[i * jointsCountAligned * 3 + e * 3 + 8 + eye]
                            };
                            Scales[i, e + eye] = v;
                        }
                    }
                }
            }
            if (blob.NumTracks > 0)
            {
                if (!blob.IsTrackConstant)
                {
                    uint asas = ((blob.NumTracks + 3U) & (~3U)) * blob.NumFrames * 4;
                    defferedBuffer.Seek(asas, SeekOrigin.Current);
                }
                else
                {
                    defferedBuffer.Seek(4, SeekOrigin.Current);
                }
            }

            var positionToCopy = new Vec3[blob.NumTranslationsToCopy];

            for (uint e = 0; e < blob.NumTranslationsToCopy; e++)
            {
                positionToCopy[e].X = br.ReadSingle();
                positionToCopy[e].Y = br.ReadSingle();
                positionToCopy[e].Z = br.ReadSingle();
            }

            var evalIndices = new short[blob.NumTranslationsToEvalAlignedToSimd];
            var copyIndices = new short[blob.NumTranslationsToCopy];

            for (uint e = 0; e < blob.NumTranslationsToCopy; e++)
            {
                copyIndices[e] = br.ReadInt16();
            }

            for (uint e = 0; e < blob.NumTranslationsToEvalAlignedToSimd; e++)
            {
                evalIndices[e] = br.ReadInt16();
            }

            var Positions = new Vec3[blob.NumFrames, blob.NumJoints];

            for (uint i = 0; i < blob.NumFrames; i++)
            {
                for (uint e = 0; e < blob.NumTranslationsToEvalAlignedToSimd; e += 4)
                {
                    for (uint eye = 0; eye < 4; eye++)
                    {
                        var v = new Vec3
                        {
                            X = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd * 3 + e * 3 + eye],
                            Y = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd * 3 + e * 3 + 4 + eye],
                            Z = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd * 3 + e * 3 + 8 + eye]
                        };

                        if (evalIndices[e + eye] > -1)
                        {
                            Positions[i, evalIndices[e + eye]] = new Vec3(v.X, v.Z, -v.Y);
                        }
                    }
                }
                for (uint e = 0; e < copyIndices.Length; e++)
                {
                    var v = new Vec3
                    {
                        X = positionToCopy[e].X,
                        Y = positionToCopy[e].Y,
                        Z = positionToCopy[e].Z
                    };

                    Positions[i, copyIndices[e]] = new Vec3(v.X, v.Z, -v.Y);
                }
            }
            var a = model.CreateAnimation(animName);

            for (var e = 0; e < blob.NumJoints - blob.NumExtraJoints; e++)
            {
                var pos  = new Dictionary <float, Vec3>();
                var rot  = new Dictionary <float, Quat>();
                var sca  = new Dictionary <float, Vec3>();
                var diff = blob.Duration / (blob.NumFrames - 1);
                for (var i = 0; i < blob.NumFrames; i++)
                {
                    pos.Add(i * diff, Positions[i, e]);
                    rot.Add(i * diff, Rotations[i, e]);
                    sca.Add(i * diff, Scales[i, e]);
                }
                a.CreateRotationChannel(model.LogicalNodes[e], rot);
                a.CreateTranslationChannel(model.LogicalNodes[e], pos);
                a.CreateScaleChannel(model.LogicalNodes[e], sca);
            }
        }
예제 #5
0
        public static void AddAnimationSIMD(ref ModelRoot model, animAnimationBufferSimd blob, string animName, Stream defferedBuffer, animAnimation animAnimDes)
        {
            Dictionary <UInt16, Dictionary <float, Vec3> > rootPositions = new Dictionary <ushort, Dictionary <float, Vec3> >();
            Dictionary <UInt16, Dictionary <float, Quat> > rootRotations = new Dictionary <ushort, Dictionary <float, Quat> >();
            bool hasRootMotion = animAnimDes.MotionExtraction.IsSerialized;

            if (hasRootMotion)
            {
                ROOT_MOTION.AddRootMotion(ref rootPositions, ref rootRotations, animAnimDes);
            }
            BinaryReader br = new BinaryReader(defferedBuffer);

            UInt32 jointsCountAligned    = (blob.NumJoints.Value + 3U) & (~3U);                          // simd 4 alignment
            UInt32 totalFloatCount       = (blob.NumFrames.Value * jointsCountAligned * 3 + 3U) & (~3U); // simd 4 alignment
            UInt32 rotCompressedBuffSize = totalFloatCount * blob.QuantizationBits.Value / 8U;

            rotCompressedBuffSize = (rotCompressedBuffSize + 15U) & (~15U); // 16byte padding aligment
            UInt32 mask = (1U << blob.QuantizationBits.Value) - 1U;

            UInt16[] floatsPacked = new UInt16[totalFloatCount];
            for (UInt32 i = 0; i < totalFloatCount; i++)
            {
                UInt32 bitOff  = i * blob.QuantizationBits.Value;
                UInt32 byteOff = bitOff / 8;
                UInt32 shift   = (bitOff % 8);
                defferedBuffer.Position = byteOff;
                UInt32 val = br.ReadUInt32();
                val             = val >> (int)shift;
                floatsPacked[i] = Convert.ToUInt16(val & mask);
            }
            float[] floatsDecompressed = new float[totalFloatCount];
            for (UInt32 i = 0; i < totalFloatCount; i++)
            {
                floatsDecompressed[i] = ((1f / mask) * floatsPacked[i] * 2) - 1f;
            }
            Quat[,] Rotations = new Quat[blob.NumFrames.Value, blob.NumJoints.Value];
            for (UInt32 i = 0; i < blob.NumFrames.Value; i++)
            {
                for (UInt32 e = 0; e < blob.NumJoints.Value; e += 4)
                {
                    for (UInt32 eye = 0; eye < 4; eye++)
                    {
                        Quat q = new Quat();
                        q.X = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + eye];
                        q.Y = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + 4 + eye];
                        q.Z = floatsDecompressed[i * jointsCountAligned * 3 + e * 3 + 8 + eye];

                        float dotPr = (q.X * q.X + q.Y * q.Y + q.Z * q.Z);
                        q.X = q.X * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                        q.Y = q.Y * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                        q.Z = q.Z * Convert.ToSingle(Math.Sqrt(2f - dotPr));
                        q.W = 1f - dotPr;
                        q   = Quat.Normalize(q);
                        if (e + eye < blob.NumJoints.Value)
                        {
                            Rotations[i, e + eye] = new Quat(q.X, q.Z, -q.Y, q.W);
                        }
                    }
                }
            }
            float[] EvalAlignedPositions = new float[blob.NumFrames.Value * blob.NumTranslationsToEvalAlignedToSimd.Value * 3];
            defferedBuffer.Position = rotCompressedBuffSize;
            for (UInt32 i = 0; i < blob.NumFrames.Value * blob.NumTranslationsToEvalAlignedToSimd.Value * 3; i++)
            {
                EvalAlignedPositions[i] = br.ReadSingle();
            }
            Vec3[,] Scales = new Vec3[blob.NumFrames.Value, blob.NumJoints.Value];
            if (blob.IsScaleConstant.Value)
            {
                float[] scalesRaw = new float[4];
                for (UInt32 i = 0; i < 4; i++)
                {
                    scalesRaw[i] = br.ReadSingle();
                }
                for (UInt32 i = 0; i < blob.NumFrames.Value; i++)
                {
                    for (UInt32 e = 0; e < blob.NumJoints.Value; e++)
                    {
                        Vec3 v = new Vec3();
                        v.X          = scalesRaw[0];
                        v.Y          = scalesRaw[1];
                        v.Z          = scalesRaw[2];
                        Scales[i, e] = v;
                    }
                }
            }
            else
            {
                float[] scalesRaw = new float[blob.NumFrames.Value * jointsCountAligned * 3];
                for (UInt32 i = 0; i < blob.NumFrames.Value * jointsCountAligned * 3; i++)
                {
                    scalesRaw[i] = br.ReadSingle();
                }
                for (UInt32 i = 0; i < blob.NumFrames.Value; i++)
                {
                    for (UInt32 e = 0; e < blob.NumJoints.Value; e += 4)
                    {
                        for (UInt32 eye = 0; eye < 4; eye++)
                        {
                            Vec3 v = new Vec3();
                            v.X = scalesRaw[i * jointsCountAligned * 3 + e * 3 + eye];
                            v.Y = scalesRaw[i * jointsCountAligned * 3 + e * 3 + 4 + eye];
                            v.Z = scalesRaw[i * jointsCountAligned * 3 + e * 3 + 8 + eye];
                            Scales[i, e + eye] = v;
                        }
                    }
                }
            }
            if (blob.NumTracks.Value > 0)
            {
                if (!blob.IsTrackConstant.Value)
                {
                    UInt32 asas = ((blob.NumTracks.Value + 3U) & (~3U)) * blob.NumFrames.Value * 4;
                    defferedBuffer.Seek(asas, SeekOrigin.Current);
                }
                else
                {
                    defferedBuffer.Seek(4, SeekOrigin.Current);
                }
            }

            Vec3[] positionToCopy = new Vec3[blob.NumTranslationsToCopy.Value];
            for (UInt32 e = 0; e < blob.NumTranslationsToCopy.Value; e++)
            {
                positionToCopy[e].X = br.ReadSingle();
                positionToCopy[e].Y = br.ReadSingle();
                positionToCopy[e].Z = br.ReadSingle();
            }

            Int16[] evalIndices = new Int16[blob.NumTranslationsToEvalAlignedToSimd.Value];
            Int16[] copyIndices = new Int16[blob.NumTranslationsToCopy.Value];
            for (UInt32 e = 0; e < blob.NumTranslationsToCopy.Value; e++)
            {
                copyIndices[e] = br.ReadInt16();
            }
            for (UInt32 e = 0; e < blob.NumTranslationsToEvalAlignedToSimd.Value; e++)
            {
                evalIndices[e] = br.ReadInt16();
            }

            Vec3[,] Positions = new Vec3[blob.NumFrames.Value, blob.NumJoints.Value];
            for (UInt32 i = 0; i < blob.NumFrames.Value; i++)
            {
                for (UInt32 e = 0; e < blob.NumTranslationsToEvalAlignedToSimd.Value; e += 4)
                {
                    for (UInt32 eye = 0; eye < 4; eye++)
                    {
                        Vec3 v = new Vec3();
                        v.X = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd.Value * 3 + e * 3 + eye];
                        v.Y = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd.Value * 3 + e * 3 + 4 + eye];
                        v.Z = EvalAlignedPositions[i * blob.NumTranslationsToEvalAlignedToSimd.Value * 3 + e * 3 + 8 + eye];

                        if (evalIndices[e + eye] > -1)
                        {
                            Positions[i, evalIndices[e + eye]] = new Vec3(v.X, v.Z, -v.Y);
                        }
                    }
                }
                for (UInt32 e = 0; e < copyIndices.Length; e++)
                {
                    Vec3 v = new Vec3();
                    v.X = positionToCopy[e].X;
                    v.Y = positionToCopy[e].Y;
                    v.Z = positionToCopy[e].Z;

                    Positions[i, copyIndices[e]] = new Vec3(v.X, v.Z, -v.Y);
                }
            }
            var a = model.CreateAnimation(animName);

            for (int e = 0; e < blob.NumJoints.Value - blob.NumExtraJoints.Value; e++)
            {
                var   pos  = new Dictionary <float, Vec3>();
                var   rot  = new Dictionary <float, Quat>();
                var   sca  = new Dictionary <float, Vec3>();
                float diff = blob.Duration.Value / (blob.NumFrames.Value - 1);
                for (int i = 0; i < blob.NumFrames.Value; i++)
                {
                    pos.Add(i * diff, Positions[i, e]);
                    rot.Add(i * diff, Rotations[i, e]);
                    sca.Add(i * diff, Scales[i, e]);
                }
                a.CreateRotationChannel(model.LogicalNodes[e], rot);
                a.CreateTranslationChannel(model.LogicalNodes[e], pos);
                a.CreateScaleChannel(model.LogicalNodes[e], sca);
            }
        }