Quellcode durchsuchen

All animations supported

Simon Ferquel vor 10 Jahren
Ursprung
Commit
fd1bfe5269

+ 47 - 4
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Animation.cs

@@ -185,6 +185,50 @@ namespace Max2Babylon
             ExportAnimation(property, animations, extractValueFunc, BabylonAnimation.DataType.Float);
         }
 
+        static void EliminateLinearAnimationKeys(List<BabylonAnimationKey> keys)
+        {
+            for(int ixFirst = 0; ixFirst < keys.Count; ++ixFirst)
+            {
+                while (keys.Count - ixFirst >= 3)
+                {
+                    if(!EliminateAnimationKey(keys, ixFirst))
+                    {
+                        break;
+                    }
+                }
+            }
+        }
+
+        static float[] weightedLerp(int frame0, int frame1, int frame2, float[] value0, float[] value2)
+        {
+            double weight2 = (double)(frame1 - frame0) / (double)(frame2 - frame0);
+            double weight0 = 1 - weight2;
+            float[] result = new float[value0.Length];
+            for(int i = 0; i < result.Length; ++i)
+            {
+                result[i] = (float)(value0[i] * weight0 + value2[i] * weight2);
+            }
+            return result;
+        }
+
+
+
+        private static bool EliminateAnimationKey(List<BabylonAnimationKey> keys, int ixFirst)
+        {
+            var first = keys[ixFirst];
+            var middle = keys[ixFirst + 1];
+            var last = keys[ixFirst + 2];
+
+            var computedMiddleValue = weightedLerp(first.frame, middle.frame, last.frame, first.values, last.values);
+            if (computedMiddleValue.IsEqualTo(middle.values))
+            {
+                keys.RemoveAt(ixFirst + 1);
+                return true;
+            }
+            return false;
+            
+        }
+
         private static void ExportAnimation(string property, List<BabylonAnimation> animations, Func<int, float[]> extractValueFunc, BabylonAnimation.DataType dataType)
         {
             var start = Loader.Core.AnimRange.Start;
@@ -196,18 +240,17 @@ namespace Max2Babylon
             {
                 var current = extractValueFunc(key);
 
-                if (key == start || key == end || !(previous.IsEqualTo(current)))
-                {
+                
                     keys.Add(new BabylonAnimationKey()
                     {
                         frame = key / Ticks,
                         values = current
                     });
-                }
+                
 
                 previous = current;
             }
-
+            EliminateLinearAnimationKeys(keys);
             if (keys.Count > 0)
             {
                 var animationPresent = true;

+ 42 - 31
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Camera.cs

@@ -50,46 +50,57 @@ namespace Max2Babylon
             babylonCamera.ellipsoid = cameraNode.MaxNode.GetVector3Property("babylonjs_ellipsoid");
 
             // Position
-            var wm = cameraNode.GetLocalTM(0);
-            var position = wm.Translation;
-            babylonCamera.position = new float[] { position.X, position.Y, position.Z };
-
-            // Target
-            var target = gameCamera.CameraTarget;
-            if (target != null)
-            {
-                babylonCamera.lockedTargetId = target.MaxNode.GetGuid().ToString();
-            }
-            else
             {
-                var dir = wm.GetRow(3);
-                babylonCamera.target = new float[] { position.X - dir.X, position.Y - dir.Y, position.Z - dir.Z };
+                var wm = cameraNode.GetLocalTM(0);
+                var position = wm.Translation;
+                babylonCamera.position = new float[] { position.X, position.Y, position.Z };
+
+                // Target
+                var target = gameCamera.CameraTarget;
+                if (target != null)
+                {
+                    babylonCamera.lockedTargetId = target.MaxNode.GetGuid().ToString();
+                }
+                else
+                {
+                    var dir = wm.GetRow(3);
+                    babylonCamera.target = new float[] { position.X - dir.X, position.Y - dir.Y, position.Z - dir.Z };
+                }
             }
 
-            // todo : handle animations
-            //// Animations
-            //var animations = new List<BabylonAnimation>();
-            //cameraNode.IGameControl.
+            // Animations
+            var animations = new List<BabylonAnimation>();
             //if (!ExportVector3Controller(cameraNode.TMController.PositionController, "position", animations))
             //{
-            //    ExportVector3Animation("position", animations, key =>
-            //    {
-            //        var worldMatrix = cameraNode.GetWorldMatrix(key, cameraNode.HasParent());
-            //        return worldMatrix.Trans.ToArraySwitched();
-            //    });
+                ExportVector3Animation("position", animations, key =>
+                {
+                    var wm = cameraNode.GetLocalTM(key);
+                    var position = wm.Translation;
+                    return  new float[] { position.X, position.Y, position.Z };
+                });
             //}
+            if (gameCamera.CameraTarget == null)
+            {
+                ExportVector3Animation("target", animations, key =>
+                {
+                    var wm = cameraNode.GetLocalTM(key);
+                    var position = wm.Translation;
+                    var dir = wm.GetRow(3);
+                    return new float[] { position.X - dir.X, position.Y - dir.Y, position.Z - dir.Z };
+                });
+            }
 
-            //ExportFloatAnimation("fov", animations, key => new[] {Tools.ConvertFov(maxCamera.GetFOV(key, Tools.Forever))});
+            ExportFloatAnimation("fov", animations, key => new[] { Tools.ConvertFov((gameCamera.MaxObject as ICameraObject).GetFOV(key, Tools.Forever)) });
 
-            //babylonCamera.animations = animations.ToArray();
+            babylonCamera.animations = animations.ToArray();
 
-            //if (cameraNode.GetBoolProperty("babylonjs_autoanimate"))
-            //{
-            //    babylonCamera.autoAnimate = true;
-            //    babylonCamera.autoAnimateFrom = (int)cameraNode.GetFloatProperty("babylonjs_autoanimate_from");
-            //    babylonCamera.autoAnimateTo = (int)cameraNode.GetFloatProperty("babylonjs_autoanimate_to");
-            //    babylonCamera.autoAnimateLoop = cameraNode.GetBoolProperty("babylonjs_autoanimateloop");
-            //}
+            if (cameraNode.MaxNode.GetBoolProperty("babylonjs_autoanimate"))
+            {
+                babylonCamera.autoAnimate = true;
+                babylonCamera.autoAnimateFrom = (int)cameraNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from");
+                babylonCamera.autoAnimateTo = (int)cameraNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to");
+                babylonCamera.autoAnimateLoop = cameraNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop");
+            }
 
             babylonScene.CamerasList.Add(babylonCamera);
         }

+ 56 - 50
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Light.cs

@@ -82,30 +82,30 @@ namespace Max2Babylon
                 }
             }
 
