浏览代码

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

QuentinRillet 7 年之前
父节点
当前提交
e31cc17370
共有 100 个文件被更改,包括 1418 次插入6452 次删除
  1. 11 2
      Exporters/3ds Max/BabylonExport.Entities/BabylonAnimationKey.cs
  2. 2 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonExport.Entities.csproj
  3. 3 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonMesh.cs
  4. 23 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonMorphTarget.cs
  5. 26 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonMorphTargetManager.cs
  6. 9 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonScene.cs
  7. 12 0
      Exporters/3ds Max/GltfExport.Entities/GLTF.cs
  8. 3 0
      Exporters/3ds Max/GltfExport.Entities/GLTFAccessor.cs
  9. 22 0
      Exporters/3ds Max/GltfExport.Entities/GLTFAnimation.cs
  10. 49 0
      Exporters/3ds Max/GltfExport.Entities/GLTFAnimationSampler.cs
  11. 2 1
      Exporters/3ds Max/GltfExport.Entities/GLTFBuffer.cs
  12. 2 1
      Exporters/3ds Max/GltfExport.Entities/GLTFBufferView.cs
  13. 21 0
      Exporters/3ds Max/GltfExport.Entities/GLTFChannel.cs
  14. 20 0
      Exporters/3ds Max/GltfExport.Entities/GLTFChannelTarget.cs
  15. 5 0
      Exporters/3ds Max/GltfExport.Entities/GLTFExport.Entities.csproj
  16. 2 2
      Exporters/3ds Max/GltfExport.Entities/GLTFMeshPrimitive.cs
  17. 16 0
      Exporters/3ds Max/GltfExport.Entities/GLTFMorphTarget.cs
  18. 二进制
      Exporters/3ds Max/Max2Babylon-0.17.0.zip
  19. 6 0
      Exporters/3ds Max/Max2Babylon/2015/Max2Babylon2015.csproj
  20. 6 0
      Exporters/3ds Max/Max2Babylon/2017/Max2Babylon2017.csproj
  21. 102 30
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Animation.cs
  22. 4 1
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.AbstractMesh.cs
  23. 416 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Animation.cs
  24. 2 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Camera.cs
  25. 3 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Light.cs
  26. 221 305
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Mesh.cs
  27. 29 9
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.cs
  28. 203 84
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs
  29. 7 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs
  30. 158 0
      Exporters/3ds Max/Max2Babylon/Exporter/GLTFBufferService.cs
  31. 18 1
      Exporters/3ds Max/Max2Babylon/Tools/Tools.cs
  32. 二进制
      Exporters/Blender/Blender2Babylon-5.4.zip
  33. 1 1
      Exporters/Blender/src/babylon-js/__init__.py
  34. 14 10
      Exporters/Blender/src/babylon-js/mesh.py
  35. 0 66
      Exporters/FBX/BabylonFBXExporter.sln
  36. 0 33
      Exporters/FBX/BabylonFbxNative/BabylonAbstractMesh.cpp
  37. 0 48
      Exporters/FBX/BabylonFbxNative/BabylonAbstractMesh.h
  38. 0 8
      Exporters/FBX/BabylonFbxNative/BabylonAnimation.cpp
  39. 0 231
      Exporters/FBX/BabylonFbxNative/BabylonAnimation.h
  40. 0 200
      Exporters/FBX/BabylonFbxNative/BabylonCamera.cpp
  41. 0 86
      Exporters/FBX/BabylonFbxNative/BabylonCamera.h
  42. 0 233
      Exporters/FBX/BabylonFbxNative/BabylonFbxNative.vcxproj
  43. 0 132
      Exporters/FBX/BabylonFbxNative/BabylonFbxNative.vcxproj.filters
  44. 0 254
      Exporters/FBX/BabylonFbxNative/BabylonLight.cpp
  45. 0 112
      Exporters/FBX/BabylonFbxNative/BabylonLight.h
  46. 0 385
      Exporters/FBX/BabylonFbxNative/BabylonMaterial.cpp
  47. 0 126
      Exporters/FBX/BabylonFbxNative/BabylonMaterial.h
  48. 0 891
      Exporters/FBX/BabylonFbxNative/BabylonMesh.cpp
  49. 0 129
      Exporters/FBX/BabylonFbxNative/BabylonMesh.h
  50. 0 69
      Exporters/FBX/BabylonFbxNative/BabylonNode.cpp
  51. 0 70
      Exporters/FBX/BabylonFbxNative/BabylonNode.h
  52. 0 258
      Exporters/FBX/BabylonFbxNative/BabylonScene.cpp
  53. 0 94
      Exporters/FBX/BabylonFbxNative/BabylonScene.h
  54. 0 41
      Exporters/FBX/BabylonFbxNative/BabylonSkeleton.cpp
  55. 0 48
      Exporters/FBX/BabylonFbxNative/BabylonSkeleton.h
  56. 0 412
      Exporters/FBX/BabylonFbxNative/BabylonVertex.h
  57. 0 11
      Exporters/FBX/BabylonFbxNative/FbxDeleter.h
  58. 0 22
      Exporters/FBX/BabylonFbxNative/FbxLoadException.cpp
  59. 0 17
      Exporters/FBX/BabylonFbxNative/FbxLoadException.h
  60. 0 12
      Exporters/FBX/BabylonFbxNative/FbxMeshHandler.cpp
  61. 0 8
      Exporters/FBX/BabylonFbxNative/FbxMeshHandler.h
  62. 0 56
      Exporters/FBX/BabylonFbxNative/FbxSceneLoader.cpp
  63. 0 61
      Exporters/FBX/BabylonFbxNative/FbxSceneLoader.h
  64. 0 13
      Exporters/FBX/BabylonFbxNative/GlobalSettings.cpp
  65. 0 17
      Exporters/FBX/BabylonFbxNative/GlobalSettings.h
  66. 0 33
      Exporters/FBX/BabylonFbxNative/MatrixDecomposition.h
  67. 0 45
      Exporters/FBX/BabylonFbxNative/NodeHelpers.h
  68. 0 37
      Exporters/FBX/BabylonFbxNative/ReadMe.txt
  69. 0 227
      Exporters/FBX/BabylonFbxNative/SkinInfo.cpp
  70. 0 79
      Exporters/FBX/BabylonFbxNative/SkinInfo.h
  71. 0 21
      Exporters/FBX/BabylonFbxNative/StringUtils.h
  72. 0 50
      Exporters/FBX/BabylonFbxNative/babylon_boundingbox.cpp
  73. 0 11
      Exporters/FBX/BabylonFbxNative/packages.config
  74. 0 8
      Exporters/FBX/BabylonFbxNative/stdafx.cpp
  75. 0 18
      Exporters/FBX/BabylonFbxNative/stdafx.h
  76. 0 8
      Exporters/FBX/BabylonFbxNative/targetver.h
  77. 0 179
      Exporters/FBX/FbxExporter/FbxExporter.cpp
  78. 0 207
      Exporters/FBX/FbxExporter/FbxExporter.vcxproj
  79. 0 39
      Exporters/FBX/FbxExporter/FbxExporter.vcxproj.filters
  80. 0 40
      Exporters/FBX/FbxExporter/ReadMe.txt
  81. 0 11
      Exporters/FBX/FbxExporter/packages.config
  82. 0 8
      Exporters/FBX/FbxExporter/stdafx.cpp
  83. 0 15
      Exporters/FBX/FbxExporter/stdafx.h
  84. 0 8
      Exporters/FBX/FbxExporter/targetver.h
  85. 0 11
      Exporters/FBX/FbxRerouteSkeleton/FbxDeleter.h
  86. 0 274
      Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.cpp
  87. 0 169
      Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.vcxproj
  88. 0 39
      Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.vcxproj.filters
  89. 0 40
      Exporters/FBX/FbxRerouteSkeleton/ReadMe.txt
  90. 0 8
      Exporters/FBX/FbxRerouteSkeleton/stdafx.cpp
  91. 0 15
      Exporters/FBX/FbxRerouteSkeleton/stdafx.h
  92. 0 8
      Exporters/FBX/FbxRerouteSkeleton/targetver.h
  93. 0 25
      Exporters/FBX/FbxTests/FbxTests.cpp
  94. 0 123
      Exporters/FBX/FbxTests/FbxTests.vcxproj
  95. 0 39
      Exporters/FBX/FbxTests/FbxTests.vcxproj.filters
  96. 0 40
      Exporters/FBX/FbxTests/ReadMe.txt
  97. 0 4
      Exporters/FBX/FbxTests/packages.config
  98. 0 8
      Exporters/FBX/FbxTests/stdafx.cpp
  99. 0 15
      Exporters/FBX/FbxTests/stdafx.h
  100. 0 0
      Exporters/FBX/FbxTests/targetver.h

+ 11 - 2
Exporters/3ds Max/BabylonExport.Entities/BabylonAnimationKey.cs

@@ -1,14 +1,23 @@
-using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
 
 namespace BabylonExport.Entities
 {
     [DataContract]
-    public class BabylonAnimationKey
+    public class BabylonAnimationKey : IComparable<BabylonAnimationKey>
     {
         [DataMember]
         public int frame { get; set; }
 
         [DataMember]
         public float[] values { get; set; }
+        
+        public int CompareTo(BabylonAnimationKey other)
+        {
+            if (other == null)
+                return 1;
+            else
+                return this.frame.CompareTo(other.frame);
+        }
     }
 }

+ 2 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonExport.Entities.csproj

@@ -56,6 +56,8 @@
   <ItemGroup>
     <Compile Include="BabylonActions.cs" />
     <Compile Include="BabylonAnimation.cs" />
+    <Compile Include="BabylonMorphTarget.cs" />
+    <Compile Include="BabylonMorphTargetManager.cs" />
     <Compile Include="BabylonPBRMetallicRoughnessMaterial.cs" />
     <Compile Include="BabylonAnimationKey.cs" />
     <Compile Include="BabylonBone.cs" />

+ 3 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonMesh.cs

@@ -110,6 +110,9 @@ namespace BabylonExport.Entities
         [DataMember]
         public string tags { get; set; }
 
+        [DataMember(EmitDefaultValue = false)]
+        public int? morphTargetManagerId { get; set; }
+
         public bool isDummy = false;
 
         public BabylonMesh()

+ 23 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonMorphTarget.cs

@@ -0,0 +1,23 @@
+using System.Runtime.Serialization;
+
+namespace BabylonExport.Entities
+{
+    [DataContract]
+    public class BabylonMorphTarget
+    {
+        [DataMember(EmitDefaultValue = false)]
+        public string name { get; set; }
+
+        [DataMember(IsRequired = true)]
+        public float influence { get; set; }
+
+        [DataMember(IsRequired = true)]
+        public float[] positions { get; set; }
+
+        [DataMember(IsRequired = true)]
+        public float[] normals { get; set; }
+
+        [DataMember(EmitDefaultValue = false)]
+        public BabylonAnimation[] animations { get; set; }
+    }
+}

+ 26 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonMorphTargetManager.cs

@@ -0,0 +1,26 @@
+using System.Runtime.Serialization;
+
+namespace BabylonExport.Entities
+{
+    [DataContract]
+    public class BabylonMorphTargetManager
+    {
+        private static int NB_BABYLON_MORPH_TARGET_MANAGER;
+
+        [DataMember(IsRequired = true)]
+        public int id { get; set; }
+
+        [DataMember(IsRequired = true)]
+        public BabylonMorphTarget[] targets { get; set; }
+
+        public static void Reset()
+        {
+            NB_BABYLON_MORPH_TARGET_MANAGER = 0;
+        }
+
+        public BabylonMorphTargetManager()
+        {
+            id = NB_BABYLON_MORPH_TARGET_MANAGER++;
+        }
+    }
+}

+ 9 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonScene.cs

@@ -89,6 +89,9 @@ namespace BabylonExport.Entities
         [DataMember]
         public bool workerCollisions { get; set; }
 
+        [DataMember]
+        public BabylonMorphTargetManager[] morphTargetManagers { get; set; }
+
         public BabylonVector3 MaxVector { get; set; }
         public BabylonVector3 MinVector { get; set; }
 
@@ -102,6 +105,7 @@ namespace BabylonExport.Entities
         public List<BabylonMultiMaterial> MultiMaterialsList { get; private set; }
         public List<BabylonShadowGenerator> ShadowGeneratorsList { get; private set; }
         public List<BabylonSkeleton> SkeletonsList { get; private set; }
+        public List<BabylonMorphTargetManager> MorphTargetManagersList { get; private set; }
 
         readonly List<string> exportedTextures = new List<string>();
 
@@ -117,6 +121,7 @@ namespace BabylonExport.Entities
             ShadowGeneratorsList = new List<BabylonShadowGenerator>();
             SkeletonsList = new List<BabylonSkeleton>();
             SoundsList = new List<BabylonSound>();
+            MorphTargetManagersList = new List<BabylonMorphTargetManager>();
 
             // Default values
             autoClear = true;
@@ -137,6 +142,10 @@ namespace BabylonExport.Entities
             multiMaterials = MultiMaterialsList.ToArray();
             shadowGenerators = ShadowGeneratorsList.ToArray();
             skeletons = SkeletonsList.ToArray();
+            if (MorphTargetManagersList.Count > 0)
+            {
+                morphTargetManagers = MorphTargetManagersList.ToArray();
+            }
 
             if (CamerasList.Count == 0 && generateDefaultCamera)
             {

+ 12 - 0
Exporters/3ds Max/GltfExport.Entities/GLTF.cs

@@ -46,6 +46,9 @@ namespace GLTFExport.Entities
         [DataMember(EmitDefaultValue = false)]
         public GLTFSampler[] samplers { get; set; }
 
+        [DataMember(EmitDefaultValue = false)]
+        public GLTFAnimation[] animations { get; set; }
+
         public string OutputFolder { get; private set; }
         public string OutputFile { get; private set; }
 
@@ -59,6 +62,7 @@ namespace GLTFExport.Entities
         public List<GLTFTexture> TexturesList { get; private set; }
         public List<GLTFImage> ImagesList { get; private set; }
         public List<GLTFSampler> SamplersList { get; private set; }
+        public List<GLTFAnimation> AnimationsList { get; private set; }
 
         public GLTFBuffer buffer;
         public GLTFBufferView bufferViewScalar;
@@ -66,6 +70,9 @@ namespace GLTFExport.Entities
         public GLTFBufferView bufferViewFloatVec4;
         public GLTFBufferView bufferViewFloatVec2;
         public GLTFBufferView bufferViewImage;
+        public GLTFBufferView bufferViewAnimationFloatScalar;
+        public GLTFBufferView bufferViewAnimationFloatVec3;
+        public GLTFBufferView bufferViewAnimationFloatVec4;
 
         public GLTF(string outputPath)
         {
@@ -82,6 +89,7 @@ namespace GLTFExport.Entities
             TexturesList = new List<GLTFTexture>();
             ImagesList = new List<GLTFImage>();
             SamplersList = new List<GLTFSampler>();
+            AnimationsList = new List<GLTFAnimation>();
         }
 
         public void Prepare()
@@ -130,6 +138,10 @@ namespace GLTFExport.Entities
             {
                 samplers = SamplersList.ToArray();
             }
+            if (AnimationsList.Count > 0)
+            {
+                animations = AnimationsList.ToArray();
+            }
         }
     }
 }

+ 3 - 0
Exporters/3ds Max/GltfExport.Entities/GLTFAccessor.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Runtime.Serialization;
 
 namespace GLTFExport.Entities
@@ -56,6 +57,8 @@ namespace GLTFExport.Entities
 
         public GLTFBufferView BufferView;
 
+        public List<byte> bytesList = new List<byte>();
+
         public int getByteLength()
         {
             return count * getElementSize();

+ 22 - 0
Exporters/3ds Max/GltfExport.Entities/GLTFAnimation.cs

@@ -0,0 +1,22 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace GLTFExport.Entities
+{
+    [DataContract]
+    public class GLTFAnimation : GLTFChildRootProperty
+    {
+        /// <summary>
+        /// An array of channels, each of which targets an animation's sampler at a node's property.
+        /// Different channels of the same animation can't have equal targets.
+        /// </summary>
+        [DataMember(IsRequired = true)]
+        public GLTFChannel[] channels { get; set; }
+
+        /// <summary>
+        /// An array of samplers that combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target).
+        /// </summary>
+        [DataMember(IsRequired = true)]
+        public GLTFAnimationSampler[] samplers { get; set; }
+    }
+}

+ 49 - 0
Exporters/3ds Max/GltfExport.Entities/GLTFAnimationSampler.cs

@@ -0,0 +1,49 @@
+using System.Runtime.Serialization;
+
+namespace GLTFExport.Entities
+{
+    [DataContract]
+    public class GLTFAnimationSampler : GLTFProperty
+    {
+        public enum Interpolation
+        {
+            LINEAR,
+            STEP,
+            CATMULLROMSPLINE,
+            CUBICSPLINE
+        }
+
+        /// <summary>
+        /// The index of an accessor containing keyframe input values, e.g., time. That accessor must have componentType FLOAT.
+        /// The values represent time in seconds with time[0] >= 0.0, and strictly increasing values, i.e., time[n + 1] > time[n].
+        /// </summary>
+        [DataMember(IsRequired = true)]
+        public int input { get; set; }
+
+        [DataMember(EmitDefaultValue = false)]
+        public string interpolation { get; private set; }
+
+        /// <summary>
+        /// The index of an accessor containing keyframe output values.
+        /// When targeting TRS target, the accessor.componentType of the output values must be FLOAT.
+        /// When targeting morph weights, the accessor.componentType of the output values must be FLOAT
+        /// or normalized integer where each output element stores values with a count equal to the number of morph targets.
+        /// </summary>
+        [DataMember(IsRequired = true)]
+        public int output { get; set; }
+
+        public int index;
+
+        public void SetInterpolation(Interpolation interpolation)
+        {
+            this.interpolation = interpolation.ToString();
+        }
+
+        public GLTFAnimationSampler()
+        {
+            // For GLTF, default value is LINEAR
+            // but gltf loader of BABYLON doesn't handle missing interpolation value
+            SetInterpolation(Interpolation.LINEAR);
+        }
+    }
+}

+ 2 - 1
Exporters/3ds Max/GltfExport.Entities/GLTFBuffer.cs

@@ -12,6 +12,7 @@ namespace GLTFExport.Entities
         [DataMember(IsRequired = true)]
         public int byteLength { get; set; }
 
-        public List<byte> bytesList;
+        public List<byte> bytesList = new List<byte>();
+        public List<GLTFBufferView> BufferViews = new List<GLTFBufferView>();
     }
 }

+ 2 - 1
Exporters/3ds Max/GltfExport.Entities/GLTFBufferView.cs

@@ -16,9 +16,10 @@ namespace GLTFExport.Entities
         public int byteLength { get; set; }
 
         [DataMember(EmitDefaultValue = false)]
-        public int? byteStride { get; set; }
+        public int? byteStride { get; set; } // Field only defined for buffer views that contain vertex attributes.
 
         public GLTFBuffer Buffer;
+        public List<GLTFAccessor> Accessors = new List<GLTFAccessor>();
         public List<byte> bytesList = new List<byte>();
     }
 }

+ 21 - 0
Exporters/3ds Max/GltfExport.Entities/GLTFChannel.cs

@@ -0,0 +1,21 @@
+using System.Runtime.Serialization;
+
+namespace GLTFExport.Entities
+{
+    [DataContract]
+    public class GLTFChannel : GLTFProperty
+    {
+        /// <summary>
+        /// The index of a sampler in this animation used to compute the value for the target,
+        /// e.g., a node's translation, rotation, or scale (TRS).
+        /// </summary>
+        [DataMember(IsRequired = true)]
+        public int sampler { get; set; }
+
+        /// <summary>
+        /// The index of the node and TRS property to target.
+        /// </summary>
+        [DataMember(IsRequired = true)]
+        public GLTFChannelTarget target { get; set; }
+    }
+}

+ 20 - 0
Exporters/3ds Max/GltfExport.Entities/GLTFChannelTarget.cs

@@ -0,0 +1,20 @@
+using System.Runtime.Serialization;
+
+namespace GLTFExport.Entities
+{
+    [DataContract]
+    public class GLTFChannelTarget : GLTFProperty
+    {
+        /// <summary>
+        /// The index of the node to target.
+        /// </summary>
+        [DataMember(EmitDefaultValue = false)]
+        public int? node { get; set; }
+
+        /// <summary>
+        /// The name of the node's TRS property to modify, or the "weights" of the Morph Targets it instantiates.
+        /// </summary>
+        [DataMember(IsRequired = true)]
+        public string path { get; set; }
+    }
+}

+ 5 - 0
Exporters/3ds Max/GltfExport.Entities/GLTFExport.Entities.csproj

@@ -42,11 +42,16 @@
   <ItemGroup>
     <Compile Include="GLTF.cs" />
     <Compile Include="GLTFAccessor.cs" />
+    <Compile Include="GLTFAnimationSampler.cs" />
+    <Compile Include="GLTFAnimation.cs" />
+    <Compile Include="GLTFChannelTarget.cs" />
+    <Compile Include="GLTFChannel.cs" />
     <Compile Include="GLTFBufferView.cs" />
     <Compile Include="GLTFBuffer.cs" />
     <Compile Include="GLTFCameraPerspective.cs" />
     <Compile Include="GLTFCameraOrthographic.cs" />
     <Compile Include="GLTFCamera.cs" />
+    <Compile Include="GLTFMorphTarget.cs" />
     <Compile Include="GLTFSampler.cs" />
     <Compile Include="GLTFIndexedChildRootProperty.cs" />
     <Compile Include="GLTFImage.cs" />

+ 2 - 2
Exporters/3ds Max/GltfExport.Entities/GLTFMeshPrimitive.cs

@@ -41,7 +41,7 @@ namespace GLTFExport.Entities
         [DataMember(EmitDefaultValue = false)]
         public int? material { get; set; }
 
-        //[DataMember]
-        //public Dictionary<string, int>[] targets { get; set; }
+        [DataMember(EmitDefaultValue = false)]
+        public GLTFMorphTarget[] targets { get; set; }
     }
 }

+ 16 - 0
Exporters/3ds Max/GltfExport.Entities/GLTFMorphTarget.cs

@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace GLTFExport.Entities
+{
+    [DataContract]
+    public class GLTFMorphTarget : Dictionary<string, int>
+    {
+        public enum Attribute
+        {
+            POSITION,
+            NORMAL,
+            TANGENT
+        }
+    }
+}

二进制
Exporters/3ds Max/Max2Babylon-0.17.0.zip


+ 6 - 0
Exporters/3ds Max/Max2Babylon/2015/Max2Babylon2015.csproj

@@ -218,6 +218,12 @@
     <Compile Include="..\Tools\WebServer.cs">
       <Link>Tools\WebServer.cs</Link>
     </Compile>
+    <Compile Include="..\Exporter\GLTFBufferService.cs">
+      <Link>Exporter\GLTFBufferService.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.GLTFExporter.Animation.cs">
+      <Link>Exporter\BabylonExporter.GLTFExporter.Animation.cs</Link>
+    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\Resources.Designer.cs">
       <AutoGen>True</AutoGen>

+ 6 - 0
Exporters/3ds Max/Max2Babylon/2017/Max2Babylon2017.csproj

@@ -218,6 +218,12 @@
     <Compile Include="..\Tools\WebServer.cs">
       <Link>Tools\WebServer.cs</Link>
     </Compile>
+    <Compile Include="..\Exporter\GLTFBufferService.cs">
+      <Link>Exporter\GLTFBufferService.cs</Link>
+    </Compile>
+    <Compile Include="..\Exporter\BabylonExporter.GLTFExporter.Animation.cs">
+      <Link>Exporter\BabylonExporter.GLTFExporter.Animation.cs</Link>
+    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\Resources.Designer.cs">
       <AutoGen>True</AutoGen>

+ 102 - 30
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Animation.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using Autodesk.Max;
 using BabylonExport.Entities;
