Ver código fonte

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

QuentinRillet 8 anos atrás
pai
commit
7af813ca43
88 arquivos alterados com 22239 adições e 21327 exclusões
  1. 11 3
      Exporters/3ds Max/BabylonExport.Entities/BabylonPBRMetallicRoughnessMaterial.cs
  2. BIN
      Exporters/3ds Max/Max2Babylon-0.16.0.zip
  3. 0 3
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.AbstractMesh.cs
  4. 4 7
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Camera.cs
  5. 0 2
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Light.cs
  6. 27 14
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Material.cs
  7. 23 34
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.cs
  8. 29 15
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Material.cs
  9. 112 13
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Texture.cs
  10. 2 2
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs
  11. 0 15
      Exporters/3ds Max/Max2Babylon/Forms/ExporterForm.Designer.cs
  12. 1 8
      Exporters/3ds Max/Max2Babylon/Forms/ExporterForm.cs
  13. 89 72
      dist/preview release/Oimo.js
  14. 3835 3818
      dist/preview release/babylon.d.ts
  15. 42 42
      dist/preview release/babylon.js
  16. 145 72
      dist/preview release/babylon.max.js
  17. 3835 3818
      dist/preview release/babylon.module.d.ts
  18. 42 42
      dist/preview release/babylon.worker.js
  19. 5539 5514
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  20. 48 48
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  21. 2130 2030
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  22. 5539 5514
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  23. 1 1
      dist/preview release/gui/babylon.gui.js
  24. 2 2
      dist/preview release/gui/babylon.gui.min.js
  25. 1 0
      dist/preview release/gui/package.json
  26. 41 0
      dist/preview release/gui/readme.md
  27. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  28. 4 0
      dist/preview release/inspector/babylon.inspector.css
  29. 42 14
      dist/preview release/inspector/babylon.inspector.js
  30. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  31. 1 0
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  32. 6 0
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  33. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  34. 1 0
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  35. 9 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  36. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  37. 1 0
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  38. 9 1
      dist/preview release/loaders/babylon.glTFFileLoader.js
  39. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  40. 6 6
      dist/preview release/loaders/babylon.objFileLoader.js
  41. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  42. 15 7
      dist/preview release/loaders/babylonjs.loaders.js
  43. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  44. 1 0
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  45. 1 0
      dist/preview release/loaders/package.json
  46. 44 0
      dist/preview release/loaders/readme.md
  47. 4 0
      dist/preview release/materialsLibrary/babylon.gridMaterial.d.ts
  48. 10 2
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  49. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  50. 10 2
      dist/preview release/materialsLibrary/babylonjs.materials.js
  51. 4 4
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  52. 4 0
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  53. 1 0
      dist/preview release/materialsLibrary/package.json
  54. 51 0
      dist/preview release/materialsLibrary/readme.md
  55. 1 0
      dist/preview release/postProcessesLibrary/package.json
  56. 51 0
      dist/preview release/postProcessesLibrary/readme.md
  57. 1 0
      dist/preview release/proceduralTexturesLibrary/package.json
  58. 53 0
      dist/preview release/proceduralTexturesLibrary/readme.md
  59. 1 0
      dist/preview release/serializers/package.json
  60. 42 0
      dist/preview release/serializers/readme.md
  61. 1 1
      gui/src/advancedDynamicTexture.ts
  62. 12 12
      loaders/src/OBJ/babylon.objFileLoader.ts
  63. 3 1
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  64. 11 0
      loaders/src/glTF/babylon.glTFFileLoader.ts
  65. 10 2
      materialsLibrary/src/grid/babylon.gridmaterial.ts
  66. 2 1
      materialsLibrary/src/grid/grid.fragment.fx
  67. 19 0
      materialsLibrary/test/addgrid.js
  68. 4 2
      package.json
  69. 33 0
      readme.md
  70. 2 2
      src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts
  71. 4 3
      src/Cameras/VR/babylon.webVRCamera.ts
  72. 1 1
      src/Gamepad/babylon.xboxGamepad.ts
  73. 2 0
      src/Materials/Textures/babylon.renderTargetTexture.ts
  74. 5 3
      src/Materials/Textures/babylon.texture.ts
  75. 24 3
      src/Materials/babylon.material.ts
  76. 17 14
      src/Mesh/babylon.mesh.ts
  77. 32 16
      src/Mesh/babylon.mesh.vertexData.ts
  78. 12 12
      src/Mesh/babylon.meshBuilder.ts
  79. 42 35
      src/Physics/Plugins/babylon.cannonJSPlugin.ts
  80. 35 30
      src/Physics/Plugins/babylon.oimoJSPlugin.ts
  81. 31 30
      src/Physics/babylon.physicsImpostor.ts
  82. 14 1
      src/PostProcess/babylon.imageProcessingPostProcess.ts
  83. 9 9
      src/Shaders/default.fragment.fx
  84. 4 3
      src/Tools/babylon.textureTools.ts
  85. 10 0
      src/Tools/babylon.tools.ts
  86. 5 0
      src/babylon.engine.ts
  87. 6 2
      src/babylon.scene.ts
  88. BIN
      tests/validation/ReferenceImages/softShadows.png

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

@@ -5,6 +5,14 @@ namespace BabylonExport.Entities
     [DataContract]
     public class BabylonPBRMetallicRoughnessMaterial : BabylonMaterial
     {
+        public enum TransparencyMode
+        {
+            OPAQUE = 0,
+            ALPHATEST = 1,
+            ALPHABLEND = 2,
+            ALPHATESTANDBLEND = 3
+        }
+
         [DataMember]
         public string customType { get; private set; }
 
@@ -51,7 +59,7 @@ namespace BabylonExport.Entities
         public float occlusionStrength { get; set; }
 
         [DataMember]
-        public BabylonTexture occlusionTexture { get; set; }
+        public BabylonTexture occlusionTexture { get; set; } // ignored
 
         [DataMember]
         public float alphaCutOff { get; set; }
@@ -60,7 +68,7 @@ namespace BabylonExport.Entities
         public int transparencyMode { get; set; }
 
         [DataMember]
-        public bool doubleSided { get; set; }
+        public bool doubleSided { get; set; } // ignored
 
         public BabylonPBRMetallicRoughnessMaterial() : base()
         {
@@ -70,7 +78,7 @@ namespace BabylonExport.Entities
             emissiveColor = new[] { 0f, 0f, 0f };
             occlusionStrength = 1.0f;
             alphaCutOff = 0.4f;
-            transparencyMode = 0;
+            transparencyMode = (int)TransparencyMode.OPAQUE;
         }
     }
 }

BIN
Exporters/3ds Max/Max2Babylon-0.16.0.zip


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

@@ -31,9 +31,6 @@ namespace Max2Babylon
 
             // Transform
             gltfNode.translation = babylonAbstractMesh.position;
