瀏覽代碼

Merge Babylon/Master

Raanan Weber 9 年之前
父節點
當前提交
2549eb8416
共有 100 個文件被更改,包括 1333 次插入1292 次删除
  1. 4 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Light.cs
  2. 1 1
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Material.cs
  3. 91 20
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs
  4. 4 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.ShadowGenerator.cs
  5. 5 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Texture.cs
  6. 35 6
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs
  7. 7 0
      Exporters/3ds Max/Max2Babylon/Exporter/GlobalVertex.cs
  8. 8 0
      Exporters/3ds Max/Max2Babylon/Forms/ActionsBuilderForm.cs
  9. 6 1
      Exporters/3ds Max/Max2Babylon/Forms/ObjectPropertiesForm.cs
  10. 834 834
      Exporters/3ds Max/Max2Babylon/Tools/Tools.cs
  11. 84 84
      Exporters/3ds Max/Max2Babylon/Tools/VNormal.cs
  12. 182 182
      Exporters/3ds Max/Max2Babylon/Tools/WebServer.cs
  13. 57 42
      Exporters/Blender/io_export_babylon.py
  14. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk.h
  15. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxalloc.h
  16. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxarch.h
  17. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxdebug.h
  18. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxnew.h
  19. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxstdcompliant.h
  20. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxtypes.h
  21. 2 0
      Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxarray.h
  22. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxbitset.h
  23. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxcharptrset.h
  24. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxcontainerallocators.h
  25. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxdynamicarray.h
  26. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxfile.h
  27. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxfolder.h
  28. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxhashmap.h
  29. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxintrusivelist.h
  30. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxmap.h
  31. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxmemorypool.h
  32. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxmultimap.h
  33. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxpair.h
  34. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxredblacktree.h
  35. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxset.h
  36. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxstatus.h
  37. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxstring.h
  38. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxstringlist.h
  39. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxtime.h
  40. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxtimecode.h
  41. 6 2
      Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxutils.h
  42. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxclassid.h
  43. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxconnectionpoint.h
  44. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxdatatypes.h
  45. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxemitter.h
  46. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxevent.h
  47. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxeventhandler.h
  48. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxlistener.h
  49. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxloadingstrategy.h
  50. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxmanager.h
  51. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxmodule.h
  52. 0 60
      Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxobject.h
  53. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxperipheral.h
  54. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxplugin.h
  55. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxplugincontainer.h
  56. 0 54
      Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxproperty.h
  57. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxpropertydef.h
  58. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxpropertyhandle.h
  59. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxpropertypage.h
  60. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxpropertytypes.h
  61. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxquery.h
  62. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxqueryevent.h
  63. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxscopedloadingdirectory.h
  64. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxscopedloadingfilename.h
  65. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxstream.h
  66. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxsymbol.h
  67. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxsystemunit.h
  68. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxxref.h
  69. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxaffinematrix.h
  70. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxdualquaternion.h
  71. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxmath.h
  72. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxmatrix.h
  73. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxquaternion.h
  74. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxtransforms.h
  75. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxvector2.h
  76. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxvector4.h
  77. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/sync/fbxatomic.h
  78. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/sync/fbxclock.h
  79. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/sync/fbxsync.h
  80. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/sync/fbxthread.h
  81. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fbxsdk_def.h
  82. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fbxsdk_nsbegin.h
  83. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fbxsdk_nsend.h
  84. 6 6
      Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fbxsdk_version.h
  85. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladaanimationelement.h
  86. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladaelement.h
  87. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladaiostream.h
  88. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladanamespace.h
  89. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladatokens.h
  90. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladautils.h
  91. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxreadercollada14.h
  92. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxwritercollada14.h
  93. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxio.h
  94. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxreaderfbx5.h
  95. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxreaderfbx6.h
  96. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxreaderfbx7.h
  97. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxwriterfbx5.h
  98. 1 0
      Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbx/fbxwriterfbx6.h
  99. 0 0
      Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxwriterfbx7.h
  100. 0 0
      Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbxbase64coder.h

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

@@ -123,7 +123,11 @@ namespace Max2Babylon
 
                 foreach (var meshNode in maxScene.NodesListBySuperClass(SClass_ID.Geomobject))
                 {
+#if MAX2017
+                    if (meshNode.CastShadows)
+#else
                     if (meshNode.CastShadows == 1)
+#endif
                     {
                         var inList = maxLight.ExclList.FindNode(meshNode) != -1;
 

+ 1 - 1
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Material.cs

@@ -48,7 +48,7 @@ namespace Max2Babylon
                 return;
             }
 
-            var babylonMaterial = new BabylonMaterial
+            var babylonMaterial = new BabylonStandardMaterial
             {
                 name = name,
                 id = id,

+ 91 - 20
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -145,7 +145,7 @@ namespace Max2Babylon
                     refDistance = meshNode.MaxNode.GetFloatProperty("babylonjs_sound_refdistance", 1.0f),
                 };
 
-                var isDirectional = meshNode.MaxNode.GetBoolProperty("babylonjs_sound_directional", 0);
+                var isDirectional = meshNode.MaxNode.GetBoolProperty("babylonjs_sound_directional");
                 
                 if (isDirectional)
                 {
@@ -167,12 +167,18 @@ namespace Max2Babylon
             }
 
             // Misc.
+#if MAX2017
+            babylonMesh.isVisible = meshNode.MaxNode.Renderable;
+            babylonMesh.receiveShadows = meshNode.MaxNode.RcvShadows;
+            babylonMesh.applyFog = meshNode.MaxNode.ApplyAtmospherics;
+#else
             babylonMesh.isVisible = meshNode.MaxNode.Renderable == 1;
-            babylonMesh.pickable = meshNode.MaxNode.GetBoolProperty("babylonjs_checkpickable");
             babylonMesh.receiveShadows = meshNode.MaxNode.RcvShadows == 1;
+            babylonMesh.applyFog = meshNode.MaxNode.ApplyAtmospherics == 1;
+#endif
+            babylonMesh.pickable = meshNode.MaxNode.GetBoolProperty("babylonjs_checkpickable");
             babylonMesh.showBoundingBox = meshNode.MaxNode.GetBoolProperty("babylonjs_showboundingbox");
             babylonMesh.showSubMeshesBoundingBox = meshNode.MaxNode.GetBoolProperty("babylonjs_showsubmeshesboundingbox");
-            babylonMesh.applyFog = meshNode.MaxNode.ApplyAtmospherics == 1;
             babylonMesh.alphaIndex = (int)meshNode.MaxNode.GetFloatProperty("babylonjs_alphaindex", 1000);
 
             // Actions
@@ -186,6 +192,7 @@ namespace Max2Babylon
             var unskinnedMesh = gameMesh;
             IGMatrix skinInitPoseMatrix = Loader.Global.GMatrix.Create(Loader.Global.Matrix3.Create(true));
             List<int> boneIds = null;
+            int nbBones = 0;
             if (isSkinned)
             {
                 bonesCount = skin.TotalSkinBoneCount;
@@ -231,17 +238,25 @@ namespace Max2Babylon
             {
                 if (unskinnedMesh.NumberOfFaces < 1)
                 {
-                    RaiseError(string.Format("Mesh {0} has no face", babylonMesh.name), 2);
+                    RaiseError($"Mesh {babylonMesh.name} has no face", 2);
                 }
 
                 if (unskinnedMesh.NumberOfVerts < 3)
                 {
-                    RaiseError(string.Format("Mesh {0} has not enough vertices", babylonMesh.name), 2);
+                    RaiseError($"Mesh {babylonMesh.name} has not enough vertices", 2);
                 }
 
                 if (unskinnedMesh.NumberOfVerts >= 65536)
                 {
-                    RaiseWarning(string.Format("Mesh {0} has tmore than 65536 vertices which means that it will require specific WebGL extension to be rendered. This may impact portability of your scene on low end devices.", babylonMesh.name), 2);
+                    RaiseWarning($"Mesh {babylonMesh.name} has tmore than 65536 vertices which means that it will require specific WebGL extension to be rendered. This may impact portability of your scene on low end devices.", 2);
+                }
+
+                if (skin != null)
+                {
+                    for (var vertexIndex = 0; vertexIndex < unskinnedMesh.NumberOfVerts; vertexIndex++)
+                    {
+                        nbBones = Math.Max(nbBones, skin.GetNumberOfBones(vertexIndex));
+                    }
                 }
 
                 // Physics
@@ -295,7 +310,11 @@ namespace Max2Babylon
                 bool hasUV2 = false;
                 for (int i = 0; i < mappingChannels.Count; ++i)
                 {
+#if MAX2017
+                    var indexer = i;
+#else
                     var indexer = new IntPtr(i);
+#endif
                     var channelNum = mappingChannels[indexer];
                     if (channelNum == 1)
                     {
@@ -325,7 +344,7 @@ namespace Max2Babylon
 
                 for (int i = 0; i < multiMatsCount; ++i)
                 {
-                    int materialId = meshNode.NodeMaterial == null ? 0 : meshNode.NodeMaterial.GetMaterialID(i);
+                    int materialId = meshNode.NodeMaterial?.GetMaterialID(i) ?? 0;
                     var indexCount = 0;
                     var minVertexIndex = int.MaxValue;
                     var maxVertexIndex = int.MinValue;
@@ -336,7 +355,7 @@ namespace Max2Babylon
                         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);
+                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds, nbBones);
                         }
                     }
                     else
@@ -344,11 +363,17 @@ namespace Max2Babylon
                         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);
-                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds);
+#endif
+                            ExtractFace(skin, unskinnedMesh, vertices, indices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, ref indexCount, ref minVertexIndex, ref maxVertexIndex, face, boneIds, nbBones);
                         }
                     }
 