+using System.Runtime.InteropServices;
 
 namespace Max2Babylon
 {
@@ -9,6 +10,101 @@ namespace Max2Babylon
     {
         const int Ticks = 160;
 
+        private static bool ExportBabylonKeys(List<BabylonAnimationKey> keys, string property, List<BabylonAnimation> animations, BabylonAnimation.DataType dataType, BabylonAnimation.LoopBehavior loopBehavior)
+        {
+            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;
+        }
+
+        // -----------------------
+        // -- From GameControl ---
+        // -----------------------
+
+        private bool ExportFloatGameController(IIGameControl control, string property, List<BabylonAnimation> animations)
+        {
+            return ExportGameController(control, property, animations, IGameControlType.Float, BabylonAnimation.DataType.Float, gameKey => new float[] { gameKey.SampleKey.Fval / 100.0f });
+        }
+
+        private bool ExportGameController(IIGameControl control, string property, List<BabylonAnimation> animations, IGameControlType type, BabylonAnimation.DataType dataType, Func<IIGameKey, float[]> extractValueFunc)
+        {
+            var keys = ExportBabylonKeysFromGameController(control, type, extractValueFunc);
+
+            if (keys == null)
+            {
+                return false;
+            }
+
+            var loopBehavior = BabylonAnimation.LoopBehavior.Cycle;
+            return ExportBabylonKeys(keys, property, animations, dataType, loopBehavior);
+        }
+
+        private List<BabylonAnimationKey> ExportBabylonKeysFromGameController(IIGameControl control, IGameControlType type, Func<IIGameKey, float[]> extractValueFunc)
+        {
+            if (control == null)
+            {
+                return null;
+            }
+
+            ITab<IIGameKey> gameKeyTab = GlobalInterface.Instance.Tab.Create<IIGameKey>();
+            control.GetQuickSampledKeys(gameKeyTab, type);
+
+            if (gameKeyTab == null)
+            {
+                return null;
+            }
+
+            var keys = new List<BabylonAnimationKey>();
+            for (int indexKey = 0; indexKey < gameKeyTab.Count; indexKey++)
+            {
+#if MAX2017
+                var indexer = indexKey;
+#else
+                    var indexer = new IntPtr(indexKey);
+                    Marshal.FreeHGlobal(indexer);
+#endif
+                var gameKey = gameKeyTab[indexer];
+
+                var key = new BabylonAnimationKey()
+                {
+                    frame = gameKey.T / Ticks,
+                    values = extractValueFunc(gameKey)
+                };
+                keys.Add(key);
+            }
+
+            return keys;
+        }
+
+        // -----------------------
+        // ---- From Control -----
+        // -----------------------
+
         private static BabylonAnimationKey GenerateFloatFunc(int index, IIKeyControl keyControl)
         {
             var key = Loader.Global.ILinFloatKey.Create();
@@ -119,9 +215,7 @@ namespace Max2Babylon
                 return false;
             }
 
-            var keys = new List<BabylonAnimationKey>();
             BabylonAnimation.LoopBehavior loopBehavior;
-
             switch (control.GetORT(2))
             {
                 case 2:
@@ -132,41 +226,19 @@ namespace Max2Babylon
                     break;
             }
 
+            var keys = new List<BabylonAnimationKey>();
             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;
+            return ExportBabylonKeys(keys, property, animations, dataType, loopBehavior);
         }
 
+        // -----------------------
+        // ---- From ext func ----
+        // -----------------------
+
         private static void ExportColor3Animation(string property, List<BabylonAnimation> animations,
             Func<int, float[]> extractValueFunc)
         {

+ 4 - 1
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.AbstractMesh.cs

@@ -5,7 +5,7 @@ namespace Max2Babylon
 {
     partial class BabylonExporter
     {
-        private GLTFNode ExportAbstractMesh(BabylonAbstractMesh babylonAbstractMesh, GLTF gltf, GLTFNode gltfParentNode)
+        private GLTFNode ExportAbstractMesh(BabylonAbstractMesh babylonAbstractMesh, GLTF gltf, GLTFNode gltfParentNode, BabylonScene babylonScene)
         {
             RaiseMessage("GLTFExporter.AbstractMesh | Export abstract mesh named: " + babylonAbstractMesh.name, 1);
 
@@ -55,6 +55,9 @@ namespace Max2Babylon
                 gltfNode.mesh = gltfMesh.index;
             }
 
+            // Animations
+            ExportNodeAnimation(babylonAbstractMesh, gltf, gltfNode, babylonScene);
+
             return gltfNode;
         }
     }

+ 416 - 0
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Animation.cs

@@ -0,0 +1,416 @@
+using BabylonExport.Entities;
+using GLTFExport.Entities;
+using System;
+using System.Collections.Generic;
+
+namespace Max2Babylon
+{
+    partial class BabylonExporter
+    {
+        private static float FPS_FACTOR = 60.0f; // TODO - Which FPS factor ?
+
+        private GLTFAnimation ExportNodeAnimation(BabylonNode babylonNode, GLTF gltf, GLTFNode gltfNode, BabylonScene babylonScene = null)
+        {
+            var channelList = new List<GLTFChannel>();
+            var samplerList = new List<GLTFAnimationSampler>();
+
+            if (babylonNode.animations != null && babylonNode.animations.Length > 0)
+            {
+                RaiseMessage("GLTFExporter.Animation | Export animation of node named: " + babylonNode.name, 2);
+
+                foreach (BabylonAnimation babylonAnimation in babylonNode.animations)
+                {
+                    // Target
+                    var gltfTarget = new GLTFChannelTarget
+                    {
+                        node = gltfNode.index
+                    };
+                    gltfTarget.path = _getTargetPath(babylonAnimation.property);
+                    if (gltfTarget.path == null)
+                    {
+                        // Unkown babylon animation property
+                        RaiseWarning("GLTFExporter.Animation | Unkown animation property '" + babylonAnimation.property + "'", 3);
+                        // Ignore this babylon animation
+                        continue;
+                    }
+
+                    // Buffer
+                    var buffer = GLTFBufferService.Instance.GetBuffer(gltf);
+
+                    // --- Input ---
+                    var accessorInput = GLTFBufferService.Instance.CreateAccessor(
+                        gltf,
+                        GLTFBufferService.Instance.GetBufferViewAnimationFloatScalar(gltf, buffer),
+                        "accessorAnimationInput",
+                        GLTFAccessor.ComponentType.FLOAT,
+                        GLTFAccessor.TypeEnum.SCALAR
+                    );
+                    // Populate accessor
+                    accessorInput.min = new float[] { float.MaxValue };
+                    accessorInput.max = new float[] { float.MinValue };
+                    foreach (var babylonAnimationKey in babylonAnimation.keys)
+                    {
+                        var inputValue = babylonAnimationKey.frame / FPS_FACTOR;
+                        // Store values as bytes
+                        accessorInput.bytesList.AddRange(BitConverter.GetBytes(inputValue));
+                        // Update min and max values
+                        GLTFBufferService.UpdateMinMaxAccessor(accessorInput, inputValue);
+                    };
+                    accessorInput.count = babylonAnimation.keys.Length;
+
+                    // --- Output ---
+                    GLTFAccessor accessorOutput = null;
+                    switch (gltfTarget.path)
+                    {
+                        case "translation":
+                            accessorOutput = GLTFBufferService.Instance.CreateAccessor(
+                                gltf,
+                                GLTFBufferService.Instance.GetBufferViewAnimationFloatVec3(gltf, buffer),
+                                "accessorAnimationPositions",
+                                GLTFAccessor.ComponentType.FLOAT,
+                                GLTFAccessor.TypeEnum.VEC3
+                            );
+                            break;
+                        case "rotation":
+                            accessorOutput = GLTFBufferService.Instance.CreateAccessor(
+                                gltf,
+                                GLTFBufferService.Instance.GetBufferViewAnimationFloatVec4(gltf, buffer),
+                                "accessorAnimationRotations",
+                                GLTFAccessor.ComponentType.FLOAT,
+                                GLTFAccessor.TypeEnum.VEC4
+                            );
+                            break;
+                        case "scale":
+                            accessorOutput = GLTFBufferService.Instance.CreateAccessor(
+                                gltf,
+                                GLTFBufferService.Instance.GetBufferViewAnimationFloatVec3(gltf, buffer),
+                                "accessorAnimationScales",
+                                GLTFAccessor.ComponentType.FLOAT,
+                                GLTFAccessor.TypeEnum.VEC3
+                            );
+                            break;
+                    }
+                    // Populate accessor
+                    foreach (var babylonAnimationKey in babylonAnimation.keys)
+                    {
+                        var outputValues = babylonAnimationKey.values;
+                        // Store values as bytes
+                        foreach (var outputValue in outputValues)
+                        {
+                            accessorOutput.bytesList.AddRange(BitConverter.GetBytes(outputValue));
+                        }
+                    };
+                    accessorOutput.count = babylonAnimation.keys.Length;
+
+                    // Animation sampler
+                    var gltfAnimationSampler = new GLTFAnimationSampler
+                    {
+                        input = accessorInput.index,
+                        output = accessorOutput.index
+                    };
+                    gltfAnimationSampler.index = samplerList.Count;
+                    samplerList.Add(gltfAnimationSampler);
+
+                    // Channel
+                    var gltfChannel = new GLTFChannel
+                    {
+                        sampler = gltfAnimationSampler.index,
+                        target = gltfTarget
+                    };
+                    channelList.Add(gltfChannel);
+                }
+            }
+
+            if (babylonNode.GetType() == typeof(BabylonMesh))
+            {
+                var babylonMesh = babylonNode as BabylonMesh;
+
+                // Morph targets
+                var babylonMorphTargetManager = GetBabylonMorphTargetManager(babylonScene, babylonMesh);
+                if (babylonMorphTargetManager != null)
+                {
+                    ExportMorphTargetWeightAnimation(babylonMorphTargetManager, gltf, gltfNode, channelList, samplerList);
+                }
+            }
+
+            // Do not export empty arrays
+            if (channelList.Count > 0)
+            {
+                // Animation
+                var gltfAnimation = new GLTFAnimation
+                {
+                    channels = channelList.ToArray(),
+                    samplers = samplerList.ToArray()
+                };
+                gltf.AnimationsList.Add(gltfAnimation);
+                return gltfAnimation;
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+        private bool ExportMorphTargetWeightAnimation(BabylonMorphTargetManager babylonMorphTargetManager, GLTF gltf, GLTFNode gltfNode, List<GLTFChannel> channelList, List<GLTFAnimationSampler> samplerList)
+        {
+            if (!_isBabylonMorphTargetManagerAnimationValid(babylonMorphTargetManager))
+            {
+                return false;
+            }
+
+            RaiseMessage("GLTFExporter.Animation | Export animation of morph target manager with id: " + babylonMorphTargetManager.id, 2);
+
+            var influencesPerFrame = _getTargetManagerAnimationsData(babylonMorphTargetManager);
+            var frames = new List<int>(influencesPerFrame.Keys);
+            frames.Sort(); // Mandatory otherwise gltf loader of babylon doesn't understand
+
+            // Target
+            var gltfTarget = new GLTFChannelTarget
+            {
+                node = gltfNode.index
+            };
+            gltfTarget.path = "weights";
+
+            // Buffer
+            var buffer = GLTFBufferService.Instance.GetBuffer(gltf);
+
+            // --- Input ---
+            var accessorInput = GLTFBufferService.Instance.CreateAccessor(
+                gltf,
+                GLTFBufferService.Instance.GetBufferViewAnimationFloatScalar(gltf, buffer),
+                "accessorAnimationInput",
+                GLTFAccessor.ComponentType.FLOAT,
+                GLTFAccessor.TypeEnum.SCALAR
+            );
+            // Populate accessor
+            accessorInput.min = new float[] { float.MaxValue };
+            accessorInput.max = new float[] { float.MinValue };
+
+            foreach (var frame in frames)
+            {
+                var inputValue = frame / FPS_FACTOR;
+                // Store values as bytes
+                accessorInput.bytesList.AddRange(BitConverter.GetBytes(inputValue));
+                // Update min and max values
+                GLTFBufferService.UpdateMinMaxAccessor(accessorInput, inputValue);
+            }
+            accessorInput.count = influencesPerFrame.Count;
+
+            // --- Output ---
+            GLTFAccessor accessorOutput = GLTFBufferService.Instance.CreateAccessor(
+                gltf,
+                GLTFBufferService.Instance.GetBufferViewAnimationFloatScalar(gltf, buffer),
+                "accessorAnimationWeights",
+                GLTFAccessor.ComponentType.FLOAT,
+                GLTFAccessor.TypeEnum.SCALAR
+            );
+            // Populate accessor
+            foreach (var frame in frames)
+            {
+                var outputValues = influencesPerFrame[frame];
+                // Store values as bytes
+                foreach (var outputValue in outputValues)
+                {
+                    accessorOutput.count++;
+                    accessorOutput.bytesList.AddRange(BitConverter.GetBytes(outputValue));
+                }
+            }
+
+            // Animation sampler
+            var gltfAnimationSampler = new GLTFAnimationSampler
+            {
+                input = accessorInput.index,
+                output = accessorOutput.index
+            };
+            gltfAnimationSampler.index = samplerList.Count;
+            samplerList.Add(gltfAnimationSampler);
+
+            // Channel
+            var gltfChannel = new GLTFChannel
+            {
+                sampler = gltfAnimationSampler.index,
+                target = gltfTarget
+            };
+            channelList.Add(gltfChannel);
+
+            return true;
+        }
+
+        private bool _isBabylonMorphTargetManagerAnimationValid(BabylonMorphTargetManager babylonMorphTargetManager)
+        {
+            bool hasAnimation = false;
+            bool areAnimationsValid = true;
+            foreach (var babylonMorphTarget in babylonMorphTargetManager.targets)
+            {
+                if (babylonMorphTarget.animations != null && babylonMorphTarget.animations.Length > 0)
+                {
+                    hasAnimation = true;
+
+                    // Ensure target has only one animation
+                    if (babylonMorphTarget.animations.Length > 1)
+                    {
+                        areAnimationsValid = false;
+                        RaiseWarning("GLTFExporter.Animation | Only one animation is supported for morph targets", 3);
+                        continue;
+                    }
+
+                    // Ensure the target animation property is 'influence'
+                    bool targetHasInfluence = false;
+                    foreach (BabylonAnimation babylonAnimation in babylonMorphTarget.animations)
+                    {
+                        if (babylonAnimation.property == "influence")
+                        {
+                            targetHasInfluence = true;
+                        }
+                    }
+                    if (targetHasInfluence == false)
+                    {
+                        areAnimationsValid = false;
+                        RaiseWarning("GLTFExporter.Animation | Only 'influence' animation is supported for morph targets", 3);
+                        continue;
+                    }
+                }
+            }
+
+            return hasAnimation && areAnimationsValid;
+        }
+
+        /// <summary>
+        /// The keys of each BabylonMorphTarget animation ARE NOT assumed to be identical.
+        /// This function merges together all keys and binds to each an influence value for all targets.
+        /// A target influence value is automatically computed when necessary.
+        /// Computation rules are:
+        /// - linear interpolation between target key range
+        /// - constant value outside target key range
+        /// </summary>
+        /// <example>
+        /// When:
+        /// animation1.keys = {0, 25, 50, 100}
+        /// animation2.keys = {50, 75, 100}
+        /// 
+        /// Gives:
+        /// mergedKeys = {0, 25, 50, 100, 75}
+        /// range1=[0, 100]
+        /// range2=[50, 100]
+        /// for animation1, the value associated to key=75 is the interpolation of its values between 50 and 100
+        /// for animation2, the value associated to key=0 is equal to the one at key=50 since 0 is out of range [50, 100] (same for key=25)</example>
+        /// <param name="babylonMorphTargetManager"></param>
+        /// <returns>A map which for each frame, gives the influence value of all targets</returns>
+        private Dictionary<int, List<float>> _getTargetManagerAnimationsData(BabylonMorphTargetManager babylonMorphTargetManager)
+        {
+            // Merge all keys into a single set (no duplicated frame)
+            var mergedFrames = new HashSet<int>();
+            foreach (var babylonMorphTarget in babylonMorphTargetManager.targets)
+            {
+                if (babylonMorphTarget.animations != null)
+                {
+                    var animation = babylonMorphTarget.animations[0];
+                    foreach (BabylonAnimationKey animationKey in animation.keys)
+                    {
+                        mergedFrames.Add(animationKey.frame);
+                    }
+                }
+            }
+
+            // For each frame, gives the influence value of all targets (gltf structure)
+            var influencesPerFrame = new Dictionary<int, List<float>>();
+            foreach (var frame in mergedFrames)
+            {
+                influencesPerFrame.Add(frame, new List<float>());
+            }
+            foreach (var babylonMorphTarget in babylonMorphTargetManager.targets)
+            {
+                // For a given target, for each frame, gives the influence value of the target (babylon structure)
+                var influencePerFrameForTarget = new Dictionary<int, float>();
+
+                if (babylonMorphTarget.animations != null && babylonMorphTarget.animations.Length > 0)
+                {
+                    var animation = babylonMorphTarget.animations[0];
+
+                    if (animation.keys.Length == 1)
+                    {
+                        // Same influence for all frames
+                        var influence = animation.keys[0].values[0];
+                        foreach (var frame in mergedFrames)
+                        {
+                            influencePerFrameForTarget.Add(frame, influence);
+                        }
+                    }
+                    else
+                    {
+                        // Retreive target animation key range [min, max]
+                        var babylonAnimationKeys = new List<BabylonAnimationKey>(animation.keys);
+                        babylonAnimationKeys.Sort();
+                        var minAnimationKey = babylonAnimationKeys[0];
+                        var maxAnimationKey = babylonAnimationKeys[babylonAnimationKeys.Count - 1];
+                        
+                        foreach (var frame in mergedFrames)
+                        {
+                            // Surround the current frame with closest keys available for the target
+                            BabylonAnimationKey lowerAnimationKey = minAnimationKey;
+                            BabylonAnimationKey upperAnimationKey = maxAnimationKey;
+                            foreach (BabylonAnimationKey animationKey in animation.keys)
+                            {
+                                if (lowerAnimationKey.frame < animationKey.frame && animationKey.frame <= frame)
+                                {
+                                    lowerAnimationKey = animationKey;
+                                }
+                                if (frame <= animationKey.frame && animationKey.frame < upperAnimationKey.frame)
+                                {
+                                    upperAnimationKey = animationKey;
+                                }
+                            }
+
+                            // In case the target has a key for this frame
+                            // or the current frame is out of target animation key range
+                            if (lowerAnimationKey.frame == upperAnimationKey.frame)
+                            {
+                                influencePerFrameForTarget.Add(frame, lowerAnimationKey.values[0]);
+                            }
+                            else
+                            {
+                                // Interpolate influence values
+                                var t = 1.0f * (frame - lowerAnimationKey.frame) / (upperAnimationKey.frame - lowerAnimationKey.frame);
+                                var influence = Tools.Lerp(lowerAnimationKey.values[0], upperAnimationKey.values[0], t);
+                                influencePerFrameForTarget.Add(frame, influence);
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    // Target is not animated
+                    // Fill all frames with 0
+                    foreach (var frame in mergedFrames)
+                    {
+                        influencePerFrameForTarget.Add(frame, 0);
+                    }
+                }
+
+                // Switch from babylon to gltf storage representation
+                foreach (var frame in mergedFrames)
+                {
+                    List<float> influences = influencesPerFrame[frame];
+                    influences.Add(influencePerFrameForTarget[frame]);
+                }
+            }
+
+            return influencesPerFrame;
+        }
+
+        private string _getTargetPath(string babylonProperty)
+        {
+            switch (babylonProperty)
+            {
+                case "position":
+                    return "translation";
+                case "rotationQuaternion":
+                    return "rotation";
+                case "scaling":
+                    return "scale";
+                default:
+                    return null;
+            }
+        }
+    }
+}

+ 2 - 0
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Camera.cs

@@ -54,6 +54,8 @@ namespace Max2Babylon
             // No scaling defined for babylon camera. Use identity instead.
             gltfNode.scale = new float[3] { 1, 1, 1 };
 
+            // Animations
+            ExportNodeAnimation(babylonCamera, gltf, gltfNode);
 
             // --- prints ---
 

+ 3 - 0
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Light.cs

@@ -41,6 +41,9 @@ namespace Max2Babylon
             // No scaling defined for babylon light. Use identity instead.
             gltfNode.scale = new float[3] { 1, 1, 1 };
 
+            // Animations
+            ExportNodeAnimation(babylonLight, gltf, gltfNode);
+
             return gltfNode;
         }
     }

+ 221 - 305
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Mesh.cs

@@ -3,7 +3,6 @@ using BabylonExport.Entities;
 using GLTFExport.Entities;
 using System;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 
 namespace Max2Babylon
@@ -70,14 +69,6 @@ namespace Max2Babylon
             // Retreive indices from babylon mesh
             List<ushort> babylonIndices = new List<ushort>();
             babylonIndices = babylonMesh.indices.ToList().ConvertAll(new Converter<int, ushort>(n => (ushort)n));
-            // For triangle primitives in gltf, the front face has a counter-clockwise (CCW) winding order
-            // Swap face side
-            //for (int i = 0; i < babylonIndices.Count; i += 3)
-            //{
-            //    var tmp = babylonIndices[i];
-            //    babylonIndices[i] = babylonIndices[i + 2];
-            //    babylonIndices[i + 2] = tmp;
-            //}
 
 
             // --------------------------
@@ -90,92 +81,7 @@ namespace Max2Babylon
             gltfMesh.index = gltf.MeshesList.Count;
             gltf.MeshesList.Add(gltfMesh);
             gltfMesh.idGroupInstance = babylonMesh.idGroupInstance;
-
-            // Buffer
-            var buffer = gltf.buffer;
-            if (buffer == null)
-            {
-                buffer = new GLTFBuffer
-                {
-                    uri = gltf.OutputFile + ".bin"
-                };
-                buffer.index = gltf.BuffersList.Count;
-                gltf.BuffersList.Add(buffer);
-                gltf.buffer = buffer;
-            }
-
-            // BufferView - Scalar
-            var bufferViewScalar = gltf.bufferViewScalar;
-            if (bufferViewScalar == null)
-            {
-                bufferViewScalar = new GLTFBufferView
-                {
-                    name = "bufferViewScalar",
-                    buffer = buffer.index,
-                    Buffer = buffer
-                };
-                bufferViewScalar.index = gltf.BufferViewsList.Count;
-                gltf.BufferViewsList.Add(bufferViewScalar);
-                gltf.bufferViewScalar = bufferViewScalar;
-            }
-
-            // BufferView - Vector3
-            var bufferViewFloatVec3 = gltf.bufferViewFloatVec3;
-            if (bufferViewFloatVec3 == null)
-            {
-                bufferViewFloatVec3 = new GLTFBufferView
-                {
-                    name = "bufferViewFloatVec3",
-                    buffer = buffer.index,
-                    Buffer = buffer,
-                    byteOffset = 0,
-                    byteStride = 12 // Field only defined for buffer views that contain vertex attributes. A vertex needs 3 * 4 bytes
-                };
-                bufferViewFloatVec3.index = gltf.BufferViewsList.Count;
-                gltf.BufferViewsList.Add(bufferViewFloatVec3);
-                gltf.bufferViewFloatVec3 = bufferViewFloatVec3;
-            }
-
-            // BufferView - Vector4
-            GLTFBufferView bufferViewFloatVec4 = null;
-            if (hasColor)
-            {
-                bufferViewFloatVec4 = gltf.bufferViewFloatVec4;
-                if (bufferViewFloatVec4 == null)
-                {
-                    bufferViewFloatVec4 = new GLTFBufferView
-                    {
-                        name = "bufferViewFloatVec4",
-                        buffer = buffer.index,
-                        Buffer = buffer,
-                        byteOffset = 0,
-                        byteStride = 16 // Field only defined for buffer views that contain vertex attributes. A vertex needs 4 * 4 bytes
-                    };
-                    bufferViewFloatVec4.index = gltf.BufferViewsList.Count;
-                    gltf.BufferViewsList.Add(bufferViewFloatVec4);
-                    gltf.bufferViewFloatVec4 = bufferViewFloatVec4;
-                }
-            }
-
-            // BufferView - Vector2
-            GLTFBufferView bufferViewFloatVec2 = null;
-            if (hasUV || hasUV2)
-            {
-                bufferViewFloatVec2 = gltf.bufferViewFloatVec2;
-                if (bufferViewFloatVec2 == null)
-                {
-                    bufferViewFloatVec2 = new GLTFBufferView
-                    {
-                        name = "bufferViewFloatVec2",
-                        buffer = buffer.index,
-                        Buffer = buffer,
-                        byteStride = 8 // Field only defined for buffer views that contain vertex attributes. A vertex needs 2 * 4 bytes
-                    };
-                    bufferViewFloatVec2.index = gltf.BufferViewsList.Count;
-                    gltf.BufferViewsList.Add(bufferViewFloatVec2);
-                    gltf.bufferViewFloatVec2 = bufferViewFloatVec2;
-                }
-            }
+            var weights = new List<float>();
 
             // --------------------------
             // ---- glTF primitives -----
@@ -183,15 +89,6 @@ namespace Max2Babylon
 
             RaiseMessage("GLTFExporter.Mesh | glTF primitives", 2);
             var meshPrimitives = new List<GLTFMeshPrimitive>();
-
-            // Global vertices are sorted per submesh
-            var globalVerticesSubMeshes = new List<List<GLTFGlobalVertex>>();
-
-            // In gltf, indices of each mesh primitive are 0-based (ie: min value is 0)
-            // Thus, the gltf indices list is a concatenation of sub lists all 0-based
-            // Example for 2 triangles, each being a submesh:
-            //      babylonIndices = {0,1,2, 3,4,5} gives as result gltfIndicies = {0,1,2, 0,1,2}
-            var gltfIndices = new List<ushort>();
             
             foreach (BabylonSubMesh babylonSubMesh in babylonMesh.subMeshes)
             {
@@ -200,19 +97,20 @@ namespace Max2Babylon
                 // --------------------------
 
                 List<GLTFGlobalVertex> globalVerticesSubMesh = globalVertices.GetRange(babylonSubMesh.verticesStart, babylonSubMesh.verticesCount);
-                globalVerticesSubMeshes.Add(globalVerticesSubMesh);
 
-                List<ushort> _indices = babylonIndices.GetRange(babylonSubMesh.indexStart, babylonSubMesh.indexCount);
-                // Indices of this submesh / primitive are updated to be 0-based
-                var minIndiceValue = _indices.Min(); // Should be equal to babylonSubMesh.indexStart
-                for (int indexIndice = 0; indexIndice < _indices.Count; indexIndice++)
+                List<ushort> gltfIndices = babylonIndices.GetRange(babylonSubMesh.indexStart, babylonSubMesh.indexCount);
+                // In gltf, indices of each mesh primitive are 0-based (ie: min value is 0)
+                // Thus, the gltf indices list is a concatenation of sub lists all 0-based
+                // Example for 2 triangles, each being a submesh:
+                //      babylonIndices = {0,1,2, 3,4,5} gives as result gltfIndicies = {0,1,2, 0,1,2}
+                var minIndiceValue = gltfIndices.Min(); // Should be equal to babylonSubMesh.indexStart
+                for (int indexIndice = 0; indexIndice < gltfIndices.Count; indexIndice++)
                 {
-                    _indices[indexIndice] -= minIndiceValue;
+                    gltfIndices[indexIndice] -= minIndiceValue;
                 }
-                gltfIndices.AddRange(_indices);
 
                 // --------------------------
-                // -- Init glTF primitive ---
+                // ----- Mesh primitive -----
                 // --------------------------
 
                 // MeshPrimitive
@@ -222,105 +120,6 @@ namespace Max2Babylon
                 };
                 meshPrimitives.Add(meshPrimitive);
 
-                // Accessor - Indices
-                var accessorIndices = new GLTFAccessor
-                {
-                    name = "accessorIndices",
-                    bufferView = bufferViewScalar.index,
-                    BufferView = bufferViewScalar,
-                    componentType = GLTFAccessor.ComponentType.UNSIGNED_SHORT,
-                    type = GLTFAccessor.TypeEnum.SCALAR.ToString()
-                };
-                accessorIndices.index = gltf.AccessorsList.Count;
-                gltf.AccessorsList.Add(accessorIndices);
-                meshPrimitive.indices = accessorIndices.index;
-
-                // Accessor - Positions
-                var accessorPositions = new GLTFAccessor
-                {
-                    name = "accessorPositions",
-                    bufferView = bufferViewFloatVec3.index,
-                    BufferView = bufferViewFloatVec3,
-                    componentType = GLTFAccessor.ComponentType.FLOAT,
-                    type = GLTFAccessor.TypeEnum.VEC3.ToString(),
-                    min = new float[] { float.MaxValue, float.MaxValue, float.MaxValue },
-                    max = new float[] { float.MinValue, float.MinValue, float.MinValue }
-                };
-                accessorPositions.index = gltf.AccessorsList.Count;
-                gltf.AccessorsList.Add(accessorPositions);
-                meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.POSITION.ToString(), accessorPositions.index);
-
-                // Accessor - Normals
-                var accessorNormals = new GLTFAccessor
-                {
-                    name = "accessorNormals",
-                    bufferView = bufferViewFloatVec3.index,
-                    BufferView = bufferViewFloatVec3,
-                    componentType = GLTFAccessor.ComponentType.FLOAT,
-                    type = GLTFAccessor.TypeEnum.VEC3.ToString()
-                };
-                accessorNormals.index = gltf.AccessorsList.Count;
-                gltf.AccessorsList.Add(accessorNormals);
-                meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.NORMAL.ToString(), accessorNormals.index);
-
-                // Accessor - Colors
-                GLTFAccessor accessorColors = null;
-                if (hasColor)
-                {
-                    accessorColors = new GLTFAccessor
-                    {
-                        name = "accessorColors",
-                        bufferView = bufferViewFloatVec4.index,
-                        BufferView = bufferViewFloatVec4,
-                        componentType = GLTFAccessor.ComponentType.FLOAT,
-                        type = GLTFAccessor.TypeEnum.VEC4.ToString()
-                    };
-                    accessorColors.index = gltf.AccessorsList.Count;
-                    gltf.AccessorsList.Add(accessorColors);
-                    meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.COLOR_0.ToString(), accessorColors.index);
-                }
-
-                // Accessor - UV
-                GLTFAccessor accessorUVs = null;
-                if (hasUV)
-                {
-                    accessorUVs = new GLTFAccessor
-                    {
-                        name = "accessorUVs",
-                        bufferView = bufferViewFloatVec2.index,
-                        BufferView = bufferViewFloatVec2,
-                        componentType = GLTFAccessor.ComponentType.FLOAT,
-                        type = GLTFAccessor.TypeEnum.VEC2.ToString()
-                    };
-                    accessorUVs.index = gltf.AccessorsList.Count;
-                    gltf.AccessorsList.Add(accessorUVs);
-                    meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_0.ToString(), accessorUVs.index);
-                }
-
-                // Accessor - UV2
-                GLTFAccessor accessorUV2s = null;
-                if (hasUV2)
-                {
-                    accessorUV2s = new GLTFAccessor
-                    {
-                        name = "accessorUV2s",
-                        bufferView = bufferViewFloatVec2.index,
-                        BufferView = bufferViewFloatVec2,
-                        componentType = GLTFAccessor.ComponentType.FLOAT,
-                        type = GLTFAccessor.TypeEnum.VEC2.ToString()
-                    };
-                    accessorUV2s.index = gltf.AccessorsList.Count;
-                    gltf.AccessorsList.Add(accessorUV2s);
-                    meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_1.ToString(), accessorUV2s.index);
-                }
-
-                
-                // --------------------------
-                // - Update glTF primitive --
-                // --------------------------
-
-                RaiseMessage("GLTFExporter.Mesh | Mesh as glTF", 3);
-
                 // Material
                 if (babylonMesh.materialId != null)
                 {
@@ -351,121 +150,249 @@ namespace Max2Babylon
                     meshPrimitive.mode = GLTFMeshPrimitive.FillMode.TRIANGLES;
                 }
 
-                // Update min and max vertex position for each component (X, Y, Z)
+                // --------------------------
+                // ------- Accessors --------
+                // --------------------------
+
+                // Buffer
+                var buffer = GLTFBufferService.Instance.GetBuffer(gltf);
+
+                // --- Indices ---
+                var accessorIndices = GLTFBufferService.Instance.CreateAccessor(
+                    gltf,
+                    GLTFBufferService.Instance.GetBufferViewScalar(gltf, buffer),
+                    "accessorIndices",
+                    GLTFAccessor.ComponentType.UNSIGNED_SHORT,
+                    GLTFAccessor.TypeEnum.SCALAR
+                );
+                meshPrimitive.indices = accessorIndices.index;
+                // Populate accessor
+                gltfIndices.ForEach(n => accessorIndices.bytesList.AddRange(BitConverter.GetBytes(n)));
+                accessorIndices.count = gltfIndices.Count;
+                
+                // --- Positions ---
+                var accessorPositions = GLTFBufferService.Instance.CreateAccessor(
+                    gltf,
+                    GLTFBufferService.Instance.GetBufferViewFloatVec3(gltf, buffer),
+                    "accessorPositions",
+                    GLTFAccessor.ComponentType.FLOAT,
+                    GLTFAccessor.TypeEnum.VEC3
+                );
+                meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.POSITION.ToString(), accessorPositions.index);
+                // Populate accessor
+                accessorPositions.min = new float[] { float.MaxValue, float.MaxValue, float.MaxValue };
+                accessorPositions.max = new float[] { float.MinValue, float.MinValue, float.MinValue };
                 globalVerticesSubMesh.ForEach((globalVertex) =>
                 {
-                    var positionArray = new float[] { globalVertex.Position.X, globalVertex.Position.Y, globalVertex.Position.Z };
-                    for (int indexComponent = 0; indexComponent < positionArray.Length; indexComponent++)
+                    var positions = new float[] { globalVertex.Position.X, globalVertex.Position.Y, globalVertex.Position.Z };
+                    // Store values as bytes
+                    foreach (var position in positions)
                     {
-                        if (positionArray[indexComponent] < accessorPositions.min[indexComponent])
-                        {
-                            accessorPositions.min[indexComponent] = positionArray[indexComponent];
-                        }
-                        if (positionArray[indexComponent] > accessorPositions.max[indexComponent])
-                        {
-                            accessorPositions.max[indexComponent] = positionArray[indexComponent];
-                        }
+                        accessorPositions.bytesList.AddRange(BitConverter.GetBytes(position));
                     }
+                    // Update min and max values
+                    GLTFBufferService.UpdateMinMaxAccessor(accessorPositions, positions);
                 });
-
-                // Update byte length and count of accessors, bufferViews and buffers
-                // Scalar
-                AddElementsToAccessor(accessorIndices, _indices.Count);
-                // Ensure the byteoffset is a multiple of 4
-                // Indices accessor element size if 2
-                // So the count needs to be even
-                if (gltfIndices.Count % 2 != 0)
-                {
-                    gltfIndices.Add(0);
-                    bufferViewScalar.byteLength += 2;
-                    buffer.byteLength += 2;
-                }
-                // Vector3
-                AddElementsToAccessor(accessorPositions, globalVerticesSubMesh.Count);
-                AddElementsToAccessor(accessorNormals, globalVerticesSubMesh.Count);
-                // Vector4
+                accessorPositions.count = globalVerticesSubMesh.Count;
+                
+                // --- Normals ---
+                var accessorNormals = GLTFBufferService.Instance.CreateAccessor(
+                    gltf,
+                    GLTFBufferService.Instance.GetBufferViewFloatVec3(gltf, buffer),
+                    "accessorNormals",
+                    GLTFAccessor.ComponentType.FLOAT,
+                    GLTFAccessor.TypeEnum.VEC3
+                );
+                meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.NORMAL.ToString(), accessorNormals.index);
+                // Populate accessor
+                List<float> normals = globalVerticesSubMesh.SelectMany(v => new[] { v.Normal.X, v.Normal.Y, v.Normal.Z }).ToList();
+                normals.ForEach(n => accessorNormals.bytesList.AddRange(BitConverter.GetBytes(n)));
+                accessorNormals.count = globalVerticesSubMesh.Count;
+                
+                // --- Colors ---
                 if (hasColor)
                 {
-                    AddElementsToAccessor(accessorColors, globalVerticesSubMesh.Count);
+                    var accessorColors = GLTFBufferService.Instance.CreateAccessor(
+                        gltf,
+                        GLTFBufferService.Instance.GetBufferViewFloatVec4(gltf, buffer),
+                        "accessorColors",
+                        GLTFAccessor.ComponentType.FLOAT,
+                        GLTFAccessor.TypeEnum.VEC4
+                    );
+                    meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.COLOR_0.ToString(), accessorColors.index);
+                    // Populate accessor
+                    List<float> colors = globalVerticesSubMesh.SelectMany(v => new[] { v.Color[0], v.Color[1], v.Color[2], v.Color[3] }).ToList();
+                    colors.ForEach(n => accessorColors.bytesList.AddRange(BitConverter.GetBytes(n)));
+                    accessorColors.count = globalVerticesSubMesh.Count;
                 }
-                // Vector2
+                
+                // --- UV ---
                 if (hasUV)
                 {
-                    AddElementsToAccessor(accessorUVs, globalVerticesSubMesh.Count);
+                    var accessorUVs = GLTFBufferService.Instance.CreateAccessor(
+                        gltf,
+                        GLTFBufferService.Instance.GetBufferViewFloatVec2(gltf, buffer),
+                        "accessorUVs",
+                        GLTFAccessor.ComponentType.FLOAT,
+                        GLTFAccessor.TypeEnum.VEC2
+                    );
+                    meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_0.ToString(), accessorUVs.index);
+                    // Populate accessor
+                    List<float> uvs = globalVerticesSubMesh.SelectMany(v => new[] { v.UV.X, v.UV.Y }).ToList();
+                    uvs.ForEach(n => accessorUVs.bytesList.AddRange(BitConverter.GetBytes(n)));
+                    accessorUVs.count = globalVerticesSubMesh.Count;
                 }
+                
+                // --- UV2 ---
                 if (hasUV2)
                 {
-                    AddElementsToAccessor(accessorUV2s, globalVerticesSubMesh.Count);
+                    var accessorUV2s = GLTFBufferService.Instance.CreateAccessor(
+                        gltf,
+                        GLTFBufferService.Instance.GetBufferViewFloatVec2(gltf, buffer),
+                        "accessorUV2s",
+                        GLTFAccessor.ComponentType.FLOAT,
+                        GLTFAccessor.TypeEnum.VEC2
+                    );
+                    meshPrimitive.attributes.Add(GLTFMeshPrimitive.Attribute.TEXCOORD_1.ToString(), accessorUV2s.index);
+                    // Populate accessor
+                    List<float> uvs2 = globalVerticesSubMesh.SelectMany(v => new[] { v.UV2.X, v.UV2.Y }).ToList();
+                    uvs2.ForEach(n => accessorUV2s.bytesList.AddRange(BitConverter.GetBytes(n)));
+                    accessorUV2s.count = globalVerticesSubMesh.Count;
+                }
+
+                // Morph targets
+                var babylonMorphTargetManager = GetBabylonMorphTargetManager(babylonScene, babylonMesh);
+                if (babylonMorphTargetManager != null)
+                {
+                    _exportMorphTargets(babylonMesh, babylonMorphTargetManager, gltf, buffer, meshPrimitive, weights);
                 }
             }
             gltfMesh.primitives = meshPrimitives.ToArray();
-            
-            // Update byte offset of bufferViews
-            GLTFBufferView lastBufferView = null;
-            gltf.BufferViewsList.FindAll(bufferView => bufferView.buffer == buffer.index).ForEach(bufferView =>
+            if (weights.Count > 0)
             {
-                if (lastBufferView != null)
-                {
-                    bufferView.byteOffset = lastBufferView.byteOffset + lastBufferView.byteLength;
-                }
-                lastBufferView = bufferView;
-            });
-
-
-            // --------------------------
-            // --------- Saving ---------
-            // --------------------------
-
-            RaiseMessage("GLTFExporter.Mesh | saving", 2);
+                gltfMesh.weights = weights.ToArray();
+            }
 
-            // BufferView - Scalar
-            gltfIndices.ForEach(n => bufferViewScalar.bytesList.AddRange(BitConverter.GetBytes(n)));
+            return gltfMesh;
+        }
 
-            // BufferView - Vector3
-            globalVerticesSubMeshes.ForEach(globalVerticesSubMesh =>
+        private BabylonMorphTargetManager GetBabylonMorphTargetManager(BabylonScene babylonScene, BabylonMesh babylonMesh)
+        {
+            if (babylonMesh.morphTargetManagerId.HasValue)
             {
-                List<float> vertices = globalVerticesSubMesh.SelectMany(v => new[] { v.Position.X, v.Position.Y, v.Position.Z }).ToList();
-                vertices.ForEach(n => bufferViewFloatVec3.bytesList.AddRange(BitConverter.GetBytes(n)));
+                if (babylonScene.morphTargetManagers == null)
+                {
+                    RaiseWarning("GLTFExporter.Mesh | morphTargetManagers is not defined", 3);
+                }
+                else
+                {
+                    var babylonMorphTargetManager = babylonScene.morphTargetManagers.ElementAtOrDefault(babylonMesh.morphTargetManagerId.Value);
 
-                List<float> normals = globalVerticesSubMesh.SelectMany(v => new[] { v.Normal.X, v.Normal.Y, v.Normal.Z }).ToList();
-                normals.ForEach(n => bufferViewFloatVec3.bytesList.AddRange(BitConverter.GetBytes(n)));
-            });
+                    if (babylonMorphTargetManager == null)
+                    {
+                        RaiseWarning($"GLTFExporter.Mesh | morphTargetManager with index {babylonMesh.morphTargetManagerId.Value} not found", 3);
+                    }
+                    return babylonMorphTargetManager;
+                }
+            }
+            return null;
+        }
 
-            // BufferView - Vector4
-            globalVerticesSubMeshes.ForEach(globalVerticesSubMesh =>
+        private void _exportMorphTargets(BabylonMesh babylonMesh, BabylonMorphTargetManager babylonMorphTargetManager, GLTF gltf, GLTFBuffer buffer, GLTFMeshPrimitive meshPrimitive, List<float> weights)
+        {
+            var gltfMorphTargets = new List<GLTFMorphTarget>();
+            foreach (var babylonMorphTarget in babylonMorphTargetManager.targets)
             {
-                if (hasColor)
+                var gltfMorphTarget = new GLTFMorphTarget();
+
+                // Positions
+                if (babylonMorphTarget.positions != null)
                 {
-                    List<float> colors = globalVerticesSubMesh.SelectMany(v => new[] { v.Color[0], v.Color[1], v.Color[2], v.Color[3] }).ToList();
-                    colors.ForEach(n => bufferViewFloatVec4.bytesList.AddRange(BitConverter.GetBytes(n)));
+                    var accessorTargetPositions = GLTFBufferService.Instance.CreateAccessor(
+                        gltf,
+                        GLTFBufferService.Instance.GetBufferViewFloatVec3(gltf, buffer),
+                        "accessorTargetPositions",
+                        GLTFAccessor.ComponentType.FLOAT,
+                        GLTFAccessor.TypeEnum.VEC3
+                    );
+                    gltfMorphTarget.Add(GLTFMorphTarget.Attribute.POSITION.ToString(), accessorTargetPositions.index);
+                    // Populate accessor
+                    accessorTargetPositions.min = new float[] { float.MaxValue, float.MaxValue, float.MaxValue };
+                    accessorTargetPositions.max = new float[] { float.MinValue, float.MinValue, float.MinValue };
+                    for (int indexPosition = 0; indexPosition < babylonMorphTarget.positions.Length; indexPosition += 3)
+                    {
+                        var positionTarget = _subArray(babylonMorphTarget.positions, indexPosition, 3);
+
+                        // Babylon stores morph target information as final data while glTF expects deltas from mesh primitive
+                        var positionMesh = _subArray(babylonMesh.positions, indexPosition, 3);
+                        for (int indexCoordinate = 0; indexCoordinate < positionTarget.Length; indexCoordinate++)
+                        {
+                            positionTarget[indexCoordinate] = positionTarget[indexCoordinate] - positionMesh[indexCoordinate];
+                        }
+
+                        // Store values as bytes
+                        foreach (var coordinate in positionTarget)
+                        {
+                            accessorTargetPositions.bytesList.AddRange(BitConverter.GetBytes(coordinate));
+                        }
+                        // Update min and max values
+                        GLTFBufferService.UpdateMinMaxAccessor(accessorTargetPositions, positionTarget);
+                    }
+                    accessorTargetPositions.count = babylonMorphTarget.positions.Length / 3;
                 }
-            });
 
-            // BufferView - Vector2
-            globalVerticesSubMeshes.ForEach(globalVerticesSubMesh =>
-            {
-                if (hasUV)
+                // Normals
+                if (babylonMorphTarget.normals != null)
                 {
-                    List<float> uvs = globalVerticesSubMesh.SelectMany(v => new[] { v.UV.X, v.UV.Y }).ToList();
-                    uvs.ForEach(n => bufferViewFloatVec2.bytesList.AddRange(BitConverter.GetBytes(n)));
+                    var accessorTargetNormals = GLTFBufferService.Instance.CreateAccessor(
+                        gltf,
+                        GLTFBufferService.Instance.GetBufferViewFloatVec3(gltf, buffer),
+                        "accessorTargetNormals",
+                        GLTFAccessor.ComponentType.FLOAT,
+                        GLTFAccessor.TypeEnum.VEC3
+                    );
+                    gltfMorphTarget.Add(GLTFMorphTarget.Attribute.NORMAL.ToString(), accessorTargetNormals.index);
+                    // Populate accessor
+                    for (int indexNormal = 0; indexNormal < babylonMorphTarget.positions.Length; indexNormal += 3)
+                    {
+                        var normalTarget = _subArray(babylonMorphTarget.normals, indexNormal, 3);
+
+                        // Babylon stores morph target information as final data while glTF expects deltas from mesh primitive
+                        var normalMesh = _subArray(babylonMesh.normals, indexNormal, 3);
+                        for (int indexCoordinate = 0; indexCoordinate < normalTarget.Length; indexCoordinate++)
+                        {
+                            normalTarget[indexCoordinate] = normalTarget[indexCoordinate] - normalMesh[indexCoordinate];
+                        }
+
+                        // Store values as bytes
+                        foreach (var coordinate in normalTarget)
+                        {
+                            accessorTargetNormals.bytesList.AddRange(BitConverter.GetBytes(coordinate));
+                        }
+                    }
+                    accessorTargetNormals.count = babylonMorphTarget.normals.Length / 3;
                 }
 
-                if (hasUV2)
+                if (gltfMorphTarget.Count > 0)
                 {
-                    List<float> uvs2 = globalVerticesSubMesh.SelectMany(v => new[] { v.UV2.X, v.UV2.Y }).ToList();
-                    uvs2.ForEach(n => bufferViewFloatVec2.bytesList.AddRange(BitConverter.GetBytes(n)));
+                    gltfMorphTargets.Add(gltfMorphTarget);
+                    weights.Add(babylonMorphTarget.influence);
                 }
-            });
-
-            //// Write data to binary file
-            //string outputBinaryFile = Path.Combine(gltf.OutputPath, gltfMesh.name + ".bin");
-            //RaiseMessage("GLTFExporter.Mesh | Saving " + outputBinaryFile, 2);
-            //using (BinaryWriter writer = new BinaryWriter(File.Open(outputBinaryFile, FileMode.Create)))
-            //{
-            //    bytesList.ForEach(b => writer.Write(b));
-            //}
+            }
+            if (gltfMorphTargets.Count > 0)
+            {
+                meshPrimitive.targets = gltfMorphTargets.ToArray();
+            }
+        }
 
-            return gltfMesh;
+        private float[] _subArray(float[] array, int startIndex, int count)
+        {
+            var result = new float[count];
+            for (int i = 0; i < count; i++)
+            {
+                result[i] = array[startIndex + i];
+            }
+            return result;
         }
 
         private IPoint2 createIPoint2(float[] array, int index)
@@ -485,16 +412,5 @@ namespace Max2Babylon
             var startIndex = index * 4;
             return Loader.Global.Point4.Create(array[startIndex], array[startIndex + 1], array[startIndex + 2], array[startIndex + 3]);
         }
-
-        private void AddElementsToAccessor(GLTFAccessor accessor, int count)
-        {
-            GLTFBufferView bufferView = accessor.BufferView;
-            GLTFBuffer buffer = bufferView.Buffer;
-
-            accessor.byteOffset = bufferView.byteLength;
-            accessor.count += count;
-            bufferView.byteLength += accessor.getByteLength();
-            buffer.byteLength += accessor.getByteLength();
-        }
     }
 }

+ 29 - 9
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.cs

@@ -84,7 +84,7 @@ namespace Max2Babylon
                 idGroupInstance = -1
             };
             scene.NodesList.Clear(); // Only root node is listed in node list
-            GLTFNode gltfRootNode = ExportAbstractMesh(rootNode, gltf, null);
+            GLTFNode gltfRootNode = ExportAbstractMesh(rootNode, gltf, null, null);
             gltfRootNode.ChildrenList.AddRange(tmpNodesList);
 
             // Materials
@@ -96,27 +96,47 @@ namespace Max2Babylon
             };
             RaiseMessage(string.Format("GLTFExporter | Nb materials exported: {0}", gltf.MaterialsList.Count), Color.Gray, 1);
 
