コード例 #1
0
ファイル: Animation.cs プロジェクト: smith076/SanAndreasUnity
        //private static Dictionary<UnityEngine.AnimationClip, List<AnimationCurve>> s_curvesPerClip = new Dictionary<AnimationClip, List<AnimationCurve>> ();


        private static UnityEngine.AnimationClip Convert(Clip animation, FrameContainer frames,
                                                         out UVector3 rootStart, out UVector3 rootEnd)
        {
            var clip = new UnityEngine.AnimationClip();

            clip.legacy = true;

            var rotateAxes = new[] {
                new { Name = "x", Mask = new UVector4(1f, 0f, 0f, 0f) },
                new { Name = "y", Mask = new UVector4(0f, 1f, 0f, 0f) },
                new { Name = "z", Mask = new UVector4(0f, 0f, 1f, 0f) },
                new { Name = "w", Mask = new UVector4(0f, 0f, 0f, 1f) }
            };

            var root = animation.Bones.FirstOrDefault(x => x.BoneId == 0);

            if (root != null && root.FrameCount > 0)
            {
                rootStart = Types.Convert(root.Frames.First().Translation);
                rootEnd   = Types.Convert(root.Frames.Last().Translation);
            }
            else
            {
                rootStart = rootEnd = UVector3.zero;
            }

            foreach (var bone in animation.Bones)
            {
                if (!frames.HasBoneWithId(bone.BoneId)) // what are these used for ?
                {
                    if (bone.BoneId != -1)
                    {
                        Debug.LogWarning($"Bone with id {bone.BoneId} does not exist");
                    }
                    continue;
                }

                var bFrames = bone.Frames;
                var frame   = frames.GetByBoneId(bone.BoneId);

                string bonePath = frame.Path;

                AnimationCurve curve;

                var axisAngle = bFrames.ToDictionary(x => x, x =>
                {
                    var q = Types.Convert(x.Rotation);
                    float ang; UnityEngine.Vector3 axis;
                    q.ToAngleAxis(out ang, out axis);
                    return(new UVector4(q.x, q.y, q.z, q.w));
                });

                foreach (var axis in rotateAxes)
                {
                    var keys = bFrames
                               .Select(x => new Keyframe(x.Time * TimeScale,
                                                         UVector4.Dot(axisAngle[x], axis.Mask)))
                               .ToArray();

                    curve = new UnityEngine.AnimationCurve(keys);

                    clip.SetCurve(bonePath, typeof(Transform), "localRotation." + axis.Name,
                                  curve);

                    //OnCurveAddedToClip (clip, curve);
                }

                var converted = bFrames.Select(x => Types.Convert(x.Translation)).ToArray();

                if (!converted.Any(x => !x.Equals(UVector3.zero)))
                {
                    continue;
                }

                var anyVelocities = false;
                var deltaVals     = converted.Select((x, i) =>
                {
                    var prev = Math.Max(0, i - 1);
                    var next = Math.Min(i + 1, converted.Length - 1);

                    var prevTime = bFrames[prev].Time * TimeScale;
                    var nextTime = bFrames[next].Time * TimeScale;

                    return(prevTime == nextTime || !(anyVelocities = true) ? UVector3.zero
                        : (converted[next] - converted[prev]) / (nextTime - prevTime));
                }).ToArray();

                foreach (var translateAxis in s_translateAxes)
                {
                    var positions = bFrames
                                    .Select((x, i) => new Keyframe(x.Time * TimeScale,
                                                                   UVector3.Dot(frame.transform.localPosition + converted[i], translateAxis.Mask)))
                                    .ToArray();

                    var deltas = bFrames.Select((x, i) => new Keyframe(x.Time * TimeScale,
                                                                       UVector3.Dot(deltaVals[i], translateAxis.Mask))).ToArray();

                    clip.SetCurve(bonePath, typeof(Transform), "localPosition." + translateAxis.Name,
                                  new UnityEngine.AnimationCurve(positions));

                    if (!anyVelocities)
                    {
                        continue;
                    }

                    clip.SetCurve(bonePath, typeof(BFrame), "LocalVelocity." + translateAxis.Name,
                                  new UnityEngine.AnimationCurve(deltas));
                }
            }

            clip.wrapMode = WrapMode.Loop;
            clip.EnsureQuaternionContinuity();

            return(clip);
        }