@@ -367,7 +392,7 @@ namespace Max2Babylon
 
                 if (vertices.Count >= 65536)
                 {
-                    RaiseWarning(string.Format("Mesh {0} has {1} vertices. This may prevent your scene to work on low end devices where 32 bits indice are not supported", babylonMesh.name, vertices.Count), 2);
+                    RaiseWarning($"Mesh {babylonMesh.name} has {vertices.Count} vertices. This may prevent your scene to work on low end devices where 32 bits indice are not supported", 2);
 
                     if (!optimizeVertices)
                     {
@@ -375,7 +400,7 @@ namespace Max2Babylon
                     }
                 }
 
-                RaiseMessage(string.Format("{0} vertices, {1} faces", vertices.Count, indices.Count / 3), 2);
+                RaiseMessage($"{vertices.Count} vertices, {indices.Count/3} faces", 2);
 
                 // Buffers
                 babylonMesh.positions = vertices.SelectMany(v => new[] { v.Position.X, v.Position.Y, v.Position.Z }).ToArray();
@@ -393,6 +418,13 @@ namespace Max2Babylon
                 {
                     babylonMesh.matricesWeights = vertices.SelectMany(v => v.Weights.ToArray()).ToArray();
                     babylonMesh.matricesIndices = vertices.Select(v => v.BonesIndices).ToArray();
+
+                    babylonMesh.numBoneInfluencers = nbBones;
+                    if (nbBones > 4)
+                    {
+                        babylonMesh.matricesWeightsExtra = vertices.SelectMany(v => v.WeightsExtra.ToArray()).ToArray();
+                        babylonMesh.matricesIndicesExtra = vertices.Select(v => v.BonesIndicesExtra).ToArray();
+                    }
                 }
 
                 if (hasColor)
@@ -416,10 +448,16 @@ namespace Max2Babylon
 
             for (var index = 0; index < tabs.Count; index++)
             {
+#if MAX2017
+                var indexer = index;
+#else
                 var indexer = new IntPtr(index);
+#endif
                 var tab = tabs[indexer];
 
+#if !MAX2017
                 Marshal.FreeHGlobal(indexer);
+#endif
 
                 if (meshNode.MaxNode.GetGuid() == tab.GetGuid())
                 {
@@ -485,11 +523,11 @@ namespace Max2Babylon
             babylonScene.MeshesList.Add(babylonMesh);
         }
 
-        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)
+        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, int nbBones)
         {
-            var a = CreateGlobalVertex(unskinnedMesh, face, 0, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
-            var b = CreateGlobalVertex(unskinnedMesh, face, 2, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
-            var c = CreateGlobalVertex(unskinnedMesh, face, 1, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds);
+            var a = CreateGlobalVertex(unskinnedMesh, face, 0, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds, nbBones);
+            var b = CreateGlobalVertex(unskinnedMesh, face, 2, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds, nbBones);
+            var c = CreateGlobalVertex(unskinnedMesh, face, 1, vertices, hasUV, hasUV2, hasColor, hasAlpha, verticesAlreadyExported, skin, boneIds, nbBones);
             indices.Add(a);
             indices.Add(b);
             indices.Add(c);
@@ -587,7 +625,7 @@ namespace Max2Babylon
         }
 
 
-        int CreateGlobalVertex(IIGameMesh mesh, IFaceEx face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, List<GlobalVertex>[] verticesAlreadyExported, IIGameSkin skin, List<int> boneIds)
+        int CreateGlobalVertex(IIGameMesh mesh, IFaceEx face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool hasColor, bool hasAlpha, List<GlobalVertex>[] verticesAlreadyExported, IIGameSkin skin, List<int> boneIds, int nbBones)
         {
             var vertexIndex = (int)face.Vert[facePart];
 
@@ -654,11 +692,11 @@ namespace Max2Babylon
                 float weight0 = 0;
                 float weight1 = 0;
                 float weight2 = 0;
+                float weight3 = 0;
                 int bone0 = bonesCount;
                 int bone1 = bonesCount;
                 int bone2 = bonesCount;
                 int bone3 = bonesCount;
-                int nbBones = skin.GetNumberOfBones(vertexIndex);
 
                 if (nbBones > 0)
                 {
@@ -681,6 +719,7 @@ namespace Max2Babylon
                 if (nbBones > 3)
                 {
                     bone3 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 3).NodeID);
+                    weight3 = skin.GetWeight(vertexIndex, 3);
                 }
 
                 if (nbBones == 0)
@@ -689,13 +728,45 @@ namespace Max2Babylon
                     bone0 = bonesCount;
                 }
 
+                vertex.Weights = Loader.Global.Point4.Create(weight0, weight1, weight2, weight3);
+                vertex.BonesIndices = (bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0;
+
                 if (nbBones > 4)
                 {
-                    RaiseError("Too many bones influences per vertex: " + nbBones + ". Babylon.js only support 4 bones influences per vertex.", 2);
+                    bone0 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 4).NodeID);
+                    weight0 = skin.GetWeight(vertexIndex, 4);
+
+                    weight1 = 0;
+                    weight2 = 0;
+                    weight3 = 0;
+
+                    if (nbBones > 5)
+                    {
+                        bone1 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 5).NodeID);
+                        weight1 = skin.GetWeight(vertexIndex, 5);
+                    }
+
+                    if (nbBones > 6)
+                    {
+                        bone2 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 6).NodeID);
+                        weight2 = skin.GetWeight(vertexIndex, 6);
+                    }
+
+                    if (nbBones > 7)
+                    {
+                        bone3 = boneIds.IndexOf(skin.GetIGameBone(vertexIndex, 7).NodeID);
+                        weight3 = skin.GetWeight(vertexIndex, 7);
+                    }
+
+                    vertex.WeightsExtra = Loader.Global.Point4.Create(weight0, weight1, weight2, weight3);
+                    vertex.BonesIndicesExtra = (bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0;
+
+                    if (nbBones > 8)
+                    {
+                        RaiseError("Too many bones influences per vertex: " + nbBones + ". Babylon.js only support 8 bones influences per vertex.", 2);
+                    }
                 }
 
-                vertex.Weights = Loader.Global.Point4.Create(weight0, weight1, weight2, 1.0 - weight0 - weight1 - weight2);
-                vertex.BonesIndices = (bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0;
             }
 
             if (verticesAlreadyExported != null)

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