+            // Prepare buffers
+            gltf.BuffersList.ForEach(buffer =>
+            {
+                buffer.BufferViews.ForEach(bufferView =>
+                {
+                    bufferView.Accessors.ForEach(accessor =>
+                    {
+                        // Chunk must be padded with trailing zeros (0x00) to satisfy alignment requirements
+                        accessor.bytesList = new List<byte>(padChunk(accessor.bytesList.ToArray(), 4, 0x00));
+
+                        // Update byte properties
+                        accessor.byteOffset = bufferView.byteLength;
+                        bufferView.byteLength += accessor.bytesList.Count;
+                        // Merge bytes
+                        bufferView.bytesList.AddRange(accessor.bytesList);
+                    });
+                    // Update byte properties
+                    bufferView.byteOffset = buffer.byteLength;
+                    buffer.byteLength += bufferView.bytesList.Count;
+                    // Merge bytes
+                    buffer.bytesList.AddRange(bufferView.bytesList);
+                });
+            });
+
             // Cast lists to arrays
             gltf.Prepare();
 
             // Output
             RaiseMessage("GLTFExporter | Saving to output file");
             
+            // Write .gltf file
             string outputGltfFile = Path.ChangeExtension(outputFile, "gltf");
             File.WriteAllText(outputGltfFile, gltfToJson(gltf));
 
-            // Write data to binary file
+            // Write .bin file
             string outputBinaryFile = Path.ChangeExtension(outputFile, "bin");
             using (BinaryWriter writer = new BinaryWriter(File.Open(outputBinaryFile, FileMode.Create)))
             {
                 gltf.BuffersList.ForEach(buffer =>
                 {
-                    buffer.bytesList = new List<byte>();
-                    gltf.BufferViewsList.FindAll(bufferView => bufferView.buffer == buffer.index).ForEach(bufferView =>
-                    {
-                        bufferView.bytesList.ForEach(b => writer.Write(b));
-                        buffer.bytesList.AddRange(bufferView.bytesList);
-                    });
+                    buffer.bytesList.ForEach(b => writer.Write(b));
                 });
             }
 
@@ -234,7 +254,7 @@ namespace Max2Babylon
             if (type == typeof(BabylonAbstractMesh) ||
                 type.IsSubclassOf(typeof(BabylonAbstractMesh)))
             {
-                gltfNode = ExportAbstractMesh(babylonNode as BabylonAbstractMesh, gltf, gltfParentNode);
+                gltfNode = ExportAbstractMesh(babylonNode as BabylonAbstractMesh, gltf, gltfParentNode, babylonScene);
             }
             else if (type == typeof(BabylonCamera))
             {

+ 203 - 84
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -43,6 +43,9 @@ namespace Max2Babylon
             // Position / rotation / scaling / hierarchy
             exportNode(babylonMesh, meshNode, scene, babylonScene);
 
+            // Animations
+            exportAnimation(babylonMesh, meshNode);
+
             babylonScene.MeshesList.Add(babylonMesh);
 
             return babylonMesh;
@@ -306,64 +309,8 @@ namespace Max2Babylon
                 var optimizeVertices = meshNode.MaxNode.GetBoolProperty("babylonjs_optimizevertices");
 
                 // Compute normals
-                List<GlobalVertex>[] verticesAlreadyExported = null;
-
-                if (optimizeVertices)
-                {
-                    verticesAlreadyExported = new List<GlobalVertex>[unskinnedMesh.NumberOfVerts];
-                }
-
                 var subMeshes = new List<BabylonSubMesh>();
-                var indexStart = 0;
-
-
-                for (int i = 0; i < multiMatsCount; ++i)
-                {
-                    int materialId = meshNode.NodeMaterial?.GetMaterialID(i) ?? 0;
-                    var indexCount = 0;
-                    var minVertexIndex = int.MaxValue;
-                    var maxVertexIndex = int.MinValue;
-                    var subMesh = new BabylonSubMesh { indexStart = indexStart, materialIndex = i };
-
-                    if (multiMatsCount == 1)
-                    {
-                        for (int j = 0; j < unskinnedMesh.NumberOfFaces; ++j)
-                        {
-                            var face = unskinnedMesh.GetFace(j);
-                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
-                        }
-                    }
-                    else
-                    {
-                        ITab<IFaceEx> materialFaces = unskinnedMesh.GetFacesFromMatID(materialId);
-                        for (int j = 0; j < materialFaces.Count; ++j)
-                        {
-#if MAX2017
-                            var faceIndexer = j;
-#else
-                            var faceIndexer = new IntPtr(j);
-#endif
-                            var face = materialFaces[faceIndexer];
-
-#if !MAX2017
-                            Marshal.FreeHGlobal(faceIndexer);
-#endif
-                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
-                        }
-                    }
-
-                    if (indexCount != 0)
-                    {
-
-                        subMesh.indexCount = indexCount;
-                        subMesh.verticesStart = minVertexIndex;
-                        subMesh.verticesCount = maxVertexIndex - minVertexIndex + 1;
-
-                        indexStart += indexCount;
-
-                        subMeshes.Add(subMesh);
-                    }
-                }
+                ExtractGeometry(vertices, indices, subMeshes, boneIds, skin, unskinnedMesh, hasUV, hasUV2, hasColor, hasAlpha, optimizeVertices, multiMatsCount, meshNode);
 
                 if (vertices.Count >= 65536)
                 {
@@ -412,6 +359,80 @@ namespace Max2Babylon
 
                 // Buffers - Indices
                 babylonMesh.indices = indices.ToArray();
+
+                // ------------------------
+                // ---- Morph targets -----
+                // ------------------------
+
+                // Retreive modifiers with morpher flag
+                List<IIGameModifier> modifiers = new List<IIGameModifier>();
+                for (int i = 0; i < meshNode.IGameObject.NumModifiers; i++)
+                {
+                    var modifier = meshNode.IGameObject.GetIGameModifier(i);
+                    if (modifier.ModifierType == Autodesk.Max.IGameModifier.ModType.Morpher)
+                    {
+                        modifiers.Add(modifier);
+                    }
+                }
+
+                // Cast modifiers to morphers
+                List<IIGameMorpher> morphers = modifiers.ConvertAll(new Converter<IIGameModifier, IIGameMorpher>(modifier => modifier.AsGameMorpher()));
+
+                var hasMorphTarget = false;
+                morphers.ForEach(morpher =>
+                {
+                    if (morpher.NumberOfMorphTargets > 0)
+                    {
+                        hasMorphTarget = true;
+                    }
+                });
+
+                if (hasMorphTarget)
+                {
+                    RaiseMessage("Export morph targets", 2);
+
+                    // Morph Target Manager
+                    var babylonMorphTargetManager = new BabylonMorphTargetManager();
+                    babylonScene.MorphTargetManagersList.Add(babylonMorphTargetManager);
+                    babylonMesh.morphTargetManagerId = babylonMorphTargetManager.id;
+
+                    // Morph Targets
+                    var babylonMorphTargets = new List<BabylonMorphTarget>();
+                    // All morphers are considered identical
+                    // Their targets are concatenated
+                    morphers.ForEach(morpher =>
+                    {
+                        for (int i = 0; i < morpher.NumberOfMorphTargets; i++)
+                        {
+                            // Morph target
+                            var maxMorphTarget = morpher.GetMorphTarget(i);
+                            var babylonMorphTarget = new BabylonMorphTarget
+                            {
+                                name = maxMorphTarget.Name
+                            };
+                            babylonMorphTargets.Add(babylonMorphTarget);
+
+                            // TODO - Influence
+                            babylonMorphTarget.influence = 0f;
+
+                            // Target geometry
+                            var targetVertices = ExtractVertices(maxMorphTarget, optimizeVertices);
+                            babylonMorphTarget.positions = targetVertices.SelectMany(v => new[] { v.Position.X, v.Position.Y, v.Position.Z }).ToArray();
+                            babylonMorphTarget.normals = targetVertices.SelectMany(v => new[] { v.Normal.X, v.Normal.Y, v.Normal.Z }).ToArray();
+
+                            // Animations
+                            var animations = new List<BabylonAnimation>();
+                            var morphWeight = morpher.GetMorphWeight(i);
+                            ExportFloatGameController(morphWeight, "influence", animations);
+                            if (animations.Count > 0)
+                            {
+                                babylonMorphTarget.animations = animations.ToArray();
+                            }
+                        }
+                    });
+
+                    babylonMorphTargetManager.targets = babylonMorphTargets.ToArray();
+                }
             }
 
             babylonScene.MeshesList.Add(babylonMesh);
@@ -419,6 +440,86 @@ namespace Max2Babylon
             return babylonMesh;
         }
 
+        private List<GlobalVertex> ExtractVertices(IIGameNode maxMorphTarget, bool optimizeVertices)
+        {
+            var gameMesh = maxMorphTarget.IGameObject.AsGameMesh();
+            bool initialized = gameMesh.InitializeData; // needed, the property is in fact a method initializing the exporter that has wrongly been auto 
+                                                        // translated into a property because it has no parameters
+
+            var mtl = maxMorphTarget.NodeMaterial;
+            var multiMatsCount = 1;
+
+            if (mtl != null)
+            {
+                multiMatsCount = Math.Max(mtl.SubMaterialCount, 1);
+            }
+
+            var vertices = new List<GlobalVertex>();
+            ExtractGeometry(vertices, new List<int>(), new List<BabylonSubMesh>(), null, null, gameMesh, false, false, false, false, optimizeVertices, multiMatsCount, maxMorphTarget);
+            return vertices;
+        }
+
+        private void ExtractGeometry(List<GlobalVertex> vertices, List<int> indices, List<BabylonSubMesh> subMeshes, List<int> boneIds, IIGameSkin skin, IIGameMesh unskinnedMesh, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, bool optimizeVertices, int multiMatsCount, IIGameNode meshNode)
+        {
+            List<GlobalVertex>[] verticesAlreadyExported = null;
+
+            if (optimizeVertices)
+            {
+                verticesAlreadyExported = new List<GlobalVertex>[unskinnedMesh.NumberOfVerts];
+            }
+
+            var indexStart = 0;
+
+
+            for (int i = 0; i < multiMatsCount; ++i)
+            {
+                int materialId = meshNode.NodeMaterial?.GetMaterialID(i) ?? 0;
+                var indexCount = 0;
+                var minVertexIndex = int.MaxValue;
+                var maxVertexIndex = int.MinValue;
+                var subMesh = new BabylonSubMesh { indexStart = indexStart, materialIndex = i };
+
+                if (multiMatsCount == 1)
+                {
+                    for (int j = 0; j < unskinnedMesh.NumberOfFaces; ++j)
+                    {
+                        var face = unskinnedMesh.GetFace(j);
+                        ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
+                    }
+                }
+                else
+                {
+                    ITab<IFaceEx> materialFaces = unskinnedMesh.GetFacesFromMatID(materialId);
+                    for (int j = 0; j < materialFaces.Count; ++j)
+                    {
+#if MAX2017
+                        var faceIndexer = j;
+#else
+                            var faceIndexer = new IntPtr(j);
+#endif
+                        var face = materialFaces[faceIndexer];
+
+#if !MAX2017
+                            Marshal.FreeHGlobal(faceIndexer);
+#endif
+                        ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
+                    }
+                }
+
+                if (indexCount != 0)
+                {
+
+                    subMesh.indexCount = indexCount;
+                    subMesh.verticesStart = minVertexIndex;
+                    subMesh.verticesCount = maxVertexIndex - minVertexIndex + 1;
+
+                    indexStart += indexCount;
+
+                    subMeshes.Add(subMesh);
+                }
+            }
+        }
+
         private void ExtractFace(IIGameSkin skin, IIGameMesh unskinnedMesh, List<GlobalVertex> vertices, List<int> indices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, List<GlobalVertex>[] verticesAlreadyExported, ref int indexCount, ref int minVertexIndex, ref int maxVertexIndex, IFaceEx face, List<int> boneIds)
         {
             var a = CreateGlobalVertex(unskinnedMesh, face, 0, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
@@ -749,41 +850,59 @@ namespace Max2Babylon
 
         public void GenerateCoordinatesAnimations(IIGameNode meshNode, List<BabylonAnimation> animations)
         {
-            ExportVector3Animation("position", animations, key =>
+            if (meshNode.IGameControl.IsAnimated(IGameControlType.Pos) ||
+                meshNode.IGameControl.IsAnimated(IGameControlType.PosX) ||
+                meshNode.IGameControl.IsAnimated(IGameControlType.PosY) ||
+                meshNode.IGameControl.IsAnimated(IGameControlType.PosZ))
             {
-                var worldMatrix = meshNode.GetObjectTM(key);
-                if (meshNode.NodeParent != null)
+                ExportVector3Animation("position", animations, key =>
                 {
-                    var parentWorld = meshNode.NodeParent.GetObjectTM(key);
-                    worldMatrix.MultiplyBy(parentWorld.Inverse);
-                }
-                var trans = worldMatrix.Translation;
-                return new[] { trans.X, trans.Y, trans.Z };
-            });
+                    var worldMatrix = meshNode.GetObjectTM(key);
+                    if (meshNode.NodeParent != null)
+                    {
+                        var parentWorld = meshNode.NodeParent.GetObjectTM(key);
+                        worldMatrix.MultiplyBy(parentWorld.Inverse);
+                    }
+                    var trans = worldMatrix.Translation;
+                    return new[] { trans.X, trans.Y, trans.Z };
+                });
+            }
 
-            ExportQuaternionAnimation("rotationQuaternion", animations, key =>
+            if (meshNode.IGameControl.IsAnimated(IGameControlType.Rot) ||
+                meshNode.IGameControl.IsAnimated(IGameControlType.EulerX) ||
+                meshNode.IGameControl.IsAnimated(IGameControlType.EulerY) ||
+                meshNode.IGameControl.IsAnimated(IGameControlType.EulerZ))
             {
-                var worldMatrix = meshNode.GetObjectTM(key);
-                if (meshNode.NodeParent != null)
+                ExportQuaternionAnimation("rotationQuaternion", animations, key =>
                 {
-                    var parentWorld = meshNode.NodeParent.GetObjectTM(key);
-                    worldMatrix.MultiplyBy(parentWorld.Inverse);
-                }
-                var rot = worldMatrix.Rotation;
-                return new[] { rot.X, rot.Y, rot.Z, -rot.W };
-            });
+                    var worldMatrix = meshNode.GetObjectTM(key);
+                    if (meshNode.NodeParent != null)
+                    {
+                        var parentWorld = meshNode.NodeParent.GetObjectTM(key);
+                        worldMatrix.MultiplyBy(parentWorld.Inverse);
+                    }
+
 
-            ExportVector3Animation("scaling", animations, key =>
+                    var rot = worldMatrix.Rotation;
+                    return new[] { rot.X, rot.Y, rot.Z, -rot.W };
+                });
+            }
+
+            if (meshNode.IGameControl.IsAnimated(IGameControlType.Scale))
             {
-                var worldMatrix = meshNode.GetObjectTM(key);
-                if (meshNode.NodeParent != null)
+                ExportVector3Animation("scaling", animations, key =>
                 {
-                    var parentWorld = meshNode.NodeParent.GetObjectTM(key);
-                    worldMatrix.MultiplyBy(parentWorld.Inverse);
-                }
-                var scale = worldMatrix.Scaling;
-                return new[] { scale.X, scale.Y, scale.Z };
-            });
+                    var worldMatrix = meshNode.GetObjectTM(key);
+                    if (meshNode.NodeParent != null)
+                    {
+                        var parentWorld = meshNode.NodeParent.GetObjectTM(key);
+                        worldMatrix.MultiplyBy(parentWorld.Inverse);
+                    }
+                    var scale = worldMatrix.Scaling;
+
+                    return new[] { scale.X, scale.Y, scale.Z };
+                });
+            }
         }
     }
 }

+ 7 - 0
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs

@@ -167,6 +167,8 @@ namespace Max2Babylon
             var progression = 10.0f;
             ReportProgressChanged((int)progression);
             referencedMaterials.Clear();
+            // Reseting is optionnal. It makes each morph target manager export starts from id = 0.
+            BabylonMorphTargetManager.Reset();
             foreach (var maxRootNode in maxRootNodes)
             {
                 exportNodeRec(maxRootNode, babylonScene, gameScene);
@@ -320,6 +322,11 @@ namespace Max2Babylon
                 case Autodesk.Max.IGameObject.ObjectTypes.Light:
                     babylonNode = ExportLight(maxGameScene, maxGameNode, babylonScene);
                     break;
+                case Autodesk.Max.IGameObject.ObjectTypes.Unknown:
+                    // Create a dummy (empty mesh) when type is unknown
+                    // An example of unknown type object is the target of target light or camera
+                    babylonNode = ExportDummy(maxGameScene, maxGameNode, babylonScene);
+                    break;
                 default:
                     // The type of node is not exportable (helper, spline, xref...)
                     hasExporter = false;

+ 158 - 0
Exporters/3ds Max/Max2Babylon/Exporter/GLTFBufferService.cs

@@ -0,0 +1,158 @@
+using GLTFExport.Entities;
+
+namespace Max2Babylon
+{
+    public class GLTFBufferService
+    {
+        private static GLTFBufferService _instance;
+
+        public static GLTFBufferService Instance
+        {
+            get
+            {
+                if (_instance == null)
+                {
+                    _instance = new GLTFBufferService();
+                }
+                return _instance;
+            }
+        }
+
+        public GLTFBuffer GetBuffer(GLTF gltf)
+        {
+            var buffer = gltf.buffer;
+            if (buffer == null)
+            {
+                buffer = new GLTFBuffer
+                {
+                    uri = gltf.OutputFile + ".bin"
+                };
+                buffer.index = gltf.BuffersList.Count;
+                gltf.BuffersList.Add(buffer);
+                gltf.buffer = buffer;
+            }
+            return buffer;
+        }
+
+        public GLTFBufferView GetBufferViewScalar(GLTF gltf, GLTFBuffer buffer)
+        {
+            if (gltf.bufferViewScalar == null)
+            {
+                gltf.bufferViewScalar = CreateBufferView(gltf, buffer, "bufferViewScalar");
+            }
+            return gltf.bufferViewScalar;
+        }
+
+        public GLTFBufferView GetBufferViewFloatVec2(GLTF gltf, GLTFBuffer buffer)
+        {
+            if (gltf.bufferViewFloatVec2 == null)
+            {
+                var bufferView = CreateBufferView(gltf, buffer, "bufferViewFloatVec2");
+                bufferView.byteStride = 8;
+                gltf.bufferViewFloatVec2 = bufferView;
+            }
+            return gltf.bufferViewFloatVec2;
+        }
+
+        public GLTFBufferView GetBufferViewFloatVec3(GLTF gltf, GLTFBuffer buffer)
+        {
+            if (gltf.bufferViewFloatVec3 == null)
+            {
+                var bufferView = CreateBufferView(gltf, buffer, "bufferViewFloatVec3");
+                bufferView.byteStride = 12;
+                gltf.bufferViewFloatVec3 = bufferView;
+            }
+            return gltf.bufferViewFloatVec3;
+        }
+
+        public GLTFBufferView GetBufferViewFloatVec4(GLTF gltf, GLTFBuffer buffer)
+        {
+            if (gltf.bufferViewFloatVec4 == null)
+            {
+                var bufferView = CreateBufferView(gltf, buffer, "bufferViewFloatVec4");
+                bufferView.byteStride = 16;
+                gltf.bufferViewFloatVec4 = bufferView;
+            }
+            return gltf.bufferViewFloatVec4;
+        }
+
+        public GLTFBufferView GetBufferViewAnimationFloatScalar(GLTF gltf, GLTFBuffer buffer)
+        {
+            if (gltf.bufferViewAnimationFloatScalar == null)
+            {
+                gltf.bufferViewAnimationFloatScalar = CreateBufferView(gltf, buffer, "bufferViewAnimationFloatScalar");
+            }
+            return gltf.bufferViewAnimationFloatScalar;
+        }
+
+        public GLTFBufferView GetBufferViewAnimationFloatVec3(GLTF gltf, GLTFBuffer buffer)
+        {
+            if (gltf.bufferViewAnimationFloatVec3 == null)
+            {
+                var bufferView = CreateBufferView(gltf, buffer, "bufferViewAnimationFloatVec3");
+                gltf.bufferViewAnimationFloatVec3 = bufferView;
+            }
+            return gltf.bufferViewAnimationFloatVec3;
+        }
+
+        public GLTFBufferView GetBufferViewAnimationFloatVec4(GLTF gltf, GLTFBuffer buffer)
+        {
+            if (gltf.bufferViewAnimationFloatVec4 == null)
+            {
+                var bufferView = CreateBufferView(gltf, buffer, "bufferViewAnimationFloatVec4");
+                gltf.bufferViewAnimationFloatVec4 = bufferView;
+            }
+            return gltf.bufferViewAnimationFloatVec4;
+        }
+
+        private GLTFBufferView CreateBufferView(GLTF gltf, GLTFBuffer buffer, string name)
+        {
+            var bufferView = new GLTFBufferView
+            {
+                name = name,
+                buffer = buffer.index,
+                Buffer = buffer
+            };
+            bufferView.index = gltf.BufferViewsList.Count;
+            gltf.BufferViewsList.Add(bufferView);
+            buffer.BufferViews.Add(bufferView);
+            return bufferView;
+        }
+
+        public GLTFAccessor CreateAccessor(GLTF gltf, GLTFBufferView bufferView, string name, GLTFAccessor.ComponentType componentType, GLTFAccessor.TypeEnum type)
+        {
+            var accessor = new GLTFAccessor
+            {
+                name = name,
+                bufferView = bufferView.index,
+                BufferView = bufferView,
+                componentType = componentType,
+                type = type.ToString()
+            };
+            accessor.index = gltf.AccessorsList.Count;
+            gltf.AccessorsList.Add(accessor);
+            bufferView.Accessors.Add(accessor);
+            return accessor;
+        }
+
+        public static void UpdateMinMaxAccessor(GLTFAccessor accessor, float[] values)
+        {
+            for (int indexComponent = 0; indexComponent < values.Length; indexComponent++)
+            {
+                UpdateMinMaxAccessor(accessor, values[indexComponent], indexComponent);
+            }
+        }
+
+        public static void UpdateMinMaxAccessor(GLTFAccessor accessor, float value, int indexComponent = 0)
+        {
+            if (value < accessor.min[indexComponent])
+            {
+                accessor.min[indexComponent] = value;
+            }
+            if (value > accessor.max[indexComponent])
+            {
+                accessor.max[indexComponent] = value;
+            }
+        }
+    }
+}

+ 18 - 1
Exporters/3ds Max/Max2Babylon/Tools/Tools.cs

@@ -13,6 +13,11 @@ namespace Max2Babylon
 {
     public static class Tools
     {
+        public static float Lerp(float min, float max, float t)
+        {
+            return min + (max - min) * t;
+        }
+
         // -------------------------
         // -- IIPropertyContainer --
         // -------------------------
@@ -105,6 +110,18 @@ namespace Max2Babylon
             }
         }
 
+        public static IIGameMorpher AsGameMorpher(this IIGameModifier obj)
+        {
+            var type = GetWrappersAssembly().GetType("Autodesk.Max.Wrappers.IGameMorpher");
+            var constructor = type.GetConstructors()[0];
+            // var pointerType = GetWrappersAssembly().GetType("IGameCamera");
+            unsafe
+            {
+                var voidPtr = obj.GetNativeHandle().ToPointer();
+                return (IIGameMorpher)constructor.Invoke(new object[] { obj.GetNativeHandle(), false });
+            }
+        }
+
         public const float Epsilon = 0.001f;
 
         public static IPoint3 XAxis { get { return Loader.Global.Point3.Create(1, 0, 0); } }
@@ -118,7 +135,7 @@ namespace Max2Babylon
         }
 
         public static IMatrix3 Identity { get { return Loader.Global.Matrix3.Create(XAxis, YAxis, ZAxis, Origin); } }