-
-            // Position
-            var wm = lightNode.GetObjectTM(0);
-            var position = wm.Translation;
-            babylonLight.position = new float[] { position.X, position.Y, position.Z };
-
-            // Direction
-            var target = gameLight.LightTarget;
-            if (target != null)
             {
-                var targetWm = target.GetObjectTM(0);
-                var targetPosition = targetWm.Translation;
+                // Position
+                var wm = lightNode.GetObjectTM(0);
+                var position = wm.Translation;
+                babylonLight.position = new float[] { position.X, position.Y, position.Z };
+
+                // Direction
+                var target = gameLight.LightTarget;
+                if (target != null)
+                {
+                    var targetWm = target.GetObjectTM(0);
+                    var targetPosition = targetWm.Translation;
 
-                var direction = targetPosition.Subtract(position).Normalize;
-                babylonLight.direction = new float[] { direction.X, direction.Y, direction.Z };
-            }
-            else
-            {
-                var vDir = Loader.Global.Point3.Create(0, -1, 0);
-                vDir = wm.ExtractMatrix3().VectorTransform(vDir).Normalize;
-                babylonLight.direction = new float[] { vDir.X, vDir.Y, vDir.Z };
+                    var direction = targetPosition.Subtract(position).Normalize;
+                    babylonLight.direction = new float[] { direction.X, direction.Y, direction.Z };
+                }
+                else
+                {
+                    var vDir = Loader.Global.Point3.Create(0, -1, 0);
+                    vDir = wm.ExtractMatrix3().VectorTransform(vDir).Normalize;
+                    babylonLight.direction = new float[] { vDir.X, vDir.Y, vDir.Z };
+                }
             }
 
