Exemplo n.º 1
0
        public static List <AnimationKey> GetBoneKeyFrames(Bone bone, FBXFile file)
        {
            var result = new List <AnimationKey>();

            var curveNodes = FBX.FBXHelper.GetAnimationCurveNodes(file, bone);

            // get curves for the curve nodes of the bone
            foreach (var curveNode in curveNodes)
            {
                var curves = file.GetAnimationCurves(curveNode);

                foreach (var curve in curves)
                {
                    // the connection defines the axis being affected
                    var axis = file.GetConnectionType(curve.Id, curveNode.Id);

                    if (axis.Contains("X"))
                    {
                        axis = "x";
                    }
                    if (axis.Contains("Y"))
                    {
                        axis = "y";
                    }
                    if (axis.Contains("Z"))
                    {
                        axis = "z";
                    }

                    curveNode.Curves.Add(axis, curve);
                }
            }

            // convert curves to animation keys
            var keys   = curveNodes.SelectMany(c => c.Curves.SelectMany(b => b.Value.KeyTime)).Distinct().OrderBy(a => a).ToArray();
            int frames = keys.Length;

            for (int i = 0; i < keys.Length; i++)
            {
                var animKey = new AnimationKey()
                {
                    Frame     = i,
                    Transform = bone.JointMatrix
                };

                // Translation
                var curveNode = curveNodes.Where(a => a.Name.Contains("T")).FirstOrDefault();

                if (curveNode != null)
                {
                    // check if the curve has a value for that frame first
                    var framePos = curveNode.Curves["x"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var x        = (framePos > -1) ? curveNode.Curves["x"].KeyValueFloat[framePos] : animKey.Translation[0];

                    framePos = curveNode.Curves["y"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var y = (framePos > -1) ? curveNode.Curves["y"].KeyValueFloat[framePos] : animKey.Translation[1];

                    framePos = curveNode.Curves["z"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var z = (framePos > -1) ? curveNode.Curves["z"].KeyValueFloat[framePos] : animKey.Translation[2];

                    animKey.Translation = new float[] { x, y, z };
                }

                // Rotation
                curveNode = curveNodes.Where(a => a.Name.Contains("R")).FirstOrDefault();

                if (curveNode != null)
                {
                    // check if the curve has a value for that frame first
                    var framePos = curveNode.Curves["x"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var x        = (framePos > -1) ? curveNode.Curves["x"].KeyValueFloat[framePos] : 0F;

                    framePos = curveNode.Curves["y"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var y = (framePos > -1) ? curveNode.Curves["y"].KeyValueFloat[framePos] : 0f;

                    framePos = curveNode.Curves["z"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var z = (framePos > -1) ? curveNode.Curves["z"].KeyValueFloat[framePos] : 0f;

                    animKey.Rotation = new float[] { x.ToRadians(), y.ToRadians(), z.ToRadians() }.QuaternionFromEuler(EulerOrder.XYZ);
                }

                // Scale
                curveNode = curveNodes.Where(a => a.Name.Contains("S")).FirstOrDefault();

                if (curveNode != null)
                {
                    // check if the curve has a value for that frame first
                    var framePos = curveNode.Curves["x"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var x        = (framePos > -1) ? curveNode.Curves["x"].KeyValueFloat[framePos] : 0f;

                    framePos = curveNode.Curves["y"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var y = (framePos > -1) ? curveNode.Curves["y"].KeyValueFloat[framePos] : 0f;

                    framePos = curveNode.Curves["z"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                    var z = (framePos > -1) ? curveNode.Curves["z"].KeyValueFloat[framePos] : 0f;

                    animKey.Scale = new float[] { x, y, z };
                }

                // add the animation key to the list
                result.Add(animKey);
            }

            return(result);
        }
Exemplo n.º 2
0
        public Animator(FBXFile file)
        {
            var bones = Bone.GetBoneHierarchy(file);

            var boneCurveNodes = new SortedList <string, List <CoreFBX.FBX.Animation.FBXAnimCurveNode> >();

            AnimationKeys = new Dictionary <string, List <AnimationKey> >();
            PoseKeys      = new Dictionary <string, AnimationKey>();

            foreach (var bone in bones)
            {
                AnimationKeys.Add(bone.Id, new List <AnimationKey>());
                var curveNodes = FBX.FBXHelper.GetAnimationCurveNodes(file, bone);

                // get curves for the curve nodes of the bone
                foreach (var curveNode in curveNodes)
                {
                    var curves = file.GetAnimationCurves(curveNode);

                    foreach (var curve in curves)
                    {
                        // the connection defines the axis being affected
                        var axis = file.GetConnectionType(curve.Id, curveNode.Id);

                        if (axis.Contains("X"))
                        {
                            axis = "x";
                        }
                        if (axis.Contains("Y"))
                        {
                            axis = "y";
                        }
                        if (axis.Contains("Z"))
                        {
                            axis = "z";
                        }

                        curveNode.Curves.Add(axis, curve);
                    }
                }

                boneCurveNodes.Add(bone.Id, curveNodes);
            }

            // convert curves to animation keys
            var keys = boneCurveNodes.SelectMany(a => a.Value.SelectMany(c => c.Curves.SelectMany(b => b.Value.KeyTime))).Distinct().OrderBy(a => a).ToArray();

            Frames = keys.Length;

            for (int i = 0; i < keys.Length; i++)
            {
                foreach (var bone in bones)
                {
                    var animKey = new AnimationKey()
                    {
                        Frame     = i,
                        Transform = bone.JointMatrix
                    };

                    // Translation
                    var curveNode = boneCurveNodes[bone.Id].Where(a => a.Name.Contains("T")).FirstOrDefault();

                    if (curveNode != null)
                    {
                        // check if the curve has a value for that frame first
                        var framePos = curveNode.Curves["x"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var x        = (framePos > -1) ? curveNode.Curves["x"].KeyValueFloat[framePos] : animKey.Translation[0];

                        framePos = curveNode.Curves["y"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var y = (framePos > -1) ? curveNode.Curves["y"].KeyValueFloat[framePos] : animKey.Translation[1];

                        framePos = curveNode.Curves["z"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var z = (framePos > -1) ? curveNode.Curves["z"].KeyValueFloat[framePos] : animKey.Translation[2];

                        animKey.Translation = new float[] { x, y, z };
                    }

                    // Rotation
                    curveNode = boneCurveNodes[bone.Id].Where(a => a.Name.Contains("R")).FirstOrDefault();

                    if (curveNode != null)
                    {
                        // check if the curve has a value for that frame first
                        var framePos = curveNode.Curves["x"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var x        = (framePos > -1) ? curveNode.Curves["x"].KeyValueFloat[framePos] : 0F;

                        framePos = curveNode.Curves["y"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var y = (framePos > -1) ? curveNode.Curves["y"].KeyValueFloat[framePos] : 0f;

                        framePos = curveNode.Curves["z"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var z = (framePos > -1) ? curveNode.Curves["z"].KeyValueFloat[framePos] : 0f;

                        animKey.Rotation = new float[] { x.ToRadians(), y.ToRadians(), z.ToRadians() }.QuaternionFromEuler(EulerOrder.XYZ);
                    }

                    // Scale
                    curveNode = boneCurveNodes[bone.Id].Where(a => a.Name.Contains("S")).FirstOrDefault();

                    if (curveNode != null)
                    {
                        // check if the curve has a value for that frame first
                        var framePos = curveNode.Curves["x"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var x        = (framePos > -1) ? curveNode.Curves["x"].KeyValueFloat[framePos] : 0f;

                        framePos = curveNode.Curves["y"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var y = (framePos > -1) ? curveNode.Curves["y"].KeyValueFloat[framePos] : 0f;

                        framePos = curveNode.Curves["z"].KeyTime.TakeWhile(a => a < keys[i]).Count() - 1;
                        var z = (framePos > -1) ? curveNode.Curves["z"].KeyValueFloat[framePos] : 0f;

                        animKey.Scale = new float[] { x, y, z };
                    }

                    // add the animation key to the list
                    bone.Keyframes.Add(animKey);
                    //AnimationKeys[bone.Id].Add(animKey);
                }
            }

            //restore bind pose
            foreach (var bone in bones)
            {
                var animKey = new AnimationKey()
                {
                    Frame     = 0,
                    Transform = bone.JointMatrix
                };

                // Translation
                var curveNode = boneCurveNodes[bone.Id].Where(a => a.Name.Contains("T")).FirstOrDefault();

                if (curveNode != null)
                {
                    animKey.Translation = curveNode.Value;
                }

                // Rotation
                curveNode = boneCurveNodes[bone.Id].Where(a => a.Name.Contains("R")).FirstOrDefault();

                if (curveNode != null)
                {
                    animKey.Rotation = curveNode.Value.ToRadians().QuaternionFromEuler(EulerOrder.XYZ);
                }

                // Scale
                curveNode = boneCurveNodes[bone.Id].Where(a => a.Name.Contains("S")).FirstOrDefault();

                if (curveNode != null)
                {
                    animKey.Scale = curveNode.Value;
                }

                // add the animation key to the list
                PoseKeys.Add(bone.Name, animKey);
            }
        }// Constructor()