-        
+
         public static Vector3 ToEulerAngles(this IQuat q)
         {
             // Store the Euler angles in radians

二进制
Exporters/Blender/Blender2Babylon-5.4.zip


+ 1 - 1
Exporters/Blender/src/babylon-js/__init__.py

@@ -1,7 +1,7 @@
 bl_info = {
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (5, 4, 0),
+    'version': (5, 4, 1),
     'blender': (2, 76, 0),
     'location': 'File > Export > Babylon.js (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',

+ 14 - 10
Exporters/Blender/src/babylon-js/mesh.py

@@ -58,17 +58,21 @@ class Mesh(FCurveAnimatable):
         if len(object.vertex_groups) > 0 and not object.data.ignoreSkeleton:
             objArmature = object.find_armature()
             if objArmature != None:
-                hasSkeleton = True
                 # used to get bone index, since could be skipping IK bones
                 skeleton = exporter.get_skeleton(objArmature.name)
-                i = 0
-                for obj in scene.objects:
-                    if obj.type == "ARMATURE":
-                        if obj == objArmature:
-                            self.skeletonId = i
-                            break
-                        else:
-                            i += 1
+                hasSkeleton = skeleton is not None
+                
+                if not hasSkeleton:
+                    Logger.warn('No skeleton with name "' + objArmature.name + '" found skeleton ignored.')
+                else:
+                    i = 0
+                    for obj in scene.objects:
+                        if obj.type == "ARMATURE":
+                            if obj == objArmature:
+                                self.skeletonId = i
+                                break
+                            else:
+                                i += 1
 
         # determine Position, rotation, & scaling
         if forcedParent is None:
@@ -627,7 +631,7 @@ class Mesh(FCurveAnimatable):
             write_float(file_handler, 'physicsRestitution', self.physicsRestitution)
 
         # Geometry
-        if hasattr(self, 'skeletonId'):
+        if self.hasSkeleton:
             write_int(file_handler, 'skeletonId', self.skeletonId)
             write_int(file_handler, 'numBoneInfluencers', self.numBoneInfluencers)
 

+ 0 - 66
Exporters/FBX/BabylonFBXExporter.sln

@@ -1,66 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BabylonFbxNative", "BabylonFbxNative\BabylonFbxNative.vcxproj", "{6C145CFB-31AC-4B28-8B74-26680D26A6E3}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FbxExporter", "FbxExporter\FbxExporter.vcxproj", "{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FbxRerouteSkeleton", "FbxRerouteSkeleton\FbxRerouteSkeleton.vcxproj", "{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{61044500-24C7-454A-9E06-79ED84EB199E}"
-	ProjectSection(SolutionItems) = preProject
-		readme.md = readme.md
-	EndProjectSection
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		Profile|Win32 = Profile|Win32
-		Profile|x64 = Profile|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|Win32.ActiveCfg = Debug|Win32
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|Win32.Build.0 = Debug|Win32
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|x64.ActiveCfg = Debug|x64
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|x64.Build.0 = Debug|x64
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|Win32.ActiveCfg = Release|Win32
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|Win32.Build.0 = Release|Win32
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|x64.ActiveCfg = Release|x64
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|x64.Build.0 = Release|x64
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|Win32.ActiveCfg = Release|Win32
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|Win32.Build.0 = Release|Win32
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|x64.ActiveCfg = Release|x64
-		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|x64.Build.0 = Release|x64
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|Win32.ActiveCfg = Debug|Win32
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|Win32.Build.0 = Debug|Win32
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|x64.ActiveCfg = Debug|x64
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|x64.Build.0 = Debug|x64
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|Win32.ActiveCfg = Release|Win32
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|Win32.Build.0 = Release|Win32
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|x64.ActiveCfg = Release|x64
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|x64.Build.0 = Release|x64
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|Win32.ActiveCfg = Release|Win32
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|Win32.Build.0 = Release|Win32
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|x64.ActiveCfg = Release|x64
-		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|x64.Build.0 = Release|x64
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|Win32.ActiveCfg = Debug|Win32
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|Win32.Build.0 = Debug|Win32
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|x64.ActiveCfg = Debug|x64
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|x64.Build.0 = Debug|x64
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|Win32.ActiveCfg = Release|Win32
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|Win32.Build.0 = Release|Win32
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|x64.ActiveCfg = Release|Win32
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|Win32.ActiveCfg = Release|Win32
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|Win32.Build.0 = Release|Win32
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|x64.ActiveCfg = Release|x64
-		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|x64.Build.0 = Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal

+ 0 - 33
Exporters/FBX/BabylonFbxNative/BabylonAbstractMesh.cpp

@@ -1,33 +0,0 @@
-#include "stdafx.h"
-#include "BabylonAbstractMesh.h"
-
-
-BabylonAbstractMesh::BabylonAbstractMesh()
-	:_position(0, 0, 0), _rotationQuaternion(0, 0, 0,0), _scaling(1,1,1)
-{
-}
-
-BabylonAbstractMesh::BabylonAbstractMesh(BabylonNode* node)
-{
-	auto localTransform = node->GetLocal();
-	_position = localTransform.translation();
-	_rotationQuaternion = localTransform.rotationQuaternion();
-	_scaling = localTransform.scaling();
-	auto n = node->name();
-	_name = std::wstring(n.begin(), n.end());
-}
-
-
-web::json::value BabylonAbstractMesh::toJson() 
-{
-	auto jobj = web::json::value::object();
-	jobj[L"name"] = web::json::value::string(_name);
-	writeVector3(jobj, L"position", position());
-	writeVector4(jobj, L"rotationQuaternion", rotationQuaternion());
-	writeVector3(jobj, L"scaling", scaling());
-	return jobj;
-}
-
-BabylonAbstractMesh::~BabylonAbstractMesh()
-{
-}

+ 0 - 48
Exporters/FBX/BabylonFbxNative/BabylonAbstractMesh.h

@@ -1,48 +0,0 @@
-#pragma once
-#include <string>
-#include <cpprest\json.h>
-#include "BabylonVertex.h"
-#include "BabylonNode.h"
-
-// base class for meshes and mesh instances (instances not implemented yet)
-class BabylonAbstractMesh
-{
-private:
-	std::wstring _name;
-	babylon_vector3 _position;
-	babylon_vector4 _rotationQuaternion;
-	babylon_vector3 _scaling;
-public:
-	const std::wstring& name() const{
-		return _name;
-	}
-	void name(const std::wstring& value){
-		_name = value;
-	}
-	babylon_vector3 position() const{
-		return _position;
-	}
-	void position(babylon_vector3 value){
-		_position = value;
-	}
-	babylon_vector4 rotationQuaternion() const{
-		return _rotationQuaternion;
-	}
-	void rotationQuaternion(babylon_vector4 value){
-		_rotationQuaternion = value;
-	}
-	babylon_vector3 scaling() const{
-		return _scaling;
-	}
-	void scaling(babylon_vector3 value){
-		_scaling = value;
-	}
-	BabylonAbstractMesh();
-
-	BabylonAbstractMesh(BabylonNode* node);
-	BabylonAbstractMesh(const BabylonAbstractMesh& ) = default;
-
-	virtual web::json::value toJson() ;
-	virtual ~BabylonAbstractMesh();
-};
-

+ 0 - 8
Exporters/FBX/BabylonFbxNative/BabylonAnimation.cpp

@@ -1,8 +0,0 @@
-#include "stdafx.h"
-#include "BabylonAnimation.h"
-
-
-BabylonAnimationBase::BabylonAnimationBase(int loopBehavior, int fps, const std::wstring& name, const std::wstring& animatedProperty, bool autoAnimate, int autoAnimateFrom, int autoAnimateTo, bool autoAnimateLoop) :
-loopBehavior(loopBehavior), framePerSecond(fps), name(name), property(animatedProperty), autoAnimate(autoAnimate), autoAnimateFrom(autoAnimateFrom), autoAnimateTo(autoAnimateTo), autoAnimateLoop(autoAnimateLoop)
-{
-}

+ 0 - 231
Exporters/FBX/BabylonFbxNative/BabylonAnimation.h

@@ -1,231 +0,0 @@
-#pragma once
-#include <string>
-#include <vector>
-#include "BabylonVertex.h"
-#include <cpprest\json.h>
-
-// base class representing babylon animations
-class BabylonAnimationBase
-{
-public:
-
-	static const int dataType_Float = 0;
-	static const int dataType_Vector3 = 1;
-	static const int dataType_Quaternion = 2;
-	static const int dataType_Matrix = 3;
-	static const int loopBehavior_Relative = 0;
-	static const int loopBehavior_Cycle = 1;
-	static const int loopBehavior_Constant = 2;
-	int dataType;
-	int loopBehavior;
-	int framePerSecond;
-	std::wstring name;
-	std::wstring property;
-	bool autoAnimate;
-	int autoAnimateFrom;
-	int autoAnimateTo;
-	bool autoAnimateLoop;
-	BabylonAnimationBase(int loopBehavior, int fps, const std::wstring& name, const std::wstring& animatedProperty, bool autoAnimate, int autoAnimateFrom, int autoAnimateTo, bool autoAnimateLoop);
-	virtual ~BabylonAnimationBase(){}
-
-
-	virtual bool isConstant() = 0;
-
-	virtual web::json::value toJson() const = 0;
-};
-
-// key frame data
-template<typename T>
-struct babylon_animation_key{
-	int frame;
-	T values;
-};
-
-// traits for animated babylon data types (must contain : 
-// static const int dataType
-// static web::json::value jsonify(const T& value)
-template<typename T>
-struct bab_anim_traits{
-
-};
-
-// specialization for vectors 3D
-template<>
-struct bab_anim_traits < babylon_vector3 >
-{
-	static const int dataType = BabylonAnimationBase::dataType_Vector3;
-
-	static web::json::value jsonify(const babylon_vector3& value){
-		auto jarray = web::json::value::array();
-		jarray[0] = web::json::value::number(value.x);
-		jarray[1] = web::json::value::number(value.y);
-		jarray[2] = web::json::value::number(value.z);
-		return jarray;
-	}
-};
-
-// specialization for quaternions
-template<>
-struct bab_anim_traits < babylon_vector4 >
-{
-	static const int dataType = BabylonAnimationBase::dataType_Quaternion;
-
-	static web::json::value jsonify(const babylon_vector4& value){
-		auto jarray = web::json::value::array();
-		jarray[0] = web::json::value::number(value.x);
-		jarray[1] = web::json::value::number(value.y);
-		jarray[2] = web::json::value::number(value.z);
-		jarray[3] = web::json::value::number(value.w);
-		return jarray;
-	}
-};
-
-// specialization for matrices
-template<>
-struct bab_anim_traits < FbxMatrix >
-{
-	static const int dataType = BabylonAnimationBase::dataType_Matrix;
-
-	static web::json::value jsonify(const FbxMatrix& value){
-		auto jmat = web::json::value::array();
-		for (auto x = 0; x < 4; ++x){
-			for (auto y = 0; y < 4; ++y){
-				jmat[x * 4 + y] = web::json::value::number(value[x][y]);
-			}
-		}
-		return jmat;
-	}
-};
-
-// specialization for scalar floats
-template<>
-struct bab_anim_traits < float >
-{
-	static const int dataType = BabylonAnimationBase::dataType_Float;
-
-	static web::json::value jsonify(float value){
-		auto jarray = web::json::value::array();
-		jarray[0] = web::json::value::number(value);
-		return jarray;
-	}
-};
-
-// used for interpolation simplification
-template<typename T>
-bool isNear(const T& lhs, const T& rhs);
-
-template <>
-inline bool isNear<float>(const float& lhs, const float& rhs){
-	auto diff = lhs - rhs;
-	return diff >= -0.000001f && diff <= 0.000001f;
-}
-
-template <>
-inline bool isNear<FbxMatrix>(const FbxMatrix& lhs, const FbxMatrix& rhs){
-	return lhs == rhs;
-}
-
-template <>
-inline bool isNear<babylon_vector3>(const babylon_vector3& lhs, const babylon_vector3& rhs){
-	return isNear(lhs.x, rhs.x)
-		&& isNear(lhs.y, rhs.y)
-		&& isNear(lhs.z, rhs.z);
-}
-template <>
-inline bool isNear<babylon_vector4>(const babylon_vector4& lhs, const babylon_vector4& rhs){
-	return isNear(lhs.x, rhs.x)
-		&& isNear(lhs.y, rhs.y)
-		&& isNear(lhs.z, rhs.z)
-		&& isNear(lhs.w, rhs.w);
-}
-
-template<typename T>
-inline T lerp(const T& start, const T& end, float factor){
-	return start + (end - start)*factor;
-}
-
-template<typename T>
-bool isLinearInterpolation(const babylon_animation_key<T>& key0, const babylon_animation_key<T>& key1, const babylon_animation_key<T>& key2){
-	auto testVal = lerp(key0.values, key2.values, static_cast<float>(key1.frame - key0.frame) / static_cast<float>(key2.frame - key0.frame));
-	return isNear(testVal, key1.values);
-}
-// typed babylon animation.
-// requires bab_anim_traits<T>, isNear<T> and basic arithmetic operators
-template<typename T>
-class BabylonAnimation : public BabylonAnimationBase
-{
-public:
-	std::vector<babylon_animation_key<T>> keys;
-	BabylonAnimation(int loopBehavior, int fps, const std::wstring& name, const std::wstring& animatedProperty, bool autoAnimate, int autoAnimateFrom, int autoAnimateTo, bool autoAnimateLoop) :
-		BabylonAnimationBase(loopBehavior, fps, name, animatedProperty, autoAnimate, autoAnimateFrom, autoAnimateTo, autoAnimateLoop)
-		
-	{
-		dataType = bab_anim_traits<T>::dataType;
-	}
-
-	void appendKey(const babylon_animation_key<T>& key){
-		if (keys.size() <= 1){
-			// nothing to simplify
-			keys.push_back(key);
-		}
-		else{
-			if (isNear(key.values, keys[keys.size() - 1].values) && isNear(key.values, keys[keys.size() - 2].values)){
-				// if 3 times the same value, eliminate intermediate key
-				keys.resize(keys.size() - 1);
-				keys.push_back(key);
-			}
-			else if (isLinearInterpolation(keys[keys.size() - 2], keys[keys.size() - 1], key)){
-				// if the 3 last values are linearly interpolated, eliminate the intermediate key
-				keys.resize(keys.size() - 1);
-				keys.push_back(key);
-
-			}
-			else{
-
-				keys.push_back(key);
-			}
-
-		}
-	}
-
-	virtual bool isConstant() override{
-		if (keys.size() < 2){
-			return true;
-		}
-		if (keys.size() > 2){
-			return false;
-		}
-
-		return isNear(keys[0].values, keys[1].values);
-	}
-
-	virtual web::json::value toJson() const override {
-		auto jobj = web::json::value::object();
-
-
-		jobj[L"dataType"] = web::json::value::number(dataType);
-		jobj[L"framePerSecond"] = web::json::value::number(framePerSecond);
-		jobj[L"loopBehavior"] = web::json::value::number(loopBehavior);
-		jobj[L"name"] = web::json::value::string(name);
-		jobj[L"property"] = web::json::value::string(property);
-		jobj[L"autoAnimate"] = web::json::value::boolean(autoAnimate);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(autoAnimateFrom);
-		jobj[L"autoAnimateTo"] = web::json::value::number(autoAnimateTo);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(autoAnimateLoop);
-
-		auto jkeys = web::json::value::array();
-
-		for (auto ix = 0u; ix < keys.size(); ++ix){
-			auto jkey = web::json::value::object();
-			jkey[L"frame"] = keys[ix].frame;
-			jkey[L"values"] = bab_anim_traits<T>::jsonify(keys[ix].values);
-			jkeys[jkeys.size()] = jkey;
-		}
-
-		jobj[L"keys"] = jkeys;
-
-		return jobj;
-	}
-};
-
-

+ 0 - 200
Exporters/FBX/BabylonFbxNative/BabylonCamera.cpp

@@ -1,200 +0,0 @@
-#include "stdafx.h"
-#include "BabylonCamera.h"
-#include "NodeHelpers.h"
-#include "GlobalSettings.h"
-
-web::json::value BabylonCamera::toJson() const
-{
-	auto jobj = web::json::value::object();
-	jobj[L"name"] = web::json::value::string(name);
-	jobj[L"id"] = web::json::value::string(id);
-	if(parentId.size()>0)
-		jobj[L"parentId"] = web::json::value::string(parentId);
-	if(lockedTargetId.size()>0)
-		jobj[L"lockedTargetId"] = web::json::value::string(lockedTargetId);
-	jobj[L"type"] = web::json::value::string(type);
-	writeVector3(jobj, L"position", position);
-	writeVector3(jobj, L"rotation", babylon_vector3(0,0,0));
-	writeVector4(jobj, L"rotationQuaternion", rotationQuaternion);
-	if(lockedTargetId.size()==0)
-		writeVector3(jobj, L"target", target);
-
-	jobj[L"fov"] = web::json::value::number(fov);
-	jobj[L"minZ"] = web::json::value::number(minZ);
-	jobj[L"maxZ"] = web::json::value::number(maxZ);
-	jobj[L"speed"] = web::json::value::number(speed);
-	jobj[L"inertia"] = web::json::value::number(inertia);
-	jobj[L"checkCollisions"] = web::json::value::boolean(checkCollisions);
-	jobj[L"applyGravity"] = web::json::value::boolean(applyGravity);
-	writeVector3(jobj, L"ellipsoid", ellipsoid);
-	if (animations.size() == 0 && quatAnimations.size() == 0){
-
-		jobj[L"autoAnimate"] = web::json::value::boolean(false);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(false);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(0);
-		jobj[L"autoAnimateTo"] = web::json::value::number(0);
-
-	}
-	else if (animations.size()>0){
-
-		jobj[L"autoAnimate"] = web::json::value::boolean(animations[0]->autoAnimate);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(animations[0]->autoAnimateLoop);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(animations[0]->autoAnimateFrom);
-		jobj[L"autoAnimateTo"] = web::json::value::number(animations[0]->autoAnimateTo);
-	}
-	else{
-		jobj[L"autoAnimate"] = web::json::value::boolean(quatAnimations[0]->autoAnimate);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(quatAnimations[0]->autoAnimateLoop);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(quatAnimations[0]->autoAnimateFrom);
-		jobj[L"autoAnimateTo"] = web::json::value::number(quatAnimations[0]->autoAnimateTo);
-	}
-
-	auto janimations = web::json::value::array();
-	for (const auto& anim : animations){
-		janimations[janimations.size()] = anim->toJson();
-	}for (const auto& anim : quatAnimations){
-		janimations[janimations.size()] = anim->toJson();
-	}
-	jobj[L"animations"] = janimations;
-	return jobj;
-}
-
-BabylonCamera::BabylonCamera()
-{
-}
-
-
-BabylonCamera buildCameraFromBoundingBox(const babylon_boundingbox& box){
-	BabylonCamera result;
-	result.name = L"defaultcamera";
-	result.id = L"defaultcamera";
-
-	result.target = box.getCenter();
-	result.position = babylon_vector3(result.target.x, result.target.y, result.target.z - 2 * std::max(box.getWidth(), std::max(box.getHeight(), box.getDepth())));
-	result.fov = 0.8576f;
-	result.minZ = -0.01f*result.position.z;
-	result.maxZ = -5 * result.position.z;
-	result.speed = (-result.position.z - result.target.z) / 10;
-	result.inertia = 0.9f;
-	result.checkCollisions = false;
-	result.applyGravity = false;
-	result.ellipsoid = babylon_vector3(.2f, .9f, .2f);
-	return result;
-}
-
-BabylonCamera::BabylonCamera(BabylonNode& babnode)
-{
-	auto node = babnode.fbxNode();
-	std::string ansiName = node->GetName();
-	name = std::wstring(ansiName.begin(), ansiName.end());
-	id = getNodeId(node);
-	auto parent = node->GetParent();
-	if (parent) {
-		parentId = getNodeId(parent);
-	}
-	auto camera = node->GetCamera();
-	if (!camera) {
-		return;
-	}
-	type = L"FreeCamera";
-	auto targetNode = node->GetTarget();
-	if (targetNode) {
-		lockedTargetId = getNodeId(targetNode);
-	}
-	else {
-		target = camera->InterestPosition.Get();
-	}
-	auto localTransformAtStart = babnode.GetLocal();
-	position = localTransformAtStart.translation();
-	rotationQuaternion = localTransformAtStart.rotationQuaternion();
-	
-	fov = static_cast<float>(camera->FieldOfViewY * Euler2Rad);
-	
-	
-	minZ = static_cast<float>(camera->NearPlane.Get());
-	maxZ = static_cast<float>(camera->FarPlane.Get());
-
-	auto hasAnimStack = node->GetScene()->GetSrcObjectCount<FbxAnimStack>() > 0;
-	if (!hasAnimStack){
-		return;
-	}
-	auto animStack = node->GetScene()->GetCurrentAnimationStack();
-	FbxString animStackName = animStack->GetName();
-	//FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
-	auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
-	auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
-	auto startFrame = animStack->GetLocalTimeSpan().GetStart().GetFrameCount(animTimeMode);
-	auto endFrame = animStack->GetLocalTimeSpan().GetStop().GetFrameCount(animTimeMode);
-	auto animLengthInFrame = endFrame - startFrame + 1;
-
-	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"position", L"position", true, 0, static_cast<int>(animLengthInFrame), true);
-	auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"rotation", L"rotation", true, 0, static_cast<int>(animLengthInFrame), true);
-	auto targetAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"target", L"target", true, 0, static_cast<int>(animLengthInFrame), true);
-	if (node->LclRotation.GetCurveNode() || node->LclScaling.GetCurveNode() || node->LclTranslation.GetCurveNode() || camera->InterestPosition.GetCurveNode()) {
-		for (auto ix = 0; ix < animLengthInFrame; ix++) {
-			FbxTime currTime;
-			currTime.SetFrame(startFrame + ix, animTimeMode);
-
-			babylon_animation_key<babylon_vector3> poskey;
-			babylon_animation_key<babylon_vector4> rotkey;
-			poskey.frame = ix;
-			rotkey.frame = ix;
-
-
-			auto transformAtT = babnode.GetLocal(currTime);
-
-			poskey.values = transformAtT.translation();
-			rotkey.values = transformAtT.rotationQuaternion();
-			posAnim->appendKey(poskey);
-			rotAnim->appendKey(rotkey);
-
-			if (lockedTargetId.size() == 0) {
-
-				babylon_animation_key<babylon_vector3> targetKey;
-				targetKey.frame = ix;
-				targetKey.values = camera->InterestPosition.EvaluateValue(currTime);
-				targetAnim->appendKey(targetKey);
-			}
-		}
-	}
-	if (!posAnim->isConstant()){
-		animations.push_back(posAnim);
-	}
-	if (!rotAnim->isConstant()){
-		quatAnimations.push_back(rotAnim);
-	}
-	if (!targetAnim->isConstant()){
-		animations.push_back(targetAnim);
-	}
-}
-
-
-BabylonCamera::BabylonCamera(BabylonCamera && moved) : 
-	name(std::move(moved.name)),
-	id(std::move(moved.id)),
-	parentId(std::move(moved.parentId)),
-	lockedTargetId(std::move(moved.lockedTargetId)),
-	type(std::move(moved.type)),
-	position(std::move(moved.position)),
-	rotationQuaternion(std::move(moved.rotationQuaternion)),
-	target(std::move(moved.target)),
-	fov(std::move(moved.fov)),
-	minZ(std::move(moved.minZ)),
-	maxZ(std::move(moved.maxZ)),
-	speed(std::move(moved.speed)),
-	inertia(std::move(moved.inertia)),
-	checkCollisions(std::move(moved.checkCollisions)),
-	applyGravity(std::move(moved.applyGravity)),
-	ellipsoid(std::move(moved.ellipsoid)),
-	autoAnimate(std::move(moved.autoAnimate)),
-	autoAnimateFrom(std::move(moved.autoAnimateFrom)),
-	autoAnimateTo(std::move(moved.autoAnimateTo)),
-	autoAnimateLoop(std::move(moved.autoAnimateLoop)),
-	animations(std::move(moved.animations)),
-	quatAnimations(std::move(moved.quatAnimations))
-{
-}
-
-BabylonCamera::~BabylonCamera()
-{
-}

+ 0 - 86
Exporters/FBX/BabylonFbxNative/BabylonCamera.h

@@ -1,86 +0,0 @@
-#pragma once
-#include <cpprest\json.h>
-#include <string>
-#include "BabylonVertex.h"
-#include <fbxsdk.h>
-#include "BabylonNode.h"
-#include "BabylonAnimation.h"
-#include <memory>
-class BabylonCamera
-{
-public:
-	
-	std::wstring name;
-
-		
-	std::wstring id;
-
-		
-	std::wstring parentId;
-
-		
-	std::wstring lockedTargetId;
-
-		
-	std::wstring type;
-
-		
-	babylon_vector3 position;
-
-		
-	babylon_vector4 rotationQuaternion = babylon_vector4(0,0,0,1);
-
-		
-	babylon_vector3 target;
-
-		
-	float fov =.8f;
-
-		
-	float minZ = .1f;
-
-		
-	float maxZ = 5000;
-
-		
-	float speed = 1;
-
-		
-	float inertia = .9f;
-
-		
-	bool checkCollisions = false;
-
-		
-	bool applyGravity = false;
-
-		
-	babylon_vector3 ellipsoid;
-
-		
-	bool autoAnimate = false;
-
-		
-	int autoAnimateFrom = 0;
-
-		
-	int autoAnimateTo = 0;
-
-		
-	bool autoAnimateLoop = false;
-
-
-	std::vector<std::shared_ptr < BabylonAnimation<babylon_vector3>>> animations;
-
-	std::vector<std::shared_ptr < BabylonAnimation<babylon_vector4>>> quatAnimations;
-	web::json::value toJson() const;
-
-	BabylonCamera();
-	BabylonCamera(BabylonNode& babnode);
-	BabylonCamera(const BabylonCamera& ) = default;
-	BabylonCamera(BabylonCamera&& moved);
-	~BabylonCamera();
-};
-
-
-BabylonCamera buildCameraFromBoundingBox(const babylon_boundingbox& box);

+ 0 - 233
Exporters/FBX/BabylonFbxNative/BabylonFbxNative.vcxproj

@@ -1,233 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{6C145CFB-31AC-4B28-8B74-26680D26A6E3}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>BabylonFbxNative</RootNamespace>
-    <SccProjectName>SAK</SccProjectName>
-    <SccAuxPath>SAK</SccAuxPath>
-    <SccLocalPath>SAK</SccLocalPath>
-    <SccProvider>SAK</SccProvider>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-    <Import Project="..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x86\debug;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x86\release;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x64\debug;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x64\release;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <AdditionalDependencies>libfbxsdk-md.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <AdditionalDependencies>libfbxsdk-md.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <AdditionalDependencies>libfbxsdk-md.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <AdditionalDependencies>libfbxsdk-md.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="BabylonAbstractMesh.h" />
-    <ClInclude Include="BabylonAnimation.h" />
-    <ClInclude Include="BabylonCamera.h" />
-    <ClInclude Include="BabylonLight.h" />
-    <ClInclude Include="BabylonMaterial.h" />
-    <ClInclude Include="BabylonMesh.h" />
-    <ClInclude Include="BabylonNode.h" />
-    <ClInclude Include="BabylonScene.h" />
-    <ClInclude Include="BabylonSkeleton.h" />
-    <ClInclude Include="BabylonVertex.h" />
-    <ClInclude Include="FbxDeleter.h" />
-    <ClInclude Include="FbxLoadException.h" />
-    <ClInclude Include="FbxSceneLoader.h" />
-    <ClInclude Include="GlobalSettings.h" />
-    <ClInclude Include="MatrixDecomposition.h" />
-    <ClInclude Include="NodeHelpers.h" />
-    <ClInclude Include="SkinInfo.h" />
-    <ClInclude Include="stdafx.h" />
-    <ClInclude Include="StringUtils.h" />
-    <ClInclude Include="targetver.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="BabylonAbstractMesh.cpp" />
-    <ClCompile Include="BabylonAnimation.cpp" />
-    <ClCompile Include="BabylonCamera.cpp" />
-    <ClCompile Include="BabylonLight.cpp" />
-    <ClCompile Include="BabylonMaterial.cpp" />
-    <ClCompile Include="BabylonMesh.cpp" />
-    <ClCompile Include="BabylonNode.cpp" />
-    <ClCompile Include="BabylonScene.cpp" />
-    <ClCompile Include="BabylonSkeleton.cpp" />
-    <ClCompile Include="babylon_boundingbox.cpp" />
-    <ClCompile Include="FbxLoadException.cpp" />
-    <ClCompile Include="FbxSceneLoader.cpp" />
-    <ClCompile Include="GlobalSettings.cpp" />
-    <ClCompile Include="SkinInfo.cpp" />
-    <ClCompile Include="stdafx.cpp">
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
-    <PropertyGroup>
-      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
-    </PropertyGroup>
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
-  </Target>
-</Project>

+ 0 - 132
Exporters/FBX/BabylonFbxNative/BabylonFbxNative.vcxproj.filters

@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="stdafx.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="targetver.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="FbxDeleter.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="FbxLoadException.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="FbxSceneLoader.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonVertex.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonNode.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonAbstractMesh.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonMesh.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonScene.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonMaterial.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonCamera.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="NodeHelpers.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonLight.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonAnimation.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="SkinInfo.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="BabylonSkeleton.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="GlobalSettings.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="MatrixDecomposition.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="StringUtils.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="stdafx.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="FbxLoadException.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="FbxSceneLoader.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="babylon_boundingbox.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonNode.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonAbstractMesh.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonMesh.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonScene.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonMaterial.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonCamera.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonLight.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonAnimation.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="SkinInfo.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="BabylonSkeleton.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="GlobalSettings.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-</Project>

+ 0 - 254
Exporters/FBX/BabylonFbxNative/BabylonLight.cpp

@@ -1,254 +0,0 @@
-#include "stdafx.h"
-#include "BabylonLight.h"
-#include "NodeHelpers.h"
-#include "GlobalSettings.h"
-
-web::json::value BabylonLight::toJson() const
-{
-	auto jobj = web::json::value::object();
-	jobj[L"name"] = web::json::value::string(name);
-	jobj[L"id"] = web::json::value::string(id);
-	if (parentId.size() > 0)
-		jobj[L"parentId"] = web::json::value::string(parentId);
-
-	writeVector3(jobj, L"position", position);
-	writeVector3(jobj, L"direction", direction);
-	jobj[L"type"] = web::json::value::number(type);
-	writeVector3(jobj, L"diffuse", diffuse);
-	writeVector3(jobj, L"specular", specular);
-	jobj[L"intensity"] = web::json::value::number(intensity);
-	jobj[L"range"] = web::json::value::number(range);
-	jobj[L"exponent"] = web::json::value::number(exponent);
-	jobj[L"angle"] = web::json::value::number(angle);
-	writeVector3(jobj, L"groundColor", groundColor);
-
-	if (animations.size() == 0) {
-
-		jobj[L"autoAnimate"] = web::json::value::boolean(false);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(false);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(0);
-		jobj[L"autoAnimateTo"] = web::json::value::number(0);
-
-	}
-	else {
-
-		jobj[L"autoAnimate"] = web::json::value::boolean(animations[0]->autoAnimate);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(animations[0]->autoAnimateLoop);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(animations[0]->autoAnimateFrom);
-		jobj[L"autoAnimateTo"] = web::json::value::number(animations[0]->autoAnimateTo);
-	}
-
-	auto janimations = web::json::value::array();
-	for (const auto& anim : animations) {
-		janimations[janimations.size()] = anim->toJson();
-	}
-	jobj[L"animations"] = janimations;
-
-	auto jarray = web::json::value::array();
-	for (auto& id : excludedMeshesIds) {
-		jarray[jarray.size()] = web::json::value::string(id);
-	}
-	jobj[L"excludedMeshesIds"] = jarray;
-
-	jarray = web::json::value::array();
-	for (auto& id : includedOnlyMeshesIds) {
-		jarray[jarray.size()] = web::json::value::string(id);
-	}
-	jobj[L"includedOnlyMeshesIds"] = jarray;
-
-	return jobj;
-}
-
-BabylonLight::BabylonLight() :
-	diffuse(1, 1, 1),
-	specular(1, 1, 1)
-{
-}
-
-BabylonLight::BabylonLight(BabylonNode & babnode) :
-	diffuse(1, 1, 1),
-	specular(1, 1, 1)
-{
-	auto node = babnode.fbxNode();
-	std::string ansiName = node->GetName();
-	name = std::wstring(ansiName.begin(), ansiName.end());
-	id = getNodeId(node);
-	auto parent = node->GetParent();
-	if (parent) {
-		parentId = getNodeId(parent);
-	}
-	auto localTransform = babnode.GetLocal();
-	position = localTransform.translation();
-	auto light = node->GetLight();
-	switch (light->LightType)
-	{
-	case FbxLight::ePoint:
-		type = type_omni;
-		break;
-	case FbxLight::eDirectional:
-		type = type_direct;
-		{
-			FbxDouble3 vDir(0, -1, 0);
-			FbxAMatrix rotM;
-			rotM.SetIdentity();
-
-			rotM.SetQ(localTransform.fbxrot());
-			auto transDir = rotM.MultT(vDir);
-			direction = transDir;
-
-		}
-		break;
-	case FbxLight::eSpot:
-		type = type_Spot;
-		{
-			FbxDouble3 vDir(0, -1, 0);
-			FbxAMatrix rotM;
-			rotM.SetIdentity();
-			rotM.SetQ(localTransform.fbxrot());
-			auto transDir = rotM.MultT(vDir);
-			direction = transDir;
-			exponent = 1;
-			angle = static_cast<float>(light->OuterAngle*Euler2Rad);
-
-		}
-		break;
-	default:
-		break;
-	}
-	diffuse = light->Color.Get();
-	intensity = static_cast<float>(light->Intensity.Get() / 100.0);
-	if (light->EnableFarAttenuation.Get()) {
-		range = static_cast<float>(light->FarAttenuationEnd.Get());
-	}
-	auto hasAnimStack = node->GetScene()->GetSrcObjectCount<FbxAnimStack>() > 0;
-	if (!hasAnimStack) {
-		return;
-	}
-	castShadows = light->CastShadows.Get();
-	if (castShadows) {
-		shadowGenerator = std::make_shared<BabylonShadowGenerator>(node);
-	}
-	auto animStack = node->GetScene()->GetCurrentAnimationStack();
-	FbxString animStackName = animStack->GetName();
-	//FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
-	auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
-	auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
-	auto startFrame = animStack->GetLocalTimeSpan().GetStart().GetFrameCount(animTimeMode);
-	auto endFrame = animStack->GetLocalTimeSpan().GetStop().GetFrameCount(animTimeMode);
-	auto animLengthInFrame = endFrame - startFrame + 1;
-	auto posAnimName = getNodeId(node);
-	auto dirAnimName = getNodeId(node);
-	posAnimName.append(L"_position");
-	dirAnimName.append(L"_direction");
-	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), posAnimName, L"position", true, 0, static_cast<int>(animLengthInFrame), true);
-	auto dirAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), dirAnimName, L"direction", true, 0, static_cast<int>(animLengthInFrame), true);
-	if (node->LclRotation.GetCurveNode() || node->LclTranslation.GetCurveNode()) {
-		for (auto ix = 0; ix < animLengthInFrame; ix++) {
-			babylon_animation_key<babylon_vector3> key;
-			key.frame = ix;
-			FbxTime currTime;
-			currTime.SetFrame(startFrame + ix, animTimeMode);
-			auto currTransform = babnode.GetLocal(currTime);
-			key.values = currTransform.translation();
-			posAnim->appendKey(key);
-
-			if (type == type_direct || type == type_Spot) {
-				babylon_animation_key<babylon_vector3> dirkey;
-				dirkey.frame = ix;
-				FbxDouble3 vDir(0, -1, 0);
-				FbxAMatrix rotM;
-				rotM.SetIdentity();
-				rotM.SetQ(currTransform.fbxrot());
-				auto transDir = rotM.MultT(vDir);
-				dirkey.values = transDir;
-				dirAnim->appendKey(dirkey);
-			}
-		}
-	}
-	if (!posAnim->isConstant()) {
-		animations.push_back(posAnim);
-	}
-	if (!dirAnim->isConstant()) {
-		animations.push_back(dirAnim);
-	}
-}
-
-
-BabylonLight::BabylonLight(BabylonLight && moved)  : 
-name(std::move(moved.name)),
-id(std::move(moved.id)),
-parentId(std::move(moved.parentId)),
-position(std::move(moved.position)),
-direction(std::move(moved.direction)),
-type(std::move(moved.type)),
-diffuse(std::move(moved.diffuse)),
-specular(std::move(moved.specular)),
-intensity(std::move(moved.intensity)),
-range(std::move(moved.range)),
-exponent(std::move(moved.exponent)),
-angle(std::move(moved.angle)),
-groundColor(std::move(moved.groundColor)),
-castShadows(std::move(moved.castShadows)),
-includedOnlyMeshesIds(std::move(moved.includedOnlyMeshesIds)),
-excludedMeshesIds(std::move(moved.excludedMeshesIds)),
-shadowGenerator(std::move(moved.shadowGenerator)),
-animations(std::move(moved.animations))
-{
-}
-
-BabylonLight::~BabylonLight()
-{
-}
-
-BabylonShadowGenerator::BabylonShadowGenerator(FbxNode * lightNode)
-{
-	auto light = lightNode->GetLight();
-	lightId = getNodeId(lightNode);
-	mapSize = 2048;
-	bias = 0.00005f;
-	useBlurVarianceShadowMap = true;
-	blurScale = 2;
-	blurBoxOffset = 1;
-	useVarianceShadowMap = false;
-	usePoissonSampling = false;
-	auto nodeCount = lightNode->GetScene()->GetNodeCount();
-	for (auto ix = 0;ix < nodeCount;++ix) {
-		auto mnode = lightNode->GetScene()->GetNode(ix);
-		auto mesh = mnode->GetMesh();
-		if (mesh && mesh->CastShadow.Get()) {
-			renderList.push_back(getNodeId(mnode));
-		}
-	}
-
-}
-
-BabylonShadowGenerator::BabylonShadowGenerator(BabylonShadowGenerator && moved) : 
-	mapSize(std::move(moved.mapSize)),
-	bias(std::move(moved.bias)),
-	lightId(std::move(moved.lightId)),
-	useVarianceShadowMap(std::move(moved.useVarianceShadowMap)),
-	usePoissonSampling(std::move(moved.usePoissonSampling)),
-	useBlurVarianceShadowMap(std::move(moved.useBlurVarianceShadowMap)),
-	blurScale(std::move(moved.blurScale)),
-	blurBoxOffset(std::move(moved.blurBoxOffset)),
-	renderList(std::move(moved.renderList))
-{
-}
-
-web::json::value BabylonShadowGenerator::toJson()
-{
-	auto jobj =web::json::value::object();
-	jobj[L"mapSize"] = web::json::value::number(mapSize);
-	jobj[L"lightId"] = web::json::value::string(lightId);
-	jobj[L"useVarianceShadowMap"] = web::json::value::boolean(useVarianceShadowMap);
-	jobj[L"usePoissonSampling"] = web::json::value::boolean(usePoissonSampling);
-	/*jobj[L"useBlurVarianceShadowMap"] = web::json::value::boolean(useBlurVarianceShadowMap);
-	jobj[L"blurScale"] = web::json::value::number(blurScale);
-	jobj[L"blurBoxOffset"] = web::json::value::number(blurBoxOffset);*/
-	auto jarr = web::json::value::array();
-	for (auto& id : renderList) {
-		jarr[jarr.size()] = web::json::value::string(id);
-	}
-	jobj[L"renderList"] = jarr;
-	return jobj;
-}

+ 0 - 112
Exporters/FBX/BabylonFbxNative/BabylonLight.h

@@ -1,112 +0,0 @@
-#pragma once
-#include "BabylonVertex.h"
-#include <limits>
-#include "BabylonNode.h"
-#include "BabylonAnimation.h"
-#include <memory>
-#include <string>
-#undef max
-
-class BabylonShadowGenerator
-{
-public:
-
-	int mapSize;
-
-		
-	float bias;
-
-		
-	std::wstring lightId;
-
-		
-	bool useVarianceShadowMap;
-
-		
-	bool usePoissonSampling;
-
-		
-	bool useBlurVarianceShadowMap;
-
-		
-	float blurScale;
-
-		
-	float blurBoxOffset;
-
-		
-	std::vector<std::wstring> renderList;
-
-	BabylonShadowGenerator(FbxNode* lightNode);
-	BabylonShadowGenerator(const BabylonShadowGenerator&) = default;
-	BabylonShadowGenerator(BabylonShadowGenerator&& moved);
-	web::json::value toJson();
-
-};
-
-
-class BabylonLight
-{
-public:
-	const int type_omni = 0;
-	const int type_Spot = 2;
-
-	const int type_direct = 1;
-
-	const int type_ambient = 3;
-	
-	std::wstring name;
-
-		
-	std::wstring id;
-
-		
-	std::wstring parentId;
-
-		
-	babylon_vector3 position;
-
-		
-	babylon_vector3 direction;
-
-		
-	int type = 0;
-
-		
-	babylon_vector3 diffuse;
-
-		
-	babylon_vector3 specular;
-
-		
-	float intensity = 1;
-
-		
-	float range = std::numeric_limits<float>::max();
-
-		
-	float exponent = 0;
-
-		
-	float angle = 0;
-
-		
-	babylon_vector3 groundColor;
-
-	bool castShadows;
-	std::vector<std::wstring> includedOnlyMeshesIds;
-	std::vector<std::wstring> excludedMeshesIds;
-
-		
-	std::shared_ptr<BabylonShadowGenerator> shadowGenerator;
-	std::vector<std::shared_ptr < BabylonAnimation<babylon_vector3>>> animations;
-
-	web::json::value toJson() const;
-
-	BabylonLight();
-	BabylonLight(BabylonNode& babnode);
-	BabylonLight(const BabylonLight&) = default;
-	BabylonLight(BabylonLight&& moved);
-	~BabylonLight();
-};
-

+ 0 - 385
Exporters/FBX/BabylonFbxNative/BabylonMaterial.cpp