@@ -47,7 +47,11 @@ namespace Max2Babylon
 
             foreach (var meshNode in Loader.Core.RootNode.NodesListBySuperClass(SClass_ID.Geomobject))
             {
+#if MAX2017
+                if (meshNode.CastShadows)
+#else
                 if (meshNode.CastShadows == 1)
+#endif
                 {
                     var inList = maxLight.ExclList.FindNode(meshNode) != -1;
 

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

@@ -120,6 +120,11 @@ namespace Max2Babylon
             }
 
             // Bitmap
+            if (texMap.GetParamBlock(0) == null || texMap.GetParamBlock(0).Owner == null)
+            {
+                return null;
+            }
+
             var texture = texMap.GetParamBlock(0).Owner as IBitmapTex;
 
             if (texture == null)

+ 35 - 6
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs

@@ -111,12 +111,22 @@ namespace Max2Babylon
             {
                 var forceSave = Loader.Core.FileSave;
 
-                if (callerForm != null)
-                {
-                    callerForm.BringToFront();
-                }
+                callerForm?.BringToFront();
             }
 
+            // Producer
+            babylonScene.producer = new BabylonProducer
+            {
+                name = "3dsmax",
+#if MAX2017
+                version = "2017",
+#else
+                version = Loader.Core.ProductVersion.ToString(),
+#endif
+                exporter_version = "0.4.5",
+                file = Path.GetFileName(outputFile)
+            };
+
             // Global
             babylonScene.autoClear = true;
             babylonScene.clearColor = Loader.Core.GetBackGround(0, Tools.Forever).ToArray();
@@ -158,9 +168,17 @@ namespace Max2Babylon
             var camerasTab = gameScene.GetIGameNodeByType(Autodesk.Max.IGameObject.ObjectTypes.Camera);
             for (int ix = 0; ix < camerasTab.Count; ++ix)
             {
+#if MAX2017
+                var indexer = ix;
+#else
                 var indexer = new IntPtr(ix);
+#endif
                 var cameraNode = camerasTab[indexer];
+
+#if !MAX2017
                 Marshal.FreeHGlobal(indexer);
+#endif
+                
                 ExportCamera(gameScene, cameraNode, babylonScene);
 
                 if (mainCamera == null && babylonScene.CamerasList.Count > 0)
@@ -197,7 +215,7 @@ namespace Max2Babylon
                         babylonScene.fogColor = fog.GetColor(0).ToArray();
                         babylonScene.fogMode = 3;
                     }
-#if !MAX2015 && !MAX2016
+#if !MAX2015 && !MAX2016 && !MAX2017
                     else
                     {
                         var paramBlock = atmospheric.GetReference(0) as IIParamBlock;
@@ -222,9 +240,16 @@ namespace Max2Babylon
             var progression = 10.0f;
             for (int ix = 0; ix < meshes.Count; ++ix)
             {
+#if MAX2017
+                var indexer = ix;
+#else
                 var indexer = new IntPtr(ix);
+#endif
                 var meshNode = meshes[indexer];
+
+#if !MAX2017
                 Marshal.FreeHGlobal(indexer);
+#endif
                 ExportMesh(gameScene, meshNode, babylonScene);
 
 
@@ -251,7 +276,11 @@ namespace Max2Babylon
             var lightNodes = gameScene.GetIGameNodeByType(Autodesk.Max.IGameObject.ObjectTypes.Light);
             for (var i = 0; i < lightNodes.Count; ++i)
             {
-                ExportLight(gameScene, lightNodes[new IntPtr(i)], babylonScene);
+#if MAX2017
+                ExportLight(gameScene, lightNodes[i], babylonScene);
+#else
+                    ExportLight(gameScene, lightNodes[new IntPtr(i)], babylonScene);
+#endif
                 CheckCancelled();
             }
 

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

@@ -12,6 +12,8 @@ namespace Max2Babylon
         public IPoint2 UV2 { get; set; }
         public int BonesIndices { get; set; }
         public IPoint4 Weights { get; set; }
+        public int BonesIndicesExtra { get; set; }
+        public IPoint4 WeightsExtra { get; set; }
         public float[] Color { get; set; }
 
         public override int GetHashCode()
@@ -58,6 +60,11 @@ namespace Max2Babylon
                 return false;
             }
 
+            if (WeightsExtra != null && !other.WeightsExtra.IsAlmostEqualTo(WeightsExtra, Tools.Epsilon))
+            {
+                return false;
+            }
+
             if (Color != null && !other.Color.IsAlmostEqualTo(Color, Tools.Epsilon))
             {
                 return false;

+ 8 - 0
Exporters/3ds Max/Max2Babylon/Forms/ActionsBuilderForm.cs

@@ -56,7 +56,11 @@ namespace Max2Babylon
             object[] names = new object[list.Count];
             for (int i = 0; i < list.Count; i++)
             {
+#if MAX2017
+                var indexer = i;
+#else
                 var indexer = new IntPtr(i);
+#endif
                 var node = list[indexer];
                 names[i] = node.MaxNode.Name;
             }
@@ -68,7 +72,11 @@ namespace Max2Babylon
             object[] names = new object[list.Count];
             for (int i = 0; i < list.Count; i++)
             {
+#if MAX2017
+                var indexer = i;
+#else
                 var indexer = new IntPtr(i);
+#endif
                 var node = list[indexer].MaxNode;
                 string soundFile = "";
 

+ 6 - 1
Exporters/3ds Max/Max2Babylon/Forms/ObjectPropertiesForm.cs

@@ -58,7 +58,12 @@ namespace Max2Babylon
             {
                 var node = Loader.Core.GetSelNode(index);
 
-                if (node.ObjectRef != null && node.ObjectRef.Eval(0).Obj.SuperClassID == SClass_ID.Geomobject)
+                if (node.ObjectRef != null && 
+                    (
+                    node.ObjectRef.Eval(0).Obj.SuperClassID == SClass_ID.Geomobject
+                    ||
+                    node.ObjectRef.Eval(0).Obj.SuperClassID == SClass_ID.Helper
+                    ))
                 {
                     objects.Add(node);
                 }

文件差異過大導致無法顯示
+ 834 - 834
Exporters/3ds Max/Max2Babylon/Tools/Tools.cs


+ 84 - 84
Exporters/3ds Max/Max2Babylon/Tools/VNormal.cs

@@ -1,84 +1,84 @@
-using Autodesk.Max;
-using SharpDX;
-
-namespace Max2Babylon
-{
-    public class VNormal
-    {
-        Vector3 norm;
-        uint smooth;
-        VNormal next;
-        bool init;
-
-        public VNormal()
-        {
-            smooth = 0;
-            next = null;
-            init = false;
-            norm = new Vector3(0, 0, 0);
-        }
-
-        public VNormal(Vector3 n, uint s)
-        {
-            next = null;
-            init = true;
-            norm = n;
-            smooth = s;
-        }
-
-        public void AddNormal(Vector3 n, uint s)
-        {
-            if (((s & smooth) == 0) && init)
-            {
-                if (next != null)
-                    next.AddNormal(n, s);
-                else
-                {
-                    next = new VNormal(n, s);
-                }
-            }
-            else
-            {
-                norm += n;
-                smooth |= s;
-                init = true;
-            }
-        }
-
-        public IPoint3 GetNormal(uint s)
-        {
-            if (((smooth & s) != 0) || next == null)
-                return norm.ToPoint3();
-
-            return next.GetNormal(s);
-        }
-
-        // Normalize each normal in the list
-        public void Normalize()
-        {
-            VNormal ptr = next;
-            VNormal prev = this;
-
-            while (ptr != null)
-            {
-                if ((ptr.smooth & smooth) != 0)
-                {
-                    norm += ptr.norm;
-                    prev.next = ptr.next;
-                    ptr = prev.next;
-                }
-                else
-                {
-                    prev = ptr;
-                    ptr = ptr.next;
-                }
-            }
-            norm.Normalize();
-
-            if (next != null)
-            {
-                next.Normalize();
-            }
-        }
-    }
-}
+using Autodesk.Max;
+using SharpDX;
+
+namespace Max2Babylon
+{
+    public class VNormal
+    {
+        Vector3 norm;
+        uint smooth;
+        VNormal next;
+        bool init;
+
+        public VNormal()
+        {
+            smooth = 0;
+            next = null;
+            init = false;
+            norm = new Vector3(0, 0, 0);
+        }
+
+        public VNormal(Vector3 n, uint s)
+        {
+            next = null;
+            init = true;
+            norm = n;
+            smooth = s;
+        }
+
+        public void AddNormal(Vector3 n, uint s)
+        {
+            if (((s & smooth) == 0) && init)
+            {
+                if (next != null)
+                    next.AddNormal(n, s);
+                else
+                {
+                    next = new VNormal(n, s);
+                }
+            }
+            else
+            {
+                norm += n;
+                smooth |= s;
+                init = true;
+            }
+        }
+
+        public IPoint3 GetNormal(uint s)
+        {
+            if (((smooth & s) != 0) || next == null)
+                return norm.ToPoint3();
+
+            return next.GetNormal(s);
+        }
+
+        // Normalize each normal in the list
+        public void Normalize()
+        {
+            VNormal ptr = next;
+            VNormal prev = this;
+
+            while (ptr != null)
+            {
+                if ((ptr.smooth & smooth) != 0)
+                {
+                    norm += ptr.norm;
+                    prev.next = ptr.next;
+                    ptr = prev.next;
+                }
+                else
+                {
+                    prev = ptr;
+                    ptr = ptr.next;
+                }
+            }
+            norm.Normalize();
+
+            if (next != null)
+            {
+                next.Normalize();
+            }
+        }
+    }
+}

+ 182 - 182
Exporters/3ds Max/Max2Babylon/Tools/WebServer.cs

@@ -1,182 +1,182 @@
-using System;
-using System.IO;
-using System.Net;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-
-namespace Max2Babylon
-{
-    public static class WebServer
-    {
-        private static readonly HttpListener listener;
-        private static Task runningTask;
-
-        const string HtmlResponseText = @"
-<!doctype html>
-<html>
-
-<head>
-    <title>Babylon.js</title>
-    <script type='text/javascript' src='http://www.babylonjs.com/oimo.js'></script>
-    <script type='text/javascript' src='http://www.babylonjs.com/cannon.js'></script>
-    <script type='text/javascript' src='http://www.babylonjs.com/babylon.js'></script>
-    <style type='text/css'>
-        html, body, div, canvas {
-            width: 100%;
-            height: 100%;
-            padding: 0;
-            margin: 0;
-            overflow: hidden;
-        }
-
-        #debugLayerButton {
-            position: absolute;
-            border: white solid 1px;
-            background: rgba(128, 128, 128, 0.3);
-            color: white;
-            left: 50%;
-            width: 100px;
-            margin-left:-50px;
-            bottom: 10px;
-        }
-    </style>
-</head>
-
-<body>
-    <canvas id='canvas'></canvas>
-    <button id='debugLayerButton'>Debug layer</button>
-    <script type='text/javascript'>
-        var canvas = document.getElementById('canvas');
-        var engine = new BABYLON.Engine(canvas, true);
-       
-        BABYLON.SceneLoader.Load('', '###SCENE###', engine, function (newScene) {
-            newScene.activeCamera.attachControl(canvas);
-
-            engine.runRenderLoop(function() {
-                newScene.render();
-            });
-
-            window.addEventListener('resize', function () {
-                engine.resize();
-            });
-
-            document.getElementById('debugLayerButton').addEventListener('click', function () {
-                if (newScene.debugLayer.isVisible()) {
-                    newScene.debugLayer.hide();
-                } else {
-                    newScene.debugLayer.show();
-                }
-            });
-        });
-    </script>
-</body>
-</html>";
-
-        public const int Port = 45478;
-
-        public static bool IsSupported { get; private set; }
-
-        static WebServer()
-        {
-            try
-            {
-                listener = new HttpListener();
-
-                if (!HttpListener.IsSupported)
-                {
-                    IsSupported = false;
-                    return;
-                }
-
-                listener.Prefixes.Add("http://localhost:" + Port + "/");
-                listener.Start();
-
-
-                runningTask = Task.Run(() => Listen());
-
-                IsSupported = true;
-            }
-            catch
-            {
-                IsSupported = false;
-            }
-        }
-
-        public static string SceneFilename { get; set; }
-        public static string SceneFolder { get; set; }
-        static Random r = new Random();
-        static void Listen()
-        {
-            try
-            {
-                while (listener.IsListening)
-                {
-                    var context = listener.GetContext();
-                    var request = context.Request;
-                    var url = request.Url;
-
-                    context.Response.AddHeader("Cache-Control", "no-cache");
-                    if (string.IsNullOrEmpty(url.LocalPath) || url.LocalPath == "/")
-                    {
-
-                        var responseText = HtmlResponseText.Replace("###SCENE###", SceneFilename+"?once="+r.Next());
-                        WriteResponse(context, responseText);
-                    }
-                    else
-                    {
-                        try
-                        {
-                            var path = Path.Combine(SceneFolder, HttpUtility.UrlDecode(url.PathAndQuery.Substring(1)));
-                            var questionMarkIndex = path.IndexOf("?");
-                            if (questionMarkIndex != -1)
-                            {
-                                path = path.Substring(0, questionMarkIndex);
-                            }
-                            var hashIndex = path.IndexOf("#");
-                            if (hashIndex != -1)
-                            {
-                                path = path.Substring(0, hashIndex);
-                            }
-                            var buffer = File.ReadAllBytes(path);
-                            WriteResponse(context, buffer);
-                        }
-                        catch
-                        {
-                            context.Response.StatusCode = 404;
-                            context.Response.Close();
-                        }
-                    }
-
-                }
-            }
-            catch
-            {
-            }
-        }
-
-        static void WriteResponse(HttpListenerContext context, string s)
-        {
-            WriteResponse(context.Response, s);
-        }
-
-        static void WriteResponse(HttpListenerContext context, byte[] buffer)
-        {
-            WriteResponse(context.Response, buffer);
-        }
-
-        static void WriteResponse(HttpListenerResponse response, string s)
-        {
-            byte[] buffer = Encoding.UTF8.GetBytes(s);
-            WriteResponse(response, buffer);
-        }
-
-        static void WriteResponse(HttpListenerResponse response, byte[] buffer)
-        {
-            response.ContentLength64 = buffer.Length;
-            Stream output = response.OutputStream;
-            output.Write(buffer, 0, buffer.Length);
-            output.Close();
-        }
-    }
-}
+using System;
+using System.IO;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+
+namespace Max2Babylon
+{
+    public static class WebServer
+    {
+        private static readonly HttpListener listener;
+        private static Task runningTask;
+
+        const string HtmlResponseText = @"
+<!doctype html>
+<html>
+
+<head>
+    <title>Babylon.js</title>
+    <script type='text/javascript' src='http://www.babylonjs.com/oimo.js'></script>
+    <script type='text/javascript' src='http://www.babylonjs.com/cannon.js'></script>
+    <script type='text/javascript' src='http://www.babylonjs.com/babylon.js'></script>
+    <style type='text/css'>
+        html, body, div, canvas {
+            width: 100%;
+            height: 100%;
+            padding: 0;
+            margin: 0;
+            overflow: hidden;
+        }
+
+        #debugLayerButton {
+            position: absolute;
+            border: white solid 1px;
+            background: rgba(128, 128, 128, 0.3);
+            color: white;
+            left: 50%;
+            width: 100px;
+            margin-left:-50px;
+            bottom: 10px;
+        }
+    </style>
+</head>
+
+<body>
+    <canvas id='canvas'></canvas>
+    <button id='debugLayerButton'>Debug layer</button>
+    <script type='text/javascript'>
+        var canvas = document.getElementById('canvas');
+        var engine = new BABYLON.Engine(canvas, true);
+       
+        BABYLON.SceneLoader.Load('', '###SCENE###', engine, function (newScene) {
+            newScene.activeCamera.attachControl(canvas);
+
+            engine.runRenderLoop(function() {
+                newScene.render();
+            });
+
+            window.addEventListener('resize', function () {
+                engine.resize();
+            });
+
+            document.getElementById('debugLayerButton').addEventListener('click', function () {
+                if (newScene.debugLayer.isVisible()) {
+                    newScene.debugLayer.hide();
+                } else {
+                    newScene.debugLayer.show();
+                }
+            });
+        });
+    </script>
+</body>
+</html>";
+
+        public const int Port = 45478;
+
+        public static bool IsSupported { get; private set; }
+
+        static WebServer()
+        {
+            try
+            {
+                listener = new HttpListener();
+
+                if (!HttpListener.IsSupported)
+                {
+                    IsSupported = false;
+                    return;
+                }
+
+                listener.Prefixes.Add("http://localhost:" + Port + "/");
+                listener.Start();
+
+
+                runningTask = Task.Run(() => Listen());
+
+                IsSupported = true;
+            }
+            catch
+            {
+                IsSupported = false;
+            }
+        }
+
+        public static string SceneFilename { get; set; }
+        public static string SceneFolder { get; set; }
+        static Random r = new Random();
+        static void Listen()
+        {
+            try
+            {
+                while (listener.IsListening)
+                {
+                    var context = listener.GetContext();
+                    var request = context.Request;
+                    var url = request.Url;
+
+                    context.Response.AddHeader("Cache-Control", "no-cache");
+                    if (string.IsNullOrEmpty(url.LocalPath) || url.LocalPath == "/")
+                    {
+
+                        var responseText = HtmlResponseText.Replace("###SCENE###", SceneFilename+"?once="+r.Next());
+                        WriteResponse(context, responseText);
+                    }
+                    else
+                    {
+                        try
+                        {
+                            var path = Path.Combine(SceneFolder, HttpUtility.UrlDecode(url.PathAndQuery.Substring(1)));
+                            var questionMarkIndex = path.IndexOf("?");
+                            if (questionMarkIndex != -1)
+                            {
+                                path = path.Substring(0, questionMarkIndex);
+                            }
+                            var hashIndex = path.IndexOf("#");
+                            if (hashIndex != -1)
+                            {
+                                path = path.Substring(0, hashIndex);
+                            }
+                            var buffer = File.ReadAllBytes(path);
+                            WriteResponse(context, buffer);
+                        }
+                        catch
+                        {
+                            context.Response.StatusCode = 404;
+                            context.Response.Close();
+                        }
+                    }
+
+                }
+            }
+            catch
+            {
+            }
+        }
+
+        static void WriteResponse(HttpListenerContext context, string s)
+        {
+            WriteResponse(context.Response, s);
+        }
+
+        static void WriteResponse(HttpListenerContext context, byte[] buffer)
+        {
+            WriteResponse(context.Response, buffer);
+        }
+
+        static void WriteResponse(HttpListenerResponse response, string s)
+        {
+            byte[] buffer = Encoding.UTF8.GetBytes(s);
+            WriteResponse(response, buffer);
+        }
+
+        static void WriteResponse(HttpListenerResponse response, byte[] buffer)
+        {
+            response.ContentLength64 = buffer.Length;
+            Stream output = response.OutputStream;
+            output.Write(buffer, 0, buffer.Length);
+            output.Close();
+        }
+    }
+}

+ 57 - 42
Exporters/Blender/io_export_babylon.py

@@ -1,7 +1,7 @@
 bl_info = {
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (4, 4, 4),
+    'version': (4, 5, 0),
     'blender': (2, 75, 0),
     'location': 'File > Export > Babylon.js (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',
@@ -601,7 +601,7 @@ class FCurveAnimatable:
                 scaleAnimation = VectorAnimation(object, 'scaling', 'scale')
 
             self.ranges = []
-            frameOffset = bpy.context.scene.frame_start - 1
+            frameOffset = 0
 
             for action in bpy.data.actions:
                 # get the range / assigning the action to the object
@@ -610,18 +610,18 @@ class FCurveAnimatable:
                     continue
 
                 if supportsRotation:
-                    hasData = rotAnimation.append_range(object, frameOffset)
+                    hasData = rotAnimation.append_range(object, animationRange)
 
                 if supportsPosition:
-                    hasData |= posAnimation.append_range(object, frameOffset)
+                    hasData |= posAnimation.append_range(object, animationRange)
 
                 if supportsScaling:
-                    hasData |= scaleAnimation.append_range(object, frameOffset)
+                    hasData |= scaleAnimation.append_range(object, animationRange)
 
                 if hasData:
-                    Main.log('processing action ' + action.name, 3)
+                    Main.log('processing action ' + animationRange.to_string(), 3)
                     self.ranges.append(animationRange)
-                    frameOffset = animationRange.frame_end + 1
+                    frameOffset = animationRange.frame_end
 
             #Set Animations
             self.animations = []
@@ -1330,7 +1330,7 @@ class Bone:
         self.parentBone = bone.parent
 
         self.matrix_world = skeleton.matrix_world
-        self.matrix = self.get_bone_matrix()
+        self.matrix = self.get_bone_matrix(True)
 
         parentId = -1
         if (bone.parent):
@@ -1347,24 +1347,24 @@ class Bone:
             self.previousBoneMatrix = None
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def append_animation_pose(self, frame, force = False):
-        currentBoneMatrix = self.get_bone_matrix()
+        currentBoneMatrix = self.get_bone_matrix(True)
 
         if (force or not same_matrix4(currentBoneMatrix, self.previousBoneMatrix)):
             self.animation.frames.append(frame)
             self.animation.values.append(currentBoneMatrix)
             self.previousBoneMatrix = currentBoneMatrix
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    def set_rest_pose(self, editBone, matrix_world):
-        self.rest = Bone.get_matrix(editBone, self.matrix_world)
+    def set_rest_pose(self, editBone):
+        self.rest = Bone.get_matrix(editBone, self.matrix_world, True)
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    def get_bone_matrix(self):
-        return Bone.get_matrix(self.posedBone, self.matrix_world)
+    def get_bone_matrix(self, doParentMult):
+        return Bone.get_matrix(self.posedBone, self.matrix_world, doParentMult)
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     @staticmethod
-    def get_matrix(bone, matrix_world):
+    def get_matrix(bone, matrix_world, doParentMult):
         SystemMatrix = mathutils.Matrix.Scale(-1, 4, mathutils.Vector((0, 0, 1))) * mathutils.Matrix.Rotation(math.radians(-90), 4, 'X')
 
-        if (bone.parent):
+        if (bone.parent and doParentMult):
             return (SystemMatrix * matrix_world * bone.parent.matrix).inverted() * (SystemMatrix * matrix_world * bone.matrix)
         else:
             return SystemMatrix * matrix_world * bone.matrix
@@ -1401,34 +1401,35 @@ class Skeleton:
 
         if (skeleton.animation_data):
             self.ranges = []
-            frameOffset = scene.frame_start - 1
+            frameOffset = 0
             for action in bpy.data.actions:
                 # get the range / assigning the action to the object
                 animationRange = AnimationRange.actionPrep(skeleton, action, FRAME_BASED_ANIMATION, frameOffset)
                 if animationRange is None:
                     continue
 
-                Main.log('processing action ' + action.name, 2)
+                Main.log('processing action ' + animationRange.to_string(), 2)
                 self.ranges.append(animationRange)
 
-                for frame in animationRange.frames:
-                    bpy.context.scene.frame_set(frame)
+                nFrames = len(animationRange.frames_in)
+                for idx in range(nFrames):
+                    bpy.context.scene.frame_set(animationRange.frames_in[idx])
+                    firstOrLast = idx == 0 or idx == nFrames - 1
 
                     for bone in self.bones:
-                        bone.append_animation_pose(frame + frameOffset, frame == animationRange.highest_frame)
+                        bone.append_animation_pose(animationRange.frames_out[idx], firstOrLast)
 
-                frameOffset = animationRange.frame_end + 1
+                frameOffset = animationRange.frame_end
 
         # mode_set's only work when there is an active object, switch bones to edit mode to rest position
         scene.objects.active = skeleton
         bpy.ops.object.mode_set(mode='EDIT')
-        matrix_world = skeleton.matrix_world
 
         # you need to access edit_bones from skeleton.data not skeleton.pose when in edit mode
         for editBone in skeleton.data.edit_bones:
             for myBoneObj in self.bones:
                 if editBone.name == myBoneObj.name:
-                    myBoneObj.set_rest_pose(editBone, matrix_world)
+                    myBoneObj.set_rest_pose(editBone)
                     break
 
         bpy.ops.object.mode_set(mode='OBJECT')
@@ -2230,11 +2231,21 @@ class BakedMaterial(Material):
 class AnimationRange:
     # constructor called by the static actionPrep method
     def __init__(self, name, frames, frameOffset):
+        # process input args to members
         self.name = name
-        self.highest_frame = frames[len(frames) - 1]
-        self.frame_start = frameOffset + 1
-        self.frame_end   = frameOffset + self.highest_frame
-        self.frames = frames
+        self.frames_in = frames        
+        self.frame_start = AnimationRange.nextStartingFrame(frameOffset)
+        
+        self.frames_out = []
+        for frame in self.frames_in:
+            self.frames_out.append(self.frame_start + frame)
+            
+        highest_idx = len(self.frames_in) - 1
+        self.highest_frame_in = self.frames_in [highest_idx]
+        self.frame_end        = self.frames_out[highest_idx]
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    def to_string(self):
+        return self.name + ': ' + ' in[' + format_int(self.frames_in[0]) + ' - ' + format_int(self.highest_frame_in) + '], out[' + format_int(self.frame_start) + ' - ' + format_int(self.frame_end) + ']'
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def to_scene_file(self, file_handler):
         file_handler.write('{')
@@ -2246,14 +2257,14 @@ class AnimationRange:
     @staticmethod
     def actionPrep(object, action, includeAllFrames, frameOffset):
         # assign the action & test if there is any data for that action for this object
-#        bpy.context.scene.objects.active = object
         object.animation_data.action = action
         if len(object.animation_data.action.fcurves) == 0:
             return None
 
         if includeAllFrames:
-            frame_start, frame_end = [int(x) for x in action.frame_range]
-            frames = range(frame_start, frame_end)
+            frame_start = int(action.frame_range[0])
+            frame_end   = int(action.frame_range[1])
+            frames = range(frame_start, frame_end + 1) # range is not inclusive with 2nd arg
 
         else:
             # capture built up from fcurves
@@ -2266,6 +2277,16 @@ class AnimationRange:
             frames = sorted(frames)
 
         return AnimationRange(action.name, frames, frameOffset)
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    @staticmethod
+    def nextStartingFrame(frameOffset):
+        if frameOffset == 0: return 0
+        
+        # ensure a gap of at least 5 frames, starting on an even multiple of 10
+        frameOffset += 4
+        remainder = frameOffset % 10
+        return frameOffset + 10 - remainder
+        
 #===============================================================================
 class Animation:
     def __init__(self, dataType, loopBehavior, name, propertyInBabylon, attrInBlender = None, mult = 1, xOffset = 0):
@@ -2285,21 +2306,15 @@ class Animation:
         self.values = [] # vector3 for ANIMATIONTYPE_VECTOR3 & matrices for ANIMATIONTYPE_MATRIX
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # a separate method outside of constructor, so can be called once for each Blender Action object participates in
-    def append_range(self, object, frameOffset):
+    def append_range(self, object, animationRange):
         # action already assigned, always using poses, not every frame, build up again filtering by attrInBlender
-        frames = dict()
-        for fcurve in object.animation_data.action.fcurves:
-            if fcurve.data_path == self.attrInBlender:
-                for key in fcurve.keyframe_points:
-                    frame = key.co.x
-                    frames[frame] = 1
+        for idx in range(len(animationRange.frames_in)):
+            bpy.context.scene.frame_set(animationRange.frames_in[idx])
 
-        for Frame in sorted(frames):
-            self.frames.append(Frame + frameOffset)
-            bpy.context.scene.frame_set(int(Frame))
+            self.frames.append(animationRange.frames_out[idx])
             self.values.append(self.get_attr(object))
 
-        return len(frames) > 0
+        return len(animationRange.frames_in) > 0
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # for auto animate
     def get_first_frame(self):
@@ -2389,7 +2404,7 @@ def format_f(num):
     s = s.rstrip('0') # ignore trailing zeroes
     s = s.rstrip('.') # ignore trailing .
     return '0' if s == '-0' else s
-
+    
 def format_matrix4(matrix):
     tempMatrix = matrix.copy()
     tempMatrix.transpose()

Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/arch/fbxalloc.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxalloc.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/arch/fbxarch.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxarch.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/arch/fbxdebug.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxdebug.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/arch/fbxnew.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxnew.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/arch/fbxstdcompliant.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxstdcompliant.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/arch/fbxtypes.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/arch/fbxtypes.h


+ 2 - 0
Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxarray.h

@@ -283,6 +283,8 @@ public:
 	* \return \c true if successful, otherwise \c false. */
 	inline void RemoveRange(const int pIndex, const int pCount)
 	{
+		FBX_ASSERT_RETURN(pIndex >= 0);
+		FBX_ASSERT_RETURN(pCount >= 0);
 		if( pIndex + pCount < mSize )
 		{
 			memmove(&mArray[pIndex], &mArray[pIndex + pCount], (mSize - pIndex - pCount) * sizeof(T));

Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxbitset.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxbitset.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxcharptrset.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxcharptrset.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxcontainerallocators.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxcontainerallocators.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxdynamicarray.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxdynamicarray.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxfile.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxfile.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxfolder.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxfolder.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxhashmap.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxhashmap.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxintrusivelist.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxintrusivelist.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxmap.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxmap.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxmemorypool.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxmemorypool.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxmultimap.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxmultimap.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxpair.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxpair.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxredblacktree.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxredblacktree.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxset.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxset.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxstatus.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxstatus.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxstring.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxstring.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxstringlist.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxstringlist.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxtime.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxtime.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxtimecode.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/base/fbxtimecode.h


+ 6 - 2
Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/base/fbxutils.h

@@ -35,8 +35,12 @@
 FBXSDK_DLL FbxString FbxGetSystemTempPath();
 
 /** Override the system temporary folder path name.
-* \param pPathUTF8 The system temporary folder to use for override. */
-FBXSDK_DLL void FbxSetSystemTempPath(const char* pPathUTF8);
+  * \param pPathUTF8 The system temporary folder to use for override.
+  * \return True if the system temporary folder path has been set and False otherwise.
+  * \remark The system temporary folder is limited to _MAX_PATH characters. Trying to set
+  * a longer value will fail and the current system temporary folder path is left unchanged.
+  */
+FBXSDK_DLL bool FbxSetSystemTempPath(const char* pPathUTF8);
 
 /** Retrieve the working directory of the system in UTF8 format.
 * \return A string that contain the current working directory of the system. */

Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxclassid.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxclassid.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxconnectionpoint.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxconnectionpoint.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxdatatypes.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxdatatypes.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxemitter.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxemitter.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxevent.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxevent.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxeventhandler.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxeventhandler.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxlistener.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxlistener.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxloadingstrategy.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxloadingstrategy.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxmanager.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxmanager.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxmodule.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxmodule.h


+ 0 - 60
Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxobject.h

@@ -161,12 +161,6 @@ class FBXSDK_DLL FbxObject : public FbxEmitter
 public:
 	//! \name General Object Management
 	//@{
-		/** Test if this class is a hierarchical children of the specified class type. This is the standard method to differentiate object classes. (Deprecated, please use Is<Type>() instead.)
-		* \param pClassId The class type to test against self.
-		* \return \c true if the object is a hierarchical children of the type specified.
-		* \remark This function will perform a complete search until it reaches the top level class, but it will stop as soon as one ClassId matches the test. */
-		FBX_DEPRECATED inline bool Is(const FbxClassId& pClassId) const { return GetClassId().Is(pClassId); }
-
 		/** Templated test if this class is a hierarchical children of the specified class type.
 		* \return \c true if the object is a hierarchical children of the type specified.
 		* \remark This function will perform a complete search until it reaches the top level class, but it will stop as soon as one ClassId matches the test. */
@@ -450,12 +444,6 @@ public:
 		  */
 		inline bool DisconnectAllSrcObject(const FbxCriteria& pCriteria) { return RootProperty.DisconnectAllSrcObject(pCriteria); }
 
-		/** Disconnects this object from all source objects of a specific class type. (Deprecated, please use DisconnectAllSrcObject<Type>() instead.)
-		  * \param pClassId The specific class type.
-		  * \return \c True if it disconnects all source objects successfully, \c false otherwise.
-		  */
-		FBX_DEPRECATED inline bool DisconnectAllSrcObject(FbxClassId pClassId) { return RootProperty.DisconnectAllSrcObject(FbxCriteria::ObjectType(pClassId)); }
-
 		/** Returns the number of source objects with which this object connects.
 		  * \return The number of source objects with which this object connects. 
 		  */
@@ -467,12 +455,6 @@ public:
 		  */
 		inline int GetSrcObjectCount(const FbxCriteria& pCriteria) const { return RootProperty.GetSrcObjectCount(pCriteria); }
 
-		/** Returns the number of source objects of the specific class type with which this object connects. (Deprecated, please use GetSrcObjectCount<Type>() instead.)
-		  * \param pClassId The specific class type.
-		  * \return The number of source objects of the specific class type with which this object connects.
-		  */
-		FBX_DEPRECATED inline int GetSrcObjectCount(FbxClassId pClassId) const { return RootProperty.GetSrcObjectCount(FbxCriteria::ObjectType(pClassId)); }
-
 		/** Returns the source object with which this object connects at the specified index.
 		  * \param pIndex The specified index whose default value is 0.
 		  * \return The source object at the specified index, NULL if not found.
@@ -486,13 +468,6 @@ public:
 		  */
 		inline FbxObject* GetSrcObject(const FbxCriteria& pCriteria, int pIndex=0) const { return RootProperty.GetSrcObject(pCriteria,pIndex); }
 
-		/** Returns the source object of the specified class type at the specified index with which this object connects. (Deprecated, please use GetSrcObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \param pIndex The specified index whose default value is 0.
-		  * \return The source object of the specified class type at the specified index, NULL if not found.
-		  */
-		FBX_DEPRECATED inline FbxObject* GetSrcObject(FbxClassId pClassId, int pIndex=0) const { return RootProperty.GetSrcObject(FbxCriteria::ObjectType(pClassId), pIndex); }
-
 		/** Searches the source object with the specified name, starting at the specified index.
 		  * \param pName The object name.
 		  * \param pStartIndex The start index.
@@ -508,14 +483,6 @@ public:
 		  */
 		inline FbxObject* FindSrcObject(const FbxCriteria& pCriteria, const char* pName, int pStartIndex=0) const { return RootProperty.FindSrcObject(pCriteria,pName,pStartIndex); }
 
-		/** Searches the source object with the specified name which is also the specified class type, starting at the specified index. (Deprecated, please use FindSrcObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \param pName The object name.
-		  * \param pStartIndex The start index.
-		  * \return The source object with the name, NULL if not found.
-		  */
-		FBX_DEPRECATED inline FbxObject* FindSrcObject(FbxClassId pClassId, const char* pName, int pStartIndex=0) const { return RootProperty.FindSrcObject(FbxCriteria::ObjectType(pClassId), pName, pStartIndex); }
-
 		/** Disconnects this object from all source objects of the specified class type.
 		* \return \c true if it disconnects all source objects successfully, \c false otherwise. */
 		template <class T> inline bool DisconnectAllSrcObject() { return RootProperty.DisconnectAllSrcObject(FbxCriteria::ObjectType(T::ClassId)); }
@@ -588,12 +555,6 @@ public:
 		  */
 		inline bool DisconnectAllDstObject(const FbxCriteria& pCriteria) { return RootProperty.DisconnectAllDstObject(pCriteria); }
 
-		/** Disconnects this object from all destination objects of the specified class type. (Deprecated, please use DisconnectAllDstObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \return \c True if it disconnects all destination objects of the specified class type successfully, \c false otherwise.
-		  */
-		FBX_DEPRECATED inline bool DisconnectAllDstObject(FbxClassId pClassId) { return RootProperty.DisconnectAllDstObject(FbxCriteria::ObjectType(pClassId)); }
-
 		/** Returns the number of destination objects with which this object connects. 
 		  * \return The number of destination objects with which this object connects. 
 		  */
@@ -605,12 +566,6 @@ public:
 		  */
 		inline int GetDstObjectCount(const FbxCriteria& pCriteria) const { return RootProperty.GetDstObjectCount(pCriteria); }
 
-		/** Returns the number of destination objects of the specified class type with which this object connects. (Deprecated, please use GetDstObjectCount<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \return The number of destination objects of the specified class type with which this object connects. 
-		  */
-		FBX_DEPRECATED inline int GetDstObjectCount(FbxClassId pClassId) const { return RootProperty.GetDstObjectCount(FbxCriteria::ObjectType(pClassId)); }
-
 		/** Returns the destination object at the specified index with which this object connects.
 		  * \param pIndex The specified index whose default value is 0.
 		  * \return The destination object at the specified index, NULL if not found.
@@ -624,13 +579,6 @@ public:
 		  */
 		inline FbxObject* GetDstObject(const FbxCriteria& pCriteria, int pIndex=0) const { return RootProperty.GetDstObject(pCriteria,pIndex); }
 
-		/** Returns the destination object of the specified class type with which this object connects at the specified index. (Deprecated, please use GetDstObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \param pIndex The specified index whose default value is 0.
-		  * \return The destination object of the specified class type at the specified index, NULL if not found.
-		  */
-		FBX_DEPRECATED inline FbxObject* GetDstObject(FbxClassId pClassId, int pIndex=0) const { return RootProperty.GetDstObject(FbxCriteria::ObjectType(pClassId), pIndex); }
-
 		/** Searches the destination object with the specified name, starting at the specified index.
 		  * \param pName The object name.
 		  * \param pStartIndex The start index.
@@ -646,14 +594,6 @@ public:
 		  */
 		inline FbxObject* FindDstObject(const FbxCriteria& pCriteria, const char* pName, int pStartIndex=0) const { return RootProperty.FindDstObject(pCriteria,pName,pStartIndex); }
 
-		/** Searches the destination object with the specified name which is the specified class type, starting at the specified index. (Deprecated, please use FindDstObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \param pName The object name.
-		  * \param pStartIndex The start index.
-		  * \return The destination object with the name, NULL if not found.
-		  */
-		FBX_DEPRECATED inline FbxObject* FindDstObject(FbxClassId pClassId, const char* pName,int pStartIndex=0) const { return RootProperty.FindDstObject(FbxCriteria::ObjectType(pClassId), pName, pStartIndex); }
-
 		/** Disconnects this object from all destination objects of the specified class type.
 		* \return \c true if it disconnects all destination objects of the specified class type successfully, \c false otherwise. */
 		template <class T> inline bool DisconnectAllDstObject() { return RootProperty.DisconnectAllDstObject(FbxCriteria::ObjectType(T::ClassId)); }

Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxperipheral.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxperipheral.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxplugin.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxplugin.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxplugincontainer.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxplugincontainer.h


+ 0 - 54
Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxproperty.h

@@ -703,12 +703,6 @@ public:
 		  */
 		bool DisconnectAllSrcObject(const FbxCriteria& pCriteria);
 
-		/** Disconnects this property from all the source objects of a specific class type. (Deprecated, please use DisconnectAllSrcObject<Type>() instead.)
-		  * \param pClassId The specific class type.
-		  * \return \c True if it disconnects all the source objects successfully, \c false otherwise.
-		  */
-		FBX_DEPRECATED bool DisconnectAllSrcObject(const FbxClassId& pClassId);
-
 		/** Returns the number of source objects with which this property connects.
 		  * \return The number of source objects with which this property connects. 
 		  */
@@ -720,12 +714,6 @@ public:
 		  */
 		int GetSrcObjectCount(const FbxCriteria& pCriteria) const;
 
-		/** Returns the number of source objects of the specific class type with which this property connects. (Deprecated, please use GetSrcObjectCount<Type>() instead.)
-		  * \param pClassId The specific class type.
-		  * \return The number of source objects of the specific class type with which this property connects.
-		  */
-		FBX_DEPRECATED int GetSrcObjectCount(const FbxClassId& pClassId) const;
-
 		/** Returns the source object at the specified index with which this property connects.
 		  * \param pIndex The specified index whose default value is 0.
 		  * \return The source object at the specified index, NULL if not found.
@@ -739,13 +727,6 @@ public:
 		  */
 		FbxObject* GetSrcObject(const FbxCriteria& pCriteria, const int pIndex=0) const;
 
-		/** Returns the source object of the specified class type at the specified index with which this property connects. (Deprecated, please use GetSrcObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \param pIndex The specified index whose default value is 0.
-		  * \return The source object of the specified class type at the specified index, NULL if not found.
-		  */
-		FBX_DEPRECATED FbxObject* GetSrcObject(const FbxClassId& pClassId, const int pIndex=0) const;
-
 		/** Searches the source object with the specified name, starting with the specified index.
 		  * \param pName The object name.
 		  * \param pStartIndex The start index.
@@ -761,14 +742,6 @@ public:
 		  */
 		FbxObject* FindSrcObject(const FbxCriteria& pCriteria, const char* pName, const int pStartIndex=0) const;
 
-		/** Searches the source object with the specified name which is of the specified class type, starting with the specified index. (Deprecated, please use FindSrcObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \param pName The object name.
-		  * \param pStartIndex The start index.
-		  * \return The source object with the name, NULL if not found.
-		  */
-		FBX_DEPRECATED FbxObject* FindSrcObject(const FbxClassId& pClassId, const char* pName, const int pStartIndex=0) const;
-
 		/** Disconnects this property from all source objects of the specified class type.
 		  * \tparam T The specified class type.
 		  * \return \c True if it disconnects all source objects successfully, \c false otherwise.
@@ -857,12 +830,6 @@ public:
 		  */
 		bool DisconnectAllDstObject(const FbxCriteria& pCriteria);
 
-		/** Disconnects this property from all the destination objects of the specified class type. (Deprecated, please use DisconnectAllDstObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \return \c True if it disconnects all the destination objects successfully, \c false otherwise.
-		  */
-		FBX_DEPRECATED bool DisconnectAllDstObject(const FbxClassId& pClassId);
-
 		/** Returns the number of destination objects with which this property connects. 
 		  * \return The number of destination objects with which this property connects. 
 		  */
@@ -874,12 +841,6 @@ public:
 		  */
 		int GetDstObjectCount(const FbxCriteria& pCriteria) const;
 
-		/** Returns the number of destination objects of the specified class type with which this property connects. (Deprecated, please use GetDstObjectCount<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \return The number of destination objects of the specified class type with which this property connects. 
-		  */
-		FBX_DEPRECATED int GetDstObjectCount(const FbxClassId& pClassId) const;
-
 		/** Returns the destination object at the specified index with which this property connects.
 		  * \param pIndex The specified index whose default value is 0.
 		  * \return The destination object at the specified index, NULL if not found.
@@ -893,13 +854,6 @@ public:
 		  */
 		FbxObject* GetDstObject(const FbxCriteria& pCriteria, const int pIndex=0) const;
 
-		/** Returns the destination object of the specified class type at the specified index with which this property connects. (Deprecated, please use GetDstObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \param pIndex The specified index whose default value is 0.
-		  * \return The destination object of the specified class type at the specified index, NULL if not found.
-		  */
-		FBX_DEPRECATED FbxObject* GetDstObject(const FbxClassId& pClassId, const int pIndex=0) const;
-
 		/** Searches the destination object with the specified name, starting with the specified index.
 		  * \param pName The object name.
 		  * \param pStartIndex The start index.
@@ -915,14 +869,6 @@ public:
 		  */
 		FbxObject* FindDstObject(const FbxCriteria& pCriteria, const char* pName, const int pStartIndex=0) const;
 
-		/** Searches the destination object with the specified name which is of the specified class type, starting with the specified index. (Deprecated, please use FindDstObject<Type>() instead.)
-		  * \param pClassId The specified class type.
-		  * \param pName The object name.
-		  * \param pStartIndex The start index.
-		  * \return The destination object with the name, NULL if not found.
-		  */
-		FBX_DEPRECATED FbxObject* FindDstObject(const FbxClassId& pClassId, const char* pName, const int pStartIndex=0) const;
-
 		/** Disconnects this property from all the destination objects of the specified class type.
 		  * \tparam T The specified class type.
 		  * \return \c True if it disconnects all the destination objects successfully, \c false otherwise.

Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxpropertydef.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxpropertydef.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxpropertyhandle.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxpropertyhandle.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxpropertypage.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxpropertypage.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxpropertytypes.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxpropertytypes.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxquery.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxquery.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxqueryevent.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxqueryevent.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxscopedloadingdirectory.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxscopedloadingdirectory.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxscopedloadingfilename.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxscopedloadingfilename.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxstream.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxstream.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxsymbol.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxsymbol.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxsystemunit.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxsystemunit.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/fbxxref.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/fbxxref.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/math/fbxaffinematrix.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxaffinematrix.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/math/fbxdualquaternion.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxdualquaternion.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/math/fbxmath.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxmath.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/math/fbxmatrix.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxmatrix.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/math/fbxquaternion.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxquaternion.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/math/fbxtransforms.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxtransforms.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/math/fbxvector2.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxvector2.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/math/fbxvector4.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/math/fbxvector4.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/sync/fbxatomic.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/sync/fbxatomic.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/sync/fbxclock.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/sync/fbxclock.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/sync/fbxsync.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/sync/fbxsync.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/core/sync/fbxthread.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/core/sync/fbxthread.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fbxsdk_def.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fbxsdk_def.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fbxsdk_nsbegin.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fbxsdk_nsbegin.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fbxsdk_nsend.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fbxsdk_nsend.h


+ 6 - 6
Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fbxsdk_version.h

@@ -20,14 +20,14 @@
 #define _FBXSDK_VERSION_H_
 
 //FBX SDK version defines
-#define FBXSDK_VERSION_MAJOR	2016		//<! Integer, version major number
-#define FBXSDK_VERSION_MINOR	1			//<! Integer, version minor number
-#define FBXSDK_VERSION_POINT	0			//<! Integer, version point number
+#define FBXSDK_VERSION_MAJOR	2017		//<! Integer, version major number
+#define FBXSDK_VERSION_MINOR	0			//<! Integer, version minor number
+#define FBXSDK_VERSION_POINT	1			//<! Integer, version point number
 #define FBXSDK_VERSION_NAME		"Release"	//<! String, version name, example: Alpha, Beta, RC, Release
 
-#define FBXSDK_VERSION_YEAR     2015		//<! Integer, release date year
-#define FBXSDK_VERSION_MONTH	06			//<! Integer, release date month
-#define FBXSDK_VERSION_DAY		30			//<! Integer, release date day
+#define FBXSDK_VERSION_YEAR     2016		//<! Integer, release date year
+#define FBXSDK_VERSION_MONTH	04			//<! Integer, release date month
+#define FBXSDK_VERSION_DAY		14			//<! Integer, release date day
 
 #ifndef FBXSDK_VERSION_REVISION
 	#define FBXSDK_VERSION_REVISION	0		//<! Integer, version revision number, set by build environment. Do not edit here!

Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/collada/fbxcolladaanimationelement.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladaanimationelement.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/collada/fbxcolladaelement.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladaelement.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/collada/fbxcolladaiostream.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladaiostream.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/collada/fbxcolladanamespace.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladanamespace.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/collada/fbxcolladatokens.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladatokens.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/collada/fbxcolladautils.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxcolladautils.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/collada/fbxreadercollada14.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxreadercollada14.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/collada/fbxwritercollada14.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/collada/fbxwritercollada14.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbx/fbxio.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxio.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbx/fbxreaderfbx5.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxreaderfbx5.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbx/fbxreaderfbx6.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxreaderfbx6.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbx/fbxreaderfbx7.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxreaderfbx7.h


Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbx/fbxwriterfbx5.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxwriterfbx5.h


+ 1 - 0
Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbx/fbxwriterfbx6.h

@@ -298,6 +298,7 @@ private:
     FbxArray<ModifiedPropertyInfo*> mModifiedProperties;
     void ReplaceUnsupportedProperties(FbxScene* pScene, bool pPreprocessPass, int pFormatV);
 	void StoreUnsupportedProperty(FbxObject* pObject, FbxProperty& pProperty);
+    bool IsLeafRoll(const FbxString& pNameWithoutNameSpacePrefix);
 
     FbxProgress* mProgress;
     bool mProgressPause;

Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbx/fbxwriterfbx7.h → Exporters/FBX/3rdParty/Fbx2017.0.1/include/fbxsdk/fileio/fbx/fbxwriterfbx7.h


+ 0 - 0
Exporters/FBX/3rdParty/Fbx2016.1/include/fbxsdk/fileio/fbxbase64coder.h


部分文件因文件數量過多而無法顯示