Ejemplo n.º 1
0
        private void ExportAnimation(string property, List<BabylonAnimation> animations, Func<int, float[]> extractValueFunc, BabylonAnimation.DataType dataType)
        {
            const int ticks = 160;
            var start = Loader.Core.AnimRange.Start;
            var end = Loader.Core.AnimRange.End;

            float[] previous = null;
            var keys = new List<BabylonAnimationKey>();
            for (var key = start; key <= end; key += ticks)
            {
                var current = extractValueFunc(key);

                if (key == start || key == end || !(previous.IsEqualTo(current)))
                {
                    keys.Add(new BabylonAnimationKey()
                    {
                        frame = key / ticks,
                        values = current
                    });
                }

                previous = current;
            }

            if (keys.Count > 0)
            {
                var animationPresent = true;

                if (keys.Count == 2)
                {
                    if (keys[0].values.IsEqualTo(keys[1].values))
                    {
                        animationPresent = false;
                    }
                }

                if (animationPresent)
                {
                    var babylonAnimation = new BabylonAnimation
                    {
                        dataType = dataType,
                        name = property + " animation",
                        keys = keys.ToArray(),
                        framePerSecond = Loader.Global.FrameRate,
                        loopBehavior = BabylonAnimation.LoopBehavior.Relative,
                        property = property
                    };

                    animations.Add(babylonAnimation);
                }
            }
        }        
Ejemplo n.º 2
0
        public static float[] Interpolate(BabylonAnimation animation, BabylonAnimationKey fromKey, BabylonAnimationKey toKey, float frame)
        {
            switch (animation.property)
            {
            case "_matrix":
                var fromMatrix = new BabylonMatrix();
                fromMatrix.m = new List <float>(fromKey.values).ToArray();
                var toMatrix = new BabylonMatrix();
                toMatrix.m = new List <float>(toKey.values).ToArray();
                var fromPosition = new BabylonVector3();
                var fromRotation = new BabylonQuaternion();
                var fromScaling  = new BabylonVector3();
                var toPosition   = new BabylonVector3();
                var toRotation   = new BabylonQuaternion();
                var toScaling    = new BabylonVector3();

                fromMatrix.decompose(fromScaling, fromRotation, fromPosition);
                toMatrix.decompose(toScaling, toRotation, toPosition);

                var lerpFactor = MathUtilities.GetLerpFactor(fromKey.frame, toKey.frame, frame);

                var interpolatedKeyPosition = BabylonVector3.FromArray(MathUtilities.Lerp(fromPosition.ToArray(), toPosition.ToArray(), lerpFactor));
                var interpolatedKeyRotation = BabylonQuaternion.Slerp(fromRotation, toRotation, lerpFactor);
                var interpolatedKeyScaling  = BabylonVector3.FromArray(MathUtilities.Lerp(fromScaling.ToArray(), toScaling.ToArray(), lerpFactor));

                return(BabylonMatrix.Compose(interpolatedKeyScaling, interpolatedKeyRotation, interpolatedKeyPosition).m);

            case "rotationQuaternion":
                return(BabylonQuaternion.Slerp(BabylonQuaternion.FromArray(fromKey.values), BabylonQuaternion.FromArray(toKey.values), MathUtilities.GetLerpFactor(fromKey.frame, toKey.frame, frame)).ToArray());

            case "scaling":
            case "position":
            default:
                return(MathUtilities.Lerp(fromKey.values, toKey.values, MathUtilities.GetLerpFactor(fromKey.frame, toKey.frame, frame)));
            }
        }
        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 void ExportSkin(IIGameSkin skin, BabylonScene babylonScene)
        {
            var babylonSkeleton = new BabylonSkeleton { id = skins.IndexOf(skin) };
            babylonSkeleton.name = "skeleton #" + babylonSkeleton.id;

            RaiseMessage(babylonSkeleton.name, 1);

            var skinIndex = skins.IndexOf(skin);

            var bones = new List<BabylonBone>();
            var gameBones = new List<IIGameNode>();
            var boneIds = new List<int>();
            var bindPoseInfos = new List<BonePoseInfo>();
            for(int i = 0; i < skin.TotalSkinBoneCount; ++i)
            {
                bones.Add(null);
                gameBones.Add(null);
                boneIds.Add(-1);
                bindPoseInfos.Add(null);
            }
            for (var index = 0; index < skin.TotalSkinBoneCount; index++)
            {
                var gameBone = skin.GetIGameBone(index, false);

                var sortedIndex = skinSortedBones[skin].IndexOf(gameBone.NodeID);

                gameBones[sortedIndex] = (gameBone);
                boneIds[sortedIndex] =(gameBone.NodeID);
                bones[sortedIndex]=(new BabylonBone { index = sortedIndex, name = gameBone.Name });

                var boneInitMatrix = gameBone.GetObjectTM(0);
                bindPoseInfos[sortedIndex] = (new BonePoseInfo { AbsoluteTransform = boneInitMatrix });
            }

            // fix hierarchy an generate animation keys
            var exportNonOptimizedAnimations = Loader.Core.RootNode.GetBoolProperty("babylonjs_exportnonoptimizedanimations");

            for (var index = 0; index < skin.TotalSkinBoneCount; index++)
            {
                var gameBone = gameBones[index];
                var parent = gameBone.NodeParent;
                var babBone = bones[index];
                if (parent != null)
                {
                    babBone.parentBoneIndex = boneIds.IndexOf(parent.NodeID);
                }

                if (babBone.parentBoneIndex == -1)
                {
                    bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform;
                }
                else
                {
                    var parentBindPoseInfos = bindPoseInfos[babBone.parentBoneIndex];
                    bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform.Multiply(parentBindPoseInfos.AbsoluteTransform.Inverse);
                }

                babBone.matrix = bindPoseInfos[index].LocalTransform.ToArray();

                var babylonAnimation = new BabylonAnimation
                {
                    name = gameBone.Name + "Animation",
                    property = "_matrix",
                    dataType = (int)BabylonAnimation.DataType.Matrix,
                    loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle,
                    framePerSecond = Loader.Global.FrameRate
                };

                var start = Loader.Core.AnimRange.Start;
                var end = Loader.Core.AnimRange.End;

                float[] previous = null;
                var keys = new List<BabylonAnimationKey>();
                for (var key = start; key <= end; key += Ticks)
                {
                    var objectTM = gameBone.GetObjectTM(key);
                    var parentNode = gameBone.NodeParent;
                    IGMatrix mat;
                    if (parentNode == null || babBone.parentBoneIndex == -1)
                    {
                        mat = objectTM;
                    }
                    else
                    {
                        mat = objectTM.Multiply(parentNode.GetObjectTM(key).Inverse);
                    }

                    var current = mat.ToArray();
                    if (key == start || key == end || exportNonOptimizedAnimations || !(previous.IsEqualTo(current)))
                    {
                        keys.Add(new BabylonAnimationKey
                        {
                            frame = key / Ticks,
                            values = current
                        });
                    }

                    previous = current;
                }

                babylonAnimation.keys = keys.ToArray();
                babBone.animation = babylonAnimation;
            }

            babylonSkeleton.needInitialSkinMatrix = true;
            babylonSkeleton.bones = bones.ToArray();

            babylonScene.SkeletonsList.Add(babylonSkeleton);
        }
