浏览代码

No default camera
Fix coordinate system conversion
Fix multimaterial when only one submaterial is used
Handle dummy

noalak 8 年之前
父节点
当前提交
091158aa47

+ 4 - 18
Exporters/3ds Max/BabylonExport.Entities/BabylonScene.cs

@@ -46,11 +46,11 @@ namespace BabylonExport.Entities
 
         [DataMember]
         public float[] physicsGravity { get; set; }
-
-        [DataMember]
+        
+        [DataMember(EmitDefaultValue = false)]
         public BabylonCamera[] cameras { get; set; }
-
-        [DataMember]
+        
+        [DataMember(EmitDefaultValue = false)]
         public string activeCameraID { get; set; }
 
         [DataMember]
@@ -144,20 +144,6 @@ namespace BabylonExport.Entities
 
                 // Default camera init gives infinit values
                 // Indeed, float.MaxValue - float.MinValue always leads to infinity
-                // Is MaxVector and MinVector update missing?
-                MaxVector = new BabylonVector3
-                {
-                    X = 1,
-                    Y = 1,
-                    Z = 1
-                };
-                MinVector = new BabylonVector3
-                {
-                    X = -1,
-                    Y = -1,
-                    Z = -1
-                };
-
                 var distanceVector = MaxVector - MinVector;
                 var midPoint = MinVector + distanceVector / 2;
                 camera.target = midPoint.ToArray();

+ 1 - 1
Exporters/3ds Max/BabylonExport.Entities/BabylonVector3.cs