-            // TODO - Choose between this method and the extra root node
-            // Switch from left to right handed coordinate system
-            //gltfNode.translation[0] *= -1;
             if (babylonAbstractMesh.rotationQuaternion != null)
             {
                 gltfNode.rotation = babylonAbstractMesh.rotationQuaternion;

+ 4 - 7
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Camera.cs

@@ -5,7 +5,6 @@ namespace Max2Babylon
 {
     partial class BabylonExporter
     {
-        // TODO - Test if ok with a gltf viewer working with custom camera (babylon loader/sandbox doesn't load them)
         private GLTFCamera ExportCamera(BabylonCamera babylonCamera, GLTF gltf, GLTFNode gltfParentNode)
         {
             RaiseMessage("GLTFExporter.Camera | Export camera named: " + babylonCamera.name, 1);
@@ -37,8 +36,6 @@ 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;
@@ -85,8 +82,8 @@ namespace Max2Babylon
             {
                 case (BabylonCamera.CameraMode.ORTHOGRAPHIC_CAMERA):
                     var gltfCameraOrthographic = new GLTFCameraOrthographic();
-                    gltfCameraOrthographic.xmag = 1; // TODO - How to retreive value from babylon? xmag:The floating-point horizontal magnification of the view
-                    gltfCameraOrthographic.ymag = 1; // TODO - How to retreive value from babylon? ymag:The floating-point vertical magnification of the view
+                    gltfCameraOrthographic.xmag = 1; // Do not bother about it - still mandatory
+                    gltfCameraOrthographic.ymag = 1; // Do not bother about it - still mandatory
                     gltfCameraOrthographic.zfar = babylonCamera.maxZ;
                     gltfCameraOrthographic.znear = babylonCamera.minZ;
 
@@ -95,8 +92,8 @@ namespace Max2Babylon
                     break;
                 case (BabylonCamera.CameraMode.PERSPECTIVE_CAMERA):
                     var gltfCameraPerspective = new GLTFCameraPerspective();
-                    gltfCameraPerspective.aspectRatio = null; // 0.8f; // TODO - How to retreive value from babylon? The aspect ratio in babylon is computed based on the engine rather than set on a camera (aspectRatio = _gl.drawingBufferWidth / _gl.drawingBufferHeight)
-                    gltfCameraPerspective.yfov = babylonCamera.fov; // WARNING - Babylon camera fov mode is assumed to be vertical (FOVMODE_VERTICAL_FIXED)
+                    gltfCameraPerspective.aspectRatio = null; // Do not bother about it - use default glTF value
+                    gltfCameraPerspective.yfov = babylonCamera.fov; // Babylon camera fov mode is assumed to be vertical (FOVMODE_VERTICAL_FIXED)
                     gltfCameraPerspective.zfar = babylonCamera.maxZ;
                     gltfCameraPerspective.znear = babylonCamera.minZ;
 

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

@@ -36,8 +36,6 @@ 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.

+ 27 - 14
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.Material.cs

@@ -353,12 +353,14 @@ namespace Max2Babylon
                 // --- Global ---
 
                 // Base color
+                // TODO - Unclear if alpha must be retreived from 'alpha' property of BABYLON.Material
+                // or from alpha channel of 'baseColor' of BABYLON.PBRMetallicRoughnessMaterial
                 gltfPbrMetallicRoughness.baseColorFactor = new float[4]
                 {
                     babylonPBRMetallicRoughnessMaterial.baseColor[0],
                     babylonPBRMetallicRoughnessMaterial.baseColor[1],
                     babylonPBRMetallicRoughnessMaterial.baseColor[2],
-                    1.0f // TODO - alpha
+                    babylonPBRMetallicRoughnessMaterial.alpha
                 };
                 gltfPbrMetallicRoughness.baseColorTexture = ExportTexture(babylonPBRMetallicRoughnessMaterial.baseTexture, gltf);
 
@@ -375,33 +377,44 @@ namespace Max2Babylon
 
         private void getAlphaMode(BabylonStandardMaterial babylonMaterial, out string alphaMode, out float? alphaCutoff)
         {
-            if ((babylonMaterial.diffuseTexture != null && babylonMaterial.diffuseTexture.hasAlpha) ||
+            if (babylonMaterial.alpha != 1.0f ||
+                (babylonMaterial.diffuseTexture != null && babylonMaterial.diffuseTexture.hasAlpha) ||
                  babylonMaterial.opacityTexture != null)
             {
-                // TODO - Babylon standard material is assumed to useAlphaFromDiffuseTexture. If not, the alpha mode is a mask.
+                // Babylon standard material is assumed to useAlphaFromDiffuseTexture. If not, the alpha mode is a mask.
                 alphaMode = GLTFMaterial.AlphaMode.BLEND.ToString();
             }
             else
             {
-                // glTF alpha mode default value is "OPAQUE"
-                alphaMode = null; // GLTFMaterial.AlphaMode.OPAQUE.ToString();
+                alphaMode = null;  // glTF alpha mode default value is "OPAQUE"
             }
             alphaCutoff = null;
         }
 
         private void getAlphaMode(BabylonPBRMetallicRoughnessMaterial babylonMaterial, out string alphaMode, out float? alphaCutoff)
         {
-            if (babylonMaterial.baseTexture != null && babylonMaterial.baseTexture.hasAlpha)
-            {
-                // TODO - Babylon standard material is assumed to useAlphaFromDiffuseTexture. If not, the alpha mode is a mask.
-                alphaMode = GLTFMaterial.AlphaMode.BLEND.ToString();
-            }
-            else
+            alphaMode = null;
+            alphaCutoff = null;
+            switch (babylonMaterial.transparencyMode)
             {
-                // glTF alpha mode default value is "OPAQUE"
-                alphaMode = null; // GLTFMaterial.AlphaMode.OPAQUE.ToString();
+                case (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.OPAQUE:
+                    alphaMode = null; // glTF alpha mode default value is "OPAQUE"
+                    break;
+                case (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHABLEND:
+                    alphaMode = GLTFMaterial.AlphaMode.BLEND.ToString();
+                    break;
+                case (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHATEST:
+                    alphaCutoff = babylonMaterial.alphaCutOff;
+                    alphaMode = GLTFMaterial.AlphaMode.MASK.ToString();
+                    break;
+                case (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHATESTANDBLEND:
+                    RaiseWarning("GLTFExporter.Material | Alpha test and blend mode is not supported in glTF. Alpha blend is used instead.", 3);
+                    alphaMode = GLTFMaterial.AlphaMode.BLEND.ToString();
+                    break;
+                default:
+                    RaiseWarning("GLTFExporter.Material | Unsupported transparency mode: " + babylonMaterial.transparencyMode, 3);
+                    break;
             }
-            alphaCutoff = null;
         }
 
         BabylonColor3 dielectricSpecular = new BabylonColor3(0.04f, 0.04f, 0.04f);

+ 23 - 34
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.GLTFExporter.cs

@@ -17,7 +17,7 @@ namespace Max2Babylon
 
         private List<BabylonNode> babylonNodes;
 
-        public void ExportGltf(BabylonScene babylonScene, string outputFile, bool generateBinary, bool exportGltfImagesAsBinary)
+        public void ExportGltf(BabylonScene babylonScene, string outputFile, bool generateBinary)
         {
             RaiseMessage("GLTFExporter | Export outputFile=" + outputFile + " generateBinary=" + generateBinary);
             RaiseMessage("GLTFExporter | Exportation started", Color.Blue);
@@ -73,10 +73,8 @@ namespace Max2Babylon
                 ReportProgressChanged((int)progression);
                 CheckCancelled();
             });
-
-            // TODO - Choose between this method and the reverse of X axis
+            
             // Switch from left to right handed coordinate system
-            RaiseMessage("GLTFExporter | Exporting root node");
             var tmpNodesList = new List<int>(scene.NodesList);
             var rootNode = new BabylonMesh
             {
@@ -85,7 +83,7 @@ namespace Max2Babylon
                 scaling = new float[] { 1, 1, -1 },
                 idGroupInstance = -1
             };
-            scene.NodesList.Clear();
+            scene.NodesList.Clear(); // Only root node is listed in node list
             GLTFNode gltfRootNode = ExportAbstractMesh(rootNode, gltf, null);
             gltfRootNode.ChildrenList.AddRange(tmpNodesList);
 
@@ -97,11 +95,6 @@ namespace Max2Babylon
                 CheckCancelled();
             };
             RaiseMessage(string.Format("GLTFExporter | Nb materials exported: {0}", gltf.MaterialsList.Count), Color.Gray, 1);
-            
-            if (exportGltfImagesAsBinary)
-            {
-                SwitchImagesFromUriToBinary(gltf);
-            }
 
             // Cast lists to arrays
             gltf.Prepare();
@@ -145,27 +138,17 @@ namespace Max2Babylon
                 {
                     gltfBuffer.uri = null;
                 }
-                // Switch images to binary if not already done
-                // TODO - make it optional
-                if (!exportGltfImagesAsBinary)
+                // Switch images to binary
+                var imageBufferViews = SwitchImagesFromUriToBinary(gltf);
+                imageBufferViews.ForEach(imageBufferView =>
                 {
-                    var imageBufferViews = SwitchImagesFromUriToBinary(gltf);
-                    imageBufferViews.ForEach(imageBufferView =>
-                    {
-                        imageBufferView.Buffer.bytesList.AddRange(imageBufferView.bytesList);
-                    });
-                }
+                    imageBufferView.Buffer.bytesList.AddRange(imageBufferView.bytesList);
+                });
                 gltf.Prepare();
                 // Serialize gltf data to JSON string then convert it to bytes
                 byte[] chunkDataJson = Encoding.ASCII.GetBytes(gltfToJson(gltf));
                 // JSON chunk must be padded with trailing Space chars (0x20) to satisfy alignment requirements 
-                var nbSpaceToAdd = chunkDataJson.Length % 4 == 0 ? 0 : (4 - chunkDataJson.Length % 4);
-                var chunkDataJsonList = new List<byte>(chunkDataJson);
-                for (int i = 0; i < nbSpaceToAdd; i++)
-                {
-                    chunkDataJsonList.Add(0x20);
-                }
-                chunkDataJson = chunkDataJsonList.ToArray();
+                chunkDataJson = padChunk(chunkDataJson, 4, 0x20);
                 UInt32 chunkLengthJson = (UInt32)chunkDataJson.Length;
                 length += chunkLengthJson + 8; // 8 = JSON chunk header length
                 
@@ -352,14 +335,8 @@ namespace Max2Babylon
                         image.Save(m, imageFormat);
                         byte[] imageBytes = m.ToArray();
 
-                        // JSON chunk must be padded with trailing Space chars (0x20) to satisfy alignment requirements 
-                        var nbSpaceToAdd = imageBytes.Length % 4 == 0 ? 0 : (4 - imageBytes.Length % 4);
-                        var imageBytesList = new List<byte>(imageBytes);
-                        for (int i = 0; i < nbSpaceToAdd; i++)
-                        {
-                            imageBytesList.Add(0x00);
-                        }
-                        imageBytes = imageBytesList.ToArray();
+                        // Chunk must be padded with trailing zeros (0x00) to satisfy alignment requirements
+                        imageBytes = padChunk(imageBytes, 4, 0x00);
 
                         // BufferView - Image
                         var buffer = gltf.buffer;
@@ -387,5 +364,17 @@ namespace Max2Babylon
             }
             return imageBufferViews;
         }
+
+        private byte[] padChunk(byte[] chunk, int padding, byte trailingChar)
+        {
+            var chunkModuloPadding = chunk.Length % padding;
+            var nbCharacterToAdd = chunkModuloPadding == 0 ? 0 : (padding - chunkModuloPadding);
+            var chunkList = new List<byte>(chunk);
+            for (int i = 0; i < nbCharacterToAdd; i++)
+            {
+                chunkList.Add(trailingChar);
+            }
+            return chunkList.ToArray();
+        }
     }
 }

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

@@ -214,9 +214,20 @@ namespace Max2Babylon
 
                 // --- Global ---
 
-                babylonMaterial.alpha = 1.0f - materialNode.MaxMaterial.GetXParency(0, false);
+                // Alpha
+                // ---
+                // TODO - Unclear if alpha must be stored within 'alpha' property of BABYLON.Material
+                // or within alpha channel of 'baseColor' of BABYLON.PBRMetallicRoughnessMaterial
+                // ---
+                // TODO - XParency seems computed from several parameters
+                // 'Transparency' property is one of them
+                // Which value to use?
+                var alphaFromXParency = 1.0f - materialNode.MaxMaterial.GetXParency(0, false);
+                var alphaFromPropertyContainer = 1.0f - propertyContainer.GetFloatProperty(17);
+                RaiseMessage("alphaFromXParency=" + alphaFromXParency, 2);
+                RaiseMessage("alphaFromPropertyContainer=" + alphaFromPropertyContainer, 2);
+                babylonMaterial.alpha = alphaFromXParency;
 
-                // TODO - Add alpha
                 babylonMaterial.baseColor = materialNode.MaxMaterial.GetDiffuse(0, false).ToArray();
 
                 babylonMaterial.metallic = propertyContainer.GetFloatProperty(6);
@@ -233,22 +244,17 @@ namespace Max2Babylon
                                                 ? materialNode.MaxMaterial.GetSelfIllumColor(0, false).ToArray()
                                                 : materialNode.MaxMaterial.GetDiffuse(0, false).Scale(materialNode.MaxMaterial.GetSelfIllum(0, false));
 
-                // TODO - occlusionStrength - use default? ignored?
-
-                // TODO - alphaCutOff - use default?
-
-                // TODO - transparencyMode - private or public ?
-
-                // TODO - doubleSided - use default?
-
                 // --- Textures ---
+                
+                babylonMaterial.baseTexture = ExportBaseColorAlphaTexture(materialNode, babylonScene, name);
 
-                // TODO - Add alpha
-                babylonMaterial.baseTexture = ExportPBRTexture(materialNode, 1, babylonScene);
+                if (babylonMaterial.alpha != 1.0f || (babylonMaterial.baseTexture != null && babylonMaterial.baseTexture.hasAlpha))
+                {
+                    babylonMaterial.transparencyMode = (int)BabylonPBRMetallicRoughnessMaterial.TransparencyMode.ALPHABLEND;
+                }
 
                 babylonMaterial.metallicRoughnessTexture = ExportMetallicRoughnessTexture(materialNode, babylonMaterial.metallic, babylonMaterial.roughness, babylonScene, name);
-
-                // TODO - environmentTexture - as simple as that?
+                
                 babylonMaterial.environmentTexture = ExportPBRTexture(materialNode, 3, babylonScene);
 
                 var normalMapAmount = propertyContainer.GetFloatProperty(91);
@@ -256,8 +262,16 @@ namespace Max2Babylon
                 
                 babylonMaterial.emissiveTexture = ExportPBRTexture(materialNode, 17, babylonScene);
                 
-                // TODO - occlusionTexture - ignored?
+                // Constraints
+                if (babylonMaterial.baseTexture != null)
+                {
+                    babylonMaterial.baseColor = new[] { 1.0f, 1.0f, 1.0f };
+                }
 
+                if (babylonMaterial.emissiveTexture != null)
+                {
+                    babylonMaterial.emissiveColor = new float[] { 0, 0, 0 };
+                }
 
                 babylonScene.MaterialsList.Add(babylonMaterial);
             }

+ 112 - 13
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Texture.cs

@@ -47,29 +47,118 @@ namespace Max2Babylon
             return null;
         }
 
-        private BabylonTexture ExportMetallicRoughnessTexture(IIGameMaterial materialNode, float metallic, float roughness, BabylonScene babylonScene, string materialName)
+        private BabylonTexture ExportBaseColorAlphaTexture(IIGameMaterial materialNode, BabylonScene babylonScene, string materialName)
         {
-            ITexmap metallicTexMap = _getTexMap(materialNode, 5);
-            ITexmap roughnessTexMap = _getTexMap(materialNode, 4);
+            ITexmap baseColorTexMap = _getTexMap(materialNode, 1);
+            ITexmap alphaTexMap = _getTexMap(materialNode, 9); // Transparency weight map
+
+            // --- Babylon texture ---
 
-            if (metallicTexMap == null && roughnessTexMap == null)
+            var baseColorTexture = _getBitmapTex(baseColorTexMap);
+            var alphaTexture = _getBitmapTex(alphaTexMap);
+
+            // Use one as a reference for UVs parameters
+            var texture = baseColorTexture != null ? baseColorTexture : alphaTexture;
+            if (texture == null)
             {
                 return null;
             }
 
-            // Use one as a reference for UVs parameters
-            var referenceTexMap = metallicTexMap != null ? metallicTexMap : roughnessTexMap;
+            var hasAlpha = alphaTexMap != null || (baseColorTexture != null && baseColorTexture.AlphaSource == 0); // Alpha source is 'Image Alpha'
+            
+            var babylonTexture = new BabylonTexture
+            {
+                name = materialName + "_baseColor" + (hasAlpha ? ".png" : ".jpg") // TODO - unsafe name, may conflict with another texture name
+            };
 
+            // Level
+            babylonTexture.level = 1.0f;
 
-            // --- Babylon texture ---
+            // Alpha
+            babylonTexture.hasAlpha = hasAlpha;
+            babylonTexture.getAlphaFromRGB = false;
 
-            if (referenceTexMap.GetParamBlock(0) == null || referenceTexMap.GetParamBlock(0).Owner == null)
+            // UVs
+            var uvGen = _exportUV(texture, babylonTexture);
+
+            // Is cube
+            _exportIsCube(texture, babylonTexture, false);
+
+
+            // --- Merge baseColor and alpha maps ---
+
+            // Load bitmaps
+            var baseColorBitmap = _loadTexture(baseColorTexMap);
+            var alphaBitmap = _loadTexture(alphaTexMap);
+
+            // Retreive dimensions
+            int width = 0;
+            int height = 0;
+            var haveSameDimensions = _getMinimalBitmapDimensions(out width, out height, baseColorBitmap, alphaBitmap);
+            if (!haveSameDimensions)
             {
-                return null;
+                RaiseWarning("Base color and transparency color maps should have same dimensions", 2);
             }
 
-            var texture = referenceTexMap.GetParamBlock(0).Owner as IBitmapTex;
+            var getAlphaFromRGB = false;
+            if (alphaTexture != null)
+            {
+                getAlphaFromRGB = (alphaTexture.AlphaSource == 2) || (alphaTexture.AlphaSource == 3); // 'RGB intensity' or 'None (Opaque)'
+            }
 
+            // Create baseColor+alpha map
+            Bitmap baseColorAlphaBitmap = new Bitmap(width, height);
+            for (int x = 0; x < width; x++)
+            {
+                for (int y = 0; y < height; y++)
+                {
+                    var baseColor = baseColorBitmap != null ? baseColorBitmap.GetPixel(x, y) : Color.FromArgb(255, 255, 255);
+
+                    Color baseColorAlpha;
+                    if (babylonTexture.hasAlpha)
+                    {
+                        if (alphaBitmap != null)
+                        {
+                            // Retreive alpha from alpha texture
+                            var alphaColor = alphaBitmap.GetPixel(x, y);
+                            var alpha = getAlphaFromRGB ? alphaColor.R : alphaColor.A;
+                            baseColorAlpha = Color.FromArgb(alpha, baseColor);
+                        }
+                        else
+                        {
+                            // Use all channels from base color
+                            baseColorAlpha = baseColor;
+                        }
+                    }
+                    else
+                    {
+                        // Only use RGB channels from base color
+                        baseColorAlpha = Color.FromArgb(baseColor.R, baseColor.G, baseColor.B);
+                    }
+                    baseColorAlphaBitmap.SetPixel(x, y, baseColorAlpha);
+                }
+            }
+
+            // Write bitmap
+            var absolutePath = Path.Combine(babylonScene.OutputPath, babylonTexture.name);
+            RaiseMessage($"Texture | write image '{babylonTexture.name}'", 2);
+            baseColorAlphaBitmap.Save(absolutePath);
+
+            return babylonTexture;
+        }
+
+        private BabylonTexture ExportMetallicRoughnessTexture(IIGameMaterial materialNode, float metallic, float roughness, BabylonScene babylonScene, string materialName)
+        {
+            ITexmap metallicTexMap = _getTexMap(materialNode, 5);
+            ITexmap roughnessTexMap = _getTexMap(materialNode, 4);
+
+            // --- Babylon texture ---
+            
+            var metallicTexture = _getBitmapTex(metallicTexMap);
+            var roughnessTexture = _getBitmapTex(roughnessTexMap);
+
+            // Use one as a reference for UVs parameters
+            var texture = metallicTexture != null ? metallicTexture : roughnessTexture;
             if (texture == null)
             {
                 return null;
@@ -170,12 +259,12 @@ namespace Max2Babylon
             if (forceAlpha)
             {
                 babylonTexture.hasAlpha = true;
-                babylonTexture.getAlphaFromRGB = (texture.AlphaSource == 2) || (texture.AlphaSource == 3);
+                babylonTexture.getAlphaFromRGB = (texture.AlphaSource == 2) || (texture.AlphaSource == 3); // 'RGB intensity' or 'None (Opaque)'
             }
             else
             {
-                babylonTexture.hasAlpha = (texture.AlphaSource != 3);
-                babylonTexture.getAlphaFromRGB = (texture.AlphaSource == 2);
+                babylonTexture.hasAlpha = (texture.AlphaSource != 3); // Not 'None (Opaque)'
+                babylonTexture.getAlphaFromRGB = (texture.AlphaSource == 2); // 'RGB intensity'
             }
 
             // UVs
@@ -408,6 +497,16 @@ namespace Max2Babylon
         // --------- Utils ---------
         // -------------------------
 
+        private IBitmapTex _getBitmapTex(ITexmap texMap)
+        {
+            if (texMap == null || texMap.GetParamBlock(0) == null || texMap.GetParamBlock(0).Owner == null)
+            {
+                return null;
+            }
+
+            return texMap.GetParamBlock(0).Owner as IBitmapTex;
+        }
+
         private ITexmap _getTexMap(IIGameMaterial materialNode, int index)
         {
             ITexmap texMap = null;

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

@@ -77,7 +77,7 @@ namespace Max2Babylon
             }
         }
 
-        public async Task ExportAsync(string outputFile, bool generateManifest, bool onlySelected, bool generateBinary, bool exportGltf, bool exportGltfImagesAsBinary, Form callerForm)
+        public async Task ExportAsync(string outputFile, bool generateManifest, bool onlySelected, bool generateBinary, bool exportGltf, Form callerForm)
         {
             var gameConversionManger = Loader.Global.ConversionManager;
             gameConversionManger.CoordSystem = Autodesk.Max.IGameConversionManager.CoordSystem.D3d;
@@ -298,7 +298,7 @@ namespace Max2Babylon
             // Export glTF
             if (exportGltf)
             {
-                ExportGltf(babylonScene, outputFile, generateBinary, exportGltfImagesAsBinary);
+                ExportGltf(babylonScene, outputFile, generateBinary);
             }
 
             watch.Stop();

+ 0 - 15
Exporters/3ds Max/Max2Babylon/Forms/ExporterForm.Designer.cs

@@ -48,7 +48,6 @@
             this.butExportAndRun = new System.Windows.Forms.Button();
             this.butClose = new System.Windows.Forms.Button();
             this.chkGltf = new System.Windows.Forms.CheckBox();
-            this.chkGltfImagesAsBinary = new System.Windows.Forms.CheckBox();
             ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
             this.groupBox1.SuspendLayout();
             this.SuspendLayout();
@@ -181,7 +180,6 @@
             // 
             this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-            this.groupBox1.Controls.Add(this.chkGltfImagesAsBinary);
             this.groupBox1.Controls.Add(this.chkBinary);
             this.groupBox1.Controls.Add(this.chkOnlySelected);
             this.groupBox1.Controls.Add(this.chkAutoSave);
@@ -279,18 +277,6 @@
             this.chkGltf.UseVisualStyleBackColor = true;
             this.chkGltf.CheckedChanged += new System.EventHandler(this.chkGltf_CheckedChanged);
             // 
-            // chkGltfImageAsBinary
-            // 
-            this.chkGltfImagesAsBinary.AutoSize = true;
-            this.chkGltfImagesAsBinary.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.chkGltfImagesAsBinary.Location = new System.Drawing.Point(166, 127);
-            this.chkGltfImagesAsBinary.Name = "chkGltfImagesAsBinary";
-            this.chkGltfImagesAsBinary.Size = new System.Drawing.Size(158, 17);
-            this.chkGltfImagesAsBinary.TabIndex = 18;
-            this.chkGltfImagesAsBinary.Text = "Export glTF images as binary";
-            this.chkGltfImagesAsBinary.UseVisualStyleBackColor = true;
-            this.chkGltfImagesAsBinary.CheckedChanged += new System.EventHandler(this.checkGltfImagesAsBinary_CheckedChanged);
-            // 
             // ExporterForm
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -344,6 +330,5 @@
         private System.Windows.Forms.Button butClose;
         private System.Windows.Forms.CheckBox chkBinary;
         private System.Windows.Forms.CheckBox chkGltf;
-        private System.Windows.Forms.CheckBox chkGltfImagesAsBinary;
     }
 }

+ 1 - 8
Exporters/3ds Max/Max2Babylon/Forms/ExporterForm.cs

@@ -33,7 +33,6 @@ namespace Max2Babylon
             Tools.PrepareCheckBox(chkOnlySelected, Loader.Core.RootNode, "babylonjs_onlySelected");
             Tools.PrepareCheckBox(chkBinary, Loader.Core.RootNode, "babylonjs_binary");
             Tools.PrepareCheckBox(chkGltf, Loader.Core.RootNode, "babylonjs_exportGltf");
-            Tools.PrepareCheckBox(chkGltfImagesAsBinary, Loader.Core.RootNode, "babylonjs_exportGltfImagesAsBinary");
         }
 
         private void butBrowse_Click(object sender, EventArgs e)
@@ -58,7 +57,6 @@ namespace Max2Babylon
             Tools.UpdateCheckBox(chkOnlySelected, Loader.Core.RootNode, "babylonjs_onlySelected");
             Tools.UpdateCheckBox(chkBinary, Loader.Core.RootNode, "babylonjs_binary");
             Tools.UpdateCheckBox(chkGltf, Loader.Core.RootNode, "babylonjs_exportGltf");