@@ -1,385 +0,0 @@
-#include "stdafx.h"
-#include "BabylonMaterial.h"
-#include <Windows.h>
-#include "NodeHelpers.h"
-#include "GlobalSettings.h"
-#include "StringUtils.h"
-
-web::json::value BabylonMaterial::toJson() const
-{
-	auto jobj = web::json::value::object();
-	jobj[L"name"] = web::json::value::string(name);
-	jobj[L"id"] = web::json::value::string(id);
-	jobj[L"backFaceCulling"] = web::json::value::boolean(backFaceCulling);
-	jobj[L"wireframe"] = web::json::value::boolean(wireframe);
-	writeVector3(jobj, L"ambient", ambient);
-	writeVector3(jobj, L"diffuse", diffuse);
-	writeVector3(jobj, L"specular", specular);
-	writeVector3(jobj, L"emissive", emissive);
-	jobj[L"specularPower"] = web::json::value::number(specularPower);
-	jobj[L"alpha"] = web::json::value::number(alpha);
-
-	if (diffuseTexture){
-		jobj[L"diffuseTexture"] = diffuseTexture->toJson();
-	}
-	if (ambientTexture){
-		jobj[L"ambientTexture"] = ambientTexture->toJson();
-
-	}
-	if (opacityTexture){
-		jobj[L"opacityTexture"] = opacityTexture->toJson();
-
-	}
-	if (reflectionTexture){
-		jobj[L"reflectionTexture"] = reflectionTexture->toJson();
-
-	}
-	if (emissiveTexture){
-		jobj[L"emissiveTexture"] = emissiveTexture->toJson();
-
-	}
-	if (specularTexture){
-		jobj[L"specularTexture"] = specularTexture->toJson();
-
-	}
-	if (bumpTexture){
-		jobj[L"bumpTexture"] = bumpTexture->toJson();
-
-	}
-
-
-	// todo : textures
-	return jobj;
-}
-
-BabylonMaterial::BabylonMaterial():
-ambient(1,1,1),
-diffuse(1,1,1),
-specular(1,1,1),
-emissive(0,0,0),
-specularPower(64),
-alpha(1)
-{
-}
-
-
-
-
-FbxDouble3 GetMaterialProperty(const FbxSurfaceMaterial * pMaterial,
-	const char * pPropertyName,
-	const char * pFactorPropertyName,
-	FbxFileTexture*& pTexture)
-{
-	FbxDouble3 lResult(0, 0, 0);
-	const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
-	const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
-	if (lProperty.IsValid() && lFactorProperty.IsValid())
-	{
-		lResult = lProperty.Get<FbxDouble3>();
-		double lFactor = lFactorProperty.Get<FbxDouble>();
-		if (lFactor != 1)
-		{
-			lResult[0] *= lFactor;
-			lResult[1] *= lFactor;
-			lResult[2] *= lFactor;
-		}
-	}
-
-	if (lProperty.IsValid())
-	{
-		const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();
-		if (lTextureCount)
-		{
-			FbxFileTexture* lTexture = lProperty.GetSrcObject<FbxFileTexture>();
-			pTexture = lTexture;
-		}
-	}
-
-	return lResult;
-}
-
-
-
-BabylonMaterial::BabylonMaterial(FbxSurfaceMaterial* mat) :
-ambient(1, 1, 1),
-diffuse(1, 1, 1),
-specular(1, 1, 1),
-emissive(0, 0, 0),
-specularPower(64),
-alpha(1){
-	std::string ansiName = mat->GetName();
-	name = std::wstring(ansiName.begin(), ansiName.end());
-	auto rawId = mat->GetUniqueID();
-	id = getMaterialId(mat);
-	FbxFileTexture* ambientTex = nullptr;
-	FbxFileTexture* diffuseTex = nullptr;
-	FbxFileTexture* specularTex = nullptr;
-	FbxFileTexture* emissiveTex = nullptr;
-	FbxFileTexture* reflectionTex = nullptr;
-	FbxFileTexture* opacityTex = nullptr;
-	FbxFileTexture* bumpTex = nullptr;
-	GetMaterialProperty(mat, FbxSurfaceMaterial::sTransparentColor, FbxSurfaceMaterial::sTransparencyFactor, opacityTex)[0];
-
-	FbxDouble3 transcolor;
-	FbxDouble transfactor;
-	auto transFactorProp = mat->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
-	auto transColorProp = mat->FindProperty(FbxSurfaceMaterial::sTransparentColor);
-	if (transFactorProp.IsValid() && transColorProp.IsValid()){
-		transfactor = transFactorProp.Get<FbxDouble>();
-		transcolor = transColorProp.Get<FbxDouble3>();
-		if (transfactor== 1.0){ // from Maya .fbx
-			if (transcolor[0] >= DBL_MIN) {
-				alpha = static_cast<float>(1 - transcolor[0]);
-			}
-			else {
-				alpha = 1;
-			}
-		}
-		else { // from 3dsmax .fbx
-			if (transfactor>=DBL_MIN){
-				alpha = static_cast<float>(1 - transfactor);
-			}
-			else {
-				alpha = 1;
-			}
-		}
-	}
-
-	ambient = GetMaterialProperty(mat, FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, ambientTex);
-	diffuse = GetMaterialProperty(mat, FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor, diffuseTex);
-	specular = GetMaterialProperty(mat, FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor, specularTex);
-	emissive = GetMaterialProperty(mat, FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor, emissiveTex);
-	GetMaterialProperty(mat, FbxSurfaceMaterial::sReflection, FbxSurfaceMaterial::sReflectionFactor, reflectionTex);
-	auto shininessProp = mat->FindProperty(FbxSurfaceMaterial::sShininess);
-	if (shininessProp.IsValid()){
-		specularPower = static_cast<float>(shininessProp.Get<FbxDouble>())*12;
-	}
-
-	auto normalMapProp = mat->FindProperty(FbxSurfaceMaterial::sNormalMap);
-	if (normalMapProp.IsValid()){
-		const int lTextureCount = normalMapProp.GetSrcObjectCount<FbxFileTexture>();
-		if (lTextureCount)
-		{
-			FbxFileTexture* lTexture = normalMapProp.GetSrcObject<FbxFileTexture>();
-			if (lTexture)
-			{
-				bumpTex = lTexture;
-			}
-		}
-	}
-	else{
-		auto bumpProp = mat->FindProperty(FbxSurfaceMaterial::sBump);
-		if (bumpProp.IsValid()){
-			const int lTextureCount = bumpProp.GetSrcObjectCount<FbxFileTexture>();
-			if (lTextureCount)
-			{
-				FbxFileTexture* lTexture = bumpProp.GetSrcObject<FbxFileTexture>();
-				if (lTexture)
-				{
-					bumpTex = lTexture;
-				}
-			}
-		}
-	}
-
-	if (ambientTex){
-		ambientTexture = std::make_shared<BabylonTexture>(ambientTex);
-	}
-	if (diffuseTex){
-		diffuseTexture = std::make_shared<BabylonTexture>(diffuseTex);
-	}
-	if (specularTex){
-		specularTexture = std::make_shared<BabylonTexture>(specularTex);
-	}
-	if (emissiveTex){
-		emissiveTexture = std::make_shared<BabylonTexture>(emissiveTex);
-	}
-	if (reflectionTex){
-		reflectionTexture = std::make_shared<BabylonTexture>(reflectionTex);
-	}
-	if (bumpTex){
-		bumpTexture = std::make_shared<BabylonTexture>(bumpTex);
-	}
-
-	if (opacityTex){
-		opacityTexture = std::make_shared<BabylonTexture>(opacityTex);
-	}
-
-}
-
-
-BabylonMaterial::BabylonMaterial(BabylonMaterial && moved) : 
-	name(std::move(moved.name)),
-	id(std::move(moved.id)),
-	backFaceCulling(std::move(moved.backFaceCulling)),
-	wireframe(std::move(moved.wireframe)),
-	ambient(std::move(moved.ambient)),
-	diffuse(std::move(moved.diffuse)),
-	specular(std::move(moved.specular)),
-	emissive(std::move(moved.emissive)),
-	specularPower(std::move(moved.specularPower)),
-	alpha(std::move(moved.alpha)),
-	diffuseTexture(std::move(moved.diffuseTexture)),
-	ambientTexture(std::move(moved.ambientTexture)),
-	opacityTexture(std::move(moved.opacityTexture)),
-	reflectionTexture(std::move(moved.reflectionTexture)),
-	emissiveTexture(std::move(moved.emissiveTexture)),
-	specularTexture(std::move(moved.specularTexture)),
-	bumpTexture(std::move(moved.bumpTexture))
-{
-}
-
-BabylonMaterial::~BabylonMaterial()
-{
-}
-
-BabylonMultiMaterial::BabylonMultiMaterial(BabylonMultiMaterial && moved) :
-	name(std::move(moved.name)),
-	id(std::move(moved.id)),
-	materials(std::move(moved.materials))
-{
-}
-
-web::json::value BabylonMultiMaterial::toJson() const
-{
-	auto jobj = web::json::value::object();
-	jobj[L"name"] = web::json::value::string(name);
-	jobj[L"id"] = web::json::value::string(id);
-
-	auto jarray = web::json::value::array();
-	for (auto& mat : materials) {
-		jarray[jarray.size()] = web::json::value::string(mat);
-	}
-	jobj[L"materials"] = jarray;
-	return jobj;
-}
-
-
-BabylonTexture::BabylonTexture(BabylonTexture && moved) : 
-	name(std::move(moved.name)),
-	fullPath(std::move(moved.fullPath)),
-	uvset(std::move(moved.uvset)),
-	level(std::move(moved.level)),
-	hasAlpha(std::move(moved.hasAlpha)),
-	getAlphaFromRGB(std::move(moved.getAlphaFromRGB)),
-	coordinatesMode(std::move(moved.coordinatesMode)),
-	isCube(std::move(moved.isCube)),
-	uOffset(std::move(moved.uOffset)),
-	vOffset(std::move(moved.vOffset)),
-	uScale(std::move(moved.uScale)),
-	vScale(std::move(moved.vScale)),
-	uAng(std::move(moved.uAng)),
-	vAng(std::move(moved.vAng)),
-	wAng(std::move(moved.wAng)),
-	wrapU(std::move(moved.wrapU)),
-	wrapV(std::move(moved.wrapV)),
-	coordinatesIndex(std::move(moved.coordinatesIndex)),
-	isRenderTarget(std::move(moved.isRenderTarget)),
-	animations(std::move(moved.animations))
-{
-}
-
-web::json::value BabylonTexture::toJson(){
-	auto jobj = web::json::value::object();
-	jobj[L"name"] = web::json::value::string(name);
-	jobj[L"level"] = web::json::value::number(level);
-	jobj[L"hasAlpha"] = web::json::value::boolean(hasAlpha);
-	jobj[L"getAlphaFromRGB"] = web::json::value::boolean(getAlphaFromRGB);
-	jobj[L"coordinatesMode"] = web::json::value::number(coordinatesMode);
-	jobj[L"isCube"] = web::json::value::boolean(isCube);
-	jobj[L"uOffset"] = web::json::value::number(uOffset);
-	jobj[L"vOffset"] = web::json::value::number(vOffset);
-	jobj[L"uScale"] = web::json::value::number(uScale);
-	jobj[L"vScale"] = web::json::value::number(vScale);
-	jobj[L"uAng"] = web::json::value::number(uAng);
-	jobj[L"vAng"] = web::json::value::number(vAng);
-	jobj[L"wAng"] = web::json::value::number(wAng);
-	jobj[L"wrapU"] = web::json::value::boolean(wrapU);
-	jobj[L"wrapV"] = web::json::value::boolean(wrapV);
-	jobj[L"coordinatesIndex"] = web::json::value::number(coordinatesIndex);
-	jobj[L"isRenderTarget"] = web::json::value::boolean(isRenderTarget);
-	auto janims = web::json::value::array();
-	for (auto& anim : animations) {
-		janims[janims.size()] = anim->toJson();
-	}
-	jobj[L"animations"] = janims;
-	return jobj;
-}
-BabylonTexture::BabylonTexture(FbxFileTexture* texture){
-	fullPath = utf8ToWstring(texture->GetFileName());
-	auto indexOfLastBackslash = fullPath.find_last_of(L'\\');
-	name = std::wstring(fullPath.begin() + indexOfLastBackslash + 1, fullPath.end());
-	auto mappingType = texture->GetMappingType();
-	switch (mappingType)
-	{
-	case fbxsdk::FbxTexture::eNull:
-		break;
-	case fbxsdk::FbxTexture::ePlanar:
-		coordinatesMode = 2;
-		break;
-	case fbxsdk::FbxTexture::eSpherical:
-		coordinatesMode = 1;
-		break;
-	case fbxsdk::FbxTexture::eCylindrical:
-		break;
-	case fbxsdk::FbxTexture::eBox:
-		coordinatesMode = 5;
-		break;
-	case fbxsdk::FbxTexture::eFace:
-		break;
-	case fbxsdk::FbxTexture::eUV:
-		break;
-	case fbxsdk::FbxTexture::eEnvironment:
-		break;
-	default:
-		break;
-	}
-	auto alphaSource = texture->GetAlphaSource();
-
-	switch (alphaSource)
-	{
-	case fbxsdk::FbxTexture::eNone:
-		hasAlpha = false;
-		getAlphaFromRGB = false;
-		break;
-	case fbxsdk::FbxTexture::eRGBIntensity:
-		hasAlpha = true;
-		getAlphaFromRGB = true;
-		break;
-	case fbxsdk::FbxTexture::eBlack:
-		hasAlpha = true;
-		getAlphaFromRGB = false;
-		break;
-	default:
-		break;
-	}
-
-	babylon_vector3 rot = texture->Rotation.Get();
-	babylon_vector3 scaling = texture->Scaling.Get();
-
-	babylon_vector2 trans((float)texture->GetTranslationU(), (float)texture->GetTranslationV());
-	
-	
-	uOffset = trans.x;
-	vOffset = trans.y;
-	uScale = scaling.x;
-	vScale = scaling.y;
-	std::string strFileName = texture->GetFileName();
-	auto lastDot = strFileName.find_last_of('.');
-	auto ext = strFileName.substr(lastDot);
-	if (_stricmp(ext.c_str(), ".dds") == 0) {
-		vScale *= -1;
-	}
-	uAng = static_cast<float>(rot.x * Euler2Rad);
-	vAng = static_cast<float>(rot.y * Euler2Rad);
-	wAng = static_cast<float>(rot.z * Euler2Rad);
-	auto uwrapMode = texture->GetWrapModeU();
-	auto vwrapMode = texture->GetWrapModeV();
-	wrapU = uwrapMode == FbxTexture::eRepeat;
-	wrapV = vwrapMode == FbxTexture::eRepeat;
-
-	uvset = texture->UVSet.Get();
-	
-	
-
-}

+ 0 - 126
Exporters/FBX/BabylonFbxNative/BabylonMaterial.h

@@ -1,126 +0,0 @@
-#pragma once
-#include <string>
-#include <sstream>
-#include <memory>
-#include "BabylonVertex.h"
-#include <vector>
-#include <fbxsdk.h>
-#include "BabylonAnimation.h"
-
-
-class BabylonTexture{
-public:
-	
-	 std::wstring name;
-	 std::wstring fullPath;
-	 std::string uvset;
-		
-	 float level = 1.0f;
-
-		
-	 bool hasAlpha = false;
-
-		
-	 bool getAlphaFromRGB = false;
-
-		
-	 int coordinatesMode =0;
-
-		
-	 bool isCube = false;
-
-		
-	 float uOffset = 0;
-
-		
-	 float vOffset = 0;
-
-		
-	 float uScale = 1;
-
-		
-	 float vScale = 1;
-
-		
-	 float uAng = 0;
-
-		
-	 float vAng = 0;
-
-		
-	 float wAng = 0;
-
-		
-	 bool wrapU = true;
-
-		
-	 bool wrapV = true;
-
-		
-	 int coordinatesIndex = 0;
-
-		
-	 bool isRenderTarget = false;
-	 std::vector<std::shared_ptr<BabylonAnimationBase>> animations;
-
-	 BabylonTexture(FbxFileTexture* texture);
-
-	 BabylonTexture(const BabylonTexture&) = default;
-	 BabylonTexture(BabylonTexture&&);
-
-	 web::json::value toJson();
-	
-};
-
-
-inline std::wstring getMaterialId(FbxSurfaceMaterial* mat){
-	std::wstringstream strstream;
-	strstream <<mat->GetUniqueID();
-	return strstream.str();
-}
-
-class BabylonMaterial
-{
-public:
-	std::wstring name;
-	std::wstring id;
-	bool backFaceCulling = true;
-	bool wireframe = false;
-	babylon_vector3 ambient;
-	babylon_vector3 diffuse;
-	babylon_vector3 specular;
-	babylon_vector3 emissive;
-	float specularPower;
-	float alpha;
-	std::shared_ptr<BabylonTexture> diffuseTexture;
-
-	std::shared_ptr<BabylonTexture> ambientTexture;
-
-	std::shared_ptr<BabylonTexture> opacityTexture;
-
-	std::shared_ptr<BabylonTexture> reflectionTexture;
-
-	std::shared_ptr<BabylonTexture> emissiveTexture;
-
-	std::shared_ptr<BabylonTexture> specularTexture;
-
-	std::shared_ptr<BabylonTexture> bumpTexture;
-
-	web::json::value toJson() const;
-	BabylonMaterial();
-	BabylonMaterial(FbxSurfaceMaterial* mat);
-	BabylonMaterial(const BabylonMaterial&) = default;
-	BabylonMaterial(BabylonMaterial&& moved);
-	~BabylonMaterial();
-};
-
-class BabylonMultiMaterial{
-public:
-	std::wstring name;
-	std::wstring id;
-	std::vector<std::wstring> materials;
-	BabylonMultiMaterial() = default;
-	BabylonMultiMaterial(const BabylonMultiMaterial&) = default;
-	BabylonMultiMaterial(BabylonMultiMaterial&& moved) ;
-	web::json::value toJson() const;
-};

+ 0 - 891
Exporters/FBX/BabylonFbxNative/BabylonMesh.cpp

@@ -1,891 +0,0 @@
-#include "stdafx.h"
-#include "BabylonMesh.h"
-#include <map>
-#include <vector>
-#include <iostream>
-#include <sstream>
-#include "NodeHelpers.h"
-#include "GlobalSettings.h"
-
-struct BabylonVertex {
-	babylon_vector3 position;
-	babylon_vector3 normal;
-	babylon_vector2 uv;
-	babylon_vector2 uv2;
-	babylon_vector2 uv3;
-	babylon_vector2 uv4;
-	babylon_vector2 uv5;
-	babylon_vector2 uv6;
-	babylon_color color;
-	std::uint32_t boneIndices[4];
-	float boneWeights[4];
-
-	BabylonVertex() {
-		boneIndices[0] = 0;
-		boneIndices[1] = 0;
-		boneIndices[2] = 0;
-		boneIndices[3] = 0;
-
-		boneWeights[0] = 0;
-		boneWeights[1] = 0;
-		boneWeights[2] = 0;
-		boneWeights[3] = 0;
-	}
-};
-
-struct triangle {
-	std::uint32_t indices[3];
-};
-inline bool operator <(const triangle& lhs, const triangle& rhs) {
-	if (lhs.indices[0] < rhs.indices[0]) {
-		return true;
-	}
-	else if (rhs.indices[0] < lhs.indices[0]) {
-		return false;
-	}
-
-	if (lhs.indices[1] < rhs.indices[1]) {
-		return true;
-	}
-	else if (rhs.indices[1] < lhs.indices[1]) {
-		return false;
-	}
-	return lhs.indices[2] < rhs.indices[2];
-}
-
-inline bool operator <(const BabylonVertex& lhs, const BabylonVertex& rhs) {
-	if (lhs.position < rhs.position) {
-		return true;
-	}
-	else if (rhs.position < lhs.position) {
-		return false;
-	}
-
-	if (lhs.normal < rhs.normal) {
-		return true;
-	}
-	else if (rhs.normal < lhs.normal) {
-		return false;
-	}
-
-	if (lhs.uv < rhs.uv) {
-		return true;
-	}
-	else if (rhs.uv < lhs.uv) {
-		return false;
-	}
-
-	if (lhs.uv2 < rhs.uv2) {
-		return true;
-	}
-	else if (rhs.uv2 < lhs.uv2) {
-		return false;
-	}
-
-
-	if (lhs.uv3 < rhs.uv3) {
-		return true;
-	}
-	else if (rhs.uv3 < lhs.uv3) {
-		return false;
-	}
-
-
-	if (lhs.uv4 < rhs.uv4) {
-		return true;
-	}
-	else if (rhs.uv4 < lhs.uv4) {
-		return false;
-	}
-
-
-	if (lhs.uv5 < rhs.uv5) {
-		return true;
-	}
-	else if (rhs.uv5 < lhs.uv5) {
-		return false;
-	}
-
-
-	if (lhs.uv6 < rhs.uv6) {
-		return true;
-	}
-	else if (rhs.uv6 < lhs.uv6) {
-		return false;
-	}
-
-	if (lhs.color < rhs.color) {
-		return true;
-	}
-	else if (rhs.color < lhs.color) {
-		return false;
-	}
-
-	if (lhs.boneIndices[0] < rhs.boneIndices[0]) {
-		return true;
-	}
-	else if (rhs.boneIndices[0] < lhs.boneIndices[0]) {
-		return false;
-	}
-
-	if (lhs.boneIndices[1] < rhs.boneIndices[1]) {
-		return true;
-	}
-	else if (rhs.boneIndices[1] < lhs.boneIndices[1]) {
-		return false;
-	}
-
-	if (lhs.boneIndices[2] < rhs.boneIndices[2]) {
-		return true;
-	}
-	else if (rhs.boneIndices[2] < lhs.boneIndices[2]) {
-		return false;
-	}
-
-	if (lhs.boneIndices[3] < rhs.boneIndices[3]) {
-		return true;
-	}
-	else if (rhs.boneIndices[3] < lhs.boneIndices[3]) {
-		return false;
-	}
-
-	if (lhs.boneWeights[0] < rhs.boneWeights[0]) {
-		return true;
-	}
-	else if (rhs.boneWeights[0] < lhs.boneWeights[0]) {
-		return false;
-	}
-
-	if (lhs.boneWeights[1] < rhs.boneWeights[1]) {
-		return true;
-	}
-	else if (rhs.boneWeights[1] < lhs.boneWeights[1]) {
-		return false;
-	}
-
-	if (lhs.boneWeights[2] < rhs.boneWeights[2]) {
-		return true;
-	}
-	else if (rhs.boneWeights[2] < lhs.boneWeights[2]) {
-		return false;
-	}
-
-	if (lhs.boneWeights[3] < rhs.boneWeights[3]) {
-		return true;
-	}
-	else if (rhs.boneWeights[3] < lhs.boneWeights[3]) {
-		return false;
-	}
-
-	return false;
-}
-
-
-struct SubmeshData {
-	std::map<BabylonVertex, std::uint32_t> knownVertices;
-	std::set<triangle> knownTriangles;
-	std::vector<BabylonVertex> vertices;
-	std::vector<std::uint32_t> indices;
-};
-
-web::json::value convertToJson(const std::vector<babylon_vector3>& v) {
-	auto result = web::json::value::array();
-	for (auto ix = 0u;ix < v.size();++ix) {
-		result[ix * 3] = web::json::value::number(v[ix].x);
-		result[ix * 3 + 1] = web::json::value::number(v[ix].y);
-		result[ix * 3 + 2] = web::json::value::number(v[ix].z);
-	}
-	return result;
-}
-
-
-web::json::value convertToJson(const std::vector<babylon_vector2>& v) {
-	auto result = web::json::value::array();
-	for (auto ix = 0u;ix < v.size();++ix) {
-		result[ix * 2] = web::json::value::number(v[ix].x);
-		result[ix * 2 + 1] = web::json::value::number(v[ix].y);
-	}
-	return result;
-}
-
-web::json::value convertToJson(const std::vector<babylon_color>& v) {
-	auto result = web::json::value::array();
-	for (auto ix = 0u;ix < v.size();++ix) {
-		result[ix * 4] = web::json::value::number(v[ix].r);
-		result[ix * 4 + 1] = web::json::value::number(v[ix].g);
-		result[ix * 4 + 2] = web::json::value::number(v[ix].b);
-		result[ix * 4 + 3] = web::json::value::number(v[ix].a);
-	}
-	return result;
-}
-
-web::json::value convertToJson(const std::vector<babylon_vector4>& v) {
-	auto result = web::json::value::array();
-	for (auto ix = 0u; ix < v.size(); ++ix) {
-		result[ix * 4] = web::json::value::number(v[ix].x);
-		result[ix * 4 + 1] = web::json::value::number(v[ix].y);
-		result[ix * 4 + 2] = web::json::value::number(v[ix].z);
-		result[ix * 4 + 3] = web::json::value::number(v[ix].w);
-	}
-	return result;
-}
-
-
-web::json::value convertToJson(const std::vector<std::uint32_t>& v){
-	auto result = web::json::value::array();
-	for (auto ix = 0u; ix < v.size() ; ++ix) {
-		result[ix ] = web::json::value::number(v[ix ]);
-	}
-	return result;
-}
-web::json::value convertToJson(const std::vector<std::uint32_t>& v, bool changeVertexOrder) {
-	if (changeVertexOrder) {
-		auto result = web::json::value::array();
-		for (auto ix = 0u;ix < v.size() / 3;++ix) {
-			result[ix * 3] = web::json::value::number(v[ix * 3]);
-			result[ix * 3 + 1] = web::json::value::number(v[ix * 3 + 2]);
-			result[ix * 3 + 2] = web::json::value::number(v[ix * 3 + 1]);
-		}
-		return result;
-	}
-	else {
-		auto result = web::json::value::array();
-		for (auto ix = 0u;ix < v.size() / 3;++ix) {
-			result[ix * 3] = web::json::value::number(v[ix * 3]);
-			result[ix * 3 + 1] = web::json::value::number(v[ix * 3 + 1]);
-			result[ix * 3 + 2] = web::json::value::number(v[ix * 3 + 2]);
-		}
-		return result;
-	}
-}
-
-web::json::value convertToJson(const std::vector<BabylonSubmesh>& v) {
-	auto result = web::json::value::array();
-
-	for (auto ix = 0u;ix < v.size();++ix) {
-		auto jsubmesh = web::json::value::object();
-
-		jsubmesh[L"materialIndex"] = web::json::value::number(v[ix].materialIndex);
-		jsubmesh[L"verticesStart"] = web::json::value::number(v[ix].verticesStart);
-		jsubmesh[L"verticesCount"] = web::json::value::number(v[ix].verticesCount);
-		jsubmesh[L"indexStart"] = web::json::value::number(v[ix].indexStart);
-		jsubmesh[L"indexCount"] = web::json::value::number(v[ix].indexCount);
-
-		result[result.size()] = jsubmesh;
-	}
-	return result;
-}
-
-web::json::value BabylonSubmesh::toJson(){
-	auto jobj = web::json::value::object();
-	jobj[L"materialIndex"] = web::json::value::number(materialIndex);
-	jobj[L"verticesStart"] = web::json::value::number(verticesStart);
-	jobj[L"verticesCount"] = web::json::value::number(verticesCount);
-	jobj[L"indexStart"] = web::json::value::number(indexStart);
-	jobj[L"indexCount"] = web::json::value::number(indexCount);
-	return jobj;
-}
-
-web::json::value BabylonMesh::toJson()
-{
-	auto jobj = BabylonAbstractMesh::toJson();
-	jobj[L"id"] = web::json::value::string(_id);
-	jobj[L"name"] = web::json::value::string(_id);
-	if (_parentId.size() > 0)
-		jobj[L"parentId"] = web::json::value::string(_parentId);
-	if (_materialId.size() > 0)
-		jobj[L"materialId"] = web::json::value::string(_materialId);
-
-
-	jobj[L"isEnabled"] = web::json::value::boolean(_isEnabled);
-	jobj[L"isVisible"] = web::json::value::boolean(_isVisible);
-	jobj[L"pickable"] = web::json::value::boolean(_pickable);
-	jobj[L"hasVertexAlpha"] = web::json::value::boolean(_hasVertexAlpha);
-	jobj[L"checkCollision"] = web::json::value::boolean(_checkCollision);
-	jobj[L"receiveShadows"] = web::json::value::boolean(_receiveShadows);
-	jobj[L"infiniteDistance"] = web::json::value::boolean(_infiniteDistance);
-	jobj[L"billboardMode"] = web::json::value::number(_billboardMode);
-	jobj[L"visibility"] = web::json::value::number(_visibility);
-	jobj[L"skeletonId"] = web::json::value::number(_skeletonId);
-
-	auto submeshesArray = web::json::value::array();
-	for (auto ix = 0u; ix < submeshes().size(); ++ix){
-		submeshesArray[ix] = submeshes()[ix].toJson();
-	}
-	jobj[L"subMeshes"] = submeshesArray;
-	jobj[L"showBoundingBox"] = web::json::value::boolean(_showBoundingBox);
-	jobj[L"showSubMeshesBoundingBox"] = web::json::value::boolean(_showSubMeshesBoundingBox);
-	jobj[L"applyFog"] = web::json::value::boolean(_applyFog);
-	jobj[L"alphaIndex"] = web::json::value::number(_alphaIndex);
-	if (_positions.size() > 0)
-		jobj[L"positions"] = convertToJson(_positions);
-	if (_normals.size() > 0)
-		jobj[L"normals"] = convertToJson(_normals);
-	if (_uvs.size() > 0)
-		jobj[L"uvs"] = convertToJson(_uvs);
-	if (_uvs2.size() > 0)
-		jobj[L"uvs2"] = convertToJson(_uvs2);
-	if (_uvs3.size() > 0)
-		jobj[L"uvs3"] = convertToJson(_uvs3);
-	if (_uvs4.size() > 0)
-		jobj[L"uvs4"] = convertToJson(_uvs4);
-	if (_uvs5.size() > 0)
-		jobj[L"uvs5"] = convertToJson(_uvs5);
-	if (_uvs6.size() > 0)
-		jobj[L"uvs6"] = convertToJson(_uvs6);
-	if (_colors.size() > 0)
-		jobj[L"colors"] = convertToJson(_colors);
-	if (_indices.size() > 0)
-		jobj[L"indices"] = convertToJson(_indices, false);
-	if (_boneIndices.size() > 0){
-		jobj[L"matricesIndices"] = convertToJson(_boneIndices);
-	}
-	if (_boneWeights.size() > 0){
-		jobj[L"matricesWeights"] = convertToJson(_boneWeights);
-	}
-	if (animations.size() == 0 && !associatedSkeleton){
-
-		jobj[L"autoAnimate"] = web::json::value::boolean(false);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(false);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(0);
-		jobj[L"autoAnimateTo"] = web::json::value::number(0);
-
-	}
-	else if (animations.size()>0){
-
-		jobj[L"autoAnimate"] = web::json::value::boolean(animations[0]->autoAnimate);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(animations[0]->autoAnimateLoop);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(animations[0]->autoAnimateFrom);
-		jobj[L"autoAnimateTo"] = web::json::value::number(animations[0]->autoAnimateTo);
-	}
-	
-	else{
-
-		jobj[L"autoAnimate"] = web::json::value::boolean(associatedSkeleton->bones[0].animation->autoAnimate);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(associatedSkeleton->bones[0].animation->autoAnimateLoop);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(associatedSkeleton->bones[0].animation->autoAnimateFrom);
-		jobj[L"autoAnimateTo"] = web::json::value::number(associatedSkeleton->bones[0].animation->autoAnimateTo);
-	}
-
-	auto janimations = web::json::value::array();
-	for (const auto& anim : animations){
-		janimations[janimations.size()] = anim->toJson();
-	}
-	jobj[L"animations"] = janimations;
-	FbxMatrix identity;
-	identity.SetIdentity();
-	if (pivotMatrix != identity){
-		auto jpivot = web::json::value::array();
-		for (auto x = 0; x < 4; ++x){
-			for (auto y = 0; y < 4; ++y){
-				jpivot[x * 4 + y] = web::json::value::number( pivotMatrix[x][y]);
-			}
-		}
-		jobj[L"pivotMatrix"] = jpivot;
-	}
-
-	auto jinstances = web::json::value::array();
-	for (auto& instance : _instances) {
-		jinstances[jinstances.size()] = instance.toJson();
-	}
-	jobj[L"instances"] = jinstances;
-	return jobj;
-}
-
-BabylonMesh::BabylonMesh() :
-	_isEnabled(true),
-	_isVisible(true),
-	_billboardMode(0),
-	_visibility(1),
-	_skeletonId(-1),
-	_pickable(true)
-{
-	pivotMatrix.SetIdentity();
-}
-
-
-
-
-BabylonMesh::BabylonMesh(BabylonNode* node) :
-	BabylonAbstractMesh(node),
-	_isEnabled(true),
-	_isVisible(true),
-	_billboardMode(0),
-	_visibility(1),
-	_skeletonId(-1),
-	_pickable(true),
-	_hasVertexAlpha(false),
-	_checkCollision(false),
-	_receiveShadows(false),
-	_infiniteDistance(false),
-	_autoAnimate(false),
-	_autoAnimateFrom(0),
-	_autoAnimateTo(0),
-	_autoAnimateLoop(false),
-	_showBoundingBox(false),
-	_showSubMeshesBoundingBox(false),
-	_applyFog(false),
-	_alphaIndex(0)
-{
-
-	pivotMatrix.SetIdentity();
-	auto fbxNode = node->fbxNode();
-	
-	std::string ansiName = fbxNode->GetName();
-	name(std::wstring(ansiName.begin(), ansiName.end()));
-	id(getNodeId(fbxNode));
-	auto parent = fbxNode->GetParent();
-	if (parent) {
-		parentId(getNodeId(parent));
-	}
-	pivotMatrix = ConvertToBabylonCoordinateSystem( GetGeometryTransformation(fbxNode));
-
-	auto mesh = fbxNode->GetMesh();
-	auto animStack = fbxNode->GetScene()->GetCurrentAnimationStack();
-
-	if (animStack) {
-		FbxString animStackName = animStack->GetName();
-		//FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
-		auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
-		auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
-		auto startFrame = animStack->GetLocalTimeSpan().GetStart().GetFrameCount(animTimeMode);
-		auto endFrame = animStack->GetLocalTimeSpan().GetStop().GetFrameCount(animTimeMode);
-		auto animLengthInFrame = endFrame - startFrame + 1;
-		_visibility = static_cast<float>(node->fbxNode()->Visibility.Get());
-		auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"position", L"position", true, 0, static_cast<int>(animLengthInFrame), true);
-		auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"rotationQuaternion", L"rotationQuaternion", true, 0, static_cast<int>(animLengthInFrame), true);
-		auto scaleAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"scaling", L"scaling", true, 0, static_cast<int>(animLengthInFrame), true);
-		auto visibilityAnim = std::make_shared<BabylonAnimation<float>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"visibility", L"visibility", true, 0, static_cast<int>(animLengthInFrame), true);
-
-		_isVisible = fbxNode->Show.Get();
-
-		auto rotCurveNode = fbxNode->LclRotation.GetCurveNode();
-		auto translateCurveNode = fbxNode->LclTranslation.GetCurveNode();
-		auto scalingCurveNode = fbxNode->LclScaling.GetCurveNode();
-		auto visibilityCurveNode = fbxNode->Visibility.GetCurveNode();
-		if (rotCurveNode || translateCurveNode || scalingCurveNode) {
-			for (auto ix = 0; ix < animLengthInFrame; ix++) {
-				FbxTime currTime;
-				currTime.SetFrame(startFrame + ix, animTimeMode);
-
-				babylon_animation_key<babylon_vector3> poskey;
-				babylon_animation_key<babylon_vector4> rotkey;
-				babylon_animation_key<babylon_vector3> scalekey;
-				poskey.frame = ix;
-				rotkey.frame = ix;
-				scalekey.frame = ix;
-				auto currTransform = node->GetLocal(currTime);
-				poskey.values = currTransform.translation();
-				rotkey.values = currTransform.rotationQuaternion();
-				scalekey.values = currTransform.scaling();
-				posAnim->appendKey(poskey);
-				rotAnim->appendKey(rotkey);
-				scaleAnim->appendKey(scalekey);
-
-
-			}
-		}
-		if (visibilityCurveNode) {
-			for (auto ix = 0; ix < animLengthInFrame; ix++) {
-				FbxTime currTime;
-				currTime.SetFrame(startFrame + ix, animTimeMode);
-
-				babylon_animation_key<float> visibilityKey;
-
-				visibilityKey.frame = ix;
-
-				visibilityKey.values = static_cast<float>(node->fbxNode()->Visibility.EvaluateValue(currTime));
-
-				visibilityAnim->appendKey(visibilityKey);
-
-
-			}
-		}
-
-		if (!posAnim->isConstant()){
-			animations.push_back(posAnim);
-		}
-		if (!rotAnim->isConstant()){
-			animations.push_back(rotAnim);
-		}
-		if (!scaleAnim->isConstant()){
-			animations.push_back(scaleAnim);
-		}
-		if (!visibilityAnim->isConstant()) {
-			animations.push_back(visibilityAnim);
-		}
-	}
-
-	if (!mesh) {
-		return;
-	}
-	if (mesh->GetPolygonCount() == 0){
-		return;
-	}
-
-	_receiveShadows =  mesh->ReceiveShadow.Get();
-	FbxGeometryConverter conv(mesh->GetFbxManager());
-	conv.ComputePolygonSmoothingFromEdgeSmoothing(mesh);
-	if (!mesh->IsTriangleMesh()) {
-		mesh = (FbxMesh*) conv.Triangulate(mesh, true);
-	}
-
-
-	mesh->RemoveBadPolygons();
-	mesh->GenerateNormals();
-
-	FbxStringList uvSetNameList;
-	mesh->GetUVSetNames(uvSetNameList);
-	std::vector<std::string> uniqueUVSets;
-
-	int uvCount = uvSetNameList.GetCount();
-	for (int i = 0; i < uvCount; ++i) {
-		std::string value = uvSetNameList.GetStringAt(i);
-		if (std::find(uniqueUVSets.begin(), uniqueUVSets.end(), value) == uniqueUVSets.end()) {
-			uniqueUVSets.push_back(value);
-		}
-	}
-	uvsets = uniqueUVSets;
-	bool hasUv = uniqueUVSets.size() > 0;
-	bool hasUv2 = uniqueUVSets.size() > 1;
-	bool hasUv3 = uniqueUVSets.size() > 2;
-	bool hasUv4 = uniqueUVSets.size() > 3;
-	bool hasUv5 = uniqueUVSets.size() > 4;
-	bool hasUv6 = uniqueUVSets.size() > 5;
-	std::string uvSetName;
-	std::string uv2SetName;
-	std::string uv3SetName;
-	std::string uv4SetName;
-	std::string uv5SetName;
-	std::string uv6SetName;
-	if (hasUv) {
-		uvSetName = uniqueUVSets[0];
-	}
-	if (hasUv2) {
-		uv2SetName = uniqueUVSets[1];
-	}
-	if (hasUv3) {
-		uv3SetName = uniqueUVSets[2];
-	}
-	if (hasUv4) {
-		uv4SetName = uniqueUVSets[3];
-	}
-	if (hasUv5) {
-		uv5SetName = uniqueUVSets[4];
-	}
-	if (hasUv6) {
-		uv6SetName = uniqueUVSets[5];
-	}
-	auto colors = mesh->GetElementVertexColor();
-	FbxLayerElement::EMappingMode colorMappingMode;
-	FbxLayerElement::EReferenceMode colorReferenceMode;
-	if (colors) {
-		colorMappingMode = colors->GetMappingMode();
-		colorReferenceMode = colors->GetReferenceMode();
-	}
-	auto normals = mesh->GetElementNormal();
-	FbxGeometryElementUV* uvs = nullptr;
-	FbxGeometryElementUV* uvs2 = nullptr;
-	FbxGeometryElementUV* uvs3 = nullptr;
-	FbxGeometryElementUV* uvs4 = nullptr;
-	FbxGeometryElementUV* uvs5 = nullptr;
-	FbxGeometryElementUV* uvs6 = nullptr;
-	FbxLayerElement::EMappingMode uvsMappingMode;
-	FbxLayerElement::EReferenceMode uvsReferenceMode;
-	FbxLayerElement::EMappingMode uvs2MappingMode;
-	FbxLayerElement::EReferenceMode uvs2ReferenceMode;
-	FbxLayerElement::EMappingMode uvs3MappingMode;
-	FbxLayerElement::EReferenceMode uvs3ReferenceMode;
-	FbxLayerElement::EMappingMode uvs4MappingMode;
-	FbxLayerElement::EReferenceMode uvs4ReferenceMode;
-	FbxLayerElement::EMappingMode uvs5MappingMode;
-	FbxLayerElement::EReferenceMode uvs5ReferenceMode;
-	FbxLayerElement::EMappingMode uvs6MappingMode;
-	FbxLayerElement::EReferenceMode uvs6ReferenceMode;
-	if (hasUv) {
-		uvs = mesh->GetElementUV(uvSetName.c_str());
-		uvsMappingMode = uvs->GetMappingMode();
-		uvsReferenceMode = uvs->GetReferenceMode();
-	}
-	if (hasUv2) {
-		uvs2 = mesh->GetElementUV(uv2SetName.c_str());
-		uvs2MappingMode = uvs2->GetMappingMode();
-		uvs2ReferenceMode = uvs2->GetReferenceMode();
-	}
-	if (hasUv3) {
-		uvs3 = mesh->GetElementUV(uv3SetName.c_str());
-		uvs3MappingMode = uvs3->GetMappingMode();
-		uvs3ReferenceMode = uvs3->GetReferenceMode();
-	}
-	if (hasUv4) {
-		uvs4 = mesh->GetElementUV(uv4SetName.c_str());
-		uvs4MappingMode = uvs4->GetMappingMode();
-		uvs4ReferenceMode = uvs4->GetReferenceMode();
-	}
-	if (hasUv5) {
-		uvs5 = mesh->GetElementUV(uv5SetName.c_str());
-		uvs5MappingMode = uvs5->GetMappingMode();
-		uvs5ReferenceMode = uvs5->GetReferenceMode();
-	}
-	if (hasUv6) {
-		uvs6 = mesh->GetElementUV(uv6SetName.c_str());
-		uvs6MappingMode = uvs6->GetMappingMode();
-		uvs6ReferenceMode = uvs6->GetReferenceMode();
-	}
-
-	auto normalMappingMode = normals->GetMappingMode();
-	auto normalReferenceMode = normals->GetReferenceMode();
-	std::vector<SubmeshData> submeshes;
-
-	auto materialCount = node->fbxNode()->GetMaterialCount();
-	if (materialCount == 0) {
-		materialCount = 1;
-	}
-	submeshes.resize(materialCount);
-	auto baseLayer = mesh->GetLayer(0);
-	auto materials = baseLayer->GetMaterials();
-	FbxLayerElement::EMappingMode materialMappingMode = materials ?
-		materials->GetMappingMode() : FbxLayerElement::eByPolygon;
-
-	// extract deformers
-	SkinInfo skinInfo(fbxNode);
-	if (skinInfo.hasSkin()){
-		associatedSkeleton = std::make_shared<BabylonSkeleton>();
-		skinInfo.buildBabylonSkeleton(*associatedSkeleton);
-	}
-
-	auto triangleCount = mesh->GetPolygonCount();
-	for (int triangleIndex = 0; triangleIndex < triangleCount; ++triangleIndex) {
-
-		int materialIndex = 0;
-		if (materialCount > 0 && materials) {
-			switch (materialMappingMode) {
-			case FbxLayerElement::eAllSame:
-				materialIndex = materials->GetIndexArray().GetAt(0);
-				break;
-			case FbxLayerElement::eByPolygon:
-				materialIndex = materials->GetIndexArray().GetAt(triangleIndex);
-			}
-			if (materialIndex < 0 || materialIndex >= materialCount) {
-				materialIndex = 0;
-			}
-		}
-
-		auto& submesh = submeshes[materialIndex];
-		triangle t;
-		for (int cornerIndex = 0; cornerIndex < 3; ++cornerIndex) {
-			auto controlPointIndex = mesh->GetPolygonVertex(triangleIndex, cornerIndex);
-			auto vertexIndex = triangleIndex * 3 + cornerIndex;
-			auto position = mesh->GetControlPoints()[controlPointIndex];
-			position[2] = -position[2];
-
-			BabylonVertex v;
-			v.position = position;
-			if (normals) {
-				int normalMapIndex = (normalMappingMode == FbxLayerElement::eByControlPoint) ?
-				controlPointIndex : vertexIndex;
-				int normalValueIndex = (normalReferenceMode == FbxLayerElement::eDirect) ?
-				normalMapIndex : normals->GetIndexArray().GetAt(normalMapIndex);
-				v.normal = normals->GetDirectArray().GetAt(normalValueIndex);
-				v.normal.z = -v.normal.z;
-			}
-			if (colors) {
-				int mappingIndex = (colorMappingMode == FbxLayerElement::eByControlPoint) ?
-				controlPointIndex : vertexIndex;
-				int valueIndex = (colorReferenceMode == FbxLayerElement::eDirect) ?
-				mappingIndex : colors->GetIndexArray().GetAt(mappingIndex);
-				v.color = colors->GetDirectArray().GetAt(valueIndex);
-			}
-			if (uvs) {
-				int mappingIndex = (uvsMappingMode == FbxLayerElement::eByControlPoint) ?
-				controlPointIndex : vertexIndex;
-				int valueIndex = (uvsReferenceMode == FbxLayerElement::eDirect) ?
-				mappingIndex : uvs->GetIndexArray().GetAt(mappingIndex);
-				v.uv = uvs->GetDirectArray().GetAt(valueIndex);
-				//v.uv.y = 1 - v.uv.y;
-			}
-
-			if (uvs2) {
-				int mappingIndex = (uvs2MappingMode == FbxLayerElement::eByControlPoint) ?
-					controlPointIndex : vertexIndex;
-				int valueIndex = (uvs2ReferenceMode == FbxLayerElement::eDirect) ?
-					mappingIndex : uvs2->GetIndexArray().GetAt(mappingIndex);
-				v.uv2 = uvs2->GetDirectArray().GetAt(valueIndex);
-			}
-			if (uvs3) {
-				int mappingIndex = (uvs3MappingMode == FbxLayerElement::eByControlPoint) ?
-					controlPointIndex : vertexIndex;
-				int valueIndex = (uvs3ReferenceMode == FbxLayerElement::eDirect) ?
-					mappingIndex : uvs3->GetIndexArray().GetAt(mappingIndex);
-				v.uv3 = uvs3->GetDirectArray().GetAt(valueIndex);
-			}
-			if (uvs4) {
-				int mappingIndex = (uvs4MappingMode == FbxLayerElement::eByControlPoint) ?
-					controlPointIndex : vertexIndex;
-				int valueIndex = (uvs4ReferenceMode == FbxLayerElement::eDirect) ?
-					mappingIndex : uvs4->GetIndexArray().GetAt(mappingIndex);
-				v.uv4 = uvs4->GetDirectArray().GetAt(valueIndex);
-			}
-			if (uvs5) {
-				int mappingIndex = (uvs5MappingMode == FbxLayerElement::eByControlPoint) ?
-					controlPointIndex : vertexIndex;
-				int valueIndex = (uvs5ReferenceMode == FbxLayerElement::eDirect) ?
-					mappingIndex : uvs5->GetIndexArray().GetAt(mappingIndex);
-				v.uv5 = uvs5->GetDirectArray().GetAt(valueIndex);
-			}
-			if (uvs6) {
-				int mappingIndex = (uvs6MappingMode == FbxLayerElement::eByControlPoint) ?
-					controlPointIndex : vertexIndex;
-				int valueIndex = (uvs6ReferenceMode == FbxLayerElement::eDirect) ?
-					mappingIndex : uvs6->GetIndexArray().GetAt(mappingIndex);
-				v.uv6 = uvs6->GetDirectArray().GetAt(valueIndex);
-			}
-			if (skinInfo.hasSkin()){
-				auto& skinData = skinInfo.controlPointBoneIndicesAndWeights(controlPointIndex);
-				for (std::size_t boneix = 0; boneix < skinData.size()&&boneix< (size_t)4; ++boneix){
-					v.boneIndices[boneix] = skinData[boneix].index;
-					v.boneWeights[boneix] = static_cast<float>(skinData[boneix].weight);
-				}
-				for (auto boneix = skinData.size(); boneix < 4; ++boneix){
-
-					v.boneIndices[boneix] = skinInfo.bonesCount();
-					v.boneWeights[boneix] = 0;
-				}
-			}
-			auto foundVertex = submesh.knownVertices.find(v);
-			if (foundVertex != submesh.knownVertices.end()) {
-				//submesh.indices.push_back(foundVertex->second);
-				t.indices[cornerIndex] = foundVertex->second;
-			}
-			else {
-				auto index = static_cast<int>(submesh.vertices.size());
-				submesh.vertices.push_back(v);
-				//submesh.indices.push_back(index);
-				submesh.knownVertices[v] = index;
-				t.indices[cornerIndex] = index;
-			}
-		}
-		if (submesh.knownTriangles.insert(t).second) {
-			submesh.indices.push_back(t.indices[0]);
-			submesh.indices.push_back(t.indices[1]);
-			submesh.indices.push_back(t.indices[2]);
-		}
-		else {
-			std::cout << "duplicate triangle found (and eliminated) in " << fbxNode->GetName() << std::endl;
-		}
-
-	}
-	std::uint32_t vertexOffset = 0;
-
-	for (auto matIndex = 0u; matIndex < submeshes.size(); ++matIndex) {
-		auto& submesh = submeshes[matIndex];
-		BabylonSubmesh babsubmesh;
-		babsubmesh.indexCount = static_cast<int>(submesh.indices.size());
-		babsubmesh.indexStart = static_cast<int>(_indices.size());
-		babsubmesh.materialIndex = matIndex;
-		babsubmesh.verticesCount = static_cast<int>(submesh.vertices.size());
-		babsubmesh.verticesStart = static_cast<int>(_positions.size());
-		for (auto& v : submesh.vertices) {
-			_positions.push_back(v.position);
-			if (normals) {
-				_normals.push_back(v.normal);
-			}
-			if (colors) {
-				_colors.push_back(v.color);
-			}
-			if (uvs) {
-				_uvs.push_back(v.uv);
-			}
-			if (uvs2) {
-				_uvs2.push_back(v.uv2);
-			}
-			if (uvs3) {
-				_uvs3.push_back(v.uv3);
-			}
-			if (uvs4) {
-				_uvs4.push_back(v.uv4);
-			}
-			if (uvs5) {
-				_uvs5.push_back(v.uv5);
-			}
-			if (uvs6) {
-				_uvs6.push_back(v.uv6);
-			}
-			if (skinInfo.hasSkin()){
-				 float weight0 = v.boneWeights[0];
-				 float weight1 = v.boneWeights[1];
-				 float weight2 = v.boneWeights[2];
-				 int bone0 = v.boneIndices[0];
-				 int bone1 = v.boneIndices[1];
-				 int bone2 = v.boneIndices[2];
-				 int bone3 = v.boneIndices[3];
-               
-				_boneWeights.push_back(babylon_vector4( weight0, weight1, weight2, 1.0f - weight0 - weight1 - weight2));
-                _boneIndices.push_back((bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0);
-			}
-		}
-		for (auto i : submesh.indices) {
-			_indices.push_back(i + vertexOffset);
-		}
-
-		vertexOffset = static_cast<int>(_positions.size());
-		_submeshes.push_back(babsubmesh);
-	}
-
-
-
-}
-
-
-BabylonMesh::BabylonMesh(BabylonMesh && moved) : 
-	BabylonAbstractMesh(moved),
-	_id(std::move(moved._id)),
-	_parentId(std::move(moved._parentId)),
-	_materialId(std::move(moved._materialId)),
-	_isEnabled(std::move(moved._isEnabled)),
-	_isVisible(std::move(moved._isVisible)),
-	_pickable(std::move(moved._pickable)),
-	_positions(std::move(moved._positions)),
-	_normals(std::move(moved._normals)),
-	_uvs(std::move(moved._uvs)),
-	_uvs2(std::move(moved._uvs2)),
-	_uvs3(std::move(moved._uvs3)),
-	_uvs4(std::move(moved._uvs4)),
-	_uvs5(std::move(moved._uvs5)),
-	_uvs6(std::move(moved._uvs6)),
-	_colors(std::move(moved._colors)),
-	_hasVertexAlpha(std::move(moved._hasVertexAlpha)),
-	_boneIndices(std::move(moved._boneIndices)),
-	_boneWeights(std::move(moved._boneWeights)),
-	_indices(std::move(moved._indices)),
-	_checkCollision(std::move(moved._checkCollision)),
-	_receiveShadows(std::move(moved._receiveShadows)),
-	_infiniteDistance(std::move(moved._infiniteDistance)),
-	_billboardMode(std::move(moved._billboardMode)),
-	_visibility(std::move(moved._visibility)),
-	_submeshes(std::move(moved._submeshes)),
-	_instances(std::move(moved._instances)),
-	_skeletonId(std::move(moved._skeletonId)),
-	_autoAnimate(std::move(moved._autoAnimate)),
-	_autoAnimateFrom(std::move(moved._autoAnimateFrom)),
-	_autoAnimateTo(std::move(moved._autoAnimateTo)),
-	_autoAnimateLoop(std::move(moved._autoAnimateLoop)),
-	_showBoundingBox(std::move(moved._showBoundingBox)),
-	_showSubMeshesBoundingBox(std::move(moved._showSubMeshesBoundingBox)),
-	_applyFog(std::move(moved._applyFog)),
-	_alphaIndex(std::move(moved._alphaIndex)),
-	uvsets(std::move(moved.uvsets)),
-	associatedSkeleton(std::move(moved.associatedSkeleton)),
-	animations(std::move(moved.animations)),
-	pivotMatrix(std::move(moved.pivotMatrix))
-{
-}
-
-void BabylonMesh::addInstance(BabylonNode * node)
-{
-	_instances.emplace_back(node);
-}
-
-BabylonMesh::~BabylonMesh()
-{
-}