-
             var maxScene = Loader.Core.RootNode;
             // Exclusion
             var inclusion = maxLight.ExclList.TestFlag(1); //NT_INCLUDE 
@@ -154,45 +154,51 @@ namespace Max2Babylon
             }
 
 
-            //// Animations
-            //var animations = new List<BabylonAnimation>();
+            // Animations
+            var animations = new List<BabylonAnimation>();
 
             //if (!ExportVector3Controller(lightNode.TMController.PositionController, "position", animations))
             //{
-            //    ExportVector3Animation("position", animations, key =>
-            //    {
-            //        var worldMatrix = lightNode.GetWorldMatrix(key, lightNode.HasParent());
-            //        return worldMatrix.Trans.ToArraySwitched();
-            //    });
+                ExportVector3Animation("position", animations, key =>
+                {
+                    var mat = lightNode.GetObjectTM(key);
+                    var pos = mat.Translation;
+                    return new float[] { pos.X, pos.Y, pos.Z };
+                });
             //}
 
-            //ExportVector3Animation("direction", animations, key =>
-            //{
-            //    var targetNode = lightNode.Target;
-            //    if (targetNode != null)
-            //    {
-            //        var targetWm = target.GetObjTMBeforeWSM(0, Tools.Forever);
-            //        var targetPosition = targetWm.Trans;
-
-            //        var direction = targetPosition.Subtract(position);
-            //        return direction.ToArraySwitched();
-            //    }
+            ExportVector3Animation("direction", animations, key =>
+            {
+                var wm = lightNode.GetObjectTM(key);
+                var position = wm.Translation;
+                var target = gameLight.LightTarget;
+                if (target != null)
+                {
+                    var targetWm = target.GetObjectTM(key);
+                    var targetPosition = targetWm.Translation;
 
-            //    var dir = wm.GetRow(2).MultiplyBy(directionScale);
-            //    return dir.ToArraySwitched();
-            //});
+                    var direction = targetPosition.Subtract(position).Normalize;
+                    return new float[] { direction.X, direction.Y, direction.Z };
+                }
+                else
+                {
+                    var vDir = Loader.Global.Point3.Create(0, -1, 0);
+                    vDir = wm.ExtractMatrix3().VectorTransform(vDir).Normalize;
+                    return new float[] { vDir.X, vDir.Y, vDir.Z };
+                }
+            });
 
-            //ExportFloatAnimation("intensity", animations, key => new[] { maxLight.GetIntensity(key, Tools.Forever) });
+            ExportFloatAnimation("intensity", animations, key => new[] { maxLight.GetIntensity(key, Tools.Forever) });
 
-            //babylonLight.animations = animations.ToArray();
+            babylonLight.animations = animations.ToArray();
 
-            //if (lightNode.GetBoolProperty("babylonjs_autoanimate"))
-            //{
-            //    babylonLight.autoAnimate = true;
-            //    babylonLight.autoAnimateFrom = (int)lightNode.GetFloatProperty("babylonjs_autoanimate_from");
-            //    babylonLight.autoAnimateTo = (int)lightNode.GetFloatProperty("babylonjs_autoanimate_to");
-            //    babylonLight.autoAnimateLoop = lightNode.GetBoolProperty("babylonjs_autoanimateloop");
-            //}
+            if (lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimate"))
+            {
+                babylonLight.autoAnimate = true;
+                babylonLight.autoAnimateFrom = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from");
+                babylonLight.autoAnimateTo = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to");
+                babylonLight.autoAnimateLoop = lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop");
+            }
 
             babylonScene.LightsList.Add(babylonLight);
         }

