private static void ExportAnimations(Transform transform, BabylonIAnimatable animatable)
 {
     var animator = transform.gameObject.GetComponent<Animator>();
     if (animator != null)
     {
         AnimatorController ac = animator.runtimeAnimatorController as AnimatorController;
         if (ac == null)
         {
             return;
         }
         var layer = ac.layers[0];
         if (layer == null)
         {
             return;
         }
         AnimatorStateMachine sm = layer.stateMachine;
         if (sm.states.Length > 0)
         {
             var state = sm.states[0].state; // We only support the first one
             AnimationClip clip = state.motion as AnimationClip;
             if (clip != null)
             {
                 ExportAnimationClip(clip, true, animatable);
             }
         }
     }
     else
     {
         var animation = transform.gameObject.GetComponent<Animation>();
         if (animation != null && animation.clip != null)
         {
             ExportAnimationClip(animation.clip, animation.playAutomatically, animatable);
         }
     }
 }
Example #2
0
        private static void ExportTransformAnimationClips(Transform transform, BabylonIAnimatable animatable, ref UnityMetaData metaData)
        {
            Animator  animator = transform.gameObject.GetComponent <Animator>();
            Animation legacy   = transform.gameObject.GetComponent <Animation>();

            if (legacy != null)
            {
                UnityEngine.Debug.LogWarning("Legacy animation component not supported for game object: " + transform.gameObject.name);
            }
            if (animator != null && animator.runtimeAnimatorController != null && animator.runtimeAnimatorController.animationClips != null && animator.runtimeAnimatorController.animationClips.Length > 0)
            {
                UnityEditor.AnimationState astate = transform.gameObject.GetComponent <UnityEditor.AnimationState>();
                if (astate == null)
                {
                    UnityEngine.Debug.LogWarning("AnimationState component not found for game object: " + transform.gameObject.name);
                }
                if (astate != null && astate.isActiveAndEnabled == true && astate.controlType == BabylonAnimationMode.Transform)
                {
                    if (animator != null)
                    {
                        animator.enabled = true;
                    }
                    List <AnimationClip> states = Tools.GetAnimationClips(animator);
                    if (states != null && states.Count > 0)
                    {
                        ExportTransformAnimationClipData(animator.gameObject, transform, animatable, astate, ref states, ref metaData, animator);
                    }
                }
            }
        }
 private static bool IsRotationQuaternionAnimated(BabylonIAnimatable animatable)
 {
     if (animatable.animations == null)
     {
         return(false);
     }
     return(animatable.animations.Any(animation => animation.property.Contains("rotationQuaternion")));
 }
        private static bool IsRotationQuaternionAnimated(BabylonIAnimatable animatable)
        {
            if (animatable.animations == null)
            {
                return false;
            }

            return animatable.animations.Any(animation => animation.property.Contains("rotationQuaternion"));
        }
        private static void ExportTransformAnimationClips(Transform transform, BabylonIAnimatable animatable, ref UnityMetaData metaData)
        {
            Animator  animator = transform.gameObject.GetComponent <Animator>();
            Animation legacy   = transform.gameObject.GetComponent <Animation>();

            if (animator != null && animator.runtimeAnimatorController != null && animator.runtimeAnimatorController.animationClips != null && animator.runtimeAnimatorController.animationClips.Length > 0)
            {
                UnityEditor.AnimationState astate = transform.gameObject.GetComponent <UnityEditor.AnimationState>();
                if (astate == null)
                {
                    UnityEngine.Debug.LogWarning("AnimationState component not found for game object: " + transform.gameObject.name);
                }
                if (astate != null && astate.isActiveAndEnabled == true && astate.controlType == BabylonAnimationMode.TransformAnimation)
                {
                    animator.enabled = true;
                    List <UnityEditor.AnimationParameters> aparams = Tools.GetAnimationParameters(animator);
                    List <AnimationClip> clips = Tools.GetAnimationClips(animator);
                    if (clips != null && clips.Count > 0)
                    {
                        ExportTransformAnimationClipData(animator.gameObject, transform, animatable, ref clips, ref metaData, aparams);
                    }
                }
            }
            else if (legacy != null && legacy.GetClipCount() > 0)
            {
                UnityEditor.AnimationState astate = transform.gameObject.GetComponent <UnityEditor.AnimationState>();
                if (astate == null)
                {
                    UnityEngine.Debug.LogWarning("AnimationState component not found for game object: " + transform.gameObject.name);
                }
                if (astate != null && astate.isActiveAndEnabled == true && astate.controlType == BabylonAnimationMode.TransformAnimation)
                {
                    legacy.enabled = true;
                    List <UnityEditor.AnimationParameters> aparams = Tools.GetAnimationParameters(legacy);
                    List <AnimationClip> clips = Tools.GetAnimationClips(legacy);
                    if (clips != null && clips.Count > 0)
                    {
                        ExportTransformAnimationClipData(legacy.gameObject, transform, animatable, ref clips, ref metaData, aparams);
                    }
                }
            }
        }