Ejemplo n.º 5
0
        private static void ExportAnimation(string property, List<BabylonAnimation> animations, Func<int, float[]> extractValueFunc, BabylonAnimation.DataType dataType)
        {
            var exportNonOptimizedAnimations = Loader.Core.RootNode.GetBoolProperty("babylonjs_exportnonoptimizedanimations");

            var start = Loader.Core.AnimRange.Start;
            var end = Loader.Core.AnimRange.End;

            float[] previous = null;
            var keys = new List<BabylonAnimationKey>();
            for (var key = start; key <= end; key += Ticks)
            {
                var current = extractValueFunc(key);

                if (exportNonOptimizedAnimations && previous != null && previous.IsEqualTo(current))
                {
                    continue; // Do not add key
                }

                keys.Add(new BabylonAnimationKey()
                {
                    frame = key / Ticks,
                    values = current
                });

                previous = current;
            }

            if (!exportNonOptimizedAnimations)
            {
                RemoveLinearAnimationKeys(keys);
            }

            if (keys.Count > 1)
            {
                var animationPresent = true;

                if (keys.Count == 2)
                {
                    if (keys[0].values.IsEqualTo(keys[1].values))
                    {
                        animationPresent = false;
                    }
                }

                if (animationPresent)
                {

                    if (keys[keys.Count - 1].frame != end / Ticks)
                    {
                        keys.Add(new BabylonAnimationKey()
                        {
                            frame = end / Ticks,
                            values = keys[keys.Count - 1].values
                        });
                    }

                    var babylonAnimation = new BabylonAnimation
                    {
                        dataType = (int)dataType,
                        name = property + " animation",
                        keys = keys.ToArray(),
                        framePerSecond = Loader.Global.FrameRate,
                        loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle,
                        property = property
                    };

                    animations.Add(babylonAnimation);
                }
            }
        }
Ejemplo n.º 6
0
        private static bool ExportController(IControl control, string property, List<BabylonAnimation> animations, uint classId, BabylonAnimation.DataType dataType, Func<int, IIKeyControl, BabylonAnimationKey> generateFunc)
        {
            if (control == null)
            {
                return false;
            }

            var keyControl = control.GetInterface(InterfaceID.Keycontrol) as IIKeyControl;

            if (keyControl == null)
            {
                return false;
            }

            if (control.ClassID.PartA != classId)
            {
                return false;
            }

            var keys = new List<BabylonAnimationKey>();
            BabylonAnimation.LoopBehavior loopBehavior;

            switch (control.GetORT(2))
            {
                case 2:
                    loopBehavior = BabylonAnimation.LoopBehavior.Cycle;
                    break;
                default:
                    loopBehavior = BabylonAnimation.LoopBehavior.Relative;
                    break;
            }

            for (var index = 0; index < keyControl.NumKeys; index++)
            {
                keys.Add(generateFunc(index, keyControl));
            }

            if (keys.Count == 0)
            {
                return false;
            }

            var end = Loader.Core.AnimRange.End;
            if (keys[keys.Count - 1].frame != end / Ticks)
            {
                keys.Add(new BabylonAnimationKey()
                {
                    frame = end / Ticks,
                    values = keys[keys.Count - 1].values
                });
            }

            var babylonAnimation = new BabylonAnimation
            {
                dataType = (int)dataType,
                name = property + " animation",
                keys = keys.ToArray(),
                framePerSecond = Loader.Global.FrameRate,
                loopBehavior = (int)loopBehavior,
                property = property
            };

            animations.Add(babylonAnimation);

            return true;
        }