-            Tools.UpdateCheckBox(chkGltfImagesAsBinary, Loader.Core.RootNode, "babylonjs_exportGltfImagesAsBinary");
 
             Loader.Core.RootNode.SetLocalData(txtFilename.Text);
 
@@ -125,7 +123,7 @@ namespace Max2Babylon
                 exporter.AutoSave3dsMaxFile = chkAutoSave.Checked;
                 exporter.ExportHiddenObjects = chkHidden.Checked;
                 exporter.CopyTexturesToOutput = chkCopyTextures.Checked;
-                await exporter.ExportAsync(txtFilename.Text, chkManifest.Checked, chkOnlySelected.Checked, chkBinary.Checked, chkGltf.Checked, chkGltfImagesAsBinary.Checked, this);
+                await exporter.ExportAsync(txtFilename.Text, chkManifest.Checked, chkOnlySelected.Checked, chkBinary.Checked, chkGltf.Checked, this);
             }
             catch (OperationCanceledException)
             {
@@ -234,10 +232,5 @@ namespace Max2Babylon
         {
 
         }
-
-        private void checkGltfImagesAsBinary_CheckedChanged(object sender, EventArgs e)
-        {
-
-        }
     }
 }

+ 89 - 72
dist/preview release/Oimo.js

@@ -1882,12 +1882,12 @@ OIMO.Mat33.prototype = {
     },
     mul: function (m1, m2) {
         var te = this.elements, tm1 = m1.elements, tm2 = m2.elements,
-        a0 = tm1[0], a3 = tm1[3], a6 = tm1[6],
-        a1 = tm1[1], a4 = tm1[4], a7 = tm1[7],
-        a2 = tm1[2], a5 = tm1[5], a8 = tm1[8],
-        b0 = tm2[0], b3 = tm2[3], b6 = tm2[6],
-        b1 = tm2[1], b4 = tm2[4], b7 = tm2[7],
-        b2 = tm2[2], b5 = tm2[5], b8 = tm2[8];
+            a0 = tm1[0], a3 = tm1[3], a6 = tm1[6],
+            a1 = tm1[1], a4 = tm1[4], a7 = tm1[7],
+            a2 = tm1[2], a5 = tm1[5], a8 = tm1[8],
+            b0 = tm2[0], b3 = tm2[3], b6 = tm2[6],
+            b1 = tm2[1], b4 = tm2[4], b7 = tm2[7],
+            b2 = tm2[2], b5 = tm2[5], b8 = tm2[8];
         te[0] = a0 * b0 + a1 * b3 + a2 * b6;
         te[1] = a0 * b1 + a1 * b4 + a2 * b7;
         te[2] = a0 * b2 + a1 * b5 + a2 * b8;
@@ -1968,10 +1968,10 @@ OIMO.Mat33.prototype = {
     },
     setQuat: function (q) {
         var te = this.elements,
-        x2 = 2 * q.x, y2 = 2 * q.y, z2 = 2 * q.z,
-        xx = q.x * x2, yy = q.y * y2, zz = q.z * z2,
-        xy = q.x * y2, yz = q.y * z2, xz = q.x * z2,
-        sx = q.s * x2, sy = q.s * y2, sz = q.s * z2;
+            x2 = 2 * q.x, y2 = 2 * q.y, z2 = 2 * q.z,
+            xx = q.x * x2, yy = q.y * y2, zz = q.z * z2,
+            xy = q.x * y2, yz = q.y * z2, xz = q.x * z2,
+            sx = q.s * x2, sy = q.s * y2, sz = q.s * z2;
 
         te[0] = 1 - yy - zz;
         te[1] = xy - sz;
@@ -1986,13 +1986,13 @@ OIMO.Mat33.prototype = {
     },
     invert: function (m) {
         var te = this.elements, tm = m.elements,
-        a0 = tm[0], a3 = tm[3], a6 = tm[6],
-        a1 = tm[1], a4 = tm[4], a7 = tm[7],
-        a2 = tm[2], a5 = tm[5], a8 = tm[8],
-        b01 = a4 * a8 - a7 * a5,
-        b11 = a7 * a2 - a1 * a8,
-        b21 = a1 * a5 - a4 * a2,
-        dt = a0 * (b01) + a3 * (b11) + a6 * (b21);
+            a0 = tm[0], a3 = tm[3], a6 = tm[6],
+            a1 = tm[1], a4 = tm[4], a7 = tm[7],
+            a2 = tm[2], a5 = tm[5], a8 = tm[8],
+            b01 = a4 * a8 - a7 * a5,
+            b11 = a7 * a2 - a1 * a8,
+            b21 = a1 * a5 - a4 * a2,
+            dt = a0 * (b01) + a3 * (b11) + a6 * (b21);
 
         if (dt != 0) { dt = 1.0 / dt; }
         te[0] = dt * b01;//(a4*a8 - a5*a7);
@@ -2051,9 +2051,9 @@ OIMO.Mat33.prototype = {
     toString: function () {
         var te = this.elements;
         var text =
-        "Mat33|" + te[0].toFixed(4) + ", " + te[1].toFixed(4) + ", " + te[2].toFixed(4) + "|\n" +
-        "     |" + te[3].toFixed(4) + ", " + te[4].toFixed(4) + ", " + te[5].toFixed(4) + "|\n" +
-        "     |" + te[6].toFixed(4) + ", " + te[7].toFixed(4) + ", " + te[8].toFixed(4) + "|";
+            "Mat33|" + te[0].toFixed(4) + ", " + te[1].toFixed(4) + ", " + te[2].toFixed(4) + "|\n" +
+            "     |" + te[3].toFixed(4) + ", " + te[4].toFixed(4) + ", " + te[5].toFixed(4) + "|\n" +
+            "     |" + te[6].toFixed(4) + ", " + te[7].toFixed(4) + ", " + te[8].toFixed(4) + "|";
         return text;
     },
 
@@ -2203,7 +2203,7 @@ OIMO.Quat.prototype = {
     },
     mul: function (q1, q2) {
         var ax = q1.x, ay = q1.y, az = q1.z, as = q1.s,
-        bx = q2.x, by = q2.y, bz = q2.z, bs = q2.s;
+            bx = q2.x, by = q2.y, bz = q2.z, bs = q2.s;
         this.x = ax * bs + as * bx + ay * bz - az * by;
         this.y = ay * bs + as * by + az * bx - ax * bz;
         this.z = az * bs + as * bz + ax * by - ay * bx;
@@ -2424,7 +2424,7 @@ OIMO.Vec3.prototype = {
     },*/
     cross: function (v1, v2) {
         var ax = v1.x, ay = v1.y, az = v1.z,
-        bx = v2.x, by = v2.y, bz = v2.z;
+            bx = v2.x, by = v2.y, bz = v2.z;
         this.x = ay * bz - az * by;
         this.y = az * bx - ax * bz;
         this.z = ax * by - ay * bx;
@@ -3766,7 +3766,7 @@ OIMO.SliderJoint.prototype.preSolve = function (timeStep, invTimeStep) {
         nx * (angAxis1Y * angAxis2Z - angAxis1Z * angAxis2Y) +
         ny * (angAxis1Z * angAxis2X - angAxis1X * angAxis2Z) +
         nz * (angAxis1X * angAxis2Y - angAxis1Y * angAxis2X) < 0
-        ) {
+    ) {
         this.rotationalLimitMotor.angle = -this.acosClamp(angAxis1X * angAxis2X + angAxis1Y * angAxis2Y + angAxis1Z * angAxis2Z);
     } else {
         this.rotationalLimitMotor.angle = this.acosClamp(angAxis1X * angAxis2X + angAxis1Y * angAxis2Y + angAxis1Z * angAxis2Z);
@@ -4654,9 +4654,9 @@ OIMO.Rotational3Constraint.prototype = {
         this.k22 += this.cfm3;
 
         var inv = 1 / (
-        this.k00 * (this.k11 * this.k22 - this.k21 * this.k12) +
-        this.k10 * (this.k21 * this.k02 - this.k01 * this.k22) +
-        this.k20 * (this.k01 * this.k12 - this.k11 * this.k02)
+            this.k00 * (this.k11 * this.k22 - this.k21 * this.k12) +
+            this.k10 * (this.k21 * this.k02 - this.k01 * this.k22) +
+            this.k20 * (this.k01 * this.k12 - this.k11 * this.k02)
         );
         this.d00 = (this.k11 * this.k22 - this.k12 * this.k21) * inv;
         this.d01 = (this.k02 * this.k21 - this.k01 * this.k22) * inv;
@@ -5580,9 +5580,9 @@ OIMO.Translational3Constraint.prototype = {
         this.k22 += this.cfm3;
 
         var inv = 1 / (
-        this.k00 * (this.k11 * this.k22 - this.k21 * this.k12) +
-        this.k10 * (this.k21 * this.k02 - this.k01 * this.k22) +
-        this.k20 * (this.k01 * this.k12 - this.k11 * this.k02)
+            this.k00 * (this.k11 * this.k22 - this.k21 * this.k12) +
+            this.k10 * (this.k21 * this.k02 - this.k01 * this.k22) +
+            this.k20 * (this.k01 * this.k12 - this.k11 * this.k02)
         );
         this.d00 = (this.k11 * this.k22 - this.k12 * this.k21) * inv;
         this.d01 = (this.k02 * this.k21 - this.k01 * this.k22) * inv;
@@ -5956,7 +5956,7 @@ OIMO.TranslationalConstraint.prototype = {
         this.a2y = this.t2x * this.i2e10 + this.t2y * this.i2e11 + this.t2z * this.i2e12;
         this.a2z = this.t2x * this.i2e20 + this.t2y * this.i2e21 + this.t2z * this.i2e22;
         this.motorDenom =
-        this.m1 + this.m2 +
+            this.m1 + this.m2 +
             this.ax * (this.a1y * this.r1z - this.a1z * this.r1y + this.a2y * this.r2z - this.a2z * this.r2y) +
             this.ay * (this.a1z * this.r1x - this.a1x * this.r1z + this.a2z * this.r2x - this.a2x * this.r2z) +
             this.az * (this.a1x * this.r1y - this.a1y * this.r1x + this.a2x * this.r2y - this.a2y * this.r2x);
@@ -6613,18 +6613,18 @@ OIMO.ContactConstraint.prototype.solve = function () {
         var rvY = lv2y - lv1y;
         var rvZ = lv2z - lv1z;
         rvn =
-        rvX * c.tanX + rvY * c.tanY + rvZ * c.tanZ +
-        av2x * c.tanT2X + av2y * c.tanT2Y + av2z * c.tanT2Z -
-        av1x * c.tanT1X - av1y * c.tanT1Y - av1z * c.tanT1Z
-        ;
+            rvX * c.tanX + rvY * c.tanY + rvZ * c.tanZ +
+            av2x * c.tanT2X + av2y * c.tanT2Y + av2z * c.tanT2Z -
+            av1x * c.tanT1X - av1y * c.tanT1Y - av1z * c.tanT1Z
+            ;
         oldImp1 = tanImp;
         newImp1 = rvn * c.tanDen;
         tanImp += newImp1;
         rvn =
-        rvX * c.binX + rvY * c.binY + rvZ * c.binZ +
-        av2x * c.binT2X + av2y * c.binT2Y + av2z * c.binT2Z -
-        av1x * c.binT1X - av1y * c.binT1Y - av1z * c.binT1Z
-        ;
+            rvX * c.binX + rvY * c.binY + rvZ * c.binZ +
+            av2x * c.binT2X + av2y * c.binT2Y + av2z * c.binT2Z -
+            av1x * c.binT1X - av1y * c.binT1Y - av1z * c.binT1Z
+            ;
         oldImp2 = binImp;
         newImp2 = rvn * c.binDen;
         binImp += newImp2;
@@ -6654,9 +6654,9 @@ OIMO.ContactConstraint.prototype.solve = function () {
 
         // restitution part
         rvn =
-        (lv2x - lv1x) * c.norX + (lv2y - lv1y) * c.norY + (lv2z - lv1z) * c.norZ +
-        av2x * c.norT2X + av2y * c.norT2Y + av2z * c.norT2Z -
-        av1x * c.norT1X - av1y * c.norT1Y - av1z * c.norT1Z;
+            (lv2x - lv1x) * c.norX + (lv2y - lv1y) * c.norY + (lv2z - lv1z) * c.norZ +
+            av2x * c.norT2X + av2y * c.norT2Y + av2z * c.norT2Z -
+            av1x * c.norT1X - av1y * c.norT1Y - av1z * c.norT1Z;
 
         oldImp1 = norImp;
         newImp1 = (rvn - c.norTar) * c.norDen;
@@ -7329,10 +7329,10 @@ OIMO.TetraShape = function (config, p1, p2, p3, p4) {
     // Vertices and faces of tetra
     this.verts = [p1, p2, p3, p4];
     this.faces = [
-      mtri(0, 1, 2),
-      mtri(1, 2, 3),
-      mtri(2, 3, 4),
-      mtri(4, 0, 1),
+        mtri(0, 1, 2),
+        mtri(1, 2, 3),
+        mtri(2, 3, 4),
+        mtri(4, 0, 1),
     ];
 };
 OIMO.TetraShape.prototype = Object.create(OIMO.Shape.prototype);
@@ -9207,14 +9207,14 @@ OIMO.BoxCylinderCollisionDetector.prototype.getSep = function (c1, c2, sep, pos,
                 return false;
             }
             if (
-            (v4y * v1z - v4z * v1y) * v0x +
-            (v4z * v1x - v4x * v1z) * v0y +
-            (v4x * v1y - v4y * v1x) * v0z < 0
+                (v4y * v1z - v4z * v1y) * v0x +
+                (v4z * v1x - v4x * v1z) * v0y +
+                (v4x * v1y - v4y * v1x) * v0z < 0
             ) {
                 if (
-                (v4y * v2z - v4z * v2y) * v0x +
-                (v4z * v2x - v4x * v2z) * v0y +
-                (v4x * v2y - v4y * v2x) * v0z < 0
+                    (v4y * v2z - v4z * v2y) * v0x +
+                    (v4z * v2x - v4x * v2z) * v0y +
+                    (v4x * v2y - v4y * v2x) * v0z < 0
                 ) {
                     v1x = v4x;
                     v1y = v4y;
@@ -9238,9 +9238,9 @@ OIMO.BoxCylinderCollisionDetector.prototype.getSep = function (c1, c2, sep, pos,
                 }
             } else {
                 if (
-                (v4y * v3z - v4z * v3y) * v0x +
-                (v4z * v3x - v4x * v3z) * v0y +
-                (v4x * v3y - v4y * v3x) * v0z < 0
+                    (v4y * v3z - v4z * v3y) * v0x +
+                    (v4z * v3x - v4x * v3z) * v0y +
+                    (v4x * v3y - v4y * v3x) * v0z < 0
                 ) {
                     v2x = v4x;
                     v2y = v4y;
@@ -10239,14 +10239,14 @@ OIMO.CylinderCylinderCollisionDetector.prototype.getSep = function (c1, c2, sep,
                 return false;
             }
             if (
-            (v4y * v1z - v4z * v1y) * v0x +
-            (v4z * v1x - v4x * v1z) * v0y +
-            (v4x * v1y - v4y * v1x) * v0z < 0
+                (v4y * v1z - v4z * v1y) * v0x +
+                (v4z * v1x - v4x * v1z) * v0y +
+                (v4x * v1y - v4y * v1x) * v0z < 0
             ) {
                 if (
-                (v4y * v2z - v4z * v2y) * v0x +
-                (v4z * v2x - v4x * v2z) * v0y +
-                (v4x * v2y - v4y * v2x) * v0z < 0
+                    (v4y * v2z - v4z * v2y) * v0x +
+                    (v4z * v2x - v4x * v2z) * v0y +
+                    (v4x * v2y - v4y * v2x) * v0z < 0
                 ) {
                     v1x = v4x;
                     v1y = v4y;
@@ -10270,9 +10270,9 @@ OIMO.CylinderCylinderCollisionDetector.prototype.getSep = function (c1, c2, sep,
                 }
             } else {
                 if (
-                (v4y * v3z - v4z * v3y) * v0x +
-                (v4z * v3x - v4x * v3z) * v0y +
-                (v4x * v3y - v4y * v3x) * v0z < 0
+                    (v4y * v3z - v4z * v3y) * v0x +
+                    (v4z * v3x - v4x * v3z) * v0y +
+                    (v4x * v3y - v4y * v3x) * v0z < 0
                 ) {
                     v2x = v4x;
                     v2y = v4y;
@@ -10932,9 +10932,9 @@ OIMO.TetraTetraCollisionDetector.prototype.detectCollision = function (tet1, tet
             j3 = vs2[fs[i].c];
 
             if (
-              tricheck(pt(vec.x, vec.y), pt(j1.x, j1.y), pt(j2.x, j2.y), pt(j3.x, j3.y)) &&
-              tricheck(pt(vec.x, vec.z), pt(j1.x, j1.z), pt(j2.x, j2.z), pt(j3.x, j3.z)) &&
-              tricheck(pt(vec.z, vec.y), pt(j1.z, j1.y), pt(j2.z, j2.y), pt(j3.z, j3.y))
+                tricheck(pt(vec.x, vec.y), pt(j1.x, j1.y), pt(j2.x, j2.y), pt(j3.x, j3.y)) &&
+                tricheck(pt(vec.x, vec.z), pt(j1.x, j1.z), pt(j2.x, j2.z), pt(j3.x, j3.z)) &&
+                tricheck(pt(vec.z, vec.y), pt(j1.z, j1.y), pt(j2.z, j2.y), pt(j3.z, j3.y))
             )
                 ts++;
 
@@ -11518,15 +11518,15 @@ OIMO.SAPBroadPhase = function () {
     this.numElementsS = 0;
     // dynamic proxies
     this.axesD = [
-       new OIMO.SAPAxis(),
-       new OIMO.SAPAxis(),
-       new OIMO.SAPAxis()
+        new OIMO.SAPAxis(),
+        new OIMO.SAPAxis(),
+        new OIMO.SAPAxis()
     ];
     // static or sleeping proxies
     this.axesS = [
-       new OIMO.SAPAxis(),
-       new OIMO.SAPAxis(),
-       new OIMO.SAPAxis()
+        new OIMO.SAPAxis(),
+        new OIMO.SAPAxis(),
+        new OIMO.SAPAxis()
     ];
 
     this.index1 = 0;
@@ -12510,3 +12510,20 @@ OIMO.World.prototype.add = function (obj) {
     }
 }
 
+//UMD simplified
+
+var root = this;
+
+if (!root['OIMO']) {
+    if (typeof exports === 'object' && typeof module === 'object')
+        module.exports = OIMO;
+    else if (typeof define === 'function' && define.amd)
+        define([], function () {
+            return OIMO;
+        });
+    else if (typeof exports === 'object')
+        exports["OIMO"] = OIMO;
+    else {
+        root["OIMO"] = OIMO;
+    }
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 3835 - 3818
dist/preview release/babylon.d.ts


Diferenças do arquivo suprimidas por serem muito extensas
+ 42 - 42
dist/preview release/babylon.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 145 - 72
dist/preview release/babylon.max.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 3835 - 3818
dist/preview release/babylon.module.d.ts


Diferenças do arquivo suprimidas por serem muito extensas
+ 42 - 42
dist/preview release/babylon.worker.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 5539 - 5514
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Diferenças do arquivo suprimidas por serem muito extensas
+ 48 - 48
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 2130 - 2030
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 5539 - 5514
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


+ 1 - 1
dist/preview release/gui/babylon.gui.js

@@ -317,7 +317,7 @@ var BABYLON;
                     var y = (scene.pointerY / engine.getHardwareScalingLevel() - viewport.y * engine.getRenderHeight()) / viewport.height;
                     _this._shouldBlockPointer = false;
                     _this._doPicking(x, y, pi.type);
-                    pi.skipOnPointerObservable = _this._shouldBlockPointer && pi.type !== BABYLON.PointerEventTypes.POINTERUP;
+                    pi.skipOnPointerObservable = _this._shouldBlockPointer;
                 });
                 this._attachToOnPointerOut(scene);
             };

Diferenças do arquivo suprimidas por serem muito extensas
+ 2 - 2
dist/preview release/gui/babylon.gui.min.js


+ 1 - 0
dist/preview release/gui/package.json

@@ -15,6 +15,7 @@
         "babylon.gui.min.js",
         "babylon.gui.d.ts",
         "babylon.gui.module.d.ts",
+        "readme.md",
         "package.json"
     ],
     "typings": "babylon.gui.module.d.ts",

+ 41 - 0
dist/preview release/gui/readme.md

@@ -0,0 +1,41 @@
+Babylon.js GUI module
+=====================
+
+For usage documentation please visit http://doc.babylonjs.com/overviews/gui
+
+# Installation instructions
+
+## CDN
+
+Compiled js files (minified and source) are offered on our public CDN here:
+
+* https://preview.babylonjs.com/gui/babylon.gui.js
+* https://preview.babylonjs.com/gui/babylon.gui.min.js
+
+## NPM
+
+To install using npm :
+
+```
+npm install --save babylonjs babylonjs-gui
+```
+
+If using TypeScript, the typing needs to be added to tsconfig.json:
+
+```
+    ....
+    "types": [
+        "babylonjs",
+        "babylonjs-gui",
+        "angularFTW"
+    ],
+    ....
+```
+
+Afterwards it can be imported to the project using:
+
+```
+import * as GUI from 'babylonjs-gui';
+```
+
+Using webpack to package your project will use the minified js file.

Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


+ 4 - 0
dist/preview release/inspector/babylon.inspector.css

@@ -282,6 +282,8 @@
     overflow-x: auto;
     color: #ccc;
     font-family: "Inconsolata", sans-serif; }
+    .insp-wrapper .insp-details .details {
+      padding-left: 5px; }
     .insp-wrapper .insp-details .base-row, .insp-wrapper .insp-details .row, .insp-wrapper .insp-details .header-row {
       display: flex;
       width: 100%; }
@@ -328,6 +330,8 @@
       height: 10px;
       display: inline-block;
       margin-left: 5px; }
+    .insp-wrapper .insp-details .color-element {
+      top: 2px; }
     .insp-wrapper .insp-details .texture-element {
       color: #f29766;
       margin-left: 10px; }

+ 42 - 14
dist/preview release/inspector/babylon.inspector.js

@@ -2075,7 +2075,6 @@ var INSPECTOR;
             var scheduler = INSPECTOR.Scheduler.getInstance();
             _this._div.className = 'color-element';
             _this._div.style.backgroundColor = _this._toRgba(color);
-            _this._div.style.top = "5px";
             _this.pline = propertyLine;
             _this._input = INSPECTOR.Helpers.CreateInput();
             _this._input.type = 'color';
@@ -2084,8 +2083,11 @@ var INSPECTOR;
             _this._input.style.height = '15px';
             _this._input.value = color.toHexString();
             _this._input.addEventListener('input', function (e) {
-                console.log('Color', _this._input.value, _this.pline);
-                _this.pline.validateInput(BABYLON.Color3.FromHexString(_this._input.value));
+                var color = BABYLON.Color3.FromHexString(_this._input.value);
+                color.r = parseFloat(color.r.toPrecision(2));
+                color.g = parseFloat(color.g.toPrecision(2));
+                color.b = parseFloat(color.b.toPrecision(2));
+                _this.pline.validateInput(color);
                 scheduler.pause = false;
             });
             _this._div.appendChild(_this._input);
@@ -3108,7 +3110,7 @@ var INSPECTOR;
                 screenShotTexture.onBeforeRenderObservable = texture.onBeforeRenderObservable;
                 // To display the texture after rendering
                 screenShotTexture.onAfterRenderObservable.add(function (faceIndex) {
-                    BABYLON.Tools.DumpFramebuffer(size_1.width, size_1.height, engine_1, function (data) { return imgs[faceIndex].src = data; }, "image/png");
+                    BABYLON.Tools.DumpFramebuffer(size_1.width, size_1.height, engine_1, function (data) { return imgs[faceIndex].src = data; });
                 });
                 // Render the texture
                 scene.incrementRenderId();
@@ -3117,23 +3119,49 @@ var INSPECTOR;
                 screenShotTexture.dispose();
             }
             else if (texture instanceof BABYLON.CubeTexture) {
+                // Cannot open correctly DDS File
                 // Display all textures of the CubeTexture
-                var i = 0;
-                for (var _i = 0, _a = texture['_files']; _i < _a.length; _i++) {
-                    var filename = _a[_i];
-                    imgs[i].src = filename;
-                    i++;
-                }
-            }
-            else if (texture.url) {
-                // If an url is present, the texture is an image
-                img.src = texture.url;
+                var pixels = texture.readPixels();
+                var canvas = document.createElement('canvas');
+                canvas.id = "MyCanvas";
+                img.parentElement.appendChild(canvas);
+                var ctx = canvas.getContext('2d');
+                var size = texture.getSize();
+                var tmp = pixels.buffer.slice(0, size.height * size.width * 4);
+                var u = new Uint8ClampedArray(tmp);
+                var colors = new ImageData(size.width * 6, size.height);
+                colors.data.set(u);
+                var imgData = ctx.createImageData(size.width * 6, size.height);
+                imgData.data.set(u);
+                // let data = imgData.data;
+                // for(let i = 0, len = size.height * size.width; i < len; i++) {
+                //     data[i] = pixels[i];
+                // }
+                ctx.putImageData(imgData, 0, 0);
+                // let i: number = 0;
+                // for(let filename of (texture as BABYLON.CubeTexture)['_files']){
+                //     imgs[i].src = filename;
+                //     i++;
+                // }
             }
             else if (texture['_canvas']) {
                 // Dynamic texture
                 var base64Image = texture['_canvas'].toDataURL("image/png");
                 img.src = base64Image;
             }
+            else if (texture.url) {
+                var pixels = texture.readPixels();
+                var canvas = document.createElement('canvas');
+                canvas.id = "MyCanvas";
+                img.parentElement.appendChild(canvas);
+                var ctx = canvas.getContext('2d');
+                var size = texture.getSize();
+                var imgData = ctx.createImageData(size.width, size.height);
+                imgData.data.set(pixels);
+                ctx.putImageData(imgData, 0, 0);
+                // If an url is present, the texture is an image
+                // img.src = texture.url;
+            }
         };
         /** Select an item in the tree */
         TextureTab.prototype.select = function (item) {

Diferenças do arquivo suprimidas por serem muito extensas
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


+ 1 - 0
dist/preview release/loaders/babylon.glTF1FileLoader.d.ts

@@ -16,6 +16,7 @@ declare module BABYLON {
     class GLTFFileLoader implements ISceneLoaderPluginAsync {
         static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
+        onParsed: (data: IGLTFLoaderData) => void;
         static HomogeneousCoordinates: boolean;
         static IncrementalLoading: boolean;
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;

+ 6 - 0
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -26,6 +26,9 @@ var BABYLON;
             if (!loaderData) {
                 return;
             }
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;
@@ -37,6 +40,9 @@ var BABYLON;
             if (!loaderData) {
                 return;
             }
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;

Diferenças do arquivo suprimidas por serem muito extensas
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 1 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -16,6 +16,7 @@ declare module BABYLON {
     class GLTFFileLoader implements ISceneLoaderPluginAsync {
         static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
+        onParsed: (data: IGLTFLoaderData) => void;
         static HomogeneousCoordinates: boolean;
         static IncrementalLoading: boolean;
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;

+ 9 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -26,6 +26,9 @@ var BABYLON;
             if (!loaderData) {
                 return;
             }
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;
@@ -37,6 +40,9 @@ var BABYLON;
             if (!loaderData) {
                 return;
             }
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;
@@ -404,7 +410,9 @@ var BABYLON;
                 this.removePendingData(this);
             };
             GLTFLoader.prototype._onError = function (message) {
-                this._errorCallback(message);
+                if (this._errorCallback) {
+                    this._errorCallback(message);
+                }
                 this.dispose();
             };
             GLTFLoader.prototype._onProgress = function (event) {

Diferenças do arquivo suprimidas por serem muito extensas
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 1 - 0
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -16,6 +16,7 @@ declare module BABYLON {
     class GLTFFileLoader implements ISceneLoaderPluginAsync {
         static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
+        onParsed: (data: IGLTFLoaderData) => void;
         static HomogeneousCoordinates: boolean;
         static IncrementalLoading: boolean;
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;

+ 9 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -26,6 +26,9 @@ var BABYLON;
             if (!loaderData) {
                 return;
             }
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;
@@ -37,6 +40,9 @@ var BABYLON;
             if (!loaderData) {
                 return;
             }
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;
@@ -2562,7 +2568,9 @@ var BABYLON;
                 this.removePendingData(this);
             };
             GLTFLoader.prototype._onError = function (message) {
-                this._errorCallback(message);
+                if (this._errorCallback) {
+                    this._errorCallback(message);
+                }
                 this.dispose();
             };
             GLTFLoader.prototype._onProgress = function (event) {

Diferenças do arquivo suprimidas por serem muito extensas
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 6 - 6
dist/preview release/loaders/babylon.objFileLoader.js

@@ -55,7 +55,7 @@ var BABYLON;
                     else if (key === "kd") {
                         // Diffuse color (color under white light) using RGB values
                         //value  = "r g b"
-                        color = value.split(delimiter_pattern, 3);
+                        color = value.split(delimiter_pattern, 3).map(parseFloat);
                         //color = [r,g,b]
                         //Set tghe color into the material
                         material.diffuseColor = BABYLON.Color3.FromArray(color);
@@ -63,7 +63,7 @@ var BABYLON;
                     else if (key === "ka") {
                         // Ambient color (color under shadow) using RGB values
                         //value = "r g b"
-                        color = value.split(delimiter_pattern, 3);
+                        color = value.split(delimiter_pattern, 3).map(parseFloat);
                         //color = [r,g,b]
                         //Set tghe color into the material
                         material.ambientColor = BABYLON.Color3.FromArray(color);
@@ -71,23 +71,23 @@ var BABYLON;
                     else if (key === "ks") {
                         // Specular color (color when light is reflected from shiny surface) using RGB values
                         //value = "r g b"
-                        color = value.split(delimiter_pattern, 3);
+                        color = value.split(delimiter_pattern, 3).map(parseFloat);
                         //color = [r,g,b]
                         //Set the color into the material
                         material.specularColor = BABYLON.Color3.FromArray(color);
                     }
                     else if (key === "ke") {
                         // Emissive color using RGB values
-                        color = value.split(delimiter_pattern, 3);
+                        color = value.split(delimiter_pattern, 3).map(parseFloat);
                         material.emissiveColor = BABYLON.Color3.FromArray(color);
                     }
                     else if (key === "ns") {
                         //value = "Integer"
-                        material.specularPower = value;
+                        material.specularPower = parseFloat(value);
                     }
                     else if (key === "d") {
                         //d is dissolve for current material. It mean alpha for BABYLON
-                        material.alpha = value;
+                        material.alpha = parseFloat(value);
                         //Texture
                         //This part can be improved by adding the possible options of texture
                     }

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 15 - 7
dist/preview release/loaders/babylonjs.loaders.js

@@ -237,7 +237,7 @@ var BABYLON;
                     else if (key === "kd") {
                         // Diffuse color (color under white light) using RGB values
                         //value  = "r g b"
-                        color = value.split(delimiter_pattern, 3);
+                        color = value.split(delimiter_pattern, 3).map(parseFloat);
                         //color = [r,g,b]
                         //Set tghe color into the material
                         material.diffuseColor = BABYLON.Color3.FromArray(color);
@@ -245,7 +245,7 @@ var BABYLON;
                     else if (key === "ka") {
                         // Ambient color (color under shadow) using RGB values
                         //value = "r g b"
-                        color = value.split(delimiter_pattern, 3);
+                        color = value.split(delimiter_pattern, 3).map(parseFloat);
                         //color = [r,g,b]
                         //Set tghe color into the material
                         material.ambientColor = BABYLON.Color3.FromArray(color);
@@ -253,23 +253,23 @@ var BABYLON;
                     else if (key === "ks") {
                         // Specular color (color when light is reflected from shiny surface) using RGB values
                         //value = "r g b"
-                        color = value.split(delimiter_pattern, 3);
+                        color = value.split(delimiter_pattern, 3).map(parseFloat);
                         //color = [r,g,b]
                         //Set the color into the material
                         material.specularColor = BABYLON.Color3.FromArray(color);
                     }
                     else if (key === "ke") {
                         // Emissive color using RGB values
-                        color = value.split(delimiter_pattern, 3);
+                        color = value.split(delimiter_pattern, 3).map(parseFloat);
                         material.emissiveColor = BABYLON.Color3.FromArray(color);
                     }
                     else if (key === "ns") {
                         //value = "Integer"
-                        material.specularPower = value;
+                        material.specularPower = parseFloat(value);
                     }
                     else if (key === "d") {
                         //d is dissolve for current material. It mean alpha for BABYLON
-                        material.alpha = value;
+                        material.alpha = parseFloat(value);
                         //Texture
                         //This part can be improved by adding the possible options of texture
                     }
@@ -996,6 +996,9 @@ var BABYLON;
             if (!loaderData) {
                 return;
             }
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;
@@ -1007,6 +1010,9 @@ var BABYLON;
             if (!loaderData) {
                 return;
             }
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;
@@ -3514,7 +3520,9 @@ var BABYLON;
                 this.removePendingData(this);
             };
             GLTFLoader.prototype._onError = function (message) {
-                this._errorCallback(message);
+                if (this._errorCallback) {
+                    this._errorCallback(message);
+                }
                 this.dispose();
             };
             GLTFLoader.prototype._onProgress = function (event) {

Diferenças do arquivo suprimidas por serem muito extensas
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 0
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -114,6 +114,7 @@ declare module BABYLON {
     class GLTFFileLoader implements ISceneLoaderPluginAsync {
         static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
+        onParsed: (data: IGLTFLoaderData) => void;
         static HomogeneousCoordinates: boolean;
         static IncrementalLoading: boolean;
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;

+ 1 - 0
dist/preview release/loaders/package.json

@@ -14,6 +14,7 @@
         "babylonjs.loaders.js",
         "babylonjs.loaders.min.js",
         "babylonjs.loaders.module.d.ts",
+        "readme.md",
         "package.json"
     ],
     "typings": "babylonjs.loaders.module.d.ts",

+ 44 - 0
dist/preview release/loaders/readme.md

@@ -0,0 +1,44 @@
+Babylon.js Loaders module
+=====================
+
+For usage documentation please visit http://doc.babylonjs.com/extensions and choose "loaders".
+
+# Installation instructions
+
+## CDN
+
+Compiled js files (minified and source) are offered on our public CDN here:
+
+* https://preview.babylonjs.com/loaders/babylonjs.loaders.js
+* https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js
+
+## NPM
+
+To install using npm :
+
+```
+npm install --save babylonjs babylonjs-loaders
+```
+
+If using TypeScript, the typing needs to be added to tsconfig.json:
+
+```
+    ....
+    "types": [
+        "babylonjs",
+        "babylonjs-loaders",
+        ""
+    ],
+    ....
+```
+
+Afterwards it can be imported to the project using:
+
+```
+import * as BABYLON from 'babylonjs';
+import from 'babylonjs-loaders';
+```
+
+This will extend Babylon's namespace with the loaders available.
+
+Using webpack to package your project will use the minified js file.

+ 4 - 0
dist/preview release/materialsLibrary/babylon.gridMaterial.d.ts

@@ -18,6 +18,10 @@ declare module BABYLON {
          */
         gridRatio: number;
         /**
+         * Allows setting an offset for the grid lines.
+         */
+        gridOffset: Vector3;
+        /**
          * The frequency of thicker lines.
          */
         majorUnitFrequency: number;

Diferenças do arquivo suprimidas por serem muito extensas
+ 10 - 2
dist/preview release/materialsLibrary/babylon.gridMaterial.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 10 - 2
dist/preview release/materialsLibrary/babylonjs.materials.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 4
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 4 - 0
dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts

@@ -472,6 +472,10 @@ declare module BABYLON {
          */
         gridRatio: number;
         /**
+         * Allows setting an offset for the grid lines.
+         */
+        gridOffset: Vector3;
+        /**
          * The frequency of thicker lines.
          */
         majorUnitFrequency: number;

+ 1 - 0
dist/preview release/materialsLibrary/package.json

@@ -14,6 +14,7 @@
         "babylonjs.materials.js",
         "babylonjs.materials.min.js",
         "babylonjs.materials.module.d.ts",
+        "readme.md",
         "package.json"
     ],
     "typings": "babylonjs.materials.module.d.ts",

+ 51 - 0
dist/preview release/materialsLibrary/readme.md

@@ -0,0 +1,51 @@
+Babylon.js Materials Library
+=====================
+
+For usage documentation please visit http://doc.babylonjs.com/extensions and choose "materials library".
+
+# Installation instructions
+
+## CDN
+
+Compiled js files (minified and source) are offered on our public CDN here:
+
+* https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.js
+* https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js
+
+## NPM
+
+To install using npm :
+
+```
+npm install --save babylonjs babylonjs-materials
+```
+
+If using TypeScript, the typing needs to be added to tsconfig.json:
+
+```
+    ....
+    "types": [
+        "babylonjs",
+        "babylonjs-materials",
+        "oneMoreDependencyThatIReallyNeed"
+    ],
+    ....
+```
+
+Afterwards it can be imported to the project using:
+
+```
+import * as BABYLON from 'babylonjs';
+import from 'babylonjs-materials';
+```
+
+This will extend Babylon's namespace with the materials available:
+
+```
+// Some awesome code
+let skyMaterial = new BABYLON.SkyMaterial("skyMaterial", scene);
+skyMaterial.backFaceCulling = false;
+// Some more awesome code
+```
+
+Using webpack to package your project will use the minified js file.

+ 1 - 0
dist/preview release/postProcessesLibrary/package.json

@@ -14,6 +14,7 @@
         "babylonjs.postProcess.js",
         "babylonjs.postProcess.min.js",
         "babylonjs.postProcess.module.d.ts",
+        "readme.md",
         "package.json"
     ],
     "typings": "babylonjs.postProcess.module.d.ts",

+ 51 - 0
dist/preview release/postProcessesLibrary/readme.md

@@ -0,0 +1,51 @@
+Babylon.js Post Processes Library
+=====================
+
+For usage documentation please visit http://doc.babylonjs.com/extensions and choose "post process library".
+
+# Installation instructions
+
+## CDN
+
+Compiled js files (minified and source) are offered on our public CDN here:
+
+* https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.js
+* https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js
+
+## NPM
+
+To install using npm :
+
+```
+npm install --save babylonjs babylonjs-post-process
+```
+
+If using TypeScript, the typing needs to be added to tsconfig.json:
+
+```
+    ....
+    "types": [
+        "babylonjs",
+        "babylonjs-post-process",
+        "oneMoreDependencyThatIReallyNeed"
+    ],
+    ....
+```
+
+Afterwards it can be imported to the project using:
+
+```
+import * as BABYLON from 'babylonjs';
+import from 'babylonjs-post-process';
+```
+
+This will extend Babylon's namespace with the post processes available:
+
+```
+// Some awesome code
+// Creates the post process
+let postProcess = new BABYLON.AsciiArtPostProcess("AsciiArt", camera);
+// Some more awesome code
+```
+
+Using webpack to package your project will use the minified js file.

+ 1 - 0
dist/preview release/proceduralTexturesLibrary/package.json

@@ -14,6 +14,7 @@
         "babylonjs.proceduralTextures.js",
         "babylonjs.proceduralTextures.min.js",
         "babylonjs.proceduralTextures.module.d.ts",
+        "readme.md",
         "package.json"
     ],
     "typings": "babylonjs.proceduralTextures.module.d.ts",

+ 53 - 0
dist/preview release/proceduralTexturesLibrary/readme.md

@@ -0,0 +1,53 @@
+Babylon.js Procedural Textures Library
+=====================
+
+For usage documentation please visit http://doc.babylonjs.com/extensions and choose "procedural textures library".
+
+# Installation instructions
+
+## CDN
+
+Compiled js files (minified and source) are offered on our public CDN here:
+
+* https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.js
+* https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js
+
+## NPM
+
+To install using npm :
+
+```
+npm install --save babylonjs babylonjs-procedural-textures
+```
+
+If using TypeScript, the typing needs to be added to tsconfig.json:
+
+```
+    ....
+    "types": [
+        "babylonjs",
+        "babylonjs-procedural-textures",
+        "oneMoreDependencyThatIReallyNeed"
+    ],
+    ....
+```
+
+Afterwards it can be imported to the project using:
+
+```
+import * as BABYLON from 'babylonjs';
+import from 'babylonjs-procedural-textures';
+```
+
+This will extend Babylon's namespace with the procedural textures available:
+
+```
+// Some awesome code
+var fireMaterial = new BABYLON.StandardMaterial("fontainSculptur2", scene);
+var fireTexture = new BABYLON.FireProceduralTexture("fire", 256, scene);
+fireMaterial.diffuseTexture = fireTexture;
+fireMaterial.opacityTexture = fireTexture;
+// Some more awesome code
+```
+
+Using webpack to package your project will use the minified js file.

+ 1 - 0
dist/preview release/serializers/package.json

@@ -14,6 +14,7 @@
         "babylonjs.serializers.js",
         "babylonjs.serializers.min.js",
         "babylonjs.serializers.module.d.ts",
+        "readme.md",
         "package.json"
     ],
     "typings": "babylonjs.serializers.module.d.ts",

+ 42 - 0
dist/preview release/serializers/readme.md

@@ -0,0 +1,42 @@
+Babylon.js Serializers
+=====================
+
+# Installation instructions
+
+## CDN
+
+Compiled js files (minified and source) are offered on our public CDN here:
+
+* https://preview.babylonjs.com/serializers/babylonjs.serializers.js
+* https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.serializers.min.js
+
+## NPM
+
+To install using npm :
+
+```
+npm install --save babylonjs babylonjs-serializers
+```
+
+If using TypeScript, the typing needs to be added to tsconfig.json:
+
+```
+    ....
+    "types": [
+        "babylonjs",
+        "babylonjs-serializers",
+        "oneMoreDependencyThatIReallyNeed"
+    ],
+    ....
+```
+
+Afterwards it can be imported to the project using:
+
+```
+import * as BABYLON from 'babylonjs';
+import from 'babylonjs-serializers';
+```
+
+This will extend Babylon's namespace with the serializers currently available.
+
+Using webpack to package your project will use the minified js file.

+ 1 - 1
gui/src/advancedDynamicTexture.ts

@@ -348,7 +348,7 @@ module BABYLON.GUI {
                 this._shouldBlockPointer = false;
                 this._doPicking(x, y, pi.type);
 
-                pi.skipOnPointerObservable = this._shouldBlockPointer && pi.type !== BABYLON.PointerEventTypes.POINTERUP;
+                pi.skipOnPointerObservable = this._shouldBlockPointer;
             });
 
             this._attachToOnPointerOut(scene);

+ 12 - 12
loaders/src/OBJ/babylon.objFileLoader.ts

@@ -45,7 +45,7 @@ module BABYLON {
                 key = key.toLowerCase();
 
                 //Get the data following the key
-                var value: any = (pos >= 0) ? line.substring(pos + 1).trim() : "";
+                var value: string = (pos >= 0) ? line.substring(pos + 1).trim() : "";
 
                 //This mtl keyword will create the new material
                 if (key === "newmtl") {
@@ -62,7 +62,7 @@ module BABYLON {
                     // Diffuse color (color under white light) using RGB values
 
                     //value  = "r g b"
-                    color = <number[]>value.split(delimiter_pattern, 3);
+                    color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
                     //color = [r,g,b]
                     //Set tghe color into the material
                     material.diffuseColor = BABYLON.Color3.FromArray(color);
@@ -70,7 +70,7 @@ module BABYLON {
                     // Ambient color (color under shadow) using RGB values
 
                     //value = "r g b"
-                    color = <number[]>value.split(delimiter_pattern, 3);
+                    color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
                     //color = [r,g,b]
                     //Set tghe color into the material
                     material.ambientColor = BABYLON.Color3.FromArray(color);
@@ -78,21 +78,21 @@ module BABYLON {
                     // Specular color (color when light is reflected from shiny surface) using RGB values
 
                     //value = "r g b"
-                    color = <number[]>value.split(delimiter_pattern, 3);
+                    color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
                     //color = [r,g,b]
                     //Set the color into the material
                     material.specularColor = BABYLON.Color3.FromArray(color);
                 } else if (key === "ke") {
                     // Emissive color using RGB values
-                    color = value.split(delimiter_pattern, 3);
+                    color = value.split(delimiter_pattern, 3).map(parseFloat);
                     material.emissiveColor = BABYLON.Color3.FromArray(color);
                 } else if (key === "ns") {
 
                     //value = "Integer"
-                    material.specularPower = value;
+                    material.specularPower = parseFloat(value);
                 } else if (key === "d") {
                     //d is dissolve for current material. It mean alpha for BABYLON
-                    material.alpha = value;
+                    material.alpha = parseFloat(value);
 
                     //Texture
                     //This part can be improved by adding the possible options of texture
@@ -237,11 +237,11 @@ module BABYLON {
             var pathOfFile = BABYLON.Tools.BaseUrl + rootUrl + url;
 
             // Loads through the babylon tools to allow fileInput search.
-            BABYLON.Tools.LoadFile(pathOfFile, 
-                onSuccess, 
-                null, 
-                null, 
-                false, 
+            BABYLON.Tools.LoadFile(pathOfFile,
+                onSuccess,
+                null,
+                null,
+                false,
                 () => { console.warn("Error - Unable to load " + pathOfFile); });
         }
 

+ 3 - 1
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -114,7 +114,9 @@ module BABYLON.GLTF2 {
         }
 
         private _onError(message: string): void {
-            this._errorCallback(message);
+            if (this._errorCallback) {
+                this._errorCallback(message);
+            }
             this.dispose();
         }
 

+ 11 - 0
loaders/src/glTF/babylon.glTFFileLoader.ts

@@ -27,6 +27,9 @@ module BABYLON {
         public static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         public static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
 
+        // Common options
+        public onParsed: (data: IGLTFLoaderData) => void;
+
         // V1 options
         public static HomogeneousCoordinates: boolean = false;
         public static IncrementalLoading: boolean = true;
@@ -61,6 +64,10 @@ module BABYLON {
                 return;
             }
 
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
+
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;
@@ -75,6 +82,10 @@ module BABYLON {
                 return;
             }
 
+            if (this.onParsed) {
+                this.onParsed(loaderData);
+            }
+
             var loader = this._getLoader(loaderData, onError);
             if (!loader) {
                 return;

+ 10 - 2
materialsLibrary/src/grid/babylon.gridmaterial.ts

@@ -37,6 +37,12 @@ module BABYLON {
         public gridRatio = 1.0;
 
         /**
+         * Allows setting an offset for the grid lines.
+         */
+        @serializeAsColor3()
+        public gridOffset = Vector3.Zero();
+
+        /**
          * The frequency of thicker lines.
          */
         @serialize()
@@ -126,7 +132,7 @@ module BABYLON {
                 var join = defines.toString();
                 subMesh.setEffect(scene.getEngine().createEffect("grid",
                     attribs,
-                    ["projection", "worldView", "mainColor", "lineColor", "gridControl", "vFogInfos", "vFogColor", "world", "view"],
+                    ["projection", "worldView", "mainColor", "lineColor", "gridControl", "gridOffset", "vFogInfos", "vFogColor", "world", "view"],
                     [],
                     join,
                     null,
@@ -166,6 +172,8 @@ module BABYLON {
                 this._activeEffect.setColor3("mainColor", this.mainColor);
                 this._activeEffect.setColor3("lineColor", this.lineColor);
 
+                this._activeEffect.setVector3("gridOffset", this.gridOffset);
+
                 this._gridControl.x = this.gridRatio;
                 this._gridControl.y = Math.round(this.majorUnitFrequency);
                 this._gridControl.z = this.minorUnitVisibility;
@@ -194,7 +202,7 @@ module BABYLON {
 
         public getClassName(): string {
             return "GridMaterial";
-        }             
+        }
 
         public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial {
             return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl);

+ 2 - 1
materialsLibrary/src/grid/grid.fragment.fx

@@ -8,6 +8,7 @@ precision highp float;
 uniform vec3 mainColor;
 uniform vec3 lineColor;
 uniform vec4 gridControl;
+uniform vec3 gridOffset;
 
 // Varying
 #ifdef TRANSPARENT
@@ -70,7 +71,7 @@ void main(void) {
     
     // Scale position to the requested ratio.
     float gridRatio = gridControl.x;
-    vec3 gridPos = vPosition / gridRatio;
+    vec3 gridPos = (vPosition + gridOffset) / gridRatio;
     
     // Find the contribution of each coords.
     float x = contributionOnAxis(gridPos.x);

+ 19 - 0
materialsLibrary/test/addgrid.js

@@ -42,6 +42,25 @@ window.prepareGrid = function() {
 	}, function() {
 		return grid.gridRatio;
 	});
+
+	registerRangeUI("grid", "OffsetX", 0, 2, function(value) {
+		grid.gridOffset.x = value;
+	}, function() {
+		return grid.gridOffset.x;
+	});
+    
+  registerRangeUI("grid", "OffsetY", 0, 2, function(value) {
+		grid.gridOffset.y = value;
+	}, function() {
+		return grid.gridOffset.y;
+	});
+    
+  registerRangeUI("grid", "OffsetZ", 0, 2, function(value) {
+		grid.gridOffset.z = value;
+	}, function() {
+		return grid.gridOffset.z;
+	});
+    
     
   registerRangeUI("grid", "MajorUnitFrequency", 1, 10, function(value) {
 		grid.majorUnitFrequency = value;

+ 4 - 2
package.json

@@ -8,7 +8,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "3.1.0-alpha3.4",
+    "version": "3.1.0-alpha3.5",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -58,7 +58,9 @@
         "webgl"
     ],
     "license": "Apache-2.0",
-    "dependencies": {},
+    "dependencies": {
+        "cannon": "0.6.2"
+    },
     "engines": {
         "node": "*"
     },

+ 33 - 0
readme.md

@@ -22,6 +22,39 @@ For preview release you can use the following ones:
 
 Additional references can be found on https://preview.babylonjs.com/xxx where xxx is the folder structure you can find in the /dist/preview release folder like https://preview.babylonjs.com/gui/babylon.gui.min.js
 
+## NPM
+
+BabylonJS and its modules are published on NPM with full typing support. To install use
+
+```
+npm install babylonjs --save
+```
+
+This will allow you to import BabylonJS entirely using:
+
+```
+import * as BABYLON from 'babylonjs';
+```
+
+or individual classes using:
+
+```
+import { Scene, Engine } from 'babylonjs';
+```
+
+If using TypeScript, don't forget to add 'babylonjs' to 'types' in tsconfig.json:
+
+```
+    ....
+    "types": [
+        "babylonjs",
+        "anotherAwesomeDependency"
+    ],
+    ....
+```
+
+To add a module install the respected package. A list of extra packages and their installation instructions can be found on [babylonjs' user at npm](https://www.npmjs.com/~babylonjs).
+
 ## Preview release
 
 **3.1-alpha** can be found [here](https://github.com/BabylonJS/Babylon.js/tree/master/dist/preview%20release).

+ 2 - 2
src/Cameras/Inputs/babylon.arcRotateCameraKeyboardMoveInput.ts

@@ -121,7 +121,7 @@ module BABYLON {
                             camera.inertialPanningY += 1 / this.panningSensibility;
                         }
                         else if (this._altPressed && this.useAltToZoom) {
-                            camera.inertialRadiusOffset -= 1 / this.zoomingSensibility;
+                            camera.inertialRadiusOffset += 1 / this.zoomingSensibility;
                         }
                         else {
                             camera.inertialBetaOffset -= 0.01;
@@ -137,7 +137,7 @@ module BABYLON {
                             camera.inertialPanningY -= 1 / this.panningSensibility;
                         }
                         else if (this._altPressed && this.useAltToZoom) {
-                            camera.inertialRadiusOffset += 1 / this.zoomingSensibility;
+                            camera.inertialRadiusOffset -= 1 / this.zoomingSensibility;
                         }
                         else {
                             camera.inertialBetaOffset += 0.01;

+ 4 - 3
src/Cameras/VR/babylon.webVRCamera.ts

@@ -99,7 +99,7 @@ module BABYLON {
             this._onVREnabled = (success: boolean) => { if (success) { this.initControllers(); } };
             engine.onVRRequestPresentComplete.add(this._onVREnabled);
             engine.initWebVR().add((event: IDisplayChangedEventArgs) => {
-                if (this._vrDevice === event.vrDisplay) {
+                if (!event.vrDisplay || this._vrDevice === event.vrDisplay) {
                     return;
                 }
 
@@ -108,12 +108,13 @@ module BABYLON {
                 //reset the rig parameters.
                 this.setCameraRigMode(Camera.RIG_MODE_WEBVR, { parentCamera: this, vrDisplay: this._vrDevice, frameData: this._frameData, specs: this._specsVersion });
 
-                if (this._attached && this._vrDevice) {
+                if (this._attached) {
                     this.getEngine().enableVR();
                 }
             });
 
-            this._frameData = new VRFrameData();
+            if (typeof(VRFrameData) !== "undefined")
+                this._frameData = new VRFrameData();
 
             /**
              * The idea behind the following lines:

+ 1 - 1
src/Gamepad/babylon.xboxGamepad.ts

@@ -56,7 +56,7 @@
         private _isXboxOnePad: boolean = false;
 
         constructor(id: string, index: number, gamepad: any, xboxOne: boolean = false) {
-            super(id, index, gamepad, 0, 1, (xboxOne ? 3 : 2), (xboxOne ? 4 : 3));
+            super(id, index, gamepad, 0, 1, 2, 3);
             this.type = Gamepad.XBOX;
             this._isXboxOnePad = xboxOne;
         }

+ 2 - 0
src/Materials/Textures/babylon.renderTargetTexture.ts

@@ -269,6 +269,8 @@
             } else {
                 this._texture = this.getScene().getEngine().createRenderTargetTexture(size, this._renderTargetOptions);
             }
+
+            this._size = size;
         }
 
         public render(useCameraPostProcess?: boolean, dumpForDebug?: boolean) {

+ 5 - 3
src/Materials/Textures/babylon.texture.ts

@@ -117,6 +117,8 @@
 
             scene = this.getScene();
 
+            scene.getEngine().onBeforeTextureInitObservable.notifyObservers(this);
+
             let load = () => {
                 if (this._onLoadObservable && this._onLoadObservable.hasObservers()) {
                     this.onLoadObservable.notifyObservers(this);
@@ -130,17 +132,17 @@
                 }
             }
 
-            if (!url) {
+            if (!this.url) {
                 this._delayedOnLoad = load;
                 this._delayedOnError = onError;
                 return;
             }
 
-            this._texture = this._getFromCache(url, noMipmap, samplingMode);
+            this._texture = this._getFromCache(this.url, noMipmap, samplingMode);
 
             if (!this._texture) {
                 if (!scene.useDelayedTextureLoading) {
-                    this._texture = scene.getEngine().createTexture(url, noMipmap, invertY, scene, this._samplingMode, load, onError, this._buffer, null, this._format);
+                    this._texture = scene.getEngine().createTexture(this.url, noMipmap, invertY, scene, this._samplingMode, load, onError, this._buffer, null, this._format);
                     if (deleteBuffer) {
                         delete this._buffer;
                     }

+ 24 - 3
src/Materials/babylon.material.ts

@@ -285,11 +285,29 @@
         public alphaMode = Engine.ALPHA_COMBINE;
 
         @serialize()
-        public needDepthPrePass = false;
+        private _needDepthPrePass = false;
+        public set needDepthPrePass(value : boolean) {
+            if (this._needDepthPrePass === value) {
+                return;
+            }
+            this._needDepthPrePass = value;
+            if (this._needDepthPrePass) {
+                this.checkReadyOnEveryCall = true;
+            }
+        }
+        public get needDepthPrePass(): boolean {
+            return this._needDepthPrePass;
+        }   
 
         @serialize()
         public disableDepthWrite = false;
 
+        @serialize()
+        public forceDepthWrite = false;
+
+        @serialize()
+        public separateCullingPass = false;
+
         @serialize("fogEnabled")
         private _fogEnabled = true;
         public set fogEnabled(value : boolean) {
@@ -433,13 +451,16 @@
             this._wasPreviouslyReady = false;
         }
 
-        public _preBind(effect?: Effect): void {
+        public _preBind(effect?: Effect, overrideOrientation? : number): boolean {
             var engine = this._scene.getEngine();
 
-            var reverse = this.sideOrientation === Material.ClockWiseSideOrientation;
+            var orientation = (overrideOrientation == null) ? this.sideOrientation : overrideOrientation;
+            var reverse = orientation === Material.ClockWiseSideOrientation;
 
             engine.enableEffect(effect ? effect : this._effect);
             engine.setState(this.backFaceCulling, this.zOffset, false, reverse);
+
+            return reverse;
         }
 
         public bind(world: Matrix, mesh?: Mesh): void {

+ 17 - 14
src/Mesh/babylon.mesh.ts

@@ -132,7 +132,12 @@
 
         public _shouldGenerateFlatShading: boolean;
         private _preActivateId: number;
-        private _sideOrientation: number = Mesh._DEFAULTSIDE;
+
+        // Use by builder only to know what orientation were the mesh build in.
+        public _originalBuilderSideOrientation: number = Mesh._DEFAULTSIDE;
+
+        public overrideMaterialSideOrientation: number = null;
+
         private _areNormalsFrozen: boolean = false; // Will be used by ribbons mainly
 
         private _sourcePositions: Float32Array; // Will be used to save original positions when using software skinning
@@ -531,18 +536,6 @@
             return super.isReady();
         }
 
-        public get sideOrientation(): number {
-            return this._sideOrientation;
-        }
-
-        /**
-         * Sets the mesh side orientation : BABYLON.Mesh.FRONTSIDE, BABYLON.Mesh.BACKSIDE, BABYLON.Mesh.DOUBLESIDE or BABYLON.Mesh.DEFAULTSIDE
-         * tuto : http://doc.babylonjs.com/tutorials/Discover_Basic_Elements#side-orientation
-         */
-        public set sideOrientation(sideO: number) {
-            this._sideOrientation = sideO;
-        }
-
         /**
          * Boolean : true if the normals aren't to be recomputed on next mesh `positions` array update.
          * This property is pertinent only for updatable parametric shapes.
@@ -1185,7 +1178,11 @@
                 effect = this._effectiveMaterial.getEffect();
             }
 
-            this._effectiveMaterial._preBind(effect);
+            var reverse = this._effectiveMaterial._preBind(effect, this.overrideMaterialSideOrientation);
+
+            if (this._effectiveMaterial.forceDepthWrite) {
+                engine.setDepthWrite(true);
+            }
 
             // Bind
             var fillMode = scene.forcePointsCloud ? Material.PointFillMode : (scene.forceWireframe ? Material.WireFrameFillMode : this._effectiveMaterial.fillMode);
@@ -1202,6 +1199,12 @@
                 this._effectiveMaterial.bind(world, this);
             }
 
+            if (!this._effectiveMaterial.backFaceCulling && this._effectiveMaterial.separateCullingPass) {
+                engine.setState(true, this._effectiveMaterial.zOffset, false, !reverse);
+                this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._effectiveMaterial);
+                engine.setState(true, this._effectiveMaterial.zOffset, false, reverse);
+            }
+
             // Draw
             this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._effectiveMaterial);
 

+ 32 - 16
src/Mesh/babylon.mesh.vertexData.ts

@@ -308,25 +308,41 @@
             }
 
             this.positions = this._mergeElement(this.positions, other.positions);
-            this.normals = this._mergeElement(this.normals, other.normals);
-            this.tangents = this._mergeElement(this.tangents, other.tangents);
-            this.uvs = this._mergeElement(this.uvs, other.uvs);
-            this.uvs2 = this._mergeElement(this.uvs2, other.uvs2);
-            this.uvs3 = this._mergeElement(this.uvs3, other.uvs3);
-            this.uvs4 = this._mergeElement(this.uvs4, other.uvs4);
-            this.uvs5 = this._mergeElement(this.uvs5, other.uvs5);
-            this.uvs6 = this._mergeElement(this.uvs6, other.uvs6);
-            this.colors = this._mergeElement(this.colors, other.colors);
-            this.matricesIndices = this._mergeElement(this.matricesIndices, other.matricesIndices);
-            this.matricesWeights = this._mergeElement(this.matricesWeights, other.matricesWeights);
-            this.matricesIndicesExtra = this._mergeElement(this.matricesIndicesExtra, other.matricesIndicesExtra);
-            this.matricesWeightsExtra = this._mergeElement(this.matricesWeightsExtra, other.matricesWeightsExtra);
+
+            var count = this.positions.length / 3;
+
+            this.normals = this._mergeElement(this.normals, other.normals, count * 3);
+            this.tangents = this._mergeElement(this.tangents, other.tangents, count * 4);
+            this.uvs = this._mergeElement(this.uvs, other.uvs, count * 2);
+            this.uvs2 = this._mergeElement(this.uvs2, other.uvs2, count * 2);
+            this.uvs3 = this._mergeElement(this.uvs3, other.uvs3, count * 2);
+            this.uvs4 = this._mergeElement(this.uvs4, other.uvs4, count * 2);
+            this.uvs5 = this._mergeElement(this.uvs5, other.uvs5, count * 2);
+            this.uvs6 = this._mergeElement(this.uvs6, other.uvs6, count * 2);
+            this.colors = this._mergeElement(this.colors, other.colors, count * 4);
+            this.matricesIndices = this._mergeElement(this.matricesIndices, other.matricesIndices, count * 4);
+            this.matricesWeights = this._mergeElement(this.matricesWeights, other.matricesWeights, count * 4);
+            this.matricesIndicesExtra = this._mergeElement(this.matricesIndicesExtra, other.matricesIndicesExtra, count * 4);
+            this.matricesWeightsExtra = this._mergeElement(this.matricesWeightsExtra, other.matricesWeightsExtra, count * 4);
             return this;
         }
 
-        private _mergeElement(source: number[] | Float32Array, other: number[] | Float32Array): number[] | Float32Array {
-            if (!other) return source;
-            if (!source) return other;
+        private _mergeElement(source: number[] | Float32Array, other: number[] | Float32Array, length = 0): number[] | Float32Array {
+            if (!other && !source) {
+                return null;
+            }
+
+            if (!other) {
+                return this._mergeElement(source, new Float32Array(source.length), length);
+            }
+
+            if (!source) {
+                if (length === other.length) {
+                    return other;
+                }
+
+                return this._mergeElement(new Float32Array(length - other.length), other, length);
+            }
 
             var len = other.length + source.length;
             var isSrcTypedArray = source instanceof Float32Array;

+ 12 - 12
src/Mesh/babylon.meshBuilder.ts

@@ -28,7 +28,7 @@
             var box = new Mesh(name, scene);
 
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            box.sideOrientation = options.sideOrientation;
+            box._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreateBox(options);
 
@@ -54,7 +54,7 @@
             var sphere = new Mesh(name, scene);
 
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            sphere.sideOrientation = options.sideOrientation;
+            sphere._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreateSphere(options);
 
@@ -78,7 +78,7 @@
             var disc = new Mesh(name, scene);
 
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            disc.sideOrientation = options.sideOrientation;
+            disc._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreateDisc(options);
 
@@ -103,7 +103,7 @@
             var sphere = new Mesh(name, scene);
 
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            sphere.sideOrientation = options.sideOrientation;
+            sphere._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreateIcoSphere(options);
 
@@ -151,7 +151,7 @@
                 var positionFunction = positions => {
                     var minlg = pathArray[0].length;
                     var i = 0;
-                    var ns = (instance.sideOrientation === Mesh.DOUBLESIDE) ? 2 : 1;
+                    var ns = (instance._originalBuilderSideOrientation === Mesh.DOUBLESIDE) ? 2 : 1;
                     for (var si = 1; si <= ns; si++) {
                         for (var p = 0; p < pathArray.length; p++) {
                             var path = pathArray[p];
@@ -250,7 +250,7 @@
             else {  // new ribbon creation
 
                 var ribbon = new Mesh(name, scene);
-                ribbon.sideOrientation = sideOrientation;
+                ribbon._originalBuilderSideOrientation = sideOrientation;
 
                 var vertexData = VertexData.CreateRibbon(options);
                 if (closePath) {
@@ -293,7 +293,7 @@
             var cylinder = new Mesh(name, scene);
             
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            cylinder.sideOrientation = options.sideOrientation;
+            cylinder._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreateCylinder(options);
 
@@ -317,7 +317,7 @@
             var torus = new Mesh(name, scene);
 
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            torus.sideOrientation = options.sideOrientation;
+            torus._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreateTorus(options);
 
@@ -342,7 +342,7 @@
             var torusKnot = new Mesh(name, scene);
 
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            torusKnot.sideOrientation = options.sideOrientation;
+            torusKnot._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreateTorusKnot(options);
 
@@ -637,7 +637,7 @@
             var plane = new Mesh(name, scene);
 
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            plane.sideOrientation = options.sideOrientation;
+            plane._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreatePlane(options);
 
@@ -814,7 +814,7 @@
 				polygonTriangulation.addHole(hole);
 			}
 			var polygon = polygonTriangulation.build(options.updatable, depth);
-            polygon.sideOrientation = options.sideOrientation;
+            polygon._originalBuilderSideOrientation = options.sideOrientation;
 			var vertexData = VertexData.CreatePolygon(polygon, options.sideOrientation, options.faceUV, options.faceColors, options.frontUVs, options.backUVs);
             vertexData.applyToMesh(polygon, options.updatable);			
 			
@@ -989,7 +989,7 @@
             var polyhedron = new Mesh(name, scene);
 
             options.sideOrientation = MeshBuilder.updateSideOrientation(options.sideOrientation, scene);
-            polyhedron.sideOrientation = options.sideOrientation;
+            polyhedron._originalBuilderSideOrientation = options.sideOrientation;
             
             var vertexData = VertexData.CreatePolyhedron(options);
 

+ 42 - 35
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -1,22 +1,26 @@
 module BABYLON {
+    declare var require;
     declare var CANNON;
 
     export class CannonJSPlugin implements IPhysicsEnginePlugin {
 
-        public world: any; //CANNON.World
+        public world: any; //this.BJSCANNON.World
         public name: string = "CannonJSPlugin";
         private _physicsMaterials = [];
         private _fixedTimeStep: number = 1 / 60;
-        //See https://github.com/schteppe/cannon.js/blob/gh-pages/demos/collisionFilter.html
+        //See https://github.com/schteppe/CANNON.js/blob/gh-pages/demos/collisionFilter.html
         private _currentCollisionGroup = 2;
+        public BJSCANNON = typeof CANNON !== 'undefined' ? CANNON : (typeof require !== 'undefined' ? require('cannon') : undefined);
+
+
 
         public constructor(private _useDeltaForWorldStep: boolean = true, iterations: number = 10) {
             if (!this.isSupported()) {
                 Tools.Error("CannonJS is not available. Please make sure you included the js file.");
                 return;
             }
-            this.world = new CANNON.World();
-            this.world.broadphase = new CANNON.NaiveBroadphase();
+            this.world = new this.BJSCANNON.World();
+            this.world.broadphase = new this.BJSCANNON.NaiveBroadphase();
             this.world.solver.iterations = iterations;
         }
 
@@ -29,7 +33,7 @@
         }
 
         public getTimeStep(): number {
-          return this._fixedTimeStep;
+            return this._fixedTimeStep;
         }
 
         public executeStep(delta: number, impostors: Array<PhysicsImpostor>): void {
@@ -38,15 +42,15 @@
         }
 
         public applyImpulse(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
-            var worldPoint = new CANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);
-            var impulse = new CANNON.Vec3(force.x, force.y, force.z);
+            var worldPoint = new this.BJSCANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);
+            var impulse = new this.BJSCANNON.Vec3(force.x, force.y, force.z);
 
             impostor.physicsBody.applyImpulse(impulse, worldPoint);
         }
 
         public applyForce(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
-            var worldPoint = new CANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);
-            var impulse = new CANNON.Vec3(force.x, force.y, force.z);
+            var worldPoint = new this.BJSCANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);
+            var impulse = new this.BJSCANNON.Vec3(force.x, force.y, force.z);
 
             impostor.physicsBody.applyForce(impulse, worldPoint);
         }
@@ -87,7 +91,7 @@
                         bodyCreationObject[key] = nativeOptions[key];
                     }
                 }
-                impostor.physicsBody = new CANNON.Body(bodyCreationObject);
+                impostor.physicsBody = new this.BJSCANNON.Body(bodyCreationObject);
                 impostor.physicsBody.addEventListener("collide", impostor.onCollide);
                 this.world.addEventListener("preStep", impostor.beforeStep);
                 this.world.addEventListener("postStep", impostor.afterStep);
@@ -109,28 +113,31 @@
         }
 
         private _processChildMeshes(mainImpostor: PhysicsImpostor) {
-            var meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes() : [];
+            var meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes(true) : [];
+            let currentRotation: Quaternion = mainImpostor.object.rotationQuaternion;
             if (meshChildren.length) {
                 var processMesh = (localPosition: Vector3, mesh: AbstractMesh) => {
                     var childImpostor = mesh.getPhysicsImpostor();
                     if (childImpostor) {
                         var parent = childImpostor.parent;
                         if (parent !== mainImpostor) {
-                            var localPosition = mesh.position;
+                            var pPosition = mesh.getAbsolutePosition().subtract(mainImpostor.object.getAbsolutePosition());
+                            let localRotation = mesh.rotationQuaternion.multiply(Quaternion.Inverse(currentRotation));
                             if (childImpostor.physicsBody) {
                                 this.removePhysicsBody(childImpostor);
                                 childImpostor.physicsBody = null;
                             }
                             childImpostor.parent = mainImpostor;
                             childImpostor.resetUpdateFlags();
-                            mainImpostor.physicsBody.addShape(this._createShape(childImpostor), new CANNON.Vec3(localPosition.x, localPosition.y, localPosition.z));
+                            mainImpostor.physicsBody.addShape(this._createShape(childImpostor), new this.BJSCANNON.Vec3(pPosition.x, pPosition.y, pPosition.z), new this.BJSCANNON.Quaternion(localRotation.x, localRotation.y, localRotation.z, localRotation.w));
                             //Add the mass of the children.
                             mainImpostor.physicsBody.mass += childImpostor.getParam("mass");
                         }
                     }
-                    mesh.getChildMeshes().forEach(processMesh.bind(this, mesh.position));
+                    currentRotation.multiplyInPlace(mesh.rotationQuaternion);
+                    mesh.getChildMeshes(true).forEach(processMesh.bind(this, mesh.getAbsolutePosition()));
                 }
-                meshChildren.forEach(processMesh.bind(this, Vector3.Zero()));
+                meshChildren.forEach(processMesh.bind(this, mainImpostor.object.getAbsolutePosition()));
             }
         }
 
@@ -149,26 +156,26 @@
             }
             var constraint;
             var jointData = impostorJoint.joint.jointData;
-            //TODO - https://github.com/schteppe/cannon.js/blob/gh-pages/demos/collisionFilter.html
+            //TODO - https://github.com/schteppe/this.BJSCANNON.js/blob/gh-pages/demos/collisionFilter.html
             var constraintData = {
-                pivotA: jointData.mainPivot ? new CANNON.Vec3().copy(jointData.mainPivot) : null,
-                pivotB: jointData.connectedPivot ? new CANNON.Vec3().copy(jointData.connectedPivot) : null,
-                axisA: jointData.mainAxis ? new CANNON.Vec3().copy(jointData.mainAxis) : null,
-                axisB: jointData.connectedAxis ? new CANNON.Vec3().copy(jointData.connectedAxis) : null,
+                pivotA: jointData.mainPivot ? new this.BJSCANNON.Vec3().copy(jointData.mainPivot) : null,
+                pivotB: jointData.connectedPivot ? new this.BJSCANNON.Vec3().copy(jointData.connectedPivot) : null,
+                axisA: jointData.mainAxis ? new this.BJSCANNON.Vec3().copy(jointData.mainAxis) : null,
+                axisB: jointData.connectedAxis ? new this.BJSCANNON.Vec3().copy(jointData.connectedAxis) : null,
                 maxForce: jointData.nativeParams.maxForce,
                 collideConnected: !!jointData.collision
             };
             switch (impostorJoint.joint.type) {
                 case PhysicsJoint.HingeJoint:
                 case PhysicsJoint.Hinge2Joint:
-                    constraint = new CANNON.HingeConstraint(mainBody, connectedBody, constraintData);
+                    constraint = new this.BJSCANNON.HingeConstraint(mainBody, connectedBody, constraintData);
                     break;
                 case PhysicsJoint.DistanceJoint:
-                    constraint = new CANNON.DistanceConstraint(mainBody, connectedBody, (<DistanceJointData>jointData).maxDistance || 2)
+                    constraint = new this.BJSCANNON.DistanceConstraint(mainBody, connectedBody, (<DistanceJointData>jointData).maxDistance || 2)
                     break;
                 case PhysicsJoint.SpringJoint:
                     var springData = <SpringJointData>jointData;
-                    constraint = new CANNON.Spring(mainBody, connectedBody, {
+                    constraint = new this.BJSCANNON.Spring(mainBody, connectedBody, {
                         restLength: springData.length,
                         stiffness: springData.stiffness,
                         damping: springData.damping,
@@ -177,12 +184,12 @@
                     });
                     break;
                 case PhysicsJoint.LockJoint:
-                    constraint = new CANNON.LockConstraint(mainBody, connectedBody, constraintData);
+                    constraint = new this.BJSCANNON.LockConstraint(mainBody, connectedBody, constraintData);
                     break;
                 case PhysicsJoint.PointToPointJoint:
                 case PhysicsJoint.BallAndSocketJoint:
                 default:
-                    constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
+                    constraint = new this.BJSCANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
                     break;
             }
             //set the collideConnected flag after the creation, since DistanceJoint ignores it.
@@ -214,7 +221,7 @@
                 }
             }
 
-            var currentMat = new CANNON.Material(name);
+            var currentMat = new this.BJSCANNON.Material(name);
             currentMat.friction = friction;
             currentMat.restitution = restitution;
 
@@ -237,32 +244,32 @@
                     var radiusY = extendSize.y;
                     var radiusZ = extendSize.z;
 
-                    returnValue = new CANNON.Sphere(Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2);
+                    returnValue = new this.BJSCANNON.Sphere(Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2);
 
                     break;
                 //TMP also for cylinder - TODO Cannon supports cylinder natively.
                 case PhysicsImpostor.CylinderImpostor:
-                    returnValue = new CANNON.Cylinder(this._checkWithEpsilon(extendSize.x) / 2, this._checkWithEpsilon(extendSize.x) / 2, this._checkWithEpsilon(extendSize.y), 16);
+                    returnValue = new this.BJSCANNON.Cylinder(this._checkWithEpsilon(extendSize.x) / 2, this._checkWithEpsilon(extendSize.x) / 2, this._checkWithEpsilon(extendSize.y), 16);
                     break;
                 case PhysicsImpostor.BoxImpostor:
                     var box = extendSize.scale(0.5);
-                    returnValue = new CANNON.Box(new CANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
+                    returnValue = new this.BJSCANNON.Box(new this.BJSCANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
                     break;
                 case PhysicsImpostor.PlaneImpostor:
                     Tools.Warn("Attention, PlaneImposter might not behave as you expect. Consider using BoxImposter instead");
-                    returnValue = new CANNON.Plane();
+                    returnValue = new this.BJSCANNON.Plane();
                     break;
                 case PhysicsImpostor.MeshImpostor:
                     var rawVerts = object.getVerticesData ? object.getVerticesData(VertexBuffer.PositionKind) : [];
                     var rawFaces = object.getIndices ? object.getIndices() : [];
                     Tools.Warn("MeshImpostor only collides against spheres.");
-                    returnValue = new CANNON.Trimesh(rawVerts, rawFaces);
+                    returnValue = new this.BJSCANNON.Trimesh(<number[]>rawVerts, <number[]>rawFaces);
                     break;
                 case PhysicsImpostor.HeightmapImpostor:
                     returnValue = this._createHeightmap(object);
                     break;
                 case PhysicsImpostor.ParticleImpostor:
-                    returnValue = new CANNON.Particle();
+                    returnValue = new this.BJSCANNON.Particle();
                     break;
             }
 
@@ -319,7 +326,7 @@
                 }
             }
 
-            var shape = new CANNON.Heightfield(matrix, {
+            var shape = new this.BJSCANNON.Heightfield(matrix, {
                 elementSize: elementSize
             });
 
@@ -371,7 +378,7 @@
                 //rotation is back
                 mesh.rotationQuaternion = rotationQuaternion;
 
-                //calculate the new center using a pivot (since Cannon.js doesn't center height maps)
+                //calculate the new center using a pivot (since this.BJSCANNON.js doesn't center height maps)
                 var p = Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSizeWorld.x, 0, -mesh.getBoundingInfo().boundingBox.extendSizeWorld.z);
                 mesh.setPivotMatrix(p);
                 mesh.computeWorldMatrix(true);
@@ -408,7 +415,7 @@
         }
 
         public isSupported(): boolean {
-            return window.CANNON !== undefined;
+            return this.BJSCANNON !== undefined;
         }
 
         public setLinearVelocity(impostor: PhysicsImpostor, velocity: Vector3) {

+ 35 - 30
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -1,13 +1,17 @@
 module BABYLON {
+    declare var require;
     declare var OIMO;
 
     export class OimoJSPlugin implements IPhysicsEnginePlugin {
 
         public world: any;
         public name: string = "OimoJSPlugin";
+        public BJSOIMO;
+
 
         constructor(iterations?: number) {
-            this.world = new OIMO.World(1 / 60, 2, iterations, true);
+            this.BJSOIMO = typeof OIMO !== 'undefined' ? OIMO : (typeof require !== 'undefined' ? require('./Oimo') : undefined);
+            this.world = new this.BJSOIMO.World(1 / 60, 2, iterations, true);
             this.world.worldscale(1);
             this.world.clear();
             //making sure no stats are calculated
@@ -23,7 +27,7 @@ module BABYLON {
         }
 
         public getTimeStep(): number {
-          return this.world.timeStep;
+            return this.world.timeStep;
         }
 
         private _tmpImpostorsArray: Array<PhysicsImpostor> = [];
@@ -68,7 +72,7 @@ module BABYLON {
 
         public applyImpulse(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
             var mass = impostor.physicsBody.massInfo.mass;
-            impostor.physicsBody.applyImpulse(contactPoint.scale(OIMO.INV_SCALE), force.scale(OIMO.INV_SCALE * mass));
+            impostor.physicsBody.applyImpulse(contactPoint.scale(this.BJSOIMO.INV_SCALE), force.scale(this.BJSOIMO.INV_SCALE * mass));
         }
         public applyForce(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
             Tools.Warn("Oimo doesn't support applying force. Using impule instead.");
@@ -105,13 +109,13 @@ module BABYLON {
                     parent.getChildMeshes().forEach(function (m) {
                         if (m.physicsImpostor) {
                             impostors.push(m.physicsImpostor);
-                            m.physicsImpostor._init();
+                            //m.physicsImpostor._init();
                         }
                     });
                 }
                 addToArray(impostor.object)
 
-                let  checkWithEpsilon = (value: number): number => {
+                let checkWithEpsilon = (value: number): number => {
                     return Math.max(value, PhysicsEngine.Epsilon);
                 }
 
@@ -119,7 +123,7 @@ module BABYLON {
 
                     //get the correct bounding box
                     var oldQuaternion = i.object.rotationQuaternion;
-                    var rot = new OIMO.Euler().setFromQuaternion({
+                    var rot = new this.BJSOIMO.Euler().setFromQuaternion({
                         x: impostor.object.rotationQuaternion.x,
                         y: impostor.object.rotationQuaternion.y,
                         z: impostor.object.rotationQuaternion.z,
@@ -140,15 +144,16 @@ module BABYLON {
                         bodyConfig.pos.push(center.z);
 
                         //tmp solution
-                        bodyConfig.rot.push(rot.x / (OIMO.degtorad || OIMO.TO_RAD));
-                        bodyConfig.rot.push(rot.y / (OIMO.degtorad || OIMO.TO_RAD));
-                        bodyConfig.rot.push(rot.z / (OIMO.degtorad || OIMO.TO_RAD));
+                        bodyConfig.rot.push(rot.x / (this.BJSOIMO.degtorad || this.BJSOIMO.TO_RAD));
+                        bodyConfig.rot.push(rot.y / (this.BJSOIMO.degtorad || this.BJSOIMO.TO_RAD));
+                        bodyConfig.rot.push(rot.z / (this.BJSOIMO.degtorad || this.BJSOIMO.TO_RAD));
                     } else {
-                        bodyConfig.pos.push(i.object.position.x);
-                        bodyConfig.pos.push(i.object.position.y);
-                        bodyConfig.pos.push(i.object.position.z);
+                        let localPosition = i.object.getAbsolutePosition().subtract(impostor.object.getAbsolutePosition());
+                        bodyConfig.pos.push(localPosition.x);
+                        bodyConfig.pos.push(localPosition.y);
+                        bodyConfig.pos.push(localPosition.z);
 
-                        //tmp solution until https://github.com/lo-th/Oimo.js/pull/37 is merged
+                        //tmp solution until https://github.com/lo-th/OIMO.js/pull/37 is merged
                         bodyConfig.rot.push(0);
                         bodyConfig.rot.push(0);
                         bodyConfig.rot.push(0);
@@ -157,7 +162,7 @@ module BABYLON {
                     // register mesh
                     switch (i.type) {
                         case PhysicsImpostor.ParticleImpostor:
-                            Tools.Warn("No Particle support in Oimo.js. using SphereImpostor instead");
+                            Tools.Warn("No Particle support in this.BJSOIMO.js. using SphereImpostor instead");
                         case PhysicsImpostor.SphereImpostor:
                             var radiusX = extendSize.x;
                             var radiusY = extendSize.y;
@@ -203,7 +208,7 @@ module BABYLON {
                     i.object.rotationQuaternion = oldQuaternion;
                 });
 
-                impostor.physicsBody = new OIMO.Body(bodyConfig).body//this.world.add(bodyConfig);
+                impostor.physicsBody = new this.BJSOIMO.Body(bodyConfig).body//this.world.add(bodyConfig);
 
             } else {
                 this._tmpPositionVector.copyFromFloats(0, 0, 0);
@@ -256,7 +261,7 @@ module BABYLON {
                     type = "jointBall";
                     break;
                 case PhysicsJoint.SpringJoint:
-                    Tools.Warn("Oimo.js doesn't support Spring Constraint. Simulating using DistanceJoint instead");
+                    Tools.Warn("this.BJSOIMO.js doesn't support Spring Constraint. Simulating using DistanceJoint instead");
                     var springData = <SpringJointData>jointData;
                     nativeJointData.min = springData.length || nativeJointData.min;
                     //Max should also be set, just make sure it is at least min
@@ -280,7 +285,7 @@ module BABYLON {
                     break;
             }
             nativeJointData.type = type;
-            impostorJoint.joint.physicsJoint = new OIMO.Link(nativeJointData).joint//this.world.add(nativeJointData);
+            impostorJoint.joint.physicsJoint = new this.BJSOIMO.Link(nativeJointData).joint//this.world.add(nativeJointData);
         }
 
         public removeJoint(impostorJoint: PhysicsImpostorJoint) {
@@ -296,7 +301,7 @@ module BABYLON {
         }
 
         public isSupported(): boolean {
-            return OIMO !== undefined;
+            return this.BJSOIMO !== undefined;
         }
 
         public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {
@@ -304,9 +309,9 @@ module BABYLON {
                 //TODO check that
                 if (impostor.physicsBody.shapes.next) {
                     var parentShape = this._getLastShape(impostor.physicsBody);
-                    impostor.object.position.x = parentShape.position.x * OIMO.WORLD_SCALE;
-                    impostor.object.position.y = parentShape.position.y * OIMO.WORLD_SCALE;
-                    impostor.object.position.z = parentShape.position.z * OIMO.WORLD_SCALE;
+                    impostor.object.position.x = parentShape.position.x * this.BJSOIMO.WORLD_SCALE;
+                    impostor.object.position.y = parentShape.position.y * this.BJSOIMO.WORLD_SCALE;
+                    impostor.object.position.z = parentShape.position.z * this.BJSOIMO.WORLD_SCALE;
                 } else {
                     impostor.object.position.copyFrom(impostor.physicsBody.getPosition());
 
@@ -319,7 +324,7 @@ module BABYLON {
         public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
             var body = impostor.physicsBody;
 
-            body.position.init(newPosition.x * OIMO.INV_SCALE, newPosition.y * OIMO.INV_SCALE, newPosition.z * OIMO.INV_SCALE);
+            body.position.init(newPosition.x * this.BJSOIMO.INV_SCALE, newPosition.y * this.BJSOIMO.INV_SCALE, newPosition.z * this.BJSOIMO.INV_SCALE);
 
             body.orientation.init(newRotation.w, newRotation.x, newRotation.y, newRotation.z);
             body.syncShapes();
@@ -361,23 +366,23 @@ module BABYLON {
             impostor.physicsBody.setupMass(staticBody ? 0x2 : 0x1);
         }
 
-        public getBodyMass(impostor: PhysicsImpostor):number {
+        public getBodyMass(impostor: PhysicsImpostor): number {
             return impostor.physicsBody.shapes.density;
         }
 
-        public getBodyFriction(impostor: PhysicsImpostor):number {
+        public getBodyFriction(impostor: PhysicsImpostor): number {
             return impostor.physicsBody.shapes.friction;
         }
 
-        public setBodyFriction(impostor: PhysicsImpostor, friction:number) {
+        public setBodyFriction(impostor: PhysicsImpostor, friction: number) {
             impostor.physicsBody.shapes.friction = friction;
         }
 
-        public getBodyRestitution(impostor: PhysicsImpostor):number {
+        public getBodyRestitution(impostor: PhysicsImpostor): number {
             return impostor.physicsBody.shapes.restitution;
         }
 
-        public setBodyRestitution(impostor: PhysicsImpostor, restitution:number) {
+        public setBodyRestitution(impostor: PhysicsImpostor, restitution: number) {
             impostor.physicsBody.shapes.restitution = restitution;
         }
 
@@ -412,7 +417,7 @@ module BABYLON {
             }
         }
 
-        public syncMeshWithImpostor(mesh:AbstractMesh, impostor:PhysicsImpostor){
+        public syncMeshWithImpostor(mesh: AbstractMesh, impostor: PhysicsImpostor) {
             var body = impostor.physicsBody;
 
             mesh.position.x = body.position.x;
@@ -425,11 +430,11 @@ module BABYLON {
             mesh.rotationQuaternion.w = body.orientation.s;
         }
 
-        public getRadius(impostor: PhysicsImpostor):number{
+        public getRadius(impostor: PhysicsImpostor): number {
             return impostor.physicsBody.shapes.radius;
         }
 
-        public getBoxSizeToRef(impostor: PhysicsImpostor, result:Vector3):void{
+        public getBoxSizeToRef(impostor: PhysicsImpostor, result: Vector3): void {
             var shape = impostor.physicsBody.shapes;
             result.x = shape.halfWidth * 2;
             result.y = shape.halfHeight * 2;

+ 31 - 30
src/Physics/babylon.physicsImpostor.ts

@@ -16,10 +16,11 @@ module BABYLON {
         getBoundingInfo?(): BoundingInfo;
         computeWorldMatrix?(force: boolean): void;
         getWorldMatrix?(): Matrix;
-        getChildMeshes?(): Array<AbstractMesh>;
+        getChildMeshes?(directDecendantsOnly?: boolean): Array<AbstractMesh>;
         getVerticesData?(kind: string): Array<number> | Float32Array;
         getIndices?(): IndicesArray;
         getScene?(): Scene;
+        getAbsolutePosition(): Vector3;
     }
 
     export class PhysicsImpostor {
@@ -49,31 +50,31 @@ module BABYLON {
         private static _tmpVecs: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         private static _tmpQuat: Quaternion = Quaternion.Identity();
 
-        get isDisposed():boolean{
+        get isDisposed(): boolean {
             return this._isDisposed;
         }
 
-        get mass():number{
+        get mass(): number {
             return this._physicsEngine.getPhysicsPlugin().getBodyMass(this);
         }
 
-        set mass(value:number){
+        set mass(value: number) {
             this.setMass(value);
         }
 
-        get friction():number{
+        get friction(): number {
             return this._physicsEngine.getPhysicsPlugin().getBodyFriction(this);
         }
 
-        set friction(value:number){
+        set friction(value: number) {
             this._physicsEngine.getPhysicsPlugin().setBodyFriction(this, value);
         }
 
-        get restitution():number {
+        get restitution(): number {
             return this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this);
         }
 
-        set restitution(value:number){
+        set restitution(value: number) {
             this._physicsEngine.getPhysicsPlugin().setBodyRestitution(this, value);
         }
 
@@ -485,11 +486,11 @@ module BABYLON {
             this._deltaRotationConjugated = this._deltaRotation.conjugate();
         }
 
-        public getBoxSizeToRef(result:Vector3){
+        public getBoxSizeToRef(result: Vector3) {
             this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);
         }
 
-        public getRadius():number{
+        public getRadius(): number {
             return this._physicsEngine.getPhysicsPlugin().getRadius(this);
         }
 
@@ -501,16 +502,16 @@ module BABYLON {
          * @param distToJoint Optional distance from the impostor to the joint.
          * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.
          */
-        public syncBoneWithImpostor(bone:Bone, boneMesh:AbstractMesh, jointPivot:Vector3, distToJoint?:number, adjustRotation?:Quaternion){
+        public syncBoneWithImpostor(bone: Bone, boneMesh: AbstractMesh, jointPivot: Vector3, distToJoint?: number, adjustRotation?: Quaternion) {
 
             var tempVec = PhysicsImpostor._tmpVecs[0];
             var mesh = <AbstractMesh>this.object;
 
-            if(adjustRotation){
+            if (adjustRotation) {
                 var tempQuat = PhysicsImpostor._tmpQuat;
                 mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);
                 bone.setRotationQuaternion(tempQuat, Space.WORLD, boneMesh);
-            }else{
+            } else {
                 bone.setRotationQuaternion(mesh.rotationQuaternion, Space.WORLD, boneMesh);
             }
 
@@ -518,27 +519,27 @@ module BABYLON {
             tempVec.y = 0;
             tempVec.z = 0;
 
-            if(jointPivot){
+            if (jointPivot) {
                 tempVec.x = jointPivot.x;
                 tempVec.y = jointPivot.y;
                 tempVec.z = jointPivot.z;
 
                 bone.getDirectionToRef(tempVec, boneMesh, tempVec);
 
-                if(distToJoint === undefined || distToJoint === null){
+                if (distToJoint === undefined || distToJoint === null) {
                     distToJoint = jointPivot.length();
                 }
-                
+
                 tempVec.x *= distToJoint;
                 tempVec.y *= distToJoint;
                 tempVec.z *= distToJoint;
             }
 
-            if(bone.getParent()){
+            if (bone.getParent()) {
                 tempVec.addInPlace(mesh.getAbsolutePosition());
-                bone.setAbsolutePosition(tempVec, boneMesh);  
-            }else{
-                boneMesh.setAbsolutePosition(mesh.getAbsolutePosition());               
+                bone.setAbsolutePosition(tempVec, boneMesh);
+            } else {
+                boneMesh.setAbsolutePosition(mesh.getAbsolutePosition());
                 boneMesh.position.x -= tempVec.x;
                 boneMesh.position.y -= tempVec.y;
                 boneMesh.position.z -= tempVec.z;
@@ -555,43 +556,43 @@ module BABYLON {
          * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.
          * @param boneAxis Optional vector3 axis the bone is aligned with
          */
-        public syncImpostorWithBone(bone:Bone, boneMesh:AbstractMesh, jointPivot:Vector3, distToJoint?:number, adjustRotation?:Quaternion, boneAxis?:Vector3){
+        public syncImpostorWithBone(bone: Bone, boneMesh: AbstractMesh, jointPivot: Vector3, distToJoint?: number, adjustRotation?: Quaternion, boneAxis?: Vector3) {
 
             var mesh = <AbstractMesh>this.object;
 
-            if(adjustRotation){
+            if (adjustRotation) {
                 var tempQuat = PhysicsImpostor._tmpQuat;
                 bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, tempQuat);
                 tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);
-            }else{
+            } else {
                 bone.getRotationQuaternionToRef(Space.WORLD, boneMesh, mesh.rotationQuaternion);
             }
 
             var pos = PhysicsImpostor._tmpVecs[0];
             var boneDir = PhysicsImpostor._tmpVecs[1];
-            
-            if(!boneAxis){
+
+            if (!boneAxis) {
                 boneAxis = PhysicsImpostor._tmpVecs[2];
-                boneAxis.x = 0; 
-                boneAxis.y = 1; 
+                boneAxis.x = 0;
+                boneAxis.y = 1;
                 boneAxis.z = 0;
             }
 
             bone.getDirectionToRef(boneAxis, boneMesh, boneDir);
             bone.getAbsolutePositionToRef(boneMesh, pos);
 
-            if((distToJoint === undefined || distToJoint === null) && jointPivot){
+            if ((distToJoint === undefined || distToJoint === null) && jointPivot) {
                 distToJoint = jointPivot.length();
             }
 
-            if(distToJoint !== undefined && distToJoint !== null){
+            if (distToJoint !== undefined && distToJoint !== null) {
                 pos.x += boneDir.x * distToJoint;
                 pos.y += boneDir.y * distToJoint;
                 pos.z += boneDir.z * distToJoint;
             }
 
             mesh.setAbsolutePosition(pos);
-            
+
         }
 
         //Impostor types

+ 14 - 1
src/PostProcess/babylon.imageProcessingPostProcess.ts

@@ -43,8 +43,21 @@
 
             // Pick the scene configuration if needed.
             if (!configuration) {
+                var scene = null;
+                var engine = this.getEngine();
                 var camera = this.getCamera();
-                var scene = camera ? camera.getScene() : BABYLON.Engine.LastCreatedScene;
+
+                if (camera) {
+                    scene = camera.getScene();
+                }
+                else if (engine && engine.scenes) {
+                    var scenes = engine.scenes;
+                    scene = scenes[scenes.length - 1];
+                }
+                else {
+                    scene = BABYLON.Engine.LastCreatedScene;
+                }
+
                 this._imageProcessingConfiguration = scene.imageProcessingConfiguration;
             }
             else {

+ 9 - 9
src/Shaders/default.fragment.fx

@@ -180,20 +180,20 @@ void main(void) {
 #ifdef DIFFUSE
 	baseColor = texture2D(diffuseSampler, vDiffuseUV + uvOffset);
 
-#ifdef ALPHATEST
-	if (baseColor.a < 0.4)
-		discard;
-#endif
-
-#include<depthPrePass>
+	#ifdef ALPHATEST
+		if (baseColor.a < 0.4)
+			discard;
+	#endif
 
-#ifdef ALPHAFROMDIFFUSE
-	alpha *= baseColor.a;
-#endif
+	#ifdef ALPHAFROMDIFFUSE
+		alpha *= baseColor.a;
+	#endif
 
 	baseColor.rgb *= vDiffuseInfos.y;
 #endif
 
+#include<depthPrePass>
+
 #ifdef VERTEXCOLOR
 	baseColor.rgb *= vColor.rgb;
 #endif

+ 4 - 3
src/Tools/babylon.textureTools.ts

@@ -8,6 +8,10 @@
 		 * @return Generated texture
 		 */
 		public static CreateResizedCopy(texture: BABYLON.Texture, width: number, height: number, useBilinearMode: boolean = true): BABYLON.Texture {
+			
+			var scene = texture.getScene();
+			var engine = scene.getEngine();
+			
 			let rtt = new BABYLON.RenderTargetTexture(
 				'resized' + texture.name,
 				{ width: width, height: height },
@@ -20,9 +24,6 @@
 				false
 			);
 
-            var scene = texture.getScene();
-			var engine = scene.getEngine();
-
 			rtt.wrapU = texture.wrapU;
 			rtt.wrapV = texture.wrapV;
             rtt.uOffset = texture.uOffset;

Diferenças do arquivo suprimidas por serem muito extensas
+ 10 - 0
src/Tools/babylon.tools.ts


+ 5 - 0
src/babylon.engine.ts

@@ -559,6 +559,11 @@
          */
         public onCanvasPointerOutObservable = new Observable<Engine>();
 
+        /**
+         * Observable event triggered before each texture is initialized
+         */
+        public onBeforeTextureInitObservable = new Observable<Texture>();
+
         //WebVR
 
         private _vrDisplay: any = undefined;

+ 6 - 2
src/babylon.scene.ts

@@ -1484,6 +1484,10 @@
             };
 
             this._onPointerUp = (evt: PointerEvent) => {
+                if (!this._isButtonPressed) {   // We are attaching the pointer up to windows because of a bug in FF                    
+                    return;                     // So we need to test it the pointer down was pressed before.
+                }
+
                 this._isButtonPressed = false;
                 this._pickedUpMesh = null;
                 this._meshPickProceed = false;
@@ -1630,7 +1634,7 @@
             }
 
             if (attachUp) {
-                canvas.addEventListener(eventPrefix + "up", this._onPointerUp, false);
+                window.addEventListener(eventPrefix + "up", this._onPointerUp, false);
             }
 
             canvas.tabIndex = 1;
@@ -1643,7 +1647,7 @@
 
             canvas.removeEventListener(eventPrefix + "move", this._onPointerMove);
             canvas.removeEventListener(eventPrefix + "down", this._onPointerDown);
-            canvas.removeEventListener(eventPrefix + "up", this._onPointerUp);
+            window.removeEventListener(eventPrefix + "up", this._onPointerUp);
 
             engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
             engine.onCanvasFocusObservable.remove(this._onCanvasFocusObserver);

BIN
tests/validation/ReferenceImages/softShadows.png