Example #6
0
        private static void ExportAnimations(Transform transform, BabylonIAnimatable animatable)
        {
            var animator = transform.gameObject.GetComponent <Animator>();

            if (animator != null)
            {
                AnimatorController ac = animator.runtimeAnimatorController as AnimatorController;
                if (ac == null)
                {
                    return;
                }

                Debug.Log("runtimeAnimatorController");
                var layer = ac.layers[0];
                if (layer == null)
                {
                    return;
                }
                Debug.Log("layer");
                AnimatorStateMachine sm = layer.stateMachine;
                if (sm.states.Length > 0)
                {
                    var           state = sm.states[0].state; // We only support the first one
                    AnimationClip clip  = state.motion as AnimationClip;
                    if (clip != null)
                    {
                        ExportAnimationClip(clip, true, animatable);
                    }
                }
            }
            else
            {
                var animation = transform.gameObject.GetComponent <Animation>();
                if (animation != null && animation.clip != null)
                {
                    ExportAnimationClip(animation.clip, animation.playAutomatically, animatable);
                }
            }
        }
        private static void ExportAnimationClip(AnimationClip clip, bool autoPlay, BabylonIAnimatable animatable)
        {
            var curveBindings = AnimationUtility.GetCurveBindings(clip);

            var animations = new List<BabylonAnimation>();

            var maxFrame = 0;

            foreach (var binding in curveBindings)
            {
                var curve = AnimationUtility.GetEditorCurve(clip, binding);
                string property;

                switch (binding.propertyName)
                {
                    case "m_LocalPosition.x":
                        property = "position.x";
                        break;
                    case "m_LocalPosition.y":
                        property = "position.y";
                        break;
                    case "m_LocalPosition.z":
                        property = "position.z";
                        break;

                    case "m_LocalRotation.x":
                        property = "rotationQuaternion.x";
                        break;
                    case "m_LocalRotation.y":
                        property = "rotationQuaternion.y";
                        break;
                    case "m_LocalRotation.z":
                        property = "rotationQuaternion.z";
                        break;
                    case "m_LocalRotation.w":
                        property = "rotationQuaternion.w";
                        break;

                    case "m_LocalScale.x":
                        property = "scaling.x";
                        break;
                    case "m_LocalScale.y":
                        property = "scaling.y";
                        break;
                    case "m_LocalScale.z":
                        property = "scaling.z";
                        break;
                    default:
                        continue;
                }

                var babylonAnimation = new BabylonAnimation
                {
                    dataType = (int)BabylonAnimation.DataType.Float,
                    name = property + " animation",
                    keys = curve.keys.Select(keyFrame => new BabylonAnimationKey
                    {
                        frame = (int)(keyFrame.time * clip.frameRate),
                        values = new[] { keyFrame.value }
                    }).ToArray(),
                    framePerSecond = (int)clip.frameRate,
                    loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property = property
                };

                maxFrame = Math.Max(babylonAnimation.keys.Last().frame, maxFrame);

                animations.Add(babylonAnimation);
            }

            if (animations.Count > 0)
            {
                animatable.animations = animations.ToArray();
                if (autoPlay)
                {
                    animatable.autoAnimate = true;
                    animatable.autoAnimateFrom = 0;
                    animatable.autoAnimateTo = maxFrame;
                    animatable.autoAnimateLoop = clip.isLooping;
                }
            }
        }