+ 0 - 129
Exporters/FBX/BabylonFbxNative/BabylonMesh.h

@@ -1,129 +0,0 @@
-#pragma once
-#include "BabylonAbstractMesh.h"
-#include <vector>
-#include <cstdint>
-#include "BabylonAnimation.h"
-#include "SkinInfo.h"
-
-struct BabylonSubmesh{
-	int materialIndex;
-	int verticesStart;
-	int verticesCount;
-	int indexStart;
-	int indexCount;
-
-
-	web::json::value toJson();
-};
-
-class BabylonMesh :
-	public BabylonAbstractMesh
-{
-private:
-	std::wstring _id;
-	std::wstring _parentId;
-	std::wstring _materialId;
-	bool _isEnabled;
-	bool _isVisible;
-	bool _pickable;
-	std::vector<babylon_vector3> _positions;
-	std::vector<babylon_vector3> _normals;
-	std::vector<babylon_vector2> _uvs;
-	std::vector<babylon_vector2> _uvs2;
-	std::vector<babylon_vector2> _uvs3;
-	std::vector<babylon_vector2> _uvs4;
-	std::vector<babylon_vector2> _uvs5;
-	std::vector<babylon_vector2> _uvs6;
-	std::vector<babylon_color> _colors;
-	bool _hasVertexAlpha;
-	std::vector<std::uint32_t> _boneIndices;
-	std::vector<babylon_vector4> _boneWeights;
-	std::vector<std::uint32_t> _indices;
-	bool _checkCollision;
-	bool _receiveShadows;
-	bool _infiniteDistance;
-	int _billboardMode;
-	float _visibility;
-	std::vector<BabylonSubmesh> _submeshes;
-	std::vector<BabylonAbstractMesh> _instances;
-	int _skeletonId;
-	bool _autoAnimate;
-	int _autoAnimateFrom;
-	int _autoAnimateTo;
-	bool _autoAnimateLoop;
-	bool _showBoundingBox;
-	bool _showSubMeshesBoundingBox;
-	bool _applyFog;
-	int _alphaIndex;
-public:
-	std::shared_ptr<BabylonSkeleton> associatedSkeleton;
-
-	std::vector<std::shared_ptr < BabylonAnimationBase>> animations;
-	FbxMatrix pivotMatrix;
-	std::vector<std::string> uvsets;
-	const std::wstring& id(){ return _id; }
-	const std::wstring& parentId(){ return _parentId; }
-	const std::wstring& materialId(){ return _materialId; }
-	bool isEnabled(){ return _isEnabled; }
-	bool isVisible(){ return _isVisible; }
-	bool pickable(){ return _pickable; }
-	std::vector<babylon_vector3>& positions(){ return _positions; }
-	std::vector<babylon_vector3>& normals(){ return _normals; }
-	std::vector<babylon_vector2>& uvs(){ return _uvs; }
-	std::vector<babylon_vector2>& uvs2(){ return _uvs2; }
-	std::vector<babylon_color>& colors(){ return _colors; }
-	bool hasVertexAlpha(){ return _hasVertexAlpha; }
-	std::vector<std::uint32_t>& boneIndices(){ return _boneIndices; }
-	std::vector<babylon_vector4>& boneWeights(){ return _boneWeights; }
-	std::vector<std::uint32_t>& indices(){ return _indices; }
-	bool checkCollision(){ return _checkCollision; }
-	bool receiveShadows(){ return _receiveShadows; }
-	bool infiniteDistance(){ return _infiniteDistance; }
-	int billboardMode(){ return _billboardMode; }
-	float visibility(){ return _visibility; }
-	std::vector<BabylonSubmesh>& submeshes(){ return _submeshes; }
-	std::vector<BabylonAbstractMesh>& instances(){ return _instances; }
-	int skeletonId(){ return _skeletonId; }
-	bool autoAnimate(){ return _autoAnimate; }
-	int autoAnimateFrom(){ return _autoAnimateFrom; }
-	int autoAnimateTo(){ return _autoAnimateTo; }
-	bool autoAnimateLoop(){ return _autoAnimateLoop; }
-	bool showBoundingBox(){ return _showBoundingBox; }
-	bool showSubMeshesBoundingBox(){ return _showSubMeshesBoundingBox; }
-	bool applyFog(){ return _applyFog; }
-	int alphaIndex(){ return _alphaIndex; }
-
-	void id(const std::wstring& value){ _id = value; }
-	void parentId(const std::wstring& value){ _parentId = value; }
-	void materialId(const std::wstring& value){ _materialId = value; }
-	void isEnabled(bool value){ _isEnabled = value; }
-	void isVisible(bool value){ _isVisible = value; }
-	void pickable(bool value){ _pickable = value; }
-	void hasVertexAlpha(bool value){ _hasVertexAlpha = value; }
-	void checkCollision(bool value){ _checkCollision = value; }
-	void receiveShadows(bool value){ _receiveShadows = value; }
-	void infiniteDistance(bool value){ _infiniteDistance = value; }
-	void billboardMode(int value){ _billboardMode = value; }
-	void visibility(float value){ _visibility = value; }
-	void skeletonId(int value){ _skeletonId = value; }
-	void autoAnimate(bool value){ _autoAnimate = value; }
-	void autoAnimateFrom(int value){ _autoAnimateFrom = value; }
-	void autoAnimateTo(int value){ _autoAnimateTo = value; }
-	void autoAnimateLoop(bool value){ _autoAnimateLoop = value; }
-	void showBoundingBox(bool value){ _showBoundingBox = value; }
-	void showSubMeshesBoundingBox(bool value){ _showSubMeshesBoundingBox = value; }
-	void applyFog(bool value){ _applyFog = value; }
-	void alphaIndex(int value){ _alphaIndex = value; }
-
-
-	
-
-	virtual web::json::value toJson() override;
-	BabylonMesh();
-	BabylonMesh(BabylonNode* node);
-	BabylonMesh(const BabylonMesh&) = default;
-	BabylonMesh(BabylonMesh&& moved);
-	void addInstance(BabylonNode* node);
-	virtual ~BabylonMesh();
-};
-

+ 0 - 69
Exporters/FBX/BabylonFbxNative/BabylonNode.cpp

@@ -1,69 +0,0 @@
-#include "stdafx.h"
-#include "BabylonNode.h"
-#include "NodeHelpers.h"
-
-BabylonNode::BabylonNode(FbxNode* fbxNode) : _node(fbxNode){
-	auto childCount = fbxNode->GetChildCount();
-	for (int i = 0; i < childCount; ++i){
-		_children.emplace_back(fbxNode->GetChild(i));
-	}
-}
-
-BabylonNode::BabylonNode(BabylonNode && moved) :
-	 _node(moved._node),
-	_children(std::move(moved._children))
-{
-}
-
-BabylonNodeType BabylonNode::nodeType(){
-	if (_node->GetMesh()){
-		return BabylonNodeType::Mesh;
-	}
-	if (_node->GetCamera()){
-		return BabylonNodeType::Camera;
-	}
-	if (_node->GetSkeleton()){
-		return BabylonNodeType::Skeleton;
-	}
-	if (_node->GetLight()) {
-		return BabylonNodeType::Light;
-	}
-	return BabylonNodeType::Empty;
-}
-
-bool BabylonNode::isEmptySkeletonOrEmptyMesh()
-{
-	auto type = nodeType();
-	switch (type)
-	{
-	case BabylonNodeType::Mesh:
-	{
-		auto mesh = _node->GetMesh();
-		if (mesh->GetPolygonCount() == 0) {
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-	case BabylonNodeType::Skeleton:
-	case BabylonNodeType::Empty:
-		return true;
-	default:
-		return false;
-	}
-}
-
-bool BabylonNode::isEmptySkeletonOrEmptyMeshRecursive()
-{
-	if (!isEmptySkeletonOrEmptyMesh()) {
-		return false;
-	}
-
-	for (auto& c : children()) {
-		if (!c.isEmptySkeletonOrEmptyMeshRecursive()) {
-			return false;
-		}
-	}
-	return true;
-}

+ 0 - 70
Exporters/FBX/BabylonFbxNative/BabylonNode.h

@@ -1,70 +0,0 @@
-#pragma once
-#include <fbxsdk.h>
-#include <vector>
-#include <cstdint>
-#include "NodeHelpers.h"
-#include "BabylonVertex.h"
-#include "MatrixDecomposition.h"
-enum class BabylonNodeType{
-	Camera,
-	Mesh,
-	Skeleton,
-	Light,
-	Empty
-};
-class BabylonNode;
-class BabylonNode
-{
-private:
-	FbxNode* _node;
-	std::vector<BabylonNode> _children;
-public:
-	BabylonNode() :_node(nullptr){}
-	
-
-
-	explicit BabylonNode(FbxNode* fbxNode);
-	BabylonNode(const BabylonNode&) = default;
-	BabylonNode(BabylonNode&& moved);
-
-	std::vector<BabylonNode>& children(){
-		return _children;
-	}
-	BabylonNodeType nodeType();
-
-	FbxNode* fbxNode(){ return _node; }
-	
-	bool isEmptySkeletonOrEmptyMesh();
-	bool isEmptySkeletonOrEmptyMeshRecursive();
-	void appendChild(FbxNode* fbxNode){
-		_children.emplace_back(fbxNode);
-	}
-
-	std::uint64_t uniqueId()const{
-		return _node->GetUniqueID();
-	}
-
-	std::string name() const{
-		return std::string(_node->GetName());
-	}
-
-	bool hasOnlySkeletonDescendants(){
-		if (nodeType() != BabylonNodeType::Skeleton){
-			return false;
-		}
-		for (auto& child : _children){
-			if (!child.hasOnlySkeletonDescendants()){
-				return false;
-			}
-		}
-		return true;
-	}
-
-	MatrixDecomposition GetLocal() {
-		return MatrixDecomposition(ConvertToBabylonCoordinateSystem(_node->EvaluateLocalTransform()));
-	}
-	MatrixDecomposition GetLocal(const FbxTime& time) {
-		return MatrixDecomposition(ConvertToBabylonCoordinateSystem(_node->EvaluateLocalTransform(time)));
-	}
-
-};

+ 0 - 258
Exporters/FBX/BabylonFbxNative/BabylonScene.cpp

@@ -1,258 +0,0 @@
-#include "stdafx.h"
-#include "BabylonScene.h"
-
-
-web::json::value BabylonScene::toJson() 
-{
-	auto jobj = web::json::value::object();
-	jobj[L"autoClear"] = web::json::value::boolean(_autoClear);
-	writeVector3(jobj, L"clearColor", _clearColor);
-	writeVector3(jobj, L"ambientColor", _ambientColor);
-	jobj[L"fogMode"] = web::json::value::number(_fogMode);
-	writeVector3(jobj, L"fogColor", _fogColor);
-	jobj[L"fogStart"] = web::json::value::number(_fogStart);
-	jobj[L"fogEnd"] = web::json::value::number(_fogEnd);
-	jobj[L"fogDensity"] = web::json::value::number(_fogDensity);
-	writeVector3(jobj, L"gravity", _gravity);
-	jobj[L"activeCameraID"] = web::json::value::string(_activeCameraID);
-
-	auto jcameras = web::json::value::array();
-
-	for (auto& cam : _cameras) {
-		jcameras[jcameras.size()] = cam.toJson();
-	}
-
-	jobj[L"cameras"] = jcameras;
-
-	auto jmeshes = web::json::value::array();
-	for (auto& mesh : _meshes) {
-		jmeshes[jmeshes.size()] = mesh.toJson();
-	}
-	jobj[L"meshes"] = jmeshes;
-
-
-	auto jmats = web::json::value::array();
-	for (auto& mat : _materials) {
-		jmats[jmats.size()] = mat.toJson();
-	}
-	jobj[L"materials"] = jmats;
-
-	auto jmulmats = web::json::value::array();
-	for (auto& mat : _multiMaterials) {
-		jmulmats[jmulmats.size()] = mat.toJson();
-	}
-	jobj[L"multiMaterials"] = jmulmats;
-
-	auto jlights = web::json::value::array();
-	for (auto& light : _lights) {
-		jlights[jlights.size()] = light.toJson();
-	}
-	jobj[L"lights"] = jlights;
-
-	auto jskeletons = web::json::value::array();
-	for (auto& skel : _skeletons){
-		jskeletons[jskeletons.size()] = skel->toJson();
-	}
-	jobj[L"skeletons"] = jskeletons;
-	auto jshadowGenerators = web::json::value::array();
-	for (auto& sg : _shadowGenerators) {
-		jshadowGenerators[jshadowGenerators.size()] = sg->toJson();
-	}
-	jobj[L"shadowGenerators"] = jshadowGenerators;
-	return jobj;
-}
-
-BabylonScene::BabylonScene() :
-_autoClear(true),
-_clearColor(.2f, .2f, .3f),
-_ambientColor(0,0,0),
-_gravity(0,0,-.9f)
-{
-}
-
-BabylonScene::BabylonScene(BabylonNode & rootNode, bool skipEmptyNodes) :
-	_autoClear(true),
-	_clearColor(.2f, .2f, .3f),
-	_ambientColor(0, 0, 0),
-	_gravity(0, 0, -.9f)
-{
-	std::map<FbxMesh*, size_t> meshInstanceMap;
-	exploreNodes(rootNode, skipEmptyNodes, meshInstanceMap);
-	if (_cameras.size() == 0) {
-		babylon_boundingbox bbox(rootNode.fbxNode()->GetScene());
-		auto cam = buildCameraFromBoundingBox(bbox);
-		_activeCameraID = cam.id;
-		_cameras.push_back(std::move(cam));
-	}
-	if (_lights.size() == 0) {
-		BabylonLight light;
-		light.diffuse = babylon_vector3(1, 1, 1);
-		light.specular = babylon_vector3(1, 1, 1);
-		light.position = babylon_vector3(0, 0, 0);
-		light.parentId = _activeCameraID;
-		light.type = 0;
-		light.id = L"default_light";
-		light.name = L"default_light";
-		light.intensity = 1;
-		_lights.push_back(std::move(light));
-	}
-}
-
-
-BabylonScene::BabylonScene(BabylonScene && moved) : 
-	_autoClear(std::move(moved._autoClear)),
-	_clearColor(std::move(moved._clearColor)),
-	_ambientColor(std::move(moved._ambientColor)),
-	_fogMode(std::move(moved._fogMode)),
-	_fogColor(std::move(moved._fogColor)),
-	_fogStart(std::move(moved._fogStart)),
-	_fogEnd(std::move(moved._fogEnd)),
-	_fogDensity(std::move(moved._fogDensity)),
-	_gravity(std::move(moved._gravity)),
-	_cameras(std::move(moved._cameras)),
-	_activeCameraID(std::move(moved._activeCameraID)),
-	_meshes(std::move(moved._meshes)),
-	_materials(std::move(moved._materials)),
-	_multiMaterials(std::move(moved._multiMaterials)),
-	_lights(std::move(moved._lights)),
-	_shadowGenerators(std::move(moved._shadowGenerators)),
-	_skeletons(std::move(moved._skeletons))
-{
-}
-
-BabylonScene::~BabylonScene()
-{
-}
-
-
-void fixupTextureCoordinateIndices(BabylonMaterial& mat, BabylonMesh& mesh) {
-	std::vector<std::shared_ptr<BabylonTexture>> textures;
-	if (mat.ambientTexture) {
-		textures.push_back(mat.ambientTexture);
-	}
-	if (mat.diffuseTexture) {
-		textures.push_back(mat.diffuseTexture);
-	}
-	if (mat.specularTexture) {
-		textures.push_back(mat.specularTexture);
-	}
-	if (mat.emissiveTexture) {
-		textures.push_back(mat.emissiveTexture);
-	}
-	if (mat.reflectionTexture) {
-		textures.push_back(mat.reflectionTexture);
-	}
-	if (mat.bumpTexture) {
-		textures.push_back(mat.bumpTexture);
-	}
-	for (auto& tex : textures) {
-		auto found = std::find(mesh.uvsets.begin(), mesh.uvsets.end(), tex->uvset);
-		if (found != mesh.uvsets.end()) {
-			tex->coordinatesIndex = static_cast<int>(found - mesh.uvsets.begin());
-		}
-	}
-}
-bool isAlreadyInstanciatedMesh(FbxNode* node, std::map<FbxMesh*, size_t>& meshInstanceMap, size_t* oIndex) {
-	auto mesh = node->GetMesh();
-	if (!mesh) {
-		return false;
-	}
-	auto found = meshInstanceMap.find(mesh);
-	if (found == meshInstanceMap.end()) {
-		return false;
-	}
-
-	*oIndex = found->second;
-	return true;
-}
-void BabylonScene::exploreNodes(BabylonNode & node, bool skipEmptyNodes, std::map<FbxMesh*, size_t>& meshInstanceMap)
-{
-	if (node.nodeType() == BabylonNodeType::Skeleton && node.hasOnlySkeletonDescendants()) {
-		return;
-	}
-	if (skipEmptyNodes && node.isEmptySkeletonOrEmptyMeshRecursive()) {
-		return;
-	}
-	// append mesh
-	switch (node.nodeType())
-	{
-	case BabylonNodeType::Empty:
-	case BabylonNodeType::Mesh:
-	case BabylonNodeType::Skeleton:
-	{
-		size_t instanceOwnerIndex;
-		if (isAlreadyInstanciatedMesh(node.fbxNode(), meshInstanceMap, &instanceOwnerIndex)) {
-			_meshes[instanceOwnerIndex].addInstance(&node);
-		}
-		else {
-			BabylonMesh mesh(&node);
-
-			auto matCount = node.fbxNode()->GetMaterialCount();
-			BabylonMultiMaterial multiMat;
-			for (auto i = 0; i < matCount; ++i) {
-				auto mat = node.fbxNode()->GetMaterial(i);
-				if (mat) {
-
-					auto id = getMaterialId(mat);
-					auto existing = std::find_if(_materials.begin(), _materials.end(), [id](const BabylonMaterial& e) {
-						return e.id == id;
-					});
-					if (existing == _materials.end()) {
-						auto babMat = BabylonMaterial(mat);
-						fixupTextureCoordinateIndices(babMat, mesh);
-						_materials.push_back(std::move(babMat));
-					}
-
-					multiMat.materials.push_back(id);
-
-				}
-			}
-
-			if (mesh.associatedSkeleton) {
-				mesh.associatedSkeleton->id = static_cast<int>(_skeletons.size() + 1);
-				mesh.skeletonId(static_cast<int>(_skeletons.size() + 1));
-				_skeletons.push_back(mesh.associatedSkeleton);
-			}
-			if (multiMat.materials.size() > 0) {
-
-				multiMat.id = mesh.id();
-				multiMat.name = mesh.name();
-				mesh.materialId(multiMat.id);
-				_multiMaterials.push_back(std::move(multiMat));
-			}
-
-			auto fbxMesh = node.fbxNode()->GetMesh();
-			if (fbxMesh) {
-				meshInstanceMap[fbxMesh] = _meshes.size();
-			}
-			_meshes.push_back(std::move(mesh));
-		}
-	}
-	break;
-	case BabylonNodeType::Camera:
-	{
-		_cameras.emplace_back(node);
-		if (_cameras.size() == 1) {
-			activeCameraID(_cameras[0].id);
-		}
-	}
-	break;
-	case BabylonNodeType::Light:
-	{
-		_lights.emplace_back(node);
-		auto& l = _lights[_lights.size() - 1];
-		if (l.shadowGenerator) {
-			_shadowGenerators.push_back(l.shadowGenerator);
-		}
-	}
-	break;
-	default:
-		break;
-	}
-
-
-	for (auto& child : node.children()) {
-		exploreNodes(child, skipEmptyNodes, meshInstanceMap);
-	}
-
-}

+ 0 - 94
Exporters/FBX/BabylonFbxNative/BabylonScene.h

@@ -1,94 +0,0 @@
-#pragma once
-#include <cpprest\json.h>
-#include "BabylonVertex.h"
-#include "BabylonMesh.h"
-#include "BabylonMaterial.h"
-#include "BabylonCamera.h"
-#include "BabylonLight.h"
-#include "BabylonSkeleton.h"
-#include <memory>
-#include "BabylonNode.h"
-
-class BabylonScene
-{
-private:
-	bool _autoClear;
-	babylon_vector3 _clearColor;
-	babylon_vector3 _ambientColor;
-	int _fogMode;
-	babylon_vector3 _fogColor;
-	float _fogStart;
-	float _fogEnd;
-	float _fogDensity;
-	babylon_vector3 _gravity;
-	std::vector<BabylonCamera> _cameras;
-	std::wstring _activeCameraID;
-	std::vector<BabylonMesh> _meshes;
-	std::vector<BabylonMaterial> _materials;
-	std::vector<BabylonMultiMaterial> _multiMaterials;
-	std::vector<BabylonLight> _lights;
-	std::vector<std::shared_ptr<BabylonShadowGenerator>> _shadowGenerators;
-	std::vector<std::shared_ptr<BabylonSkeleton>> _skeletons;
-	// particleSystems
-	// lensFlareSystems
-	// shadowGenerators
-	// skeletons
-
-public:
-
-	bool autoClear(){ return _autoClear; }
-	babylon_vector3 clearColor(){ return _clearColor; }
-	babylon_vector3 ambientColor(){ return _ambientColor; }
-	int fogMode(){ return _fogMode; }
-	babylon_vector3 fogColor(){ return _fogColor; }
-	float fogStart(){ return _fogStart; }
-	float fogEnd(){ return _fogEnd; }
-	float fogDensity(){ return _fogDensity; }
-	babylon_vector3 gravity(){ return _gravity; }
-
-	std::vector<BabylonCamera>& cameras() { return _cameras; }
-	const std::wstring& activeCameraID() { return _activeCameraID; }
-	// lights
-	std::vector<BabylonMesh>& meshes() { return _meshes; }
-	std::vector<BabylonMaterial>& materials(){ return _materials; }
-	std::vector<BabylonMultiMaterial>& multiMaterials(){ return _multiMaterials; }
-
-	std::vector<BabylonLight>& lights() { return _lights; }
-	std::vector<std::shared_ptr<BabylonShadowGenerator>>& shadowGenerators() { return _shadowGenerators; }
-	std::vector<std::shared_ptr<BabylonSkeleton>>& skeletons() { return _skeletons; }
-	// particleSystems
-	// lensFlareSystems
-	// shadowGenerators
-	// skeletons
-
-	void autoClear(bool value){ _autoClear = value; }
-	void clearColor(babylon_vector3 value){ _clearColor = value; }
-	void ambientColor(babylon_vector3 value){ _ambientColor = value; }
-	void fogMode(int value){ _fogMode = value; }
-	void fogColor(babylon_vector3 value){ _fogColor = value; }
-	void fogStart(float value){ _fogStart = value; }
-	void fogEnd(float value){ _fogEnd = value; }
-	void fogDensity(float value){ _fogDensity = value; }
-	void gravity(babylon_vector3 value){ _gravity = value; }
-
-
-	void activeCameraID(const std::wstring& value) { _activeCameraID = value; }
-	// lights
-	// materials
-	// multiMaterials
-	// particleSystems
-	// lensFlareSystems
-	// shadowGenerators
-	// skeletons
-
-	web::json::value toJson() ;
-
-	BabylonScene();
-	BabylonScene(BabylonNode& rootNode, bool skipEmptyNodes);
-	BabylonScene(const BabylonScene&) = default;
-	BabylonScene(BabylonScene&& moved);
-	~BabylonScene();
-private:
-	void exploreNodes(BabylonNode& node, bool skipEmptyNodes, std::map<FbxMesh*, size_t>& meshInstanceMap);
-};
-

+ 0 - 41
Exporters/FBX/BabylonFbxNative/BabylonSkeleton.cpp

@@ -1,41 +0,0 @@
-#include "stdafx.h"
-#include "BabylonSkeleton.h"
-
-
-BabylonSkeleton::BabylonSkeleton()
-{
-}
-
-
-
-web::json::value BabylonBone::toJson(){
-	auto jobj = web::json::value::object();
-	jobj[L"name"] = web::json::value::string(name);
-	jobj[L"index"] = web::json::value::number(index);
-	jobj[L"parentBoneIndex"] = web::json::value::number(parentBoneIndex);
-
-	auto jmat = web::json::value::array();
-	for (auto x = 0; x < 4; ++x){
-		for (auto y = 0; y < 4; ++y){
-			jmat[x * 4 + y] = web::json::value::number(matrix[x][y]);
-		}
-	}
-	jobj[L"matrix"] = jmat;
-	if (animation){
-		jobj[L"animation"] = animation->toJson();
-	}
-	return jobj;
-}
-
-
-web::json::value BabylonSkeleton::toJson(){
-	auto jobj = web::json::value::object();
-	jobj[L"name"] = web::json::value::string(name);
-	jobj[L"id"] = web::json::value::number(id);
-	auto jbones = web::json::value::array();
-	for (auto ix = 0u; ix < bones.size(); ++ix){
-		jbones[ix] = bones[ix].toJson();
-	}
-	jobj[L"bones"] = jbones;
-	return jobj;
-}

+ 0 - 48
Exporters/FBX/BabylonFbxNative/BabylonSkeleton.h

@@ -1,48 +0,0 @@
-#pragma once
-#include <string>
-#include <vector>
-#include <fbxsdk.h>
-#include <cpprest\json.h>
-#include "BabylonAnimation.h"
-
-class BabylonBone{
-public:
-
-	std::wstring name;
-	int index;
-	int parentBoneIndex = -1;
-	FbxMatrix matrix;
-	std::shared_ptr<BabylonAnimation<FbxMatrix>> animation;
-	web::json::value toJson();
-	BabylonBone() = default;
-	BabylonBone(const BabylonBone&) = default;
-	BabylonBone(BabylonBone&& moved) :
-		name(std::move(moved.name)),
-		index(std::move(moved.index)),
-		parentBoneIndex(std::move(moved.parentBoneIndex)),
-		matrix(std::move(moved.matrix)),
-		animation(std::move(moved.animation))
-	{}
-	//public BabylonAnimation animation{ get; set; }
-};
-class BabylonSkeleton
-{
-public:
-	int id;
-
-	std::wstring name;
-
-	std::vector<BabylonBone> bones;
-
-	web::json::value toJson();
-	BabylonSkeleton();
-	BabylonSkeleton(const BabylonSkeleton&) = default;
-	BabylonSkeleton(BabylonSkeleton&& moved) :
-		id(std::move(moved.id)),
-		name(std::move(moved.name)),
-		bones(std::move(moved.bones))
-	{
-
-	}
-};
-

+ 0 - 412
Exporters/FBX/BabylonFbxNative/BabylonVertex.h

@@ -1,412 +0,0 @@
-#pragma once
-#include <vector>
-#include <set>
-#include <string>
-#include <memory>
-#include <fbxsdk.h>
-#include <cpprest\json.h>
-
-struct babylon_vector4{
-	float x;
-	float y;
-	float z;
-	float w;
-	babylon_vector4() :x(0), y(0), z(0), w(0){}
-	babylon_vector4(float x, float y, float z, float w) :x(x), y(y), z(z), w(w){}
-	babylon_vector4(const babylon_vector4& v) :x(v.x), y(v.y), z(v.z), w(v.w) {}
-	babylon_vector4(const FbxQuaternion& v) :x(static_cast<float>(v[0])), y(static_cast<float>(v[1])), z(static_cast<float>(v[2])), w(static_cast<float>(v[3])) {}
-};
-struct babylon_vector3{
-	float x;
-	float y;
-	float z;
-	babylon_vector3() :x(0), y(0), z(0){}
-	babylon_vector3(float x, float y, float z) :x(x), y(y), z(z){}
-	babylon_vector3(const babylon_vector3& v) :x(v.x), y(v.y), z(v.z){}
-	babylon_vector3(const FbxDouble3& v) : x((float) v[0]), y((float) v[1]), z((float) v[2]){}
-	babylon_vector3(const FbxDouble4& v) : x((float) v[0]), y((float) v[1]), z((float) v[2]){}
-};
-
-inline babylon_vector3 operator *(const babylon_vector3& v, float factor){
-	return babylon_vector3(v.x*factor, v.y*factor, v.z*factor);
-}
-inline babylon_vector3 operator *(float factor, const babylon_vector3& v){
-	return v*factor;
-}
-
-inline babylon_vector3 operator + (const  babylon_vector3& lhs, const  babylon_vector3& rhs){
-	return babylon_vector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
-}
-inline babylon_vector3 operator - (const  babylon_vector3& lhs, const  babylon_vector3& rhs){
-	return babylon_vector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
-}
-
-
-
-inline babylon_vector4 operator *(const babylon_vector4& v, float factor){
-	return babylon_vector4(v.x*factor, v.y*factor, v.z*factor, v.w*factor);
-}
-inline babylon_vector4 operator *(float factor, const babylon_vector4& v){
-	return v*factor;
-}
-
-inline babylon_vector4 operator + (const  babylon_vector4& lhs, const  babylon_vector4& rhs){
-	return babylon_vector4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w+rhs.w);
-}
-inline babylon_vector4 operator - (const  babylon_vector4& lhs, const  babylon_vector4& rhs){
-	return babylon_vector4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
-}
-
-
-
-
-inline bool operator <(const babylon_vector3& lhs, const babylon_vector3& rhs){
-	if (lhs.x < rhs.x){
-		return true;
-	}
-	else if (lhs.x > rhs.x){
-		return false;
-	}
-
-	if (lhs.y < rhs.y){
-		return true;
-	}
-	else if (lhs.y > rhs.y){
-		return false;
-	}
-
-	return lhs.z < rhs.z;
-}
-
-
-struct babylon_vector2{
-	float x;
-	float y;
-	babylon_vector2() :x(0), y(0){}
-	babylon_vector2(float x, float y) :x(x), y(y){}
-	babylon_vector2(const babylon_vector2& v) :x(v.x), y(v.y){}
-	babylon_vector2(const FbxDouble2& v) :x(static_cast<float>(v[0])), y(static_cast<float>(v[1])){}
-
-};
-
-inline bool operator <(const babylon_vector2& lhs, const babylon_vector2& rhs){
-	if (lhs.x < rhs.x){
-		return true;
-	}
-	else if (lhs.x > rhs.x){
-		return false;
-	}
-
-
-
-	return lhs.y < rhs.y;
-}
-
-struct babylon_vertex_normal_uv_color{
-	float pos_x;
-	float pos_y;
-	float pos_z;
-	float normal_x;
-	float normal_y;
-	float normal_z;
-	float uv_x;
-	float uv_y;
-	float color_r;
-	float color_g;
-	float color_b;
-	float color_a;
-
-	babylon_vector3 getTransformedPosition(const FbxAMatrix& transform) const{
-		auto result = transform.MultT(FbxVector4(pos_x, pos_y, pos_z));
-		return babylon_vector3((float) result[0], (float) result[1], (float) result[2]);
-	}
-};
-
-class babylon_boundingbox
-{
-private:
-	float _minX;
-	float _minY;
-	float _minZ;
-	float _maxX;
-	float _maxY;
-	float _maxZ;
-public:
-	void addPosition(float x, float y, float z);
-
-	void addPosition(const babylon_vector3& v){
-		addPosition(v.x, v.y, v.z);
-	}
-	float getMinX() const{
-		return _minX;
-	}
-	float getMinY() const{
-		return _minY;
-	}
-	float getMinZ() const{
-		return _minZ;
-	}
-
-
-	float getMaxX() const{
-		return _maxX;
-	}
-	float getMaxY() const{
-		return _maxY;
-	}
-	float getMaxZ() const{
-		return _maxZ;
-	}
-	float getWidth() const{
-		return _maxX - _minX;
-	}
-	float getHeight() const{
-		return _maxY - _minY;
-	}
-	float getDepth() const{
-		return _maxZ - _minZ;
-	}
-	babylon_vector3 getMin() const{
-		return babylon_vector3(getMinX(), getMinY(), getMinZ());
-	}
-	babylon_vector3 getMax() const{
-		return babylon_vector3(getMaxX(), getMaxY(), getMaxZ());
-	}
-	babylon_vector3 getCenter() const{
-		return babylon_vector3(
-			0.5f*(_maxX + _minX),
-			0.5f*(_maxY + _minY),
-			0.5f*(_maxZ + _minZ));
-	}
-	babylon_boundingbox();
-
-	babylon_boundingbox(FbxScene* scene);
-	~babylon_boundingbox();
-};
-
-
-babylon_boundingbox mergeBoundingBoxes(const std::vector<babylon_boundingbox>& boxes);
-
-struct babylon_submesh{
-	std::string material_id;
-	int index_start;
-	int index_count;
-};
-template<typename TVertex>
-class babylon_mesh{
-private:
-	std::string _name;
-	std::vector<TVertex> _vertices;
-	std::vector<int> _indices;
-	std::vector<babylon_submesh> _submeshes;
-	FbxAMatrix _transform;
-	babylon_boundingbox _boundingBox;
-public:
-
-	babylon_mesh(const char* name, std::vector<TVertex>&& vertices, std::vector<int>&& indices, std::vector<babylon_submesh>&& submeshes, FbxAMatrix transform) :
-		_name(name),
-		_vertices(std::move(vertices)),
-		_indices(std::move(indices)),
-		_submeshes(std::move(submeshes)),
-		_transform(transform)
-	{
-		for (const auto& v : _vertices){
-			babylon_vector3 pos = v.getTransformedPosition(_transform);
-			_boundingBox.addPosition(pos.x, pos.y, pos.z);
-		}
-	}
-
-	babylon_mesh() :_materialIndex(-1){
-
-	}
-
-	babylon_mesh(babylon_mesh&& mesh) :
-		_name(std::move(mesh._name)),
-		_vertices(std::move(mesh._vertices)),
-		_indices(std::move(mesh._indices)),
-		_transform(mesh._transform),
-		_submeshes(std::move(mesh._submeshes)),
-		_boundingBox(mesh._boundingBox)
-	{
-
-	}
-	babylon_boundingbox getBoundingBox()const{
-		return _boundingBox;
-	}
-	const FbxAMatrix& getTransform() const{ return _transform; }
-	const std::string& getName() const{ return _name; }
-	const std::vector<TVertex>& getVertices() const{ return _vertices; }
-	const std::vector<int>& getIndices() const{ return _indices; }
-	const std::vector<babylon_submesh>& getSubmeshes() const { return _submeshes; }
-	int getUniqueIndexCount(const babylon_submesh& subMesh) const{
-		std::set<int> knownIndices;
-		for (int i = 0; i < subMesh.index_count; ++i){
-			knownIndices.insert(_indices[i + subMesh.index_start]);
-		}
-		return knownIndices.size();
-	}
-};
-
-struct babylon_color{
-	float r;
-	float g;
-	float b;
-	float a;
-
-	babylon_color() :r(0), g(0), b(0), a(0){}
-	babylon_color(const FbxColor& v) : r(static_cast<float>(v.mRed)), g(static_cast<float>(v.mGreen)), b(static_cast<float>(v.mBlue)), a(static_cast<float>(v.mAlpha)){}
-};
-
-inline bool operator <(const babylon_color& lhs, const babylon_color& rhs){
-	if (lhs.r < rhs.r){
-		return true;
-	}
-	else if (lhs.r > rhs.r){
-		return false;
-	}
-	if (lhs.g < rhs.g){
-		return true;
-	}
-	else if (lhs.g > rhs.g){
-		return false;
-	}
-	if (lhs.b < rhs.b){
-		return true;
-	}
-	else if (lhs.b > rhs.b){
-		return false;
-	}
-
-
-
-	return lhs.a < rhs.a;
-}
-
-struct babylon_texture{
-	std::string name;
-	bool hasAlpha;
-};
-
-
-struct babylon_material{
-	std::string id;
-	std::string name;
-	bool backFaceCulling;
-	babylon_vector3 ambient;
-	babylon_vector3 diffuse;
-	babylon_vector3 specular;
-	babylon_vector3 emissive;
-	float specularPower;
-	float alpha;
-	std::shared_ptr<babylon_texture> diffuseTexture;
-	std::shared_ptr<babylon_texture> ambientTexture;
-	std::shared_ptr<babylon_texture> opacityTexture;
-	std::shared_ptr<babylon_texture> reflectionTexture;
-	std::shared_ptr<babylon_texture> emissiveTexture;
-	std::shared_ptr<babylon_texture> specularTexture;
-	std::shared_ptr<babylon_texture> bumpTexture;
-
-};
-
-struct babylon_global_settings{
-	bool autoClear;
-	babylon_vector3 clearColor;
-	babylon_vector3 ambientColor;
-	babylon_vector3 gravity;
-	int fogMode;
-	babylon_vector3 fogColor;
-	float fogStart;
-	float fogEnd;
-	float fogDensity;
-	babylon_global_settings(){
-		autoClear = true;
-		clearColor = babylon_vector3(0.2f, 0.2f, 0.3f);
-		ambientColor = babylon_vector3(0.0f, 0.0f, 0.0f);
-		gravity = babylon_vector3(0.0f, 0.0f, -0.9f);
-		fogMode = 0;
-		fogColor = babylon_vector3(0.0f, 0.0f, 0.0f);
-		fogStart = 0;
-		fogEnd = 0;
-		fogDensity = 0;
-	}
-};
-
-struct babylon_camera{
-	std::string name;
-	std::string id;
-	babylon_vector3 position;
-	babylon_vector3 target;
-	babylon_vector3 rotation;
-	float fov;
-	float minZ;
-	float maxZ;
-	float speed;
-	float inertia;
-	bool checkCollisions;
-	bool applyGravity;
-	babylon_vector3 ellipsoid;
-
-
-};
-
-
-
-
-inline void writeVector3(web::json::value& obj, const wchar_t* name, const babylon_vector3& v) {
-	obj[name] = web::json::value::array();
-	obj[name][0] = v.x;
-	obj[name][1] = v.y;
-	obj[name][2] = v.z;
-}inline void writeVector4(web::json::value& obj, const wchar_t* name, const babylon_vector4& v) {
-	obj[name] = web::json::value::array();
-	obj[name][0] = v.x;
-	obj[name][1] = v.y;
-	obj[name][2] = v.z;
-	obj[name][3] = v.w;
-}
-
-inline void writeVector2(web::json::value& obj, const wchar_t* name, const babylon_vector2& v) {
-	obj[name] = web::json::value::array();
-	obj[name][0] = v.x;
-	obj[name][1] = v.y;
-}
-
-inline void writeFbxQuaterntion(web::json::value& obj, const wchar_t* name, const FbxQuaternion& v) {
-	obj[name] = web::json::value::array();
-	obj[name][0] = (float) v[0];
-	obj[name][1] = (float) v[1];
-	obj[name][2] = (float) v[2];
-	obj[name][3] = (float) v[3];
-}
-
-inline void writeVector3IntoStream(web::json::value& array, const babylon_vector3& v) {
-	auto size = array.size();
-	array[size] = v.x;
-	array[size + 1] = v.y;
-	array[size + 2] = v.z;
-}
-inline void writeVector2IntoStream(web::json::value& array, float x, float y) {
-	auto size = array.size();
-	array[size] = x;
-	array[size + 1] = y;
-}
-
-inline void writeMatrix(web::json::value& obj, const wchar_t* name, const FbxMatrix& v) {
-	obj[name] = web::json::value::array();
-	obj[name][0] = v.mData[0][0];
-	obj[name][1] = v.mData[1][0];
-	obj[name][2] = v.mData[2][0];
-	obj[name][3] = v.mData[3][0];
-	obj[name][4] = v.mData[0][1];
-	obj[name][5] = v.mData[1][1];
-	obj[name][6] = v.mData[2][1];
-	obj[name][7] = v.mData[3][1];
-	obj[name][8] = v.mData[0][2];
-	obj[name][9] = v.mData[1][2];
-	obj[name][10] = v.mData[2][2];
-	obj[name][11] = v.mData[3][2];
-	obj[name][12] = v.mData[0][3];
-	obj[name][13] = v.mData[1][3];
-	obj[name][14] = v.mData[2][3];
-	obj[name][15] = v.mData[3][3];
-}

+ 0 - 11
Exporters/FBX/BabylonFbxNative/FbxDeleter.h

@@ -1,11 +0,0 @@
-#pragma once
-#include <fbxsdk.h>
-template <typename T>
-struct FbxBaseDeleter{
-	void operator()(T* fbxObject){
-		fbxObject->Destroy();
-	}
-};
-
-struct FbxManagerDeleter : public FbxBaseDeleter<FbxManager>{};
-struct FbxDeleter : public FbxBaseDeleter<FbxObject>{};

+ 0 - 22
Exporters/FBX/BabylonFbxNative/FbxLoadException.cpp

@@ -1,22 +0,0 @@
-#include "stdafx.h"
-#include "FbxLoadException.h"
-
-
-FbxLoadException::FbxLoadException(const char* message) : std::exception(message)
-{
-}
-
-
-FbxLoadException::~FbxLoadException()
-{
-}
-
-
-UnknownVertexTypeException::UnknownVertexTypeException(const char* message) : std::exception(message)
-{
-}
-
-
-UnknownVertexTypeException::~UnknownVertexTypeException()
-{
-}

+ 0 - 17
Exporters/FBX/BabylonFbxNative/FbxLoadException.h

@@ -1,17 +0,0 @@
-#pragma once
-#include <exception>
-
-class FbxLoadException : public std::exception
-{
-public:
-	explicit FbxLoadException(const char* message);
-	~FbxLoadException();
-};
-
-class UnknownVertexTypeException : public std::exception{
-
-public:
-	explicit UnknownVertexTypeException(const char* message);
-	~UnknownVertexTypeException();
-};
-

+ 0 - 12
Exporters/FBX/BabylonFbxNative/FbxMeshHandler.cpp

@@ -1,12 +0,0 @@
-#include "stdafx.h"
-#include "FbxMeshHandler.h"
-
-
-FbxMeshHandler::FbxMeshHandler()
-{
-}
-
-
-FbxMeshHandler::~FbxMeshHandler()
-{
-}

+ 0 - 8
Exporters/FBX/BabylonFbxNative/FbxMeshHandler.h

@@ -1,8 +0,0 @@
-#pragma once
-class FbxMeshHandler
-{
-public:
-	FbxMeshHandler();
-	~FbxMeshHandler();
-};
-

+ 0 - 56
Exporters/FBX/BabylonFbxNative/FbxSceneLoader.cpp

@@ -1,56 +0,0 @@
-#include "stdafx.h"
-#include "FbxSceneLoader.h"
-#include "FbxLoadException.h"
-#include <vector>
-
-
-void MapNodes(std::map<std::uint64_t, BabylonNode*> map, BabylonNode* node){
-	map[node->uniqueId()] = node;
-	for (auto& child : node->children()){
-		MapNodes(map, &child);
-	}
-}
-
-FbxSceneLoader::FbxSceneLoader(const std::string& filePath) :_scene(nullptr), _filePath(filePath), _fbxMgr(FbxManager::Create())
-{
-	std::unique_ptr<FbxIOSettings, FbxDeleter> iosettings(FbxIOSettings::Create(_fbxMgr.get(), IOSROOT));
-
-	iosettings->SetBoolProp(IMP_FBX_MATERIAL, true);
-	iosettings->SetBoolProp(IMP_FBX_TEXTURE, true);
-	iosettings->SetBoolProp(IMP_FBX_LINK, true);
-	iosettings->SetBoolProp(IMP_FBX_SHAPE, true);
-	iosettings->SetBoolProp(IMP_FBX_GOBO, true);
-	iosettings->SetBoolProp(IMP_FBX_ANIMATION, true);
-	iosettings->SetBoolProp(IMP_SKINS, true);
-	iosettings->SetBoolProp(IMP_DEFORMATION, true);
-	iosettings->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);
-	iosettings->SetBoolProp(IMP_TAKE, true);
-	_fbxMgr->SetIOSettings(iosettings.get());
-
-	std::unique_ptr<FbxImporter, FbxDeleter> importer(FbxImporter::Create(_fbxMgr.get(), "SceneImporter"));
-	if (!importer->Initialize(_filePath.c_str())){
-		throw FbxLoadException(importer->GetStatus().GetErrorString());
-	}
-	_scene = FbxScene::Create(_fbxMgr.get(), filePath.c_str());
-	importer->Import(_scene);
-
-	
-	
-	_rootNode = std::make_unique<BabylonNode>(_scene->GetRootNode());
-	MapNodes(_nodesMap, _rootNode.get());
-}
-
-
-
-FbxSceneLoader::~FbxSceneLoader()
-{
-	_scene->Destroy(true);
-}
-
-
-babylon_global_settings FbxSceneLoader::getGlobalSettings(){
-	babylon_global_settings result;
-	auto& settings = _scene->GetGlobalSettings();
-	
-	return result;
-}