Ejemplo n.º 7
0
        private static void ExportSkeletonAnimationClipData(Animator animator, bool autoPlay, BabylonSkeleton skeleton, Transform[] bones, BabylonMesh babylonMesh, AnimationClip clip)
        {
            var frameTime = 1.0f / clip.frameRate;
            int animationFrameCount = (int)(clip.length * clip.frameRate);

            if (autoPlay)
            {
                babylonMesh.autoAnimate = true;
                babylonMesh.autoAnimateFrom = 0;
                babylonMesh.autoAnimateTo = animationFrameCount;
                babylonMesh.autoAnimateLoop = true;
            }

            foreach (var bone in skeleton.bones)
            {
                var keys = new List<BabylonAnimationKey>();
                var transform = bones.Single(b => b.name == bone.name);

                AnimationMode.BeginSampling();
                for (var i = 0; i < animationFrameCount; i++)
                {
                    clip.SampleAnimation(animator.gameObject, i * frameTime);

                    var local = (transform.parent.localToWorldMatrix.inverse * transform.localToWorldMatrix);
                    float[] matrix = new[] {
                        local[0, 0], local[1, 0], local[2, 0], local[3, 0],
                        local[0, 1], local[1, 1], local[2, 1], local[3, 1],
                        local[0, 2], local[1, 2], local[2, 2], local[3, 2],
                        local[0, 3], local[1, 3], local[2, 3], local[3, 3]
                    };

                    var key = new BabylonAnimationKey
                    {
                        frame = i,
                        values = matrix,
                    };
                    keys.Add(key);
                }
                AnimationMode.EndSampling();

                var babylonAnimation = new BabylonAnimation
                {
                    name = bone.name + "Animation",
                    property = "_matrix",
                    dataType = (int)BabylonAnimation.DataType.Matrix,
                    loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle,
                    framePerSecond = (int)clip.frameRate,
                    keys = keys.ToArray()
                };

                bone.animation = babylonAnimation;
            }
        }
        private void ExportSkin(IISkin skin, BabylonScene babylonScene)
        {
            var babylonSkeleton = new BabylonSkeleton {id = skins.IndexOf(skin)};
            babylonSkeleton.name = "skeleton #" + babylonSkeleton.id;

            RaiseMessage(babylonSkeleton.name, 1);

            var bones = new List<BabylonBone>();

            for (var index = 0; index < skin.NumBones; index++)
            {
                var bone = new BabylonBone {name = skin.GetBoneName(index), index = index};

                var maxBone = skin.GetBone(index);
                var parentNode = maxBone.ParentNode;

                if (parentNode != null)
                {
                    for (var recurseIndex = 0; recurseIndex < index; recurseIndex++)
                    {
                        if (skin.GetBone(recurseIndex).GetGuid() == parentNode.GetGuid())
                        {
                            bone.parentBoneIndex = recurseIndex;
                            break;
                        }
                    }
                }
                var hasParent = bone.parentBoneIndex != -1;
                bone.matrix = GetBoneMatrix(skin, maxBone, 0, hasParent);

                // Animation
                var babylonAnimation = new BabylonAnimation
                {
                    name = bone.name + "Animation", 
                    property = "_matrix", 
                    dataType = BabylonAnimation.DataType.Matrix, 
                    loopBehavior = BabylonAnimation.LoopBehavior.Cycle,
                    framePerSecond = Loader.Global.FrameRate
                };

                var start = Loader.Core.AnimRange.Start;
                var end = Loader.Core.AnimRange.End;

                float[] previous = null;
                var keys = new List<BabylonAnimationKey>();
                for (var key = start; key <= end; key += Ticks)
                {
                    var current = GetBoneMatrix(skin, maxBone, key, hasParent);

                    if (key == start || key == end || !(previous.IsEqualTo(current)))
                    {
                        keys.Add(new BabylonAnimationKey
                        {
                            frame = key / Ticks,
                            values = current
                        });
                    }

                    previous = current;
                }

                babylonAnimation.keys = keys.ToArray();
                bone.animation = babylonAnimation;

                bones.Add(bone);
            }

            babylonSkeleton.bones = bones.ToArray();

            babylonScene.SkeletonsList.Add(babylonSkeleton);
        }