コード例 #1
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);
            }
        }
コード例 #2
0
ファイル: AnimSIMD.cs プロジェクト: HitmanHimself/WolvenKit
        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);
            }
        }