+ 0 - 61
Exporters/FBX/BabylonFbxNative/FbxSceneLoader.h

@@ -1,61 +0,0 @@
-#pragma once
-#include "FbxDeleter.h"
-#include <fbxsdk.h>
-#include <string>
-#include <vector>
-#include <memory>
-#include "BabylonNode.h"
-#include "BabylonVertex.h"
-#include <map>
-
-class FbxSceneLoader
-{
-private:
-	std::string _filePath;
-	std::unique_ptr<FbxManager, FbxManagerDeleter> _fbxMgr;
-	FbxScene* _scene;
-	std::unique_ptr<BabylonNode> _rootNode;
-	std::map<std::uint64_t, BabylonNode*> _nodesMap;
-public:
-	FbxSceneLoader(const std::string& filePath);
-	~FbxSceneLoader();
-	FbxScene* getScene(){
-		
-		return _scene;
-	}
-
-	BabylonNode* rootNode() const{
-		return _rootNode.get();
-	}
-
-	std::map<std::uint64_t, BabylonNode*>& getNodeMap(){
-		return _nodesMap;
-	}
-
-	
-	FbxScene* getScene() const{
-		return _scene;
-	}
-	FbxCamera* GetDefaultCamera() const{
-		const int nodeCount = _scene->GetSrcObjectCount<FbxNode>();
-
-		for (int index = 0; index < nodeCount; index++)
-		{
-			auto node = _scene->GetSrcObject<FbxNode>(index);
-			auto camera = node->GetCamera();
-			if (!camera){
-				// not a geometry node, go to next
-				continue;
-			}
-			return camera;
-			// ignore skinned meshes
-			/*if (mesh->GetDeformerCount(FbxDeformer::eSkin) == 0){
-			this->_meshes.push_back(mesh);
-			}*/
-
-		}
-		return nullptr;
-	}
-	babylon_global_settings getGlobalSettings();
-};
-

+ 0 - 13
Exporters/FBX/BabylonFbxNative/GlobalSettings.cpp

@@ -1,13 +0,0 @@
-#include "stdafx.h"
-#include "GlobalSettings.h"
-
-
-
-GlobalSettings::GlobalSettings()
-{
-}
-
-GlobalSettings& GlobalSettings::Current(){
-	static GlobalSettings settings;
-	return settings;
-}

+ 0 - 17
Exporters/FBX/BabylonFbxNative/GlobalSettings.h

@@ -1,17 +0,0 @@
-#pragma once
-#include <cstdint>
-#include <fbxsdk.h>
-
-class GlobalSettings
-{
-private:
-
-	GlobalSettings();
-public:
-	FbxTime::EMode AnimationsTimeMode = FbxTime::eFrames24;
-	double AnimationsFrameRate(){
-		return FbxTime::GetFrameRate(AnimationsTimeMode);
-	}
-	std::uint32_t AnimStackIndex = 0;
-	static GlobalSettings& Current();
-};

+ 0 - 33
Exporters/FBX/BabylonFbxNative/MatrixDecomposition.h

@@ -1,33 +0,0 @@
-#pragma once
-#include <fbxsdk.h>
-#include "BabylonVertex.h"
-class MatrixDecomposition
-{
-	babylon_vector3 _trans;
-	babylon_vector4 _quat;
-	babylon_vector3 _scaling;
-
-	FbxVector4 _fbxtrans;
-	FbxQuaternion _fbxrot;
-	FbxVector4 _fbxshearing;
-	FbxVector4 _fbxscaling;
-public:
-	const babylon_vector3& translation() { return _trans; }
-	const babylon_vector4& rotationQuaternion() { return _quat; }
-	const babylon_vector3& scaling() { return _scaling; }
-
-
-	const FbxVector4& fbxtrans() { return _fbxtrans; };
-	const FbxQuaternion& fbxrot() { return _fbxrot; };
-	const FbxVector4& fbxshearing() { return _fbxshearing; };
-	const FbxVector4& fbxscaling() { return _fbxscaling; };
-	MatrixDecomposition(const FbxMatrix& mat){
-		
-		double sign;
-		mat.GetElements(_fbxtrans, _fbxrot, _fbxshearing, _fbxscaling, sign);
-		_trans = _fbxtrans;
-		_quat = _fbxrot;
-		_scaling = _fbxscaling;
-	}
-};
-

+ 0 - 45
Exporters/FBX/BabylonFbxNative/NodeHelpers.h

@@ -1,45 +0,0 @@
-#pragma once
-#include <string>
-#include <sstream>
-#include <fbxsdk.h>
-#include <DirectXMath.h>
-
-inline std::wstring getNodeId(FbxNode* node) {
-	auto nId = node->GetUniqueID();
-	std::wstringstream strstream;
-	strstream << nId;
-	auto name = node->GetName();
-	if (name) {
-		strstream << L"_" << name;
-	}
-	return strstream.str();
-}
-
-const double Euler2Rad = 3.141592653589793238462 / 180;
-
-inline FbxMatrix GetGeometryTransformation(FbxNode* inNode)
-{
-	if (!inNode)
-	{
-		throw std::exception("Null for mesh geometry");
-	}
-
-	const FbxVector4 lT = inNode->GetGeometricTranslation(FbxNode::eSourcePivot);
-	const FbxVector4 lR = inNode->GetGeometricRotation(FbxNode::eSourcePivot);
-	const FbxVector4 lS = inNode->GetGeometricScaling(FbxNode::eSourcePivot);
-
-	return FbxMatrix(lT, lR, lS);
-}
-
-inline FbxMatrix ConvertToBabylonCoordinateSystem(const FbxMatrix& origin){
-	FbxVector4 trans;
-	FbxQuaternion rot;
-	FbxVector4 shearing;
-	FbxVector4 scaling;
-	double sign;
-	origin.GetElements(trans, rot, shearing, scaling, sign);
-	trans[2] = -trans[2]; // This negate Z of Translation Component of the matrix
-	rot[0] = -rot[0];
-	rot[1] = -rot[1];
-	return FbxMatrix (trans, rot, scaling);
-}

+ 0 - 37
Exporters/FBX/BabylonFbxNative/ReadMe.txt

@@ -1,37 +0,0 @@
-========================================================================
-    STATIC LIBRARY : BabylonFbxNative Project Overview
-========================================================================
-
-AppWizard has created this BabylonFbxNative library project for you.
-
-This file contains a summary of what you will find in each of the files that
-make up your BabylonFbxNative application.
-
-
-BabylonFbxNative.vcxproj
-    This is the main project file for VC++ projects generated using an Application Wizard.
-    It contains information about the version of Visual C++ that generated the file, and
-    information about the platforms, configurations, and project features selected with the
-    Application Wizard.
-
-BabylonFbxNative.vcxproj.filters
-    This is the filters file for VC++ projects generated using an Application Wizard. 
-    It contains information about the association between the files in your project 
-    and the filters. This association is used in the IDE to show grouping of files with
-    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
-    "Source Files" filter).
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-StdAfx.h, StdAfx.cpp
-    These files are used to build a precompiled header (PCH) file
-    named BabylonFbxNative.pch and a precompiled types file named StdAfx.obj.
-
-/////////////////////////////////////////////////////////////////////////////
-Other notes:
-
-AppWizard uses "TODO:" comments to indicate parts of the source code you
-should add to or customize.
-
-/////////////////////////////////////////////////////////////////////////////

+ 0 - 227
Exporters/FBX/BabylonFbxNative/SkinInfo.cpp

@@ -1,227 +0,0 @@
-#include "stdafx.h"
-#include <iostream>
-#include "SkinInfo.h"
-#include "NodeHelpers.h"
-#include "GlobalSettings.h"
-
-void ComputeBoneHierarchy(const std::vector<FbxNode*>& unsortedFlatListOfNodes,
-	const std::vector<FbxCluster*>& unsortedFlatListOfClusters,
-	std::vector<BoneInfo>& output, std::map<int, int>& clusterIndexToBoneIndex, std::map<int, std::vector<BoneIndexAndWeight>>& controlPointsData, FbxNode* currentRoot = nullptr, int currentRootIndex = -1){
-	for (auto ix = 0u; ix < unsortedFlatListOfNodes.size(); ++ix){
-		auto node = unsortedFlatListOfNodes[ix];
-		auto nodeParent = node->GetParent();
-		if (currentRoot == nullptr){
-			// node is a match if its parent is not in the flat list
-			auto foundParent = std::find(unsortedFlatListOfNodes.begin(), unsortedFlatListOfNodes.end(), nodeParent);
-			if (foundParent != unsortedFlatListOfNodes.end()){
-				continue;
-			}
-		}
-		else{
-			// node is a match if its parent is current root
-			if (currentRoot != nodeParent){
-				continue;
-			}
-		}
-
-		// create boneInfo
-		BoneInfo info;
-		info.cluster = unsortedFlatListOfClusters[ix];
-		info.FbxClusterIndex = ix;
-		info.linkNode = unsortedFlatListOfNodes[ix];
-		info.parentBoneIndex = currentRootIndex;
-		info.name = getNodeId(node);
-		auto boneIndex = static_cast<int>(output.size());
-		output.push_back(info);
-		clusterIndexToBoneIndex[ix] = boneIndex;
-
-		auto controlledPointsCount = info.cluster->GetControlPointIndicesCount();
-		for (auto cpIndex = 0; cpIndex < controlledPointsCount; ++cpIndex){
-			auto controlPoint = info.cluster->GetControlPointIndices()[cpIndex];
-			auto weight = info.cluster->GetControlPointWeights()[cpIndex];
-			BoneIndexAndWeight biw;
-			biw.index = boneIndex;
-			biw.weight = weight;
-			controlPointsData[controlPoint].push_back(biw);
-		}
-		// recursively parse children
-		ComputeBoneHierarchy(unsortedFlatListOfNodes, unsortedFlatListOfClusters, output, clusterIndexToBoneIndex, controlPointsData, node, static_cast<int>(boneIndex));
-	}
-}
-FbxAMatrix NotDecomposedMultiply(const FbxAMatrix& lhs, const FbxAMatrix& rhs){
-	FbxMatrix matL(lhs);
-	FbxMatrix matR(rhs);
-	auto result = matL*matR;
-	return *(FbxAMatrix*) (double*) &result;
-}
-//FbxAMatrix ComputeTotalMatrix(FbxNode* node, FbxTime time = FBXSDK_TIME_INFINITE){
-//
-//}
-SkinInfo::SkinInfo(FbxNode* meshNode) :
-_node(meshNode), _mesh(meshNode->GetMesh()), _skin(nullptr)
-{
-	int deformerCount = _mesh->GetDeformerCount();
-	for (auto ix = 0; ix < deformerCount; ++ix){
-		auto skin = reinterpret_cast<FbxSkin*>(_mesh->GetDeformer(ix, FbxDeformer::eSkin));
-		if (skin){
-			_skin = skin;
-			break;
-		}
-	}
-	if (!_skin){
-		return;
-	}
-
-	std::vector<FbxPose*> bindPoses;
-	auto poseCount = _node->GetScene()->GetPoseCount();
-	for (auto ix = 0; ix < poseCount; ++ix){
-		auto pose = _node->GetScene()->GetPose(ix);
-		if (pose->IsBindPose()){
-			bindPoses.push_back(pose);
-		}
-	}
-
-	std::vector<FbxNode*> unsortedFlatListOfNodes;
-	std::vector<FbxCluster*> unsortedFlatListOfClusters;
-	auto clusterCount = _skin->GetClusterCount();
-	for (auto ix = 0; ix < clusterCount; ++ix){
-		auto cluster = _skin->GetCluster(ix);
-		if (!cluster)
-		{
-			std::cout << "Invalid skin" << std::endl;
-			_skin = nullptr;
-			return;
-		}
-		auto linkNode = cluster->GetLink();
-		if (!linkNode){
-			std::cout << "Invalid skin" << std::endl;
-			_skin = nullptr;
-			return;
-		}
-		unsortedFlatListOfClusters.push_back(cluster);
-		unsortedFlatListOfNodes.push_back(linkNode);
-	}
-
-	ComputeBoneHierarchy(unsortedFlatListOfNodes, unsortedFlatListOfClusters, _bones, _fbxClusterIndexToBoneIndex, _controlPointToBoneIndicesAndWeights);
-	auto deformType = _skin->GetDeformerType();
-
-	auto geometryTransform = GetGeometryTransformation(meshNode);
-	// compute all bones global inverse and global matrix
-	for (auto& bone : _bones){
-		FbxAMatrix transformMatrix;
-		FbxAMatrix transformLinkMatrix;
-		FbxMatrix globalBindposeInverseMatrix;
-
-		bone.cluster->GetTransformMatrix(transformMatrix);	// The transformation of the mesh at binding time
-		bone.cluster->GetTransformLinkMatrix(transformLinkMatrix);	// The transformation of the cluster(joint) at binding time from joint space to world space
-		/*for (auto pose : bindPoses){
-			auto inPoseIndex = pose->Find(bone.linkNode);
-			if (inPoseIndex >= 0){
-				auto tempMat = pose->GetMatrix(inPoseIndex);
-				transformLinkMatrix = *(FbxAMatrix*) (double*) &tempMat;
-				break;
-			}
-		}*/
-		globalBindposeInverseMatrix = FbxMatrix(transformLinkMatrix.Inverse()) * FbxMatrix(transformMatrix) * geometryTransform;
-
-
-		bone.matrixGlobalBindPose = ConvertToBabylonCoordinateSystem(globalBindposeInverseMatrix.Inverse());
-	
-
-		if (bone.parentBoneIndex == -1){
-			bone.matrixLocalBindPose = bone.matrixGlobalBindPose;
-		}
-		else{
-			bone.matrixLocalBindPose =
-				_bones[bone.parentBoneIndex].matrixGlobalBindPose.Inverse()* bone.matrixGlobalBindPose;
-			
-		}
-	}
-
-
-	// compute anim
-	auto animStack = _node->GetScene()->GetCurrentAnimationStack();
-	FbxString animStackName = animStack->GetName();
-	//FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
-	auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
-	auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
-	auto startFrame = animStack->GetLocalTimeSpan().GetStart().GetFrameCount(animTimeMode);
-	auto endFrame = animStack->GetLocalTimeSpan().GetStop().GetFrameCount(animTimeMode);
-	auto animLengthInFrame = endFrame - startFrame + 1;
-
-
-	for (auto ix = 0; ix < animLengthInFrame; ix++){
-		FbxTime currTime;
-		currTime.SetFrame(startFrame + ix, animTimeMode);
-
-
-		auto currTransformOffset = FbxMatrix(meshNode->EvaluateGlobalTransform(currTime)) * geometryTransform;
-		auto currTransformOffsetInverse = currTransformOffset.Inverse();
-
-		// compute global transform and local
-		for (auto& bone : _bones){
-			BoneAnimKeyFrame kf;
-			kf.frame = ix;
-			kf.matrixGlobal = ConvertToBabylonCoordinateSystem(currTransformOffsetInverse*bone.linkNode->EvaluateGlobalTransform(currTime));
-			
-
-
-			if (bone.parentBoneIndex == -1){
-				kf.matrixLocal = kf.matrixGlobal;
-			}
-			else{
-				auto& parentBone = _bones[bone.parentBoneIndex];
-				
-				kf.matrixLocal = //bone.matrixLocalBindPose;
-					parentBone.keyFrames[parentBone.keyFrames.size() - 1].matrixGlobal.Inverse()* kf.matrixGlobal;
-
-			}
-
-
-			bone.keyFrames.push_back(kf);
-		}
-
-	}
-}
-
-
-void SkinInfo::buildBabylonSkeleton(BabylonSkeleton& skel){
-	if (!hasSkin()){
-		return;
-	}
-	skel.name = getNodeId(_node) + L"_skeleton";
-	for (auto& b : _bones){
-		BabylonBone babbone;
-		babbone.index = static_cast<int>(skel.bones.size());
-		//babbone.matrix = ConvertToBabylonCoordinateSystem( b.matrixLocalBindPose);
-		babbone.matrix = b.matrixLocalBindPose;
-		babbone.name = b.name;
-		babbone.parentBoneIndex = b.parentBoneIndex;
-
-		auto animStack = _node->GetScene()->GetCurrentAnimationStack();
-		FbxString animStackName = animStack->GetName();
-		//FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
-		auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
-		auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
-		auto startFrame = animStack->GetLocalTimeSpan().GetStart().GetFrameCount(animTimeMode);
-		auto endFrame = animStack->GetLocalTimeSpan().GetStop().GetFrameCount(animTimeMode);
-		auto animLengthInFrame = endFrame - startFrame + 1;
-
-		auto matrixAnim = std::make_shared<BabylonAnimation<FbxMatrix>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"_matrix", L"_matrix", true, 0, static_cast<int>(animLengthInFrame), true);
-		for (auto& kf : b.keyFrames){
-
-			babylon_animation_key<FbxMatrix> key;
-			key.frame = kf.frame;
-			//key.values = ConvertToBabylonCoordinateSystem(kf.matrixLocal);
-			key.values = kf.matrixLocal;
-			matrixAnim->appendKey(key);
-		}
-
-		babbone.animation = matrixAnim;
-
-
-		skel.bones.push_back(babbone);
-	}
-}
-
-

+ 0 - 79
Exporters/FBX/BabylonFbxNative/SkinInfo.h