Example #8
0
        private static void ExportTransformAnimationClipData(GameObject source, Transform transform, BabylonIAnimatable animatable, UnityEditor.AnimationState animationState, ref List <AnimationClip> states, ref UnityMetaData metaData, Animator animator)
        {
            ExporterWindow.ReportProgress(1, "Exporting transform clips: " + transform.gameObject.name);
            int                     frameRate       = 0;
            int                     firstClipEnd    = 0;
            int                     totalFrameCount = 0;
            List <string>           stateNameCache  = new List <string>();
            List <BabylonAnimation> animations      = new List <BabylonAnimation>();

            var positionX = new List <BabylonAnimationKey>();
            var positionY = new List <BabylonAnimationKey>();
            var positionZ = new List <BabylonAnimationKey>();

            var rotationX = new List <BabylonAnimationKey>();
            var rotationY = new List <BabylonAnimationKey>();
            var rotationZ = new List <BabylonAnimationKey>();
            var rotationW = new List <BabylonAnimationKey>();

            var scaleX = new List <BabylonAnimationKey>();
            var scaleY = new List <BabylonAnimationKey>();
            var scaleZ = new List <BabylonAnimationKey>();

            int   frameOffest   = 0;
            float playbackSpeed = (animationState != null) ? animationState.playbackSpeed : 1.0f;

            foreach (var state in states)
            {
                if (state == null)
                {
                    continue;
                }
                AnimationClip clip = state as AnimationClip;
                if (frameRate <= 0)
                {
                    frameRate = (int)clip.frameRate;
                }
                //var frameTime = 1.0f / frameRate;
                int clipFrameCount = (int)(clip.length * frameRate);
                if (firstClipEnd <= 0)
                {
                    firstClipEnd = (clipFrameCount - 1);
                }
                var settings = AnimationUtility.GetAnimationClipSettings(clip);
                BabylonLoopBehavior behavior = (settings.loopTime) ? BabylonLoopBehavior.Cycle : BabylonLoopBehavior.Constant;
                if (settings.loopTime && settings.loopBlend)
                {
                    behavior = BabylonLoopBehavior.Relative;
                }
                ExporterWindow.ReportProgress(1, "Transforming: " + transform.gameObject.name + " - " + clip.name);
                // Set Animation State Meta Data
                if (!stateNameCache.Contains(clip.name))
                {
                    stateNameCache.Add(clip.name);
                    // Animation Clip Information
                    Dictionary <string, object> animStateInfo = new Dictionary <string, object>();
                    animStateInfo.Add("type", "transform");
                    animStateInfo.Add("name", clip.name);
                    animStateInfo.Add("start", frameOffest);
                    animStateInfo.Add("stop", (frameOffest + clipFrameCount - 1));
                    animStateInfo.Add("rate", frameRate);
                    animStateInfo.Add("behavior", (int)behavior);
                    animStateInfo.Add("playback", playbackSpeed);
                    metaData.animationClips.Add(animStateInfo);
                }

                // Animation Curve Bindings
                var curveBindings = AnimationUtility.GetCurveBindings(clip);
                foreach (var binding in curveBindings)
                {
                    var curve = AnimationUtility.GetEditorCurve(clip, binding);
                    switch (binding.propertyName)
                    {
                    //Position
                    case "m_LocalPosition.x":
                        IEnumerable <BabylonAnimationKey> px_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionX.AddRange(px_keys);
                        break;

                    case "m_LocalPosition.y":
                        IEnumerable <BabylonAnimationKey> py_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionY.AddRange(py_keys);
                        break;

                    case "m_LocalPosition.z":
                        IEnumerable <BabylonAnimationKey> pz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionZ.AddRange(pz_keys);
                        break;

                    // Rotation
                    case "localEulerAnglesRaw.x":
                        IEnumerable <BabylonAnimationKey> rx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationX.AddRange(rx_keys);
                        break;

                    case "localEulerAnglesRaw.y":
                        IEnumerable <BabylonAnimationKey> ry_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationY.AddRange(ry_keys);
                        break;

                    case "localEulerAnglesRaw.z":
                        IEnumerable <BabylonAnimationKey> rz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationZ.AddRange(rz_keys);
                        break;

                    case "localEulerAnglesRaw.w":
                        IEnumerable <BabylonAnimationKey> rw_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationW.AddRange(rw_keys);
                        break;

                    // Scaling
                    case "m_LocalScale.x":
                        IEnumerable <BabylonAnimationKey> sx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scaleX.AddRange(sx_keys);
                        break;

                    case "m_LocalScale.y":
                        IEnumerable <BabylonAnimationKey> sy_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scaleY.AddRange(sy_keys);
                        break;

                    case "m_LocalScale.z":
                        IEnumerable <BabylonAnimationKey> sz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scaleZ.AddRange(sz_keys);
                        break;

                    default:
                        continue;
                    }
                }
                frameOffest     += clipFrameCount;
                totalFrameCount += clipFrameCount;
            }

            // Position properties
            string property = "none";

            if (positionX.Count > 0)
            {
                property = "position.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = positionX.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (positionY.Count > 0)
            {
                property = "position.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = positionY.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (positionZ.Count > 0)
            {
                property = "position.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = positionZ.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }

            // Rotation properties
            property = "none";
            if (rotationX.Count > 0)
            {
                property = "rotation.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = rotationX.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (rotationY.Count > 0)
            {
                property = "rotation.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = rotationY.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (rotationZ.Count > 0)
            {
                property = "rotation.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = rotationZ.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (rotationW.Count > 0)
            {
                property = "rotation.w";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = rotationW.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }

            // Scale properties
            property = "none";
            if (scaleX.Count > 0)
            {
                property = "scaling.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = scaleX.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (scaleY.Count > 0)
            {
                property = "scaling.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = scaleY.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (scaleZ.Count > 0)
            {
                property = "scaling.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = scaleZ.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            if (animations.Count > 0)
            {
                animatable.animations = animations.ToArray();
            }
        }
Example #9
0
        private static void ExportAnimationClip(AnimationClip clip, bool autoPlay, BabylonIAnimatable animatable)
        {
            var curveBindings = AnimationUtility.GetCurveBindings(clip);
            var animations    = new List <BabylonAnimation>();

            var maxFrame = 0;

            foreach (var binding in curveBindings)
            {
                var    curve = AnimationUtility.GetEditorCurve(clip, binding);
                string property;

                switch (binding.propertyName)
                {
                case "m_LocalPosition.x":
                    property = "position.x";
                    break;

                case "m_LocalPosition.y":
                    property = "position.y";
                    break;

                case "m_LocalPosition.z":
                    property = "position.z";
                    break;

                case "m_LocalRotation.x":
                    property = "rotationQuaternion.x";
                    break;

                case "m_LocalRotation.y":
                    property = "rotationQuaternion.y";
                    break;

                case "m_LocalRotation.z":
                    property = "rotationQuaternion.z";
                    break;

                case "m_LocalRotation.w":
                    property = "rotationQuaternion.w";
                    break;

                case "m_LocalScale.x":
                    property = "scaling.x";
                    break;

                case "m_LocalScale.y":
                    property = "scaling.y";
                    break;

                case "m_LocalScale.z":
                    property = "scaling.z";
                    break;

                default:
                    continue;
                }

                var babylonAnimation = new BabylonAnimation
                {
                    dataType = (int)BabylonAnimation.DataType.Float,
                    name     = property + " animation",
                    keys     = curve.keys.Select(keyFrame => new BabylonAnimationKey
                    {
                        frame  = (int)(keyFrame.time * clip.frameRate),
                        values = new[] { keyFrame.value }
                    }).ToArray(),
                    framePerSecond = (int)clip.frameRate,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                };

                maxFrame = Math.Max(babylonAnimation.keys.Last().frame, maxFrame);

                animations.Add(babylonAnimation);
            }

            if (animations.Count > 0)
            {
                animatable.animations = animations.ToArray();
                if (autoPlay)
                {
                    animatable.autoAnimate     = true;
                    animatable.autoAnimateFrom = 0;
                    animatable.autoAnimateTo   = maxFrame;
                    animatable.autoAnimateLoop = clip.isLooping;
                }
            }
        }
        private static void ExportTransformAnimationClipData(GameObject source, Transform transform, BabylonIAnimatable animatable, ref List <AnimationClip> clips, ref UnityMetaData metaData, List <UnityEditor.AnimationParameters> aparams)
        {
            ExporterWindow.ReportProgress(1, "Baking " + transform.gameObject.name.ToLower() + " transform... This may take a while.");
            string sourceId  = GetID(source);
            int    frameRate = 0;
            var    anims     = new List <BabylonAnimation>();
            List <BabylonRange>     ranges         = new List <BabylonRange>();
            List <string>           stateNameCache = new List <string>();
            List <BabylonAnimation> animations     = new List <BabylonAnimation>();

            var positionX = new List <BabylonAnimationKey>();
            var positionY = new List <BabylonAnimationKey>();
            var positionZ = new List <BabylonAnimationKey>();

            var rotationX = new List <BabylonAnimationKey>();
            var rotationY = new List <BabylonAnimationKey>();
            var rotationZ = new List <BabylonAnimationKey>();

            var quaternionX = new List <BabylonAnimationKey>();
            var quaternionY = new List <BabylonAnimationKey>();
            var quaternionZ = new List <BabylonAnimationKey>();
            var quaternionW = new List <BabylonAnimationKey>();

            var scalingX = new List <BabylonAnimationKey>();
            var scalingY = new List <BabylonAnimationKey>();
            var scalingZ = new List <BabylonAnimationKey>();

            int frameOffest = 0;

            foreach (var clip in clips)
            {
                if (clip == null)
                {
                    continue;
                }
                string clipName = FormatSafeClipName(clip.name);
                BabylonLoopBehavior behavior = (clip.wrapMode == WrapMode.Loop) ? BabylonLoopBehavior.Cycle : BabylonLoopBehavior.Constant;
                if (clip.wrapMode == WrapMode.PingPong)
                {
                    UnityEngine.Debug.LogWarning("PingPong transform animation wrap mode not supported for clip: " + clip.name);
                }
                // ..
                // Sample Animation Frame
                // ..
                if (frameRate <= 0)
                {
                    frameRate = (int)clip.frameRate;
                }
                int clipFrameCount = (int)(clip.length * clip.frameRate);
                int lastFrameCount = clipFrameCount - 1;
                // ..
                // Animation Curve Bindings
                // ..
                var curveBindings = AnimationUtility.GetCurveBindings(clip);
                foreach (var binding in curveBindings)
                {
                    var curve = AnimationUtility.GetEditorCurve(clip, binding);
                    switch (binding.propertyName)
                    {
                    //Positions
                    case "m_LocalPosition.x":
                        IEnumerable <BabylonAnimationKey> px_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionX.AddRange(px_keys);
                        break;

                    case "m_LocalPosition.y":
                        IEnumerable <BabylonAnimationKey> py_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionY.AddRange(py_keys);
                        break;

                    case "m_LocalPosition.z":
                        IEnumerable <BabylonAnimationKey> pz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionZ.AddRange(pz_keys);
                        break;

                    // Rotations
                    case "localEuler.x":
                    case "localEulerAnglesRaw.x":
                    case "localEulerAnglesBaked.x":
                        IEnumerable <BabylonAnimationKey> rx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationX.AddRange(rx_keys);
                        break;

                    case "localEuler.y":
                    case "localEulerAnglesRaw.y":
                    case "localEulerAnglesBaked.y":
                        IEnumerable <BabylonAnimationKey> ry_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationY.AddRange(ry_keys);
                        break;

                    case "localEuler.z":
                    case "localEulerAnglesRaw.z":
                    case "localEulerAnglesBaked.z":
                        IEnumerable <BabylonAnimationKey> rz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationZ.AddRange(rz_keys);
                        break;

                    // Quaternions
                    case "localRotation.x":
                    case "m_LocalRotation.x":
                        IEnumerable <BabylonAnimationKey> qx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        quaternionX.AddRange(qx_keys);
                        break;

                    case "localRotation.y":
                    case "m_LocalRotation.y":
                        IEnumerable <BabylonAnimationKey> qy_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        quaternionY.AddRange(qy_keys);
                        break;

                    case "localRotation.z":
                    case "m_LocalRotation.z":
                        IEnumerable <BabylonAnimationKey> qz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        quaternionZ.AddRange(qz_keys);
                        break;

                    case "localRotation.w":
                    case "m_LocalRotation.w":
                        IEnumerable <BabylonAnimationKey> qw_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        quaternionW.AddRange(qw_keys);
                        break;

                    // Scaling
                    case "m_LocalScale.x":
                        IEnumerable <BabylonAnimationKey> sx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scalingX.AddRange(sx_keys);
                        break;

                    case "m_LocalScale.y":
                        IEnumerable <BabylonAnimationKey> sy_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scalingY.AddRange(sy_keys);
                        break;

                    case "m_LocalScale.z":
                        IEnumerable <BabylonAnimationKey> sz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scalingZ.AddRange(sz_keys);
                        break;

                    default:
                        continue;
                    }
                }
                // ..
                // Set Animation State Meta Data
                // ..
                if (!stateNameCache.Contains(clipName))
                {
                    stateNameCache.Add(clipName);
                    // Animation Clip Information
                    int fromFrame = frameOffest, toFrame = frameOffest + lastFrameCount;
                    Dictionary <string, object> animStateInfo = new Dictionary <string, object>();
                    animStateInfo.Add("type", "transform");
                    animStateInfo.Add("wrap", clip.wrapMode);
                    animStateInfo.Add("name", clipName);
                    animStateInfo.Add("start", fromFrame);
                    animStateInfo.Add("stop", toFrame);
                    animStateInfo.Add("rate", clip.frameRate);
                    animStateInfo.Add("frames", clipFrameCount);
                    animStateInfo.Add("weight", 1.0f);
                    animStateInfo.Add("behavior", (int)behavior);
                    animStateInfo.Add("apparentSpeed", clip.apparentSpeed);
                    animStateInfo.Add("averageSpeed", clip.averageSpeed.ToFloat());
                    animStateInfo.Add("averageDuration", clip.averageDuration);
                    animStateInfo.Add("averageAngularSpeed", clip.averageAngularSpeed);
                    List <string> customCurveKeyNames = new List <string>();
                    // ..
                    // UnityEditor.AnimationParameters;
                    // ..
                    if (aparams != null && aparams.Count > 0)
                    {
                        foreach (var aparam in aparams)
                        {
                            if (aparam.curve == true)
                            {
                                var curve = Tools.GetAnimationCurve(clip, aparam.name);
                                if (curve != null)
                                {
                                    IEnumerable <BabylonAnimationKey> cx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                                        frame  = (int)(keyFrame.time * frameRate),
                                        values = new[] { keyFrame.value }
                                    });
                                    BabylonAnimationKey[] xkeys = (cx_keys != null && cx_keys.Count() > 0) ? cx_keys.ToArray() : null;
                                    if (xkeys != null && xkeys.Length > 0)
                                    {
                                        string xkey  = aparam.name;
                                        string xprop = "metadata.state.floats." + xkey;
                                        string xname = "custom:" + clipName.Replace(" ", "") + ":" + System.Guid.NewGuid().ToString();
                                        customCurveKeyNames.Add(xname);
                                        anims.Add(new BabylonAnimation
                                        {
                                            dataType       = (int)BabylonAnimation.DataType.Float,
                                            name           = xname,
                                            keys           = xkeys,
                                            framePerSecond = frameRate,
                                            enableBlending = false,
                                            blendingSpeed  = 0.0f,
                                            loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                                            property       = xprop
                                        });
                                    }
                                }
                            }
                        }
                    }
                    animStateInfo.Add("customCurveKeyNames", (customCurveKeyNames.Count > 0) ? customCurveKeyNames.ToArray() : null);
                    metaData.animationClips.Add(animStateInfo);
                    ranges.Add(new BabylonRange {
                        name = clipName, from = fromFrame, to = toFrame
                    });
                }
                // ..
                frameOffest += clipFrameCount;
            }

            // Position properties
            string prefix   = "transform:";
            string suffix   = ":animation";
            string property = "none";

            if (positionX.Count > 0)
            {
                property = "position.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = positionX.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (positionY.Count > 0)
            {
                property = "position.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = positionY.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (positionZ.Count > 0)
            {
                property = "position.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = positionZ.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }

            // Rotation properties
            property = "none";
            if (rotationX.Count > 0)
            {
                property = "rotation.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = rotationX.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (rotationY.Count > 0)
            {
                property = "rotation.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = rotationY.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (rotationZ.Count > 0)
            {
                property = "rotation.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = rotationZ.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }

            // Quaternion properties
            property = "none";
            if (quaternionX.Count > 0)
            {
                property = "rotationQuaternion.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = quaternionX.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (quaternionY.Count > 0)
            {
                property = "rotationQuaternion.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = quaternionY.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (quaternionZ.Count > 0)
            {
                property = "rotationQuaternion.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = quaternionZ.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (quaternionW.Count > 0)
            {
                property = "rotationQuaternion.w";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = quaternionW.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }

            // Scaling properties
            property = "none";
            if (scalingX.Count > 0)
            {
                property = "scaling.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = scalingX.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (scalingY.Count > 0)
            {
                property = "scaling.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = scalingY.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (scalingZ.Count > 0)
            {
                property = "scaling.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = scalingZ.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            // Serialize animations
            if (animations.Count > 0)
            {
                animatable.animations = animations.ToArray();
            }
            //
            // Cache Babylon Animation Keys
            //
            if (anims.Count > 0)
            {
                List <BabylonAnimation> sourceAnimiamtions = null;
                if (SceneBuilder.AnimationCurveKeys.ContainsKey(sourceId))
                {
                    sourceAnimiamtions = SceneBuilder.AnimationCurveKeys[sourceId];
                }
                else
                {
                    sourceAnimiamtions = new List <BabylonAnimation>();
                    SceneBuilder.AnimationCurveKeys.Add(sourceId, sourceAnimiamtions);
                }
                foreach (var anim in anims)
                {
                    sourceAnimiamtions.Add(anim);
                }
            }
        }