+ 81 - 139
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -69,6 +69,7 @@ namespace Max2Babylon
                 //var localTM = unskinnedMesh.IGameObjectTM;
                 //var worldTM = meshNode.GetWorldTM(0);
                 var localTM = meshNode.GetObjectTM(0);
+
                 var meshTrans = localTM.Translation;
                 var meshRotation = localTM.Rotation;
                 var meshScale = localTM.Scaling;
@@ -93,11 +94,11 @@ namespace Max2Babylon
             // Mesh
 
             RaiseMessage(meshNode.Name, 1);
-            
+
             if (unskinnedMesh != null && unskinnedMesh.IGameType == Autodesk.Max.IGameObject.ObjectTypes.Mesh && unskinnedMesh.MaxMesh != null)
             {
-             
-                
+
+
                 if (unskinnedMesh.NumberOfFaces < 1)
                 {
                     RaiseError(string.Format("Mesh {0} has no face", babylonMesh.name), 2);
@@ -136,14 +137,15 @@ namespace Max2Babylon
                 var mappingChannels = unskinnedMesh.ActiveMapChannelNum;
                 bool hasUV = false;
                 bool hasUV2 = false;
-                for(int i=0;i< mappingChannels.Count; ++i)
+                for (int i = 0; i < mappingChannels.Count; ++i)
                 {
                     IntPtr indexer = new IntPtr(i);
                     var channelNum = mappingChannels[indexer];
-                    if(channelNum == 1)
+                    if (channelNum == 1)
                     {
                         hasUV = true;
-                    }else if(channelNum == 2)
+                    }
+                    else if (channelNum == 2)
                     {
                         hasUV2 = true;
                     }
@@ -153,10 +155,10 @@ namespace Max2Babylon
 
                 var optimizeVertices = meshNode.MaxNode.GetBoolProperty("babylonjs_optimizevertices");
 
-               
+
 
                 // Compute normals
-               // VNormal[] vnorms = Tools.ComputeNormals(mesh, optimizeVertices);
+                // VNormal[] vnorms = Tools.ComputeNormals(mesh, optimizeVertices);
                 List<GlobalVertex>[] verticesAlreadyExported = null;
 
                 if (optimizeVertices)
@@ -168,13 +170,13 @@ namespace Max2Babylon
                 var indexStart = 0;
 
                 List<Guid> orderedSubMeshes = new List<Guid>();
-                for(int i=0;i< meshNode.NodeMaterial.SubMaterialCount; ++i)
+                for (int i = 0; i < meshNode.NodeMaterial.SubMaterialCount; ++i)
                 {
                     orderedSubMeshes.Add(meshNode.NodeMaterial.GetSubMaterial(i).MaxMaterial.GetGuid());
                 }
 
                 var materialIds = unskinnedMesh.ActiveMatIDs;
-                for(int i=0; i< materialIds.Count; ++i)
+                for (int i = 0; i < materialIds.Count; ++i)
                 {
                     var materialIndexer = new IntPtr(i);
                     int materialId = materialIds[materialIndexer];
@@ -190,11 +192,11 @@ namespace Max2Babylon
 
 
 
-                    for (int j= 0; j<materialFaces.Count; ++j)
+                    for (int j = 0; j < materialFaces.Count; ++j)
                     {
                         var faceIndexer = new IntPtr(j);
                         var face = materialFaces[faceIndexer];
-                      
+
                         Marshal.FreeHGlobal(faceIndexer);
                         var a = CreateGlobalVertex(unskinnedMesh, face, 0, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin);
                         var b = CreateGlobalVertex(unskinnedMesh, face, 2, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin);
@@ -251,7 +253,7 @@ namespace Max2Babylon
                 }
 
 
-              
+
                 if (vertices.Count >= 65536)
                 {
                     RaiseError(string.Format("Mesh {0} has too many vertices: {1} (limit is 65535)", babylonMesh.name, vertices.Count), 2);
@@ -269,11 +271,11 @@ namespace Max2Babylon
                 babylonMesh.normals = vertices.SelectMany(v => new float[] { v.Normal.X, v.Normal.Y, v.Normal.Z }).ToArray();
                 if (hasUV)
                 {
-                    babylonMesh.uvs = vertices.SelectMany(v => new float[] { v.UV.X, 1-v.UV.Y }).ToArray();
+                    babylonMesh.uvs = vertices.SelectMany(v => new float[] { v.UV.X, 1 - v.UV.Y }).ToArray();
                 }
                 if (hasUV2)
                 {
-                    babylonMesh.uvs2 = vertices.SelectMany(v => new float[] { v.UV2.X, 1-v.UV2.Y }).ToArray();
+                    babylonMesh.uvs2 = vertices.SelectMany(v => new float[] { v.UV2.X, 1 - v.UV2.Y }).ToArray();
                 }
 
                 if (skin != null)
@@ -288,8 +290,8 @@ namespace Max2Babylon
                     babylonMesh.hasVertexAlpha = hasAlpha;
                 }
 
-                
-               
+
+
                 babylonMesh.subMeshes = subMeshes.ToArray();
 
 
@@ -303,7 +305,7 @@ namespace Max2Babylon
 
             // Instances
             var tabs = Loader.Global.NodeTab.Create();
-            
+
             Loader.Global.IInstanceMgr.InstanceMgr.GetInstances(meshNode.MaxNode, tabs);
             var instances = new List<BabylonAbstractMesh>();
 
@@ -319,7 +321,7 @@ namespace Max2Babylon
                     continue;
                 }
                 var instanceGameNode = scene.GetIGameNode(tab);
-                if(instanceGameNode == null)
+                if (instanceGameNode == null)
                 {
                     continue;
                 }
@@ -327,8 +329,9 @@ namespace Max2Babylon
 
                 var instance = new BabylonAbstractMesh { name = tab.Name };
                 {
-                    
-                    var localTM = instanceGameNode.GetLocalTM(0);
+
+                    var localTM = meshNode.GetObjectTM(0);
+
                     //var worldTM = meshNode.GetWorldTM(0);
                     //var objTM = meshNode.GetObjectTM(0);
                     var meshTrans = localTM.Translation;
@@ -343,9 +346,9 @@ namespace Max2Babylon
                     instance.rotation = new float[] { rotx, roty, rotz };
                     instance.scaling = new float[] { meshScale.X, meshScale.Y, meshScale.Z };
                 }
-                //var instanceAnimations = new List<BabylonAnimation>();
-                //GenerateCoordinatesAnimations(tab, instanceAnimations);
-                //instance.animations = instanceAnimations.ToArray();
+                var instanceAnimations = new List<BabylonAnimation>();
+                GenerateCoordinatesAnimations(meshNode, instanceAnimations);
+                instance.animations = instanceAnimations.ToArray();
 
                 instances.Add(instance);
             }
@@ -353,16 +356,16 @@ namespace Max2Babylon
             babylonMesh.instances = instances.ToArray();
 
             // Animations
-            //var animations = new List<BabylonAnimation>();
-            //GenerateCoordinatesAnimations(meshNode, animations);
+            var animations = new List<BabylonAnimation>();
+            GenerateCoordinatesAnimations(meshNode, animations);
 
 
-            //if (!ExportFloatController(meshNode.VisController, "visibility", animations))
-            //{
-            //    ExportFloatAnimation("visibility", animations, key => new[] { meshNode.GetVisibility(key, Tools.Forever) });
-            //}
+            if (!ExportFloatController(meshNode.MaxNode.VisController, "visibility", animations))
+            {
+                ExportFloatAnimation("visibility", animations, key => new[] { meshNode.MaxNode.GetVisibility(key, Tools.Forever) });
+            }
 
-            //babylonMesh.animations = animations.ToArray();
+            babylonMesh.animations = animations.ToArray();
 
             if (meshNode.MaxNode.GetBoolProperty("babylonjs_autoanimate", 1))
             {
@@ -375,130 +378,69 @@ namespace Max2Babylon
             babylonScene.MeshesList.Add(babylonMesh);
         }
 
-        //public static void GenerateCoordinatesAnimations(IIGameNode meshNode, List<BabylonAnimation> animations)
-        //{
-        //    var control = meshNode.IGameControl;
-        //    if (control.IsAnimated(IGameControlType.Tm))
-        //    {
-        //        // combined tm anim
-        //        ExportTMAnimation(control, animations);
-        //    }
-        //    else
-        //    {
-        //        if (control.IsAnimated(IGameControlType.Pos))
-        //        {
-        //            ExportPosAnimation(control, animations);
-        //        }
-        //    }
-        //    //if (!ExportVector3Controller(meshNode.TMController.PositionController, "position", animations))
-        //    //{
-        //    //    ExportVector3Animation("position", animations, key =>
-        //    //    {
-        //    //        var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent());
-        //    //        return worldMatrix.Trans.ToArraySwitched();
-        //    //    });
-        //    //}
-
-        //    //if (!ExportQuaternionController(meshNode.TMController.RotationController, "rotationQuaternion", animations))
-        //    //{
-        //    //    ExportQuaternionAnimation("rotationQuaternion", animations, key =>
-        //    //    {
-        //    //        var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent());
-
-        //    //        var affineParts = Loader.Global.AffineParts.Create();
-        //    //        Loader.Global.DecompAffine(worldMatrix, affineParts);
-
-        //    //        return affineParts.Q.ToArray();
-        //    //    });
-        //    //}
-
-        //    //if (!ExportVector3Controller(meshNode.TMController.ScaleController, "scaling", animations))
-        //    //{
-        //    //    ExportVector3Animation("scaling", animations, key =>
-        //    //    {
-        //    //        var worldMatrix = meshNode.GetWorldMatrix(key, meshNode.HasParent());
-
-        //    //        var affineParts = Loader.Global.AffineParts.Create();
-        //    //        Loader.Global.DecompAffine(worldMatrix, affineParts);
-
-        //    //        return affineParts.K.ToArraySwitched();
-        //    //    });
-        //    //}
-        //}
-
-        //private static void ExportPosAnimation(IIGameControl control, List<BabylonAnimation> animations)
-        //{
-        //    ITab<IIGameKey> keys = Loader.Global.Tab.Create<IIGameKey>();
-        //    if(control.GetLinearKeys(keys, IGameControlType.Pos))
-        //    {
-        //        if(keys.Count != 0)
-        //        {
-        //            // todo
-
-        //            return;
-        //        }
-        //    }
-
-        //    // full sampling
-        //    if(control.GetFullSampledKeys(keys, Loader.Global.FrameRate, IGameControlType.Pos, false))
-        //    {
-        //        if(keys.Count != 0)
-        //        {
-        //            List<BabylonAnimationKey> babKeys = new List<BabylonAnimationKey>();
-
-        //            for(int i = 0; i < keys.Count; ++i)
-        //            {
-        //                var keyIndexer = new IntPtr(i);
-        //                var key = keys[keyIndexer];
-        //                babKeys.Add(new BabylonAnimationKey {
-        //                frame = key.T /Ticks,
-        //                values = new float[] { key.SampleKey.Pval.X, key.SampleKey.Pval.Y, key.SampleKey.Pval.Z }
-        //                });
-        //            }
-
-        //            var babylonAnimation = new BabylonAnimation
-        //            {
-        //                dataType = BabylonAnimation.DataType.Vector3,
-        //                name = "position animation",
-        //                keys = babKeys.ToArray(),
-        //                framePerSecond = Loader.Global.FrameRate,
-        //                loopBehavior = BabylonAnimation.LoopBehavior.Cycle,
-        //                property = "position",
-                       
-        //            };
-        //            animations.Add(babylonAnimation);
-        //        }
-        //    }
-        //}
-
-        //private static void ExportTMAnimation(IIGameControl control, List<BabylonAnimation> animations)
-        //{
-
-        //}
-
-        int CreateGlobalVertex(IIGameMesh mesh, IFaceEx face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha,  List<GlobalVertex>[] verticesAlreadyExported, IIGameSkin skin)
+        public static void GenerateCoordinatesAnimations(IIGameNode meshNode, List<BabylonAnimation> animations)
+        {
+            //if (!ExportVector3Controller(meshNode.TMController.PositionController, "position", animations))
+            //{
+            ExportVector3Animation("position", animations, key =>
+            {
+                var worldMatrix = meshNode.GetObjectTM(key);
+                var trans = worldMatrix.Translation;
+                return new float[] { trans.X, trans.Y, trans.Z };
+            });
+            //}
+
+
+            //if (!ExportQuaternionController(meshNode.TMController.RotationController, "rotationQuaternion", animations))
+            //{
+                ExportQuaternionAnimation("rotationQuaternion", animations, key =>
+                {
+                    var worldMatrix = meshNode.GetObjectTM(key);
+
+
+
+                    var rot = worldMatrix.Rotation;
+                    return new float[] { rot.X, rot.Y, rot.Z, -rot.W };
+                });
+            //}
+
+
+            //if (!ExportVector3Controller(meshNode.TMController.ScaleController, "scaling", animations))
+            //{
+                ExportVector3Animation("scaling", animations, key =>
+                {
+                    var worldMatrix = meshNode.GetObjectTM(key);
+                    var scale = worldMatrix.Scaling;
+
+                    return new float[] { scale.X, scale.Y, scale.Z };
+                });
+           // }
+        }
+
+
+        int CreateGlobalVertex(IIGameMesh mesh, IFaceEx face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, List<GlobalVertex>[] verticesAlreadyExported, IIGameSkin skin)
         {
             var vertexIndex = (int)face.Vert[facePart];
-           
+
             var vertex = new GlobalVertex
             {
                 BaseIndex = vertexIndex,
                 Position = mesh.GetVertex(vertexIndex, true),
                 Normal = mesh.GetNormal((int)face.Norm[facePart], true) //vnorms[vertexIndex].GetNormal(verticesAlreadyExported != null ? 1 : faceObject.SmGroup)
             };
-          
+
             if (hasUV)
             {
                 int[] indices = new int[3];
                 unsafe
                 {
-                    fixed(int* indicesPtr = indices)
+                    fixed (int* indicesPtr = indices)
                     {
                         mesh.GetMapFaceIndex(1, face.MeshFaceIndex, new IntPtr(indicesPtr));
                     }
                 }
                 var texCoord = mesh.GetMapVertex(1, indices[facePart]);
-                vertex.UV = Loader.Global.Point2.Create( texCoord.X, -texCoord.Y);
+                vertex.UV = Loader.Global.Point2.Create(texCoord.X, -texCoord.Y);
             }
 
             if (hasUV2)
@@ -527,7 +469,7 @@ namespace Max2Babylon
                     alpha = p.X;
                 }
 
-                vertex.Color = new float[] { vertexColor.X, vertexColor.Y, vertexColor.Z, alpha};
+                vertex.Color = new float[] { vertexColor.X, vertexColor.Y, vertexColor.Z, alpha };
             }
 
             if (skin != null)
@@ -543,7 +485,7 @@ namespace Max2Babylon
 
                 if (nbBones > 0)
                 {
-                    bone0 = skin.GetBoneIndex(skin.GetBone(vertexIndex, 0),false);
+                    bone0 = skin.GetBoneIndex(skin.GetBone(vertexIndex, 0), false);
                     weight0 = skin.GetWeight(vertexIndex, 0);
                 }