@@ -40,7 +40,7 @@ namespace BabylonExport.Entities
 
         public BabylonQuaternion toQuaternionGltf()
         {
-            BabylonQuaternion babylonQuaternion = RotationYawPitchRollToRefBabylon(X, Y, Z);
+            BabylonQuaternion babylonQuaternion = RotationYawPitchRollToRefBabylon(X, -Y, -Z);
             // Doing following computation is ugly but works
             // The goal is to switch from left to right handed coordinate system
             // Swap X and Y

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

@@ -37,6 +37,8 @@ namespace Max2Babylon
 
             // Transform
             gltfNode.translation = babylonCamera.position;
+            // Switch from left to right handed coordinate system
+            //gltfNode.translation[0] *= -1;
             if (babylonCamera.rotationQuaternion != null)
             {
                 gltfNode.rotation = babylonCamera.rotationQuaternion;

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

@@ -36,6 +36,8 @@ namespace Max2Babylon
 
             // Transform
             gltfNode.translation = babylonLight.position;
+            // Switch from left to right handed coordinate system
+            //gltfNode.translation[0] *= -1;
             // No rotation defined for babylon light. Use identity instead.
             gltfNode.rotation = new float[4] { 0, 0, 0, 1 };
             // No scaling defined for babylon light. Use identity instead.

+ 24 - 13
Exporters/3ds Max/Max2Babylon/2017/Exporter/BabylonExporter.GLTFExporter.Mesh.cs

@@ -10,7 +10,7 @@ namespace Max2Babylon
 {
     partial class BabylonExporter
     {
-        private GLTFMesh ExportMesh(BabylonMesh babylonMesh, GLTF gltf, GLTFNode gltfParentNode, BabylonScene babylonScene)
+        private GLTFNode ExportMesh(BabylonMesh babylonMesh, GLTF gltf, GLTFNode gltfParentNode, BabylonScene babylonScene)
         {
             RaiseMessage("GLTFExporter.Mesh | Export mesh named: " + babylonMesh.name, 1);
 
@@ -41,6 +41,9 @@ namespace Max2Babylon
 
             // Transform
             gltfNode.translation = babylonMesh.position;
+            // TODO - Choose between this method and the extra root node
+            // Switch from left to right handed coordinate system
+            //gltfNode.translation[0] *= -1;
             if (babylonMesh.rotationQuaternion != null)
             {
                 gltfNode.rotation = babylonMesh.rotationQuaternion;
@@ -63,16 +66,20 @@ namespace Max2Babylon
             // --- Mesh from babylon ----
             // --------------------------
 
+            if (babylonMesh.positions == null)
+            {
+                RaiseMessage("GLTFExporter.Mesh | Mesh is a dummy", 2);
+                return gltfNode;
+            }
+
             RaiseMessage("GLTFExporter.Mesh | Mesh from babylon", 2);
             // Retreive general data from babylon mesh
             int nbVertices = babylonMesh.positions.Length / 3;
-            bool isMultimaterial = babylonMesh.subMeshes.Length > 1;
             bool hasUV = babylonMesh.uvs != null && babylonMesh.uvs.Length > 0;
             bool hasUV2 = babylonMesh.uvs2 != null && babylonMesh.uvs2.Length > 0;
             bool hasColor = babylonMesh.colors != null && babylonMesh.colors.Length > 0;
 
             RaiseMessage("GLTFExporter.Mesh | nbVertices=" + nbVertices, 3);
-            RaiseMessage("GLTFExporter.Mesh | isMultimaterial=" + isMultimaterial, 3);
             RaiseMessage("GLTFExporter.Mesh | hasUV=" + hasUV, 3);
             RaiseMessage("GLTFExporter.Mesh | hasUV2=" + hasUV2, 3);
             RaiseMessage("GLTFExporter.Mesh | hasColor=" + hasColor, 3);
@@ -83,6 +90,8 @@ namespace Max2Babylon
             {
                 GLTFGlobalVertex globalVertex = new GLTFGlobalVertex();
                 globalVertex.Position = createIPoint3(babylonMesh.positions, indexVertex);
+                // Switch from left to right handed coordinate system
+                //globalVertex.Position.X *= -1;
                 globalVertex.Normal = createIPoint3(babylonMesh.normals, indexVertex);
                 if (hasUV)
                 {
@@ -111,12 +120,12 @@ namespace Max2Babylon
             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;
-            }
+            //for (int i = 0; i < babylonIndices.Count; i += 3)
+            //{
+            //    var tmp = babylonIndices[i];
+            //    babylonIndices[i] = babylonIndices[i + 2];
+            //    babylonIndices[i + 2] = tmp;
+            //}
 
 
             // --------------------------
@@ -341,14 +350,16 @@ namespace Max2Babylon
                 {
                     // Retreive the babylon material
                     var babylonMaterialId = babylonMesh.materialId;
-                    if (isMultimaterial)
+                    var babylonMaterials = new List<BabylonMaterial>(babylonScene.materials);
+                    var babylonMaterial = babylonMaterials.Find(_babylonMaterial => _babylonMaterial.id == babylonMaterialId);
+                    if (babylonMaterial == null)
                     {
+                        // It's a multi material
                         var babylonMultiMaterials = new List<BabylonMultiMaterial>(babylonScene.multiMaterials);
                         var babylonMultiMaterial = babylonMultiMaterials.Find(_babylonMultiMaterial => _babylonMultiMaterial.id == babylonMesh.materialId);
                         babylonMaterialId = babylonMultiMaterial.materials[babylonSubMesh.materialIndex];
+                        babylonMaterial = babylonMaterials.Find(_babylonMaterial => _babylonMaterial.id == babylonMaterialId);
                     }
-                    var babylonMaterials = new List<BabylonMaterial>(babylonScene.materials);
-                    var babylonMaterial = babylonMaterials.Find(_babylonMaterial => _babylonMaterial.id == babylonMaterialId);
 
                     // Update primitive material index
                     var indexMaterial = babylonMaterialsToExport.FindIndex(_babylonMaterial => _babylonMaterial == babylonMaterial);
@@ -466,7 +477,7 @@ namespace Max2Babylon
                 });
             }
 
-            return gltfMesh;
+            return gltfNode;
         }
 
         private IPoint2 createIPoint2(float[] array, int index)

+ 35 - 10
Exporters/3ds Max/Max2Babylon/2017/Exporter/BabylonExporter.GLTFExporter.cs

@@ -1,6 +1,7 @@
 using BabylonExport.Entities;
 using GLTFExport.Entities;
 using Newtonsoft.Json;
+using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
@@ -12,6 +13,7 @@ namespace Max2Babylon
     internal partial class BabylonExporter
     {
         List<BabylonMaterial> babylonMaterialsToExport;
+        GLTFNode gltfRootNode;
 
         public void ExportGltf(BabylonScene babylonScene, string outputFile, bool generateBinary)
         {
@@ -39,10 +41,7 @@ namespace Max2Babylon
             gltf.scenes = scenes;
 
             // Nodes
-            List<BabylonNode> babylonNodes = new List<BabylonNode>();
-            babylonNodes.AddRange(babylonScene.meshes);
-            babylonNodes.AddRange(babylonScene.lights);
-            babylonNodes.AddRange(babylonScene.cameras);
+            List<BabylonNode> babylonNodes = getNodes(babylonScene);
 
             // Root nodes
             RaiseMessage("GLTFExporter | Exporting nodes");
@@ -59,6 +58,19 @@ namespace Max2Babylon
                 CheckCancelled();
             });
 
+            // TODO - Choose between this method and the reverse of X axis
+            // Switch from left to right handed coordinate system
+            var tmpNodesList = new List<int>(scene.NodesList);
+            var rootNode = new BabylonMesh
+            {
+                name = "root",
+                rotation = new float[] { 0, (float)Math.PI, 0 },
+                scaling = new float[] { 1, 1, -1 }
+            };
+            scene.NodesList.Clear();
+            gltfRootNode = ExportMesh(rootNode as BabylonMesh, gltf, null, babylonScene);
+            gltfRootNode.ChildrenList.AddRange(tmpNodesList);
+
             // Materials
             RaiseMessage("GLTFExporter | Exporting materials");
             foreach (var babylonMaterial in babylonMaterialsToExport)
@@ -101,8 +113,7 @@ namespace Max2Babylon
             GLTFNode gltfNode = null; 
             if (babylonNode.GetType() == typeof(BabylonMesh))
             {
-                GLTFMesh gltfMesh = ExportMesh(babylonNode as BabylonMesh, gltf, gltfParentNode, babylonScene);
-                gltfNode = gltfMesh.gltfNode;
+                gltfNode = ExportMesh(babylonNode as BabylonMesh, gltf, gltfParentNode, babylonScene);
             }
             else if (babylonNode.GetType() == typeof(BabylonCamera))
             {
@@ -138,13 +149,27 @@ namespace Max2Babylon
             }
         }
 
-        private List<BabylonNode> getDescendants(BabylonNode babylonNode, BabylonScene babylonScene)
+        private List<BabylonNode> getNodes(BabylonScene babylonScene)
         {
             List<BabylonNode> babylonNodes = new List<BabylonNode>();
-            babylonNodes.AddRange(babylonScene.meshes);
-            babylonNodes.AddRange(babylonScene.lights);
-            babylonNodes.AddRange(babylonScene.cameras);
+            if (babylonScene.meshes != null)
+            {
+                babylonNodes.AddRange(babylonScene.meshes);
+            }
+            if (babylonScene.lights != null)
+            {
+                babylonNodes.AddRange(babylonScene.lights);
+            }
+            if (babylonScene.cameras != null)
+            {
+                babylonNodes.AddRange(babylonScene.cameras);
+            }
+            return babylonNodes;
+        }
 
+        private List<BabylonNode> getDescendants(BabylonNode babylonNode, BabylonScene babylonScene)
+        {
+            List<BabylonNode> babylonNodes = getNodes(babylonScene);
             return babylonNodes.FindAll(node => node.parentId == babylonNode.id);
         }
 

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

@@ -309,7 +309,7 @@ namespace Max2Babylon
 
             // Output
             RaiseMessage("Saving to output file");
-            babylonScene.Prepare(false);
+            babylonScene.Prepare(false, false);
             var jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings());
             var sb = new StringBuilder();
             var sw = new StringWriter(sb, CultureInfo.InvariantCulture);