@@ -1,79 +0,0 @@
-#pragma once
-#include <fbxsdk.h>
-#include <memory>
-#include <vector>
-#include <map>
-#include <string>
-#include "BabylonSkeleton.h"
-
-struct BoneAnimKeyFrame{
-	int frame;
-	FbxMatrix matrixLocal;
-	FbxMatrix matrixGlobal;
-};
-struct BoneInfo{
-	FbxNode*  linkNode;
-	FbxCluster* cluster;
-	int FbxClusterIndex;
-	int parentBoneIndex;
-	std::wstring name;
-
-	FbxMatrix matrixGlobalBindPose;
-	FbxMatrix matrixLocalBindPose;
-	std::vector<BoneAnimKeyFrame> keyFrames;
-	BoneInfo(const BoneInfo&) = default;
-	BoneInfo(BoneInfo&& moved) :
-		linkNode(std::move(moved.linkNode)),
-		cluster(std::move(moved.cluster)),
-		FbxClusterIndex(std::move(moved.FbxClusterIndex)),
-		parentBoneIndex(std::move(moved.parentBoneIndex)),
-		name(std::move(moved.name)),
-		matrixGlobalBindPose(std::move(moved.matrixGlobalBindPose)),
-		matrixLocalBindPose(std::move(moved.matrixLocalBindPose)),
-		keyFrames(std::move(moved.keyFrames))
-	{
-	}
-	BoneInfo() = default;
-};
-
-struct BoneIndexAndWeight{
-	int index;
-	double weight;
-};
-
-class SkinInfo
-{
-private:
-	FbxNode* _node;
-	FbxMesh* _mesh;
-	FbxSkin* _skin;
-	std::vector<BoneInfo> _bones;
-	std::map<int, int> _fbxClusterIndexToBoneIndex;
-	std::map<int, std::vector<BoneIndexAndWeight>> _controlPointToBoneIndicesAndWeights;
-	
-public:
-	SkinInfo(FbxNode* meshNode);
-
-	SkinInfo(const SkinInfo&) = default;
-	SkinInfo(SkinInfo&& moved) : 
-		_node(std::move(moved._node)),
-		_mesh(std::move(moved._mesh)),
-		_skin(std::move(moved._skin)),
-		_bones(std::move(moved._bones)),
-		_fbxClusterIndexToBoneIndex(std::move(moved._fbxClusterIndexToBoneIndex)),
-		_controlPointToBoneIndicesAndWeights(std::move(moved._controlPointToBoneIndicesAndWeights))
-	{}
-	bool hasSkin() const{
-		return _skin != nullptr;
-	}
-	const std::vector<BoneIndexAndWeight>& controlPointBoneIndicesAndWeights(int cpIndex)const {
-		return _controlPointToBoneIndicesAndWeights.find(cpIndex)->second;
-	}
-
-	int bonesCount() const{
-		return static_cast<int>( _bones.size());
-	}
-
-	void buildBabylonSkeleton(BabylonSkeleton& skel);
-};
-

+ 0 - 21
Exporters/FBX/BabylonFbxNative/StringUtils.h

@@ -1,21 +0,0 @@
-#pragma once
-#include <string>
-#include <Windows.h>
-
-inline std::string wstringToUtf8(const std::wstring& src) {
-	auto size = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), nullptr, 0, nullptr, nullptr);
-	std::string result;
-	result.resize(size, ' ');
-	WideCharToMultiByte(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), &result[0], size, nullptr, nullptr);
-	return result;
-}
-
-
-
-inline std::wstring utf8ToWstring(const std::string& src) {
-	auto size = MultiByteToWideChar(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), nullptr, 0);
-	std::wstring result;
-	result.resize(size, ' ');
-	MultiByteToWideChar(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), &result[0], size);
-	return result;
-}

+ 0 - 50
Exporters/FBX/BabylonFbxNative/babylon_boundingbox.cpp

@@ -1,50 +0,0 @@
-#include "stdafx.h"
-#include "BabylonVertex.h"
-#include <numeric>
-#include <algorithm>
-#include "BabylonCamera.h"
-
-
-babylon_boundingbox::babylon_boundingbox()
-	: _minX(std::numeric_limits<float>::max()),
-	  _minY(std::numeric_limits<float>::max()),
-	  _minZ(std::numeric_limits<float>::max()),
-	  _maxX(std::numeric_limits<float>::min()),
-	  _maxY(std::numeric_limits<float>::min()),
-	  _maxZ(std::numeric_limits<float>::min())
-{
-}
-
-
-babylon_boundingbox::babylon_boundingbox(FbxScene* scene){
-	FbxVector4 vmin, vmax, vcenter;
-	scene->ComputeBoundingBoxMinMaxCenter(vmin, vmax, vcenter);
-	_minX = static_cast<float>(vmin[0]);
-	_minY = static_cast<float>(vmin[1]);
-	_minZ = static_cast<float>(vmin[2]);
-	_maxX = static_cast<float>(vmax[0]);
-	_maxY = static_cast<float>(vmax[1]);
-	_maxZ = static_cast<float>(vmax[2]);
-
-}
-void babylon_boundingbox::addPosition(float x, float y, float z){
-	_minX = std::min(x, _minX);
-	_minY = std::min(y, _minY);
-	_minZ = std::min(z, _minZ);
-
-	_maxX = std::max(x, _maxX);
-	_maxY = std::max(y, _maxY);
-	_maxZ = std::max(z, _maxZ);
-}
-
-babylon_boundingbox::~babylon_boundingbox()
-{
-}
-babylon_boundingbox mergeBoundingBoxes(const std::vector<babylon_boundingbox>& boxes){
-	babylon_boundingbox result;
-	for (const auto& b : boxes){
-		result.addPosition(b.getMin());
-		result.addPosition(b.getMax());
-	}
-	return result;
-}

+ 0 - 11
Exporters/FBX/BabylonFbxNative/packages.config

@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="cpprestsdk" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-</packages>

+ 0 - 8
Exporters/FBX/BabylonFbxNative/stdafx.cpp

@@ -1,8 +0,0 @@
-// stdafx.cpp : source file that includes just the standard includes
-// BabylonFbxNative.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file

+ 0 - 18
Exporters/FBX/BabylonFbxNative/stdafx.h

@@ -1,18 +0,0 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#pragma once
-
-#include "targetver.h"
-
-#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
-
-#include <fbxsdk.h>
-#include <string>
-#include <memory>
-
-
-
-// TODO: reference additional headers your program requires here

+ 0 - 8
Exporters/FBX/BabylonFbxNative/targetver.h

@@ -1,8 +0,0 @@
-#pragma once
-
-// Including SDKDDKVer.h defines the highest available Windows platform.
-
-// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
-// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
-
-#include <SDKDDKVer.h>

+ 0 - 179
Exporters/FBX/FbxExporter/FbxExporter.cpp

@@ -1,179 +0,0 @@
-// FbxExporter.cpp : Defines the entry point for the console application.
-//
-
-#include "stdafx.h"
-#include "..\BabylonFbxNative\FbxSceneLoader.h"
-#include <iostream>
-#include <fstream>
-#include <Windows.h>
-#include <string>
-#include <sstream>
-#include "..\BabylonFbxNative\BabylonScene.h"
-#include "..\BabylonFbxNative\GlobalSettings.h"
-#include "..\BabylonFbxNative\StringUtils.h"
-
-
-
-
-void exportTexture(const std::shared_ptr<BabylonTexture>& tex, const std::wstring& wOutputPath){
-	if (!tex){
-		return;
-	}
-	auto fullPath = tex->fullPath;
-	for (;;){
-		auto indexOfSlash = fullPath.find(L'/');
-		if (indexOfSlash == fullPath.npos){
-			break;
-		}
-		fullPath[indexOfSlash] = L'\\';
-	}
-	auto outputPath = tex->name;
-	for (;;){
-		auto indexOfSlash = outputPath.find(L'/');
-		if (indexOfSlash == outputPath.npos){
-			break;
-		}
-		outputPath[indexOfSlash] = L'\\';
-	}
-	size_t start = 0;
-	for (;;){
-		auto indexOfSlash = outputPath.find(L'\\', start);
-		if (indexOfSlash == outputPath.npos){
-			break;
-		}
-		auto pathToCreate = wOutputPath;
-		if (pathToCreate[pathToCreate.size() - 1] != L'\\'){
-			pathToCreate.push_back(L'\\');
-		}
-		pathToCreate.append(outputPath.begin(), outputPath.begin() + indexOfSlash);
-		CreateDirectory(pathToCreate.c_str(), nullptr);
-		start = indexOfSlash + 1;
-	}
-	auto fullOutputPath = wOutputPath;
-	if (fullOutputPath[fullOutputPath.size() - 1] != L'\\'){
-		fullOutputPath.push_back(L'\\');
-	}
-	fullOutputPath.append(outputPath);
-	CopyFile(fullPath.c_str(), fullOutputPath.c_str(), false);
-}
-
-int _tmain(int argc, _TCHAR* argv[])
-{
-	std::wcout << L"version : 2015.09.14" << std::endl;
-	std::wcout << L"Usage : FbxExporter <path to fbx file> <outdir> [/fps:60|30|24] [/skipemptynodes] [/animstack:\"animstack name\"]" << std::endl;
-	if (argc < 3) {
-		std::wcerr << L"Invalid argument count" << std::endl;
-		return -1;
-	}
-	std::wstring wInputPath(argv[1]);
-	std::wstring wInputDir(argv[1]);
-	std::wstring wInputFileName(argv[1]);
-	auto lastDirSeparator = wInputDir.find_last_of(L'\\');
-	if (lastDirSeparator == wInputDir.npos) {
-		wInputDir = L".";
-	}
-	else {
-		wInputDir.erase(lastDirSeparator);
-		wInputFileName.erase(0, lastDirSeparator + 1);
-	}
-	std::wstring wOutputPath(argv[2]);
-	CreateDirectory(wOutputPath.c_str(), nullptr);
-	bool skipEmptyNodes = false;
-	std::wstring animStackName;
-	for (int i = 3; i < argc; ++i){
-		std::wstring warg = argv[i];
-		if (warg == L"/skipemptynodes") {
-			skipEmptyNodes = true;
-		}
-		else if (warg.find(L"/fps:") == 0){
-			if (warg == L"/fps:60"){
-				GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames60;
-			}
-			else if (warg == L"/fps:30"){
-				GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames30;
-			}
-			else if (warg == L"/fps:24"){
-				GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames24;
-			}
-			else{
-				std::wcerr << L"Unrecognized fps parameter" << std::endl;
-				return -2;
-			}
-		}
-		else if (warg.find(L"/animstack:") == 0) {
-			animStackName = warg.substr(11);
-			
-			if (animStackName.size()>0 && animStackName[0] == L'\"') {
-				animStackName.erase(0, 1);
-			}
-			if (animStackName.size() > 0 && animStackName[animStackName.size() - 1] == L'\"') {
-				animStackName.erase(animStackName.size() - 1, 1);
-			}
-		}
-		
-	}
-	
-
-	FbxSceneLoader sceneLoader(wstringToUtf8(wInputPath));
-	auto animStackCount = sceneLoader.getScene()->GetSrcObjectCount<FbxAnimStack>();
-	if (animStackName.size() == 0) {
-		GlobalSettings::Current().AnimStackIndex = 0;
-	}
-	else {
-		for (auto ix = 0; ix < animStackCount; ++ix) {
-			auto animStack = sceneLoader.getScene()->GetSrcObject<FbxAnimStack>(ix);
-			if (utf8ToWstring(animStack->GetName()) == animStackName) {
-				GlobalSettings::Current().AnimStackIndex = ix;
-			}
-		}
-	}
-	std::wcout << L"Animation stacks : " << std::endl;
-	for (auto ix = 0; ix < animStackCount; ++ix) {
-		auto animStack = sceneLoader.getScene()->GetSrcObject<FbxAnimStack>(ix);
-		if (ix == GlobalSettings::Current().AnimStackIndex) {
-			std::wcout << L"[X] ";
-			sceneLoader.getScene()->SetCurrentAnimationStack(animStack);
-		}
-		else {
-			std::wcout << L"[ ] ";
-		}
-		
-		std::wcout << utf8ToWstring(animStack->GetName());
-		auto ts=animStack->GetLocalTimeSpan();
-		auto start = ts.GetStart();
-		auto stop = ts.GetStop();
-		std::wcout << L"(" << start.GetMilliSeconds() << L" - " << stop.GetMilliSeconds() << L")" << std::endl;
-	}
-
-	auto root = sceneLoader.rootNode();
-
-	BabylonScene babScene(*root, skipEmptyNodes);
-
-	for (auto& mat : babScene.materials()){
-		exportTexture(mat.ambientTexture, wOutputPath);
-		exportTexture(mat.diffuseTexture, wOutputPath);
-		exportTexture(mat.specularTexture, wOutputPath);
-		exportTexture(mat.emissiveTexture, wOutputPath);
-		exportTexture(mat.reflectionTexture, wOutputPath);
-		exportTexture(mat.bumpTexture, wOutputPath);
-		
-	}
-	
-	
-
-	auto json = babScene.toJson();
-	if (L'\\' != *wOutputPath.crbegin()) {
-		wOutputPath.append(L"\\");
-	}
-	wOutputPath.append(wInputFileName);
-
-	auto lastDot = wOutputPath.find_last_of(L'.');
-	wOutputPath.erase(lastDot);
-	wOutputPath.append(L".babylon");
-	DeleteFile(wOutputPath.c_str());
-	std::ofstream stream(wOutputPath);
-	json.serialize(stream);
-	stream.flush();
-	return 0;
-}
-

+ 0 - 207
Exporters/FBX/FbxExporter/FbxExporter.vcxproj

@@ -1,207 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}</ProjectGuid>
-    <SccProjectName>SAK</SccProjectName>
-    <SccAuxPath>SAK</SccAuxPath>
-    <SccLocalPath>SAK</SccLocalPath>
-    <SccProvider>SAK</SccProvider>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>FbxExporter</RootNamespace>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-    <Import Project="..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.targets')" />
-    <Import Project="..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-  </PropertyGroup>
-    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x86\debug;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x86\release;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x64\debug;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x64\release;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="stdafx.h" />
-    <ClInclude Include="targetver.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="FbxExporter.cpp" />
-    <ClCompile Include="stdafx.cpp">
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\BabylonFbxNative\BabylonFbxNative.vcxproj">
-      <Project>{6c145cfb-31ac-4b28-8b74-26680d26a6e3}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
-    <PropertyGroup>
-      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
-    </PropertyGroup>
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn.targets'))" />
-    <Error Condition="!Exists('..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.6.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
-  </Target>
-</Project>

+ 0 - 39
Exporters/FBX/FbxExporter/FbxExporter.vcxproj.filters

@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="stdafx.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="targetver.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="stdafx.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="FbxExporter.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-</Project>

+ 0 - 40
Exporters/FBX/FbxExporter/ReadMe.txt

@@ -1,40 +0,0 @@
-========================================================================
-    CONSOLE APPLICATION : FbxExporter Project Overview
-========================================================================
-
-AppWizard has created this FbxExporter application for you.
-
-This file contains a summary of what you will find in each of the files that
-make up your FbxExporter application.
-
-
-FbxExporter.vcxproj
-    This is the main project file for VC++ projects generated using an Application Wizard.
-    It contains information about the version of Visual C++ that generated the file, and
-    information about the platforms, configurations, and project features selected with the
-    Application Wizard.
-
-FbxExporter.vcxproj.filters
-    This is the filters file for VC++ projects generated using an Application Wizard. 
-    It contains information about the association between the files in your project 
-    and the filters. This association is used in the IDE to show grouping of files with
-    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
-    "Source Files" filter).
-
-FbxExporter.cpp
-    This is the main application source file.
-
-/////////////////////////////////////////////////////////////////////////////
-Other standard files:
-
-StdAfx.h, StdAfx.cpp
-    These files are used to build a precompiled header (PCH) file
-    named FbxExporter.pch and a precompiled types file named StdAfx.obj.
-
-/////////////////////////////////////////////////////////////////////////////
-Other notes:
-
-AppWizard uses "TODO:" comments to indicate parts of the source code you
-should add to or customize.
-
-/////////////////////////////////////////////////////////////////////////////

+ 0 - 11
Exporters/FBX/FbxExporter/packages.config

@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="cpprestsdk" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-  <package id="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" version="2.6.0" targetFramework="native" userInstalled="true" />
-</packages>

+ 0 - 8
Exporters/FBX/FbxExporter/stdafx.cpp

@@ -1,8 +0,0 @@
-// stdafx.cpp : source file that includes just the standard includes
-// FbxExporter.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file

+ 0 - 15
Exporters/FBX/FbxExporter/stdafx.h

@@ -1,15 +0,0 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#pragma once
-
-#include "targetver.h"
-
-#include <stdio.h>
-#include <tchar.h>
-
-
-
-// TODO: reference additional headers your program requires here

+ 0 - 8
Exporters/FBX/FbxExporter/targetver.h

@@ -1,8 +0,0 @@
-#pragma once
-
-// Including SDKDDKVer.h defines the highest available Windows platform.
-
-// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
-// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
-
-#include <SDKDDKVer.h>

+ 0 - 11
Exporters/FBX/FbxRerouteSkeleton/FbxDeleter.h

@@ -1,11 +0,0 @@
-#pragma once
-#include <fbxsdk.h>
-template <typename T>
-struct FbxBaseDeleter{
-	void operator()(T* fbxObject){
-		fbxObject->Destroy();
-	}
-};
-
-struct FbxManagerDeleter : public FbxBaseDeleter<FbxManager>{};
-struct FbxDeleter : public FbxBaseDeleter<FbxObject>{};

+ 0 - 274
Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.cpp

@@ -1,274 +0,0 @@
-// FbxRerouteSkeleton.cpp : Defines the entry point for the console application.
-//
-
-#include "stdafx.h"
-#include <fbxsdk.h>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <Windows.h>
-#include <map>
-#include "FbxDeleter.h"
-#include <memory>
-
-std::string wstringToUtf8(const std::wstring& src){
-	auto size = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), nullptr, 0, nullptr, nullptr);
-	std::string result;
-	result.resize(size, ' ');
-	WideCharToMultiByte(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), &result[0], size, nullptr, nullptr);
-	return result;
-}
-
-void populateNodeMap(std::map<std::string, FbxNode*>& m, FbxNode* currNode){
-	if (currNode == nullptr){
-		return;
-	}
-	m[currNode->GetName()] = currNode;
-	auto mesh = currNode->GetMesh();
-	if (mesh) {
-		currNode->SetNodeAttribute(nullptr);
-	}
-	for (auto ix = 0; ix < currNode->GetChildCount(); ++ix){
-		populateNodeMap(m, currNode->GetChild(ix));
-	}
-}
-
-struct ScopedScene{
-	FbxScene* scene = nullptr;
-	ScopedScene(FbxManager* mgr) :scene(FbxScene::Create(mgr, "TempScene")){}
-	~ScopedScene(){
-		if (scene){
-			scene->Destroy(true);
-		}
-	}
-};
-
-void DeepClone(FbxNode* n, FbxNode* container){
-	auto cloned = n->Clone(FbxObject::ECloneType::eDeepClone, container);
-	for (auto ix = 0; ix < n->GetChildCount(); ++ix){
-		DeepClone(n->GetChild(ix), (FbxNode*) cloned);
-	}
-}
-
-void importAdditionalFile(FbxScene* globalScene, FbxImporter* importer, const std::string& file){
-	importer->Initialize(file.c_str());
-	ScopedScene tempScene(globalScene->GetFbxManager());
-	importer->Import(tempScene.scene);
-	auto tempRootNode = tempScene.scene->GetRootNode();
-
-	std::vector<FbxNode*> childrenToMove;
-	int lNumChildren = tempRootNode->GetChildCount();
-	for (int i = 0; i < lNumChildren; i++) {
-
-		// Obtain a child node from the currently loaded scene.
-		FbxNode* lChildNode = tempRootNode->GetChild(i);
-
-		if (lChildNode){
-			childrenToMove.push_back(lChildNode);
-		}
-	}
-	for (auto item : childrenToMove){
-		//DeepClone(item, globalScene->GetRootNode());
-		globalScene->GetRootNode()->AddChild(item);
-	}
-
-	// Remove the children from the root node.
-	tempScene.scene->GetRootNode()->DisconnectAllSrcObject();
-
-
-	std::vector<FbxObject* > objsToMove;
-	// Move other objects to the reference scene.
-	int lNumSceneObjects = tempScene.scene->GetSrcObjectCount();
-	for (int i = 0; i < lNumSceneObjects; i++) {
-		FbxObject* lObj = tempScene.scene->GetSrcObject(i);
-		auto isAnimStack = lObj->GetClassId() == FbxAnimStack::ClassId;
-		if (lObj == tempScene.scene->GetRootNode() || *lObj == tempScene.scene->GetGlobalSettings() || isAnimStack){
-			// Don't move the root node or the scene's global settings; these
-			// objects are created for every scene.
-			continue;
-		}
-
-		objsToMove.push_back(lObj);
-	}
-
-	for (auto obj : objsToMove){
-		obj->ConnectDstObject(globalScene);
-	}
-
-	tempScene.scene->DisconnectAllSrcObject();
-}
-
-void patchSkins(FbxNode* currentRoot, const std::map<std::string, FbxNode*>& animatedNodes, const std::string& prefix){
-	auto mesh = currentRoot->GetMesh();
-	if (mesh){
-		auto skinCount = mesh->GetDeformerCount(FbxDeformer::EDeformerType::eSkin);
-		for (auto ix = 0; ix < skinCount; ++ix){
-			auto skin = (FbxSkin*) mesh->GetDeformer(ix, FbxDeformer::EDeformerType::eSkin);
-			if (skin){
-				std::vector<FbxCluster*> replacements;
-				auto clusterCount = skin->GetClusterCount();
-				for (auto clusterIx = 0; clusterIx < clusterCount; ++clusterIx){
-					auto cluster = skin->GetCluster(clusterIx);
-					if (cluster){
-						auto linkNode = cluster->GetLink();
-						if (linkNode){
-							auto candidateName = prefix;
-							candidateName.append(linkNode->GetName());
-							auto found = animatedNodes.find(candidateName);
-							if (found != animatedNodes.end()){
-								FbxCluster* newCluster = FbxCluster::Create(currentRoot->GetScene(), "");
-								newCluster->SetLink(found->second);
-								newCluster->SetLinkMode(cluster->GetLinkMode());
-								FbxAMatrix mat;
-								newCluster->SetTransformAssociateModelMatrix(cluster->GetTransformAssociateModelMatrix(mat));
-								newCluster->SetAssociateModel(cluster->GetAssociateModel());
-								newCluster->SetTransformLinkMatrix(cluster->GetTransformLinkMatrix(mat));
-								newCluster->SetTransformMatrix(cluster->GetTransformMatrix(mat));
-								newCluster->SetTransformParentMatrix(cluster->GetTransformParentMatrix(mat));
-
-								auto indicesAndWeightsCount = cluster->GetControlPointIndicesCount();
-								for (auto ix = 0; ix < indicesAndWeightsCount; ++ix){
-									newCluster->AddControlPointIndex(cluster->GetControlPointIndices()[ix], cluster->GetControlPointWeights()[ix]);
-
-								}
-
-
-								replacements.push_back(newCluster);
-							}
-						}
-					}
-				}
-				if (replacements.size() == clusterCount){
-					while (skin->GetClusterCount()>0){
-						auto oldCluster = skin->GetCluster(skin->GetClusterCount() - 1);
-						skin->RemoveCluster(oldCluster);
-						oldCluster->Destroy();
-					}
-					for (auto c : replacements){
-						skin->AddCluster(c);
-					}
-				}
-				else{
-					for (auto c : replacements){
-						c->Destroy();
-					}
-				}
-			}
-		}
-	}
-
-	for (auto ix = 0; ix < currentRoot->GetChildCount(); ++ix){
-		patchSkins(currentRoot->GetChild(ix), animatedNodes, prefix);
-	}
-}
-
-int _tmain(int argc, _TCHAR* argv [])
-{
-	std::cout << "usage : FbxRerouteSkeleton.exe /m:<origin mesh and skeleton data.fbx> /m:<other origin mesh and skeleton data.fbx> /a:<animated skeleton.fbx> /o:<output fbx> [/prefix:<prefix added to each bone in animated skeleton.fbx>]" << std::endl;
-	std::vector<std::string> meshFiles;
-	std::string skeletonFile;
-	std::string outputPath;
-	std::string prefix;
-	for (auto ix = 1; ix < argc; ++ix){
-		std::wstring warg = argv[ix];
-		if (warg.find(L"/m:") == 0){
-			meshFiles.push_back(wstringToUtf8(warg.substr(3)));
-		}
-		else if (warg.find(L"/a:") == 0)
-		{
-			if (skeletonFile.size()>0){
-
-				std::wcout << L"only one animated skeleton file is allowed" << std::endl;
-				return -2;
-			}
-			skeletonFile = wstringToUtf8(warg.substr(3));
-		}
-		else if (warg.find(L"/o:") == 0){
-			if (outputPath.size() > 0){
-
-				std::wcout << L"only one output file is allowed" << std::endl;
-				return -3;
-			}
-
-			CloseHandle(CreateFile(warg.substr(3).c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr));
-			outputPath = wstringToUtf8(warg.substr(3));
-		}
-		else if (warg.find(L"/prefix:") == 0){
-			if (prefix.size() > 0){
-
-				std::wcout << L"only one prefix is allowed" << std::endl;
-				return -4;
-			}
-			prefix = wstringToUtf8(warg.substr(8));
-		}
-		else{
-			std::wcout << L"unrecognized parameter " << warg << std::endl;
-			return -1;
-		}
-	}
-	if (meshFiles.size() == 0){
-
-		std::wcout << L"no origin mesh file" << std::endl;
-		return -5;
-	}
-	if (skeletonFile.size() == 0){
-
-		std::wcout << L"skeleton file unspecified" << std::endl;
-		return -6;
-	}
-	if (outputPath.size() == 0){
-
-		std::wcout << L"output file unspecified" << std::endl;
-		return -7;
-	}
-
-	auto fbxManager = std::unique_ptr<FbxManager, FbxManagerDeleter>( FbxManager::Create());
-	auto iosettings = std::unique_ptr<FbxIOSettings, FbxDeleter>(FbxIOSettings::Create(fbxManager.get(), IOSROOT));
-
-	iosettings->SetBoolProp(IMP_FBX_MATERIAL, true);
-	iosettings->SetBoolProp(IMP_FBX_TEXTURE, true);
-	iosettings->SetBoolProp(IMP_FBX_LINK, true);
-	iosettings->SetBoolProp(IMP_FBX_SHAPE, true);
-	iosettings->SetBoolProp(IMP_FBX_GOBO, true);
-	iosettings->SetBoolProp(IMP_FBX_ANIMATION, true);
-	iosettings->SetBoolProp(IMP_SKINS, true);
-	iosettings->SetBoolProp(IMP_DEFORMATION, true);
-	iosettings->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);
-	iosettings->SetBoolProp(IMP_TAKE, true);
-
-
-	iosettings->SetBoolProp(EXP_FBX_MATERIAL, true);
-	iosettings->SetBoolProp(EXP_FBX_TEXTURE, true);
-	iosettings->SetBoolProp(EXP_MESHPOLY, true);
-	iosettings->SetBoolProp(EXP_FBX_SHAPE, true);
-	iosettings->SetBoolProp(EXP_FBX_GOBO, true);
-	iosettings->SetBoolProp(EXP_FBX_ANIMATION, true);
-	iosettings->SetBoolProp(EXP_SKINS, true);
-	iosettings->SetBoolProp(EXP_DEFORMATION, true);
-	iosettings->SetBoolProp(EXP_FBX_GLOBAL_SETTINGS, true);
-	iosettings->SetBoolProp(EXP_MESHTRIANGLE, true);
-	iosettings->SetBoolProp(EXP_EMBEDTEXTURE, true);
-	fbxManager->SetIOSettings(iosettings.get());
-
-	auto importer = std::unique_ptr<FbxImporter, FbxDeleter> (FbxImporter::Create(fbxManager.get(), "SceneImporter"));
-	importer->Initialize(skeletonFile.c_str(), -1, iosettings.get());
-	auto globalScene = std::unique_ptr<FbxScene, FbxDeleter>(FbxScene::Create(fbxManager.get(), "merged scene"));
-	importer->Import(globalScene.get());
-
-	std::map<std::string, FbxNode*> animatedSkeletonNodesMap;
-	populateNodeMap(animatedSkeletonNodesMap, globalScene->GetRootNode());
-
-	for (auto& f : meshFiles){
-		importAdditionalFile(globalScene.get(), importer.get(), f);
-	}
-
-	patchSkins(globalScene->GetRootNode(), animatedSkeletonNodesMap, prefix);
-
-	auto exporter = std::unique_ptr<FbxExporter, FbxDeleter>(FbxExporter::Create(fbxManager.get(), "SceneExporter"));
-	auto res = exporter->Initialize(outputPath.c_str(), -1, iosettings.get());
-	res = exporter->Export(globalScene.get());
-	auto status = exporter->GetStatus();
-
-	return 0;
-}
-

+ 0 - 169
Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.vcxproj

@@ -1,169 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>FbxRerouteSkeleton</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x86\debug;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x86\release;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x64\debug;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2017.0.1\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2017.0.1\lib\vs2015\x64\release;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>libfbxsdk-md.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>libfbxsdk-md.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>libfbxsdk-md.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>libfbxsdk-md.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="FbxDeleter.h" />
-    <ClInclude Include="stdafx.h" />
-    <ClInclude Include="targetver.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="FbxRerouteSkeleton.cpp" />
-    <ClCompile Include="stdafx.cpp">
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
-    </ClCompile>
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>

+ 0 - 39
Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.vcxproj.filters

@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="stdafx.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="targetver.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="FbxDeleter.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="stdafx.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="FbxRerouteSkeleton.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-</Project>

+ 0 - 40
Exporters/FBX/FbxRerouteSkeleton/ReadMe.txt

@@ -1,40 +0,0 @@
-========================================================================
-    CONSOLE APPLICATION : FbxRerouteSkeleton Project Overview
-========================================================================
-
-AppWizard has created this FbxRerouteSkeleton application for you.
-
-This file contains a summary of what you will find in each of the files that
-make up your FbxRerouteSkeleton application.
-
-
-FbxRerouteSkeleton.vcxproj
-    This is the main project file for VC++ projects generated using an Application Wizard.
-    It contains information about the version of Visual C++ that generated the file, and
-    information about the platforms, configurations, and project features selected with the
-    Application Wizard.
-
-FbxRerouteSkeleton.vcxproj.filters
-    This is the filters file for VC++ projects generated using an Application Wizard. 
-    It contains information about the association between the files in your project 
-    and the filters. This association is used in the IDE to show grouping of files with
-    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
-    "Source Files" filter).
-
-FbxRerouteSkeleton.cpp
-    This is the main application source file.
-
-/////////////////////////////////////////////////////////////////////////////
-Other standard files:
-
-StdAfx.h, StdAfx.cpp
-    These files are used to build a precompiled header (PCH) file
-    named FbxRerouteSkeleton.pch and a precompiled types file named StdAfx.obj.
-
-/////////////////////////////////////////////////////////////////////////////
-Other notes:
-
-AppWizard uses "TODO:" comments to indicate parts of the source code you
-should add to or customize.
-
-/////////////////////////////////////////////////////////////////////////////

+ 0 - 8
Exporters/FBX/FbxRerouteSkeleton/stdafx.cpp

@@ -1,8 +0,0 @@
-// stdafx.cpp : source file that includes just the standard includes
-// FbxRerouteSkeleton.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file

+ 0 - 15
Exporters/FBX/FbxRerouteSkeleton/stdafx.h

@@ -1,15 +0,0 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#pragma once
-
-#include "targetver.h"
-
-#include <stdio.h>
-#include <tchar.h>
-
-
-
-// TODO: reference additional headers your program requires here

+ 0 - 8
Exporters/FBX/FbxRerouteSkeleton/targetver.h

@@ -1,8 +0,0 @@
-#pragma once
-
-// Including SDKDDKVer.h defines the highest available Windows platform.
-
-// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
-// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
-
-#include <SDKDDKVer.h>

+ 0 - 25
Exporters/FBX/FbxTests/FbxTests.cpp

@@ -1,25 +0,0 @@
-// FbxTests.cpp : Defines the entry point for the console application.
-//
-
-#include "stdafx.h"
-#include "..\BabylonFbxNative\FbxSceneLoader.h"
-#include "..\BabylonFbxNative\FbxMeshLoader.h"
-#include "..\BabylonFbxNative\Export.h"
-
-
-int _tmain(int argc, _TCHAR* argv[])
-{
-	std::vector<babylon_mesh<babylon_vertex_normal_uv_color>> meshes;
-	
-	FbxSceneLoader sceneLoader("C:\\ws\\babylon\\BabylonExport\\Test scenes\\Dude\\dude.fbx");
-	auto camera = sceneLoader.GetDefaultCamera();
-	auto spaceshipSettings = sceneLoader.getGlobalSettings();
-	FbxMaterialStore materials(L"C:\\ws\\babylon\\BabylonExport\\Test scenes\\Dude", L".", TextureFormat::Dds);
-	for (int i = 0; i < sceneLoader.getMeshCount(); ++i){
-		meshes.push_back(loadStaticMesh<babylon_vertex_normal_uv_color>(sceneLoader.getFbxMesh(i), sceneLoader.getScene(), materials));
-	}
-	auto json = exportScene(spaceshipSettings, materials.buildMaterialVector(), meshes);
-	auto text = json.serialize();
-	return 0;
-}
-

+ 0 - 123
Exporters/FBX/FbxTests/FbxTests.vcxproj

@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="..\packages\cpprestsdk.2.0.1\build\native\cpprestsdk.props" Condition="Exists('..\packages\cpprestsdk.2.0.1\build\native\cpprestsdk.props')" />
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{F86E88E6-D8E0-4CC6-8B9B-F4CF2363EE20}</ProjectGuid>
-    <SccProjectName>SAK</SccProjectName>
-    <SccAuxPath>SAK</SccAuxPath>
-    <SccLocalPath>SAK</SccLocalPath>
-    <SccProvider>SAK</SccProvider>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>FbxTests</RootNamespace>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2015\include;$(IncludePath)</IncludePath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <IncludePath>$(SolutionDir)\3rdParty\Fbx2015\include;$(IncludePath)</IncludePath>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="stdafx.h" />
-    <ClInclude Include="targetver.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="FbxTests.cpp" />
-    <ClCompile Include="stdafx.cpp">
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\3rdParty\DirectXTex\DirectXTex_Desktop_2013.vcxproj">
-      <Project>{371b9fa9-4c90-4ac6-a123-aced756d6c77}</Project>
-    </ProjectReference>
-    <ProjectReference Include="..\BabylonFbxNative\BabylonFbxNative.vcxproj">
-      <Project>{6c145cfb-31ac-4b28-8b74-26680d26a6e3}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-    <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
-    <Import Project="..\packages\cpprestsdk.2.0.1\build\native\cpprestsdk.targets" Condition="Exists('..\packages\cpprestsdk.2.0.1\build\native\cpprestsdk.targets')" />
-  </ImportGroup>
-  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
-    <PropertyGroup>
-      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
-    </PropertyGroup>
-    <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
-  </Target>
-</Project>

+ 0 - 39
Exporters/FBX/FbxTests/FbxTests.vcxproj.filters

@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="stdafx.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="targetver.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="stdafx.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="FbxTests.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-</Project>

+ 0 - 40
Exporters/FBX/FbxTests/ReadMe.txt

@@ -1,40 +0,0 @@
-========================================================================
-    CONSOLE APPLICATION : FbxTests Project Overview
-========================================================================
-
-AppWizard has created this FbxTests application for you.
-
-This file contains a summary of what you will find in each of the files that
-make up your FbxTests application.
-
-
-FbxTests.vcxproj
-    This is the main project file for VC++ projects generated using an Application Wizard.
-    It contains information about the version of Visual C++ that generated the file, and
-    information about the platforms, configurations, and project features selected with the
-    Application Wizard.
-
-FbxTests.vcxproj.filters
-    This is the filters file for VC++ projects generated using an Application Wizard. 
-    It contains information about the association between the files in your project 
-    and the filters. This association is used in the IDE to show grouping of files with
-    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
-    "Source Files" filter).
-
-FbxTests.cpp
-    This is the main application source file.
-
-/////////////////////////////////////////////////////////////////////////////
-Other standard files:
-
-StdAfx.h, StdAfx.cpp
-    These files are used to build a precompiled header (PCH) file
-    named FbxTests.pch and a precompiled types file named StdAfx.obj.
-
-/////////////////////////////////////////////////////////////////////////////
-Other notes:
-
-AppWizard uses "TODO:" comments to indicate parts of the source code you
-should add to or customize.
-
-/////////////////////////////////////////////////////////////////////////////

+ 0 - 4
Exporters/FBX/FbxTests/packages.config

@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="cpprestsdk" version="2.0.1" targetFramework="Native" />
-</packages>

+ 0 - 8
Exporters/FBX/FbxTests/stdafx.cpp

@@ -1,8 +0,0 @@
-// stdafx.cpp : source file that includes just the standard includes
-// FbxTests.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file

+ 0 - 15
Exporters/FBX/FbxTests/stdafx.h

@@ -1,15 +0,0 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#pragma once
-
-#include "targetver.h"
-
-#include <stdio.h>
-#include <tchar.h>
-
-
-
-// TODO: reference additional headers your program requires here

+ 0 - 0
Exporters/FBX/FbxTests/targetver.h


部分文件因为文件数量过多而无法显示