Explorar o código

split obj loader

David Catuhe %!s(int64=5) %!d(string=hai) anos
pai
achega
6fa0969827
Modificáronse 32 ficheiros con 8559 adicións e 2679 borrados
  1. 997 317
      dist/preview release/babylon.d.ts
  2. 2 2
      dist/preview release/babylon.js
  3. 1592 228
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 2061 674
      dist/preview release/babylon.module.d.ts
  6. 1032 323
      dist/preview release/documentation.d.ts
  7. 52 19
      dist/preview release/loaders/babylon.objFileLoader.js
  8. 1 1
      dist/preview release/loaders/babylon.objFileLoader.js.map
  9. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  10. 8 1
      dist/preview release/loaders/babylonjs.loaders.d.ts
  11. 52 19
      dist/preview release/loaders/babylonjs.loaders.js
  12. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  13. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  14. 26 10
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  15. 1 1
      dist/preview release/packagesSizeBaseLine.json
  16. 108 41
      dist/preview release/serializers/babylon.glTF2Serializer.js
  17. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.js.map
  18. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  19. 27 5
      dist/preview release/serializers/babylonjs.serializers.d.ts
  20. 108 41
      dist/preview release/serializers/babylonjs.serializers.js
  21. 1 1
      dist/preview release/serializers/babylonjs.serializers.js.map
  22. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  23. 54 10
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  24. 2061 674
      dist/preview release/viewer/babylon.module.d.ts
  25. 110 78
      dist/preview release/viewer/babylon.viewer.js
  26. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  27. 26 10
      dist/preview release/viewer/babylonjs.loaders.module.d.ts
  28. 1 0
      loaders/src/OBJ/index.ts
  29. 210 0
      loaders/src/OBJ/mtlFileLoader.ts
  30. 11 205
      loaders/src/OBJ/objFileLoader.ts
  31. 4 2
      tests/validation/config.json
  32. 4 7
      tests/validation/validation.js

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 997 - 317
dist/preview release/babylon.d.ts


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 2
dist/preview release/babylon.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1592 - 228
dist/preview release/babylon.max.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/babylon.max.js.map


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2061 - 674
dist/preview release/babylon.module.d.ts


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1032 - 323
dist/preview release/documentation.d.ts


+ 52 - 19
dist/preview release/loaders/babylon.objFileLoader.js

@@ -136,38 +136,33 @@ module.exports = g;
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony import */ var _objFileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./objFileLoader */ "./OBJ/objFileLoader.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MTLFileLoader", function() { return _objFileLoader__WEBPACK_IMPORTED_MODULE_0__["MTLFileLoader"]; });
+/* harmony import */ var _mtlFileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mtlFileLoader */ "./OBJ/mtlFileLoader.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MTLFileLoader", function() { return _mtlFileLoader__WEBPACK_IMPORTED_MODULE_0__["MTLFileLoader"]; });
 
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OBJFileLoader", function() { return _objFileLoader__WEBPACK_IMPORTED_MODULE_0__["OBJFileLoader"]; });
+/* harmony import */ var _objFileLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./objFileLoader */ "./OBJ/objFileLoader.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OBJFileLoader", function() { return _objFileLoader__WEBPACK_IMPORTED_MODULE_1__["OBJFileLoader"]; });
 
 
+
 
 
 /***/ }),
 
-/***/ "./OBJ/objFileLoader.ts":
+/***/ "./OBJ/mtlFileLoader.ts":
 /*!******************************!*\
-  !*** ./OBJ/objFileLoader.ts ***!
+  !*** ./OBJ/mtlFileLoader.ts ***!
   \******************************/
-/*! exports provided: MTLFileLoader, OBJFileLoader */
+/*! exports provided: MTLFileLoader */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MTLFileLoader", function() { return MTLFileLoader; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJFileLoader", function() { return OBJFileLoader; });
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
 
 
 
-
-
-
-
-
-
 /**
  * Class reading and parsing the MTL file bundled with the obj file.
  */
@@ -373,11 +368,40 @@ var MTLFileLoader = /** @class */ (function () {
         else {
             url += value;
         }
-        return new babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Texture"](url, scene, false, OBJFileLoader.INVERT_TEXTURE_Y);
+        return new babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Texture"](url, scene, false, MTLFileLoader.INVERT_TEXTURE_Y);
     };
+    /**
+     * Invert Y-Axis of referenced textures on load
+     */
+    MTLFileLoader.INVERT_TEXTURE_Y = true;
     return MTLFileLoader;
 }());
 
+
+
+/***/ }),
+
+/***/ "./OBJ/objFileLoader.ts":
+/*!******************************!*\
+  !*** ./OBJ/objFileLoader.ts ***!
+  \******************************/
+/*! exports provided: OBJFileLoader */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJFileLoader", function() { return OBJFileLoader; });
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _mtlFileLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mtlFileLoader */ "./OBJ/mtlFileLoader.ts");
+
+
+
+
+
+
+
+
 /**
  * OBJ file type loader.
  * This is a babylon scene loader plugin.
@@ -432,6 +456,19 @@ var OBJFileLoader = /** @class */ (function () {
         this.facePattern5 = /f\s+(((-[\d]{1,}\/-[\d]{1,}\/-[\d]{1,}[\s]?){3,})+)/;
         this._meshLoadOptions = meshLoadOptions || OBJFileLoader.currentMeshLoadOptions;
     }
+    Object.defineProperty(OBJFileLoader, "INVERT_TEXTURE_Y", {
+        /**
+         * Invert Y-Axis of referenced textures on load
+         */
+        get: function () {
+            return _mtlFileLoader__WEBPACK_IMPORTED_MODULE_1__["MTLFileLoader"].INVERT_TEXTURE_Y;
+        },
+        set: function (value) {
+            _mtlFileLoader__WEBPACK_IMPORTED_MODULE_1__["MTLFileLoader"].INVERT_TEXTURE_Y = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
     Object.defineProperty(OBJFileLoader, "currentMeshLoadOptions", {
         get: function () {
             return {
@@ -587,7 +624,7 @@ var OBJFileLoader = /** @class */ (function () {
         var triangles = []; //Indices from new triangles coming from polygons
         var materialNameFromObj = ""; //The name of the current material
         var fileToLoad = ""; //The name of the mtlFile to load
-        var materialsFromMTLFile = new MTLFileLoader();
+        var materialsFromMTLFile = new _mtlFileLoader__WEBPACK_IMPORTED_MODULE_1__["MTLFileLoader"]();
         var objMeshName = ""; //The name of the current obj mesh
         var increment = 1; //Id for meshes created by the multimaterial
         var isFirstMaterial = true;
@@ -1180,10 +1217,6 @@ var OBJFileLoader = /** @class */ (function () {
      */
     OBJFileLoader.INVERT_Y = false;
     /**
-     * Invert Y-Axis of referenced textures on load
-     */
-    OBJFileLoader.INVERT_TEXTURE_Y = true;
-    /**
      * Include in meshes the vertex colors available in some OBJ files.  This is not part of OBJ standard.
      */
     OBJFileLoader.IMPORT_VERTEX_COLORS = false;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.js.map


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


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

@@ -2024,6 +2024,10 @@ declare module BABYLON {
      */
     export class MTLFileLoader {
         /**
+         * Invert Y-Axis of referenced textures on load
+         */
+        static INVERT_TEXTURE_Y: boolean;
+        /**
          * All material loaded from the mtl will be set here
          */
         materials: StandardMaterial[];
@@ -2050,6 +2054,8 @@ declare module BABYLON {
          */
         private static _getTexture;
     }
+}
+declare module BABYLON {
     /**
      * Options for loading OBJ/MTL files
      */
@@ -2103,7 +2109,8 @@ declare module BABYLON {
         /**
          * Invert Y-Axis of referenced textures on load
          */
-        static INVERT_TEXTURE_Y: boolean;
+        static get INVERT_TEXTURE_Y(): boolean;
+        static set INVERT_TEXTURE_Y(value: boolean);
         /**
          * Include in meshes the vertex colors available in some OBJ files.  This is not part of OBJ standard.
          */

+ 52 - 19
dist/preview release/loaders/babylonjs.loaders.js

@@ -365,38 +365,33 @@ module.exports = g;
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony import */ var _objFileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./objFileLoader */ "./OBJ/objFileLoader.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MTLFileLoader", function() { return _objFileLoader__WEBPACK_IMPORTED_MODULE_0__["MTLFileLoader"]; });
+/* harmony import */ var _mtlFileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mtlFileLoader */ "./OBJ/mtlFileLoader.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MTLFileLoader", function() { return _mtlFileLoader__WEBPACK_IMPORTED_MODULE_0__["MTLFileLoader"]; });
 
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OBJFileLoader", function() { return _objFileLoader__WEBPACK_IMPORTED_MODULE_0__["OBJFileLoader"]; });
+/* harmony import */ var _objFileLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./objFileLoader */ "./OBJ/objFileLoader.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OBJFileLoader", function() { return _objFileLoader__WEBPACK_IMPORTED_MODULE_1__["OBJFileLoader"]; });
 
 
+
 
 
 /***/ }),
 
-/***/ "./OBJ/objFileLoader.ts":
+/***/ "./OBJ/mtlFileLoader.ts":
 /*!******************************!*\
-  !*** ./OBJ/objFileLoader.ts ***!
+  !*** ./OBJ/mtlFileLoader.ts ***!
   \******************************/
-/*! exports provided: MTLFileLoader, OBJFileLoader */
+/*! exports provided: MTLFileLoader */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MTLFileLoader", function() { return MTLFileLoader; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJFileLoader", function() { return OBJFileLoader; });
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
 
 
 
-
-
-
-
-
-
 /**
  * Class reading and parsing the MTL file bundled with the obj file.
  */
@@ -602,11 +597,40 @@ var MTLFileLoader = /** @class */ (function () {
         else {
             url += value;
         }
-        return new babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Texture"](url, scene, false, OBJFileLoader.INVERT_TEXTURE_Y);
+        return new babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Texture"](url, scene, false, MTLFileLoader.INVERT_TEXTURE_Y);
     };
+    /**
+     * Invert Y-Axis of referenced textures on load
+     */
+    MTLFileLoader.INVERT_TEXTURE_Y = true;
     return MTLFileLoader;
 }());
 
+
+
+/***/ }),
+
+/***/ "./OBJ/objFileLoader.ts":
+/*!******************************!*\
+  !*** ./OBJ/objFileLoader.ts ***!
+  \******************************/
+/*! exports provided: OBJFileLoader */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJFileLoader", function() { return OBJFileLoader; });
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _mtlFileLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mtlFileLoader */ "./OBJ/mtlFileLoader.ts");
+
+
+
+
+
+
+
+
 /**
  * OBJ file type loader.
  * This is a babylon scene loader plugin.
@@ -661,6 +685,19 @@ var OBJFileLoader = /** @class */ (function () {
         this.facePattern5 = /f\s+(((-[\d]{1,}\/-[\d]{1,}\/-[\d]{1,}[\s]?){3,})+)/;
         this._meshLoadOptions = meshLoadOptions || OBJFileLoader.currentMeshLoadOptions;
     }
+    Object.defineProperty(OBJFileLoader, "INVERT_TEXTURE_Y", {
+        /**
+         * Invert Y-Axis of referenced textures on load
+         */
+        get: function () {
+            return _mtlFileLoader__WEBPACK_IMPORTED_MODULE_1__["MTLFileLoader"].INVERT_TEXTURE_Y;
+        },
+        set: function (value) {
+            _mtlFileLoader__WEBPACK_IMPORTED_MODULE_1__["MTLFileLoader"].INVERT_TEXTURE_Y = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
     Object.defineProperty(OBJFileLoader, "currentMeshLoadOptions", {
         get: function () {
             return {
@@ -816,7 +853,7 @@ var OBJFileLoader = /** @class */ (function () {
         var triangles = []; //Indices from new triangles coming from polygons
         var materialNameFromObj = ""; //The name of the current material
         var fileToLoad = ""; //The name of the mtlFile to load
-        var materialsFromMTLFile = new MTLFileLoader();
+        var materialsFromMTLFile = new _mtlFileLoader__WEBPACK_IMPORTED_MODULE_1__["MTLFileLoader"]();
         var objMeshName = ""; //The name of the current obj mesh
         var increment = 1; //Id for meshes created by the multimaterial
         var isFirstMaterial = true;
@@ -1409,10 +1446,6 @@ var OBJFileLoader = /** @class */ (function () {
      */
     OBJFileLoader.INVERT_Y = false;
     /**
-     * Invert Y-Axis of referenced textures on load
-     */
-    OBJFileLoader.INVERT_TEXTURE_Y = true;
-    /**
      * Include in meshes the vertex colors available in some OBJ files.  This is not part of OBJ standard.
      */
     OBJFileLoader.IMPORT_VERTEX_COLORS = false;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


+ 26 - 10
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -2220,21 +2220,18 @@ declare module "babylonjs-loaders/glTF/index" {
     import * as GLTF2 from "babylonjs-loaders/glTF/2.0/index";
     export { GLTF1, GLTF2 };
 }
-declare module "babylonjs-loaders/OBJ/objFileLoader" {
-    import { Vector2 } from "babylonjs/Maths/math";
-    import { AnimationGroup } from "babylonjs/Animations/animationGroup";
-    import { Skeleton } from "babylonjs/Bones/skeleton";
-    import { IParticleSystem } from "babylonjs/Particles/IParticleSystem";
+declare module "babylonjs-loaders/OBJ/mtlFileLoader" {
     import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
-    import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
-    import { ISceneLoaderPluginAsync, SceneLoaderProgressEvent, ISceneLoaderPluginFactory, ISceneLoaderPlugin } from "babylonjs/Loading/sceneLoader";
-    import { AssetContainer } from "babylonjs/assetContainer";
     import { Scene } from "babylonjs/scene";
     /**
      * Class reading and parsing the MTL file bundled with the obj file.
      */
     export class MTLFileLoader {
         /**
+         * Invert Y-Axis of referenced textures on load
+         */
+        static INVERT_TEXTURE_Y: boolean;
+        /**
          * All material loaded from the mtl will be set here
          */
         materials: StandardMaterial[];
@@ -2261,6 +2258,16 @@ declare module "babylonjs-loaders/OBJ/objFileLoader" {
          */
         private static _getTexture;
     }
+}
+declare module "babylonjs-loaders/OBJ/objFileLoader" {
+    import { Vector2 } from "babylonjs/Maths/math";
+    import { AnimationGroup } from "babylonjs/Animations/animationGroup";
+    import { Skeleton } from "babylonjs/Bones/skeleton";
+    import { IParticleSystem } from "babylonjs/Particles/IParticleSystem";
+    import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
+    import { ISceneLoaderPluginAsync, SceneLoaderProgressEvent, ISceneLoaderPluginFactory, ISceneLoaderPlugin } from "babylonjs/Loading/sceneLoader";
+    import { AssetContainer } from "babylonjs/assetContainer";
+    import { Scene } from "babylonjs/scene";
     /**
      * Options for loading OBJ/MTL files
      */
@@ -2314,7 +2321,8 @@ declare module "babylonjs-loaders/OBJ/objFileLoader" {
         /**
          * Invert Y-Axis of referenced textures on load
          */
-        static INVERT_TEXTURE_Y: boolean;
+        static get INVERT_TEXTURE_Y(): boolean;
+        static set INVERT_TEXTURE_Y(value: boolean);
         /**
          * Include in meshes the vertex colors available in some OBJ files.  This is not part of OBJ standard.
          */
@@ -2455,6 +2463,7 @@ declare module "babylonjs-loaders/OBJ/objFileLoader" {
     }
 }
 declare module "babylonjs-loaders/OBJ/index" {
+    export * from "babylonjs-loaders/OBJ/mtlFileLoader";
     export * from "babylonjs-loaders/OBJ/objFileLoader";
 }
 declare module "babylonjs-loaders/STL/stlFileLoader" {
@@ -4600,6 +4609,10 @@ declare module BABYLON {
      */
     export class MTLFileLoader {
         /**
+         * Invert Y-Axis of referenced textures on load
+         */
+        static INVERT_TEXTURE_Y: boolean;
+        /**
          * All material loaded from the mtl will be set here
          */
         materials: StandardMaterial[];
@@ -4626,6 +4639,8 @@ declare module BABYLON {
          */
         private static _getTexture;
     }
+}
+declare module BABYLON {
     /**
      * Options for loading OBJ/MTL files
      */
@@ -4679,7 +4694,8 @@ declare module BABYLON {
         /**
          * Invert Y-Axis of referenced textures on load
          */
-        static INVERT_TEXTURE_Y: boolean;
+        static get INVERT_TEXTURE_Y(): boolean;
+        static set INVERT_TEXTURE_Y(value: boolean);
         /**
          * Include in meshes the vertex colors available in some OBJ files.  This is not part of OBJ standard.
          */

+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"thinEngineOnly":111570,"engineOnly":148415,"sceneOnly":502199,"minGridMaterial":632586,"minStandardMaterial":757114}
+{"thinEngineOnly":111570,"engineOnly":148415,"sceneOnly":502177,"minGridMaterial":632519,"minStandardMaterial":757058}

+ 108 - 41
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -432,8 +432,9 @@ var KHR_lights_punctual = /** @class */ (function () {
                 }
                 else {
                     var lightPosition = babylonLight.position.clone();
+                    var convertToRightHandedSystem = _this._exporter._convertToRightHandedSystemMap[babylonNode.uniqueId];
                     if (!lightPosition.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero())) {
-                        if (_this._exporter._convertToRightHandedSystem) {
+                        if (convertToRightHandedSystem) {
                             _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(lightPosition);
                         }
                         node.translation = lightPosition.asArray();
@@ -444,7 +445,7 @@ var KHR_lights_punctual = /** @class */ (function () {
                         var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
                         var pitch = -Math.atan2(localAxis.y, len);
                         var lightRotationQuaternion = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(yaw, pitch, 0);
-                        if (_this._exporter._convertToRightHandedSystem) {
+                        if (convertToRightHandedSystem) {
                             _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(lightRotationQuaternion);
                         }
                         if (!lightRotationQuaternion.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity())) {
@@ -928,6 +929,7 @@ var _GLTFAnimation = /** @class */ (function () {
      * @param bufferViews
      * @param accessors
      * @param convertToRightHandedSystem
+     * @param animationSampleRate
      */
     _GLTFAnimation._CreateNodeAnimationFromNodeAnimations = function (babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
         var glTFAnimation;
@@ -961,9 +963,10 @@ var _GLTFAnimation = /** @class */ (function () {
      * @param binaryWriter
      * @param bufferViews
      * @param accessors
-     * @param convertToRightHandedSystem
+     * @param convertToRightHandedSystemMap
+     * @param animationSampleRate
      */
-    _GLTFAnimation._CreateNodeAnimationFromAnimationGroups = function (babylonScene, glTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
+    _GLTFAnimation._CreateNodeAnimationFromAnimationGroups = function (babylonScene, glTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystemMap, animationSampleRate) {
         var glTFAnimation;
         if (babylonScene.animationGroups) {
             var animationGroups = babylonScene.animationGroups;
@@ -982,6 +985,7 @@ var _GLTFAnimation = /** @class */ (function () {
                         var animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);
                         if (animationInfo) {
                             var babylonTransformNode = target instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["TransformNode"] ? target : target[0];
+                            var convertToRightHandedSystem = convertToRightHandedSystemMap[babylonTransformNode.uniqueId];
                             _GLTFAnimation.AddAnimation("" + animation.name, glTFAnimation, babylonTransformNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate);
                         }
                     }
@@ -1591,7 +1595,6 @@ var _Exporter = /** @class */ (function () {
         this._samplers = [];
         this._animations = [];
         this._imageData = {};
-        this._convertToRightHandedSystem = !this._babylonScene.useRightHandedSystem;
         this._options = options || {};
         this._animationSampleRate = options && options.animationSampleRate ? options.animationSampleRate : 1 / 60;
         this._glTFMaterialExporter = new _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_2__["_GLTFMaterialExporter"](this);
@@ -1784,20 +1787,21 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray The vertex attribute data
      * @param byteOffset The offset to the binary data
      * @param binaryWriter The binary data for the glTF file
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.reorderVertexAttributeDataBasedOnPrimitiveMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
-        if (this._convertToRightHandedSystem && sideOrientation === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].ClockWiseSideOrientation) {
+    _Exporter.prototype.reorderVertexAttributeDataBasedOnPrimitiveMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
+        if (convertToRightHandedSystem && sideOrientation === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].ClockWiseSideOrientation) {
             switch (primitiveMode) {
                 case babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].TriangleFillMode: {
-                    this.reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
+                    this.reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
                     break;
                 }
                 case babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].TriangleStripDrawMode: {
-                    this.reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
+                    this.reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
                     break;
                 }
                 case babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].TriangleFanDrawMode: {
-                    this.reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
+                    this.reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
                     break;
                 }
             }
@@ -1813,8 +1817,9 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray The vertex attribute data
      * @param byteOffset The offset to the binary data
      * @param binaryWriter The binary data for the glTF file
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.reorderTriangleFillMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
+    _Exporter.prototype.reorderTriangleFillMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
         var vertexBuffer = this.getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
         if (vertexBuffer) {
             var stride = vertexBuffer.byteStride / babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].GetTypeByteLength(vertexBuffer.type);
@@ -1875,7 +1880,7 @@ var _Exporter = /** @class */ (function () {
                         babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Error("Unsupported Vertex Buffer type: " + vertexBufferKind);
                     }
                 }
-                this.writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter);
+                this.writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
             }
         }
         else {
@@ -1892,8 +1897,9 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray The vertex attribute data
      * @param byteOffset The offset to the binary data
      * @param binaryWriter The binary data for the glTF file
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.reorderTriangleStripDrawMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
+    _Exporter.prototype.reorderTriangleStripDrawMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
         var vertexBuffer = this.getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
         if (vertexBuffer) {
             var stride = vertexBuffer.byteStride / babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].GetTypeByteLength(vertexBuffer.type);
@@ -1933,7 +1939,7 @@ var _Exporter = /** @class */ (function () {
                     babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Error("Unsupported Vertex Buffer type: " + vertexBufferKind);
                 }
             }
-            this.writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter);
+            this.writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
         }
         else {
             babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("reorderTriangleStripDrawMode: Vertex buffer kind " + vertexBufferKind + " not present!");
@@ -1949,8 +1955,9 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray The vertex attribute data
      * @param byteOffset The offset to the binary data
      * @param binaryWriter The binary data for the glTF file
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.reorderTriangleFanMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
+    _Exporter.prototype.reorderTriangleFanMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
         var vertexBuffer = this.getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
         if (vertexBuffer) {
             var stride = vertexBuffer.byteStride / babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].GetTypeByteLength(vertexBuffer.type);
@@ -1992,7 +1999,7 @@ var _Exporter = /** @class */ (function () {
                     babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Error("Unsupported Vertex Buffer type: " + vertexBufferKind);
                 }
             }
-            this.writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter);
+            this.writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
         }
         else {
             babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("reorderTriangleFanMode: Vertex buffer kind " + vertexBufferKind + " not present!");
@@ -2005,11 +2012,12 @@ var _Exporter = /** @class */ (function () {
      * @param vertexAttributeKind The vertex attribute type
      * @param meshAttributeArray The vertex attribute data
      * @param binaryWriter The writer containing the binary data
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.writeVertexAttributeData = function (vertices, byteOffset, vertexAttributeKind, meshAttributeArray, binaryWriter) {
+    _Exporter.prototype.writeVertexAttributeData = function (vertices, byteOffset, vertexAttributeKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem) {
         for (var _i = 0, vertices_1 = vertices; _i < vertices_1.length; _i++) {
             var vertex = vertices_1[_i];
-            if (this._convertToRightHandedSystem && !(vertexAttributeKind === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind) && !(vertex instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector2"])) {
+            if (convertToRightHandedSystem && !(vertexAttributeKind === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind) && !(vertex instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector2"])) {
                 if (vertex instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"]) {
                     if (vertexAttributeKind === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind) {
                         _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(vertex);
@@ -2045,8 +2053,9 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray Array containing the attribute data
      * @param binaryWriter The buffer to write the binary data to
      * @param indices Used to specify the order of the vertex data
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, byteStride, binaryWriter) {
+    _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, byteStride, binaryWriter, convertToRightHandedSystem) {
         var stride = byteStride / 4;
         var vertexAttributes = [];
         var index;
@@ -2055,7 +2064,7 @@ var _Exporter = /** @class */ (function () {
                 for (var k = 0, length_2 = meshAttributeArray.length / stride; k < length_2; ++k) {
                     index = k * stride;
                     var vertexData = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(meshAttributeArray, index);
-                    if (this._convertToRightHandedSystem) {
+                    if (convertToRightHandedSystem) {
                         _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(vertexData);
                     }
                     vertexAttributes.push(vertexData.asArray());
@@ -2066,7 +2075,7 @@ var _Exporter = /** @class */ (function () {
                 for (var k = 0, length_3 = meshAttributeArray.length / stride; k < length_3; ++k) {
                     index = k * stride;
                     var vertexData = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(meshAttributeArray, index);
-                    if (this._convertToRightHandedSystem) {
+                    if (convertToRightHandedSystem) {
                         _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(vertexData);
                     }
                     vertexData.normalize();
@@ -2078,7 +2087,7 @@ var _Exporter = /** @class */ (function () {
                 for (var k = 0, length_4 = meshAttributeArray.length / stride; k < length_4; ++k) {
                     index = k * stride;
                     var vertexData = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector4"].FromArray(meshAttributeArray, index);
-                    if (this._convertToRightHandedSystem) {
+                    if (convertToRightHandedSystem) {
                         _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedVector4FromRef(vertexData);
                     }
                     _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._NormalizeTangentFromRef(vertexData);
@@ -2098,7 +2107,7 @@ var _Exporter = /** @class */ (function () {
             case babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind: {
                 for (var k = 0, length_6 = meshAttributeArray.length / stride; k < length_6; ++k) {
                     index = k * stride;
-                    vertexAttributes.push(this._convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]);
+                    vertexAttributes.push(convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]);
                 }
                 break;
             }
@@ -2327,13 +2336,14 @@ var _Exporter = /** @class */ (function () {
      * Sets the TRS for each node
      * @param node glTF Node for storing the transformation data
      * @param babylonTransformNode Babylon mesh used as the source for the transformation data
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.setNodeTransformation = function (node, babylonTransformNode) {
+    _Exporter.prototype.setNodeTransformation = function (node, babylonTransformNode, convertToRightHandedSystem) {
         if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) {
             babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Pivot points are not supported in the glTF serializer");
         }
         if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) {
-            node.translation = this._convertToRightHandedSystem ? _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedPositionVector3(babylonTransformNode.position).asArray() : babylonTransformNode.position.asArray();
+            node.translation = convertToRightHandedSystem ? _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedPositionVector3(babylonTransformNode.position).asArray() : babylonTransformNode.position.asArray();
         }
         if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) {
             node.scale = babylonTransformNode.scaling.asArray();
@@ -2343,7 +2353,7 @@ var _Exporter = /** @class */ (function () {
             rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion);
         }
         if (!(rotationQuaternion.x === 0 && rotationQuaternion.y === 0 && rotationQuaternion.z === 0 && rotationQuaternion.w === 1)) {
-            if (this._convertToRightHandedSystem) {
+            if (convertToRightHandedSystem) {
                 _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(rotationQuaternion);
             }
             node.rotation = rotationQuaternion.normalize().asArray();
@@ -2363,8 +2373,9 @@ var _Exporter = /** @class */ (function () {
      * @param kind Indicates the type of vertices data
      * @param babylonTransformNode The Babylon mesh to get the vertices data from
      * @param binaryWriter The buffer to write the bufferview data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.createBufferViewKind = function (kind, babylonTransformNode, binaryWriter, byteStride) {
+    _Exporter.prototype.createBufferViewKind = function (kind, babylonTransformNode, binaryWriter, byteStride, convertToRightHandedSystem) {
         var bufferMesh = babylonTransformNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Mesh"] ?
             babylonTransformNode : babylonTransformNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["InstancedMesh"] ?
             babylonTransformNode.sourceMesh : null;
@@ -2374,7 +2385,7 @@ var _Exporter = /** @class */ (function () {
                 var byteLength = vertexData.length * 4;
                 var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, kind + " - " + bufferMesh.name);
                 this._bufferViews.push(bufferView);
-                this.writeAttributeData(kind, vertexData, byteStride, binaryWriter);
+                this.writeAttributeData(kind, vertexData, byteStride, binaryWriter, convertToRightHandedSystem);
             }
         }
     };
@@ -2470,8 +2481,9 @@ var _Exporter = /** @class */ (function () {
      * @param mesh glTF Mesh object to store the primitive attribute information
      * @param babylonTransformNode Babylon mesh to get the primitive attribute data from
      * @param binaryWriter Buffer to write the attribute data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.setPrimitiveAttributesAsync = function (mesh, babylonTransformNode, binaryWriter) {
+    _Exporter.prototype.setPrimitiveAttributesAsync = function (mesh, babylonTransformNode, binaryWriter, convertToRightHandedSystem) {
         var promises = [];
         var bufferMesh = null;
         var bufferView;
@@ -2504,7 +2516,7 @@ var _Exporter = /** @class */ (function () {
                     if (attribute.byteStride === 12) {
                         attribute.accessorType = "VEC3" /* VEC3 */;
                     }
-                    this.createBufferViewKind(attributeKind, babylonTransformNode, binaryWriter, attribute.byteStride);
+                    this.createBufferViewKind(attributeKind, babylonTransformNode, binaryWriter, attribute.byteStride, convertToRightHandedSystem);
                     attribute.bufferViewIndex = this._bufferViews.length - 1;
                     vertexAttributeBufferViews[attributeKind] = attribute.bufferViewIndex;
                 }
@@ -2572,7 +2584,7 @@ var _Exporter = /** @class */ (function () {
                                 if (bufferViewIndex != undefined) { // check to see if bufferviewindex has a numeric value assigned.
                                     minMax = { min: null, max: null };
                                     if (attributeKind == babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind) {
-                                        minMax = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, this._convertToRightHandedSystem);
+                                        minMax = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, convertToRightHandedSystem);
                                     }
                                     var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateAccessor(bufferViewIndex, attributeKind + " - " + babylonTransformNode.name, attribute.accessorType, 5126 /* FLOAT */, vertexData.length / stride, 0, minMax.min, minMax.max);
                                     this._accessors.push(accessor);
@@ -2590,7 +2602,7 @@ var _Exporter = /** @class */ (function () {
                     if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
                         var sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;
                         // Only reverse the winding if we have a clockwise winding
-                        if (sideOrientation === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].ClockWiseSideOrientation) {
+                        if (convertToRightHandedSystem && sideOrientation === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].ClockWiseSideOrientation) {
                             var byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;
                             if (byteOffset == null) {
                                 byteOffset = 0;
@@ -2611,7 +2623,7 @@ var _Exporter = /** @class */ (function () {
                                         if (!byteOffset_1) {
                                             byteOffset_1 = 0;
                                         }
-                                        this.reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter);
+                                        this.reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter, convertToRightHandedSystem);
                                     }
                                 }
                             }
@@ -2631,6 +2643,32 @@ var _Exporter = /** @class */ (function () {
         });
     };
     /**
+     * Check if the node is used to convert its descendants from right-handed to left-handed
+     * @param node The node to check
+     * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
+     */
+    _Exporter.prototype.isNodeConvertingToLeftHanded = function (node) {
+        if (node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["TransformNode"]) {
+            // Transform
+            var matrix = node.getWorldMatrix();
+            var matrixToLeftHanded = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Compose(new babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"](-1, 1, 1), babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Identity(), babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero());
+            var matrixProduct = matrix.multiply(matrixToLeftHanded);
+            var matrixIdentity = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Matrix"].IdentityReadOnly;
+            for (var i = 0; i < 16; i++) {
+                if (Math.abs(matrixProduct.m[i] - matrixIdentity.m[i]) > babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Epsilon"]) {
+                    return false;
+                }
+            }
+            // Geometry
+            if ((node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Mesh"] && node.geometry !== null) ||
+                (node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["InstancedMesh"] && node.sourceMesh.geometry !== null)) {
+                return false;
+            }
+            return true;
+        }
+        return false;
+    };
+    /**
      * Creates a glTF scene based on the array of meshes
      * Returns the the total byte offset
      * @param babylonScene Babylon scene to get the mesh data from
@@ -2643,6 +2681,32 @@ var _Exporter = /** @class */ (function () {
         var glTFNode;
         var directDescendents;
         var nodes = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spreadArrays"])(babylonScene.transformNodes, babylonScene.meshes, babylonScene.lights);
+        var rootNodesToLeftHanded = [];
+        this._convertToRightHandedSystemMap = {};
+        // Set default values for all nodes
+        babylonScene.rootNodes.forEach(function (rootNode) {
+            _this._convertToRightHandedSystemMap[rootNode.uniqueId] = !babylonScene.useRightHandedSystem;
+            rootNode.getDescendants(false).forEach(function (descendant) {
+                _this._convertToRightHandedSystemMap[descendant.uniqueId] = !babylonScene.useRightHandedSystem;
+            });
+        });
+        if (!babylonScene.useRightHandedSystem) {
+            // Check if root nodes converting to left-handed are present
+            babylonScene.rootNodes.forEach(function (rootNode) {
+                if (_this.isNodeConvertingToLeftHanded(rootNode)) {
+                    rootNodesToLeftHanded.push(rootNode);
+                    // Exclude the node from list of nodes to export
+                    var indexRootNode = nodes.indexOf(rootNode);
+                    if (indexRootNode !== -1) { // should always be true
+                        nodes.splice(indexRootNode, 1);
+                    }
+                    // Cancel conversion to right handed system
+                    rootNode.getDescendants(false).forEach(function (descendant) {
+                        _this._convertToRightHandedSystemMap[descendant.uniqueId] = false;
+                    });
+                }
+            });
+        }
         return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(babylonScene.materials, "image/png" /* PNG */, true).then(function () {
             return _this.createNodeMapAndAnimationsAsync(babylonScene, nodes, binaryWriter).then(function (nodeMap) {
                 _this._nodeMap = nodeMap;
@@ -2664,12 +2728,13 @@ var _Exporter = /** @class */ (function () {
                                 glTFNode.extras = babylonNode.metadata.gltf.extras;
                             }
                         }
-                        if (!babylonNode.parent) {
+                        if (!babylonNode.parent || rootNodesToLeftHanded.indexOf(babylonNode.parent) !== -1) {
                             if (_this._options.shouldExportNode && !_this._options.shouldExportNode(babylonNode)) {
                                 babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Log("Omitting " + babylonNode.name + " from scene.");
                             }
                             else {
-                                if (_this._convertToRightHandedSystem) {
+                                var convertToRightHandedSystem = _this._convertToRightHandedSystemMap[babylonNode.uniqueId];
+                                if (convertToRightHandedSystem) {
                                     if (glTFNode.translation) {
                                         glTFNode.translation[2] *= -1;
                                         glTFNode.translation[0] *= -1;
@@ -2721,7 +2786,8 @@ var _Exporter = /** @class */ (function () {
         var _loop_1 = function (babylonNode) {
             if (!this_1._options.shouldExportNode || this_1._options.shouldExportNode(babylonNode)) {
                 promiseChain = promiseChain.then(function () {
-                    return _this.createNodeAsync(babylonNode, binaryWriter).then(function (node) {
+                    var convertToRightHandedSystem = _this._convertToRightHandedSystemMap[babylonNode.uniqueId];
+                    return _this.createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem).then(function (node) {
                         var promise = _this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode);
                         if (promise == null) {
                             babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Not exporting node " + babylonNode.name);
@@ -2736,7 +2802,7 @@ var _Exporter = /** @class */ (function () {
                                 nodeIndex = _this._nodes.length - 1;
                                 nodeMap[babylonNode.uniqueId] = nodeIndex;
                                 if (!babylonScene.animationGroups.length && babylonNode.animations.length) {
-                                    _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystem, _this._animationSampleRate);
+                                    _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
                                 }
                             });
                         }
@@ -2762,7 +2828,7 @@ var _Exporter = /** @class */ (function () {
                 }
             });
             if (babylonScene.animationGroups.length) {
-                _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromAnimationGroups(babylonScene, _this._animations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystem, _this._animationSampleRate);
+                _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromAnimationGroups(babylonScene, _this._animations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystemMap, _this._animationSampleRate);
             }
             return nodeMap;
         });
@@ -2771,9 +2837,10 @@ var _Exporter = /** @class */ (function () {
      * Creates a glTF node from a Babylon mesh
      * @param babylonMesh Source Babylon mesh
      * @param binaryWriter Buffer for storing geometry data
+     * @param convertToRightHandedSystem Converts the values to right-handed
      * @returns glTF node
      */
-    _Exporter.prototype.createNodeAsync = function (babylonNode, binaryWriter) {
+    _Exporter.prototype.createNodeAsync = function (babylonNode, binaryWriter, convertToRightHandedSystem) {
         var _this = this;
         return Promise.resolve().then(function () {
             // create node to hold translation/rotation/scale and the mesh
@@ -2785,8 +2852,8 @@ var _Exporter = /** @class */ (function () {
             }
             if (babylonNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["TransformNode"]) {
                 // Set transformation
-                _this.setNodeTransformation(node, babylonNode);
-                return _this.setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter).then(function () {
+                _this.setNodeTransformation(node, babylonNode, convertToRightHandedSystem);
+                return _this.setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(function () {
                     if (mesh.primitives.length) {
                         _this._meshes.push(mesh);
                         node.mesh = _this._meshes.length - 1;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.js.map


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 27 - 5
dist/preview release/serializers/babylonjs.serializers.d.ts

@@ -573,9 +573,11 @@ declare module BABYLON.GLTF2.Exporter {
          */
         private _nodeMap;
         /**
-         * Specifies if the Babylon scene should be converted to right-handed on export
+         * Specifies if a Babylon node should be converted to right-handed on export
          */
-        _convertToRightHandedSystem: boolean;
+        _convertToRightHandedSystemMap: {
+            [nodeId: number]: boolean;
+        };
         /**
          * Baked animation sample rate
          */
@@ -634,6 +636,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderVertexAttributeDataBasedOnPrimitiveMode;
         /**
@@ -646,6 +649,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleFillMode;
         /**
@@ -658,6 +662,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleStripDrawMode;
         /**
@@ -670,6 +675,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleFanMode;
         /**
@@ -679,6 +685,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param vertexAttributeKind The vertex attribute type
          * @param meshAttributeArray The vertex attribute data
          * @param binaryWriter The writer containing the binary data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private writeVertexAttributeData;
         /**
@@ -688,8 +695,9 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray Array containing the attribute data
          * @param binaryWriter The buffer to write the binary data to
          * @param indices Used to specify the order of the vertex data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
-        writeAttributeData(vertexBufferKind: string, meshAttributeArray: FloatArray, byteStride: number, binaryWriter: _BinaryWriter): void;
+        writeAttributeData(vertexBufferKind: string, meshAttributeArray: FloatArray, byteStride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean): void;
         /**
          * Generates glTF json data
          * @param shouldUseGlb Indicates whether the json should be written for a glb file
@@ -724,6 +732,7 @@ declare module BABYLON.GLTF2.Exporter {
          * Sets the TRS for each node
          * @param node glTF Node for storing the transformation data
          * @param babylonTransformNode Babylon mesh used as the source for the transformation data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private setNodeTransformation;
         private getVertexBufferFromMesh;
@@ -732,6 +741,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param kind Indicates the type of vertices data
          * @param babylonTransformNode The Babylon mesh to get the vertices data from
          * @param binaryWriter The buffer to write the bufferview data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private createBufferViewKind;
         /**
@@ -757,9 +767,16 @@ declare module BABYLON.GLTF2.Exporter {
          * @param mesh glTF Mesh object to store the primitive attribute information
          * @param babylonTransformNode Babylon mesh to get the primitive attribute data from
          * @param binaryWriter Buffer to write the attribute data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private setPrimitiveAttributesAsync;
         /**
+         * Check if the node is used to convert its descendants from right-handed to left-handed
+         * @param node The node to check
+         * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
+         */
+        private isNodeConvertingToLeftHanded;
+        /**
          * Creates a glTF scene based on the array of meshes
          * Returns the the total byte offset
          * @param babylonScene Babylon scene to get the mesh data from
@@ -778,6 +795,7 @@ declare module BABYLON.GLTF2.Exporter {
          * Creates a glTF node from a Babylon mesh
          * @param babylonMesh Source Babylon mesh
          * @param binaryWriter Buffer for storing geometry data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          * @returns glTF node
          */
         private createNodeAsync;
@@ -923,6 +941,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param bufferViews
          * @param accessors
          * @param convertToRightHandedSystem
+         * @param animationSampleRate
          */
         static _CreateNodeAnimationFromNodeAnimations(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
@@ -937,11 +956,14 @@ declare module BABYLON.GLTF2.Exporter {
          * @param binaryWriter
          * @param bufferViews
          * @param accessors
-         * @param convertToRightHandedSystem
+         * @param convertToRightHandedSystemMap
+         * @param animationSampleRate
          */
         static _CreateNodeAnimationFromAnimationGroups(babylonScene: Scene, glTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
-        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
+        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystemMap: {
+            [nodeId: number]: boolean;
+        }, animationSampleRate: number): void;
         private static AddAnimation;
         /**
          * Create a baked animation

+ 108 - 41
dist/preview release/serializers/babylonjs.serializers.js

@@ -610,8 +610,9 @@ var KHR_lights_punctual = /** @class */ (function () {
                 }
                 else {
                     var lightPosition = babylonLight.position.clone();
+                    var convertToRightHandedSystem = _this._exporter._convertToRightHandedSystemMap[babylonNode.uniqueId];
                     if (!lightPosition.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero())) {
-                        if (_this._exporter._convertToRightHandedSystem) {
+                        if (convertToRightHandedSystem) {
                             _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(lightPosition);
                         }
                         node.translation = lightPosition.asArray();
@@ -622,7 +623,7 @@ var KHR_lights_punctual = /** @class */ (function () {
                         var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
                         var pitch = -Math.atan2(localAxis.y, len);
                         var lightRotationQuaternion = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(yaw, pitch, 0);
-                        if (_this._exporter._convertToRightHandedSystem) {
+                        if (convertToRightHandedSystem) {
                             _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(lightRotationQuaternion);
                         }
                         if (!lightRotationQuaternion.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity())) {
@@ -1106,6 +1107,7 @@ var _GLTFAnimation = /** @class */ (function () {
      * @param bufferViews
      * @param accessors
      * @param convertToRightHandedSystem
+     * @param animationSampleRate
      */
     _GLTFAnimation._CreateNodeAnimationFromNodeAnimations = function (babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
         var glTFAnimation;
@@ -1139,9 +1141,10 @@ var _GLTFAnimation = /** @class */ (function () {
      * @param binaryWriter
      * @param bufferViews
      * @param accessors
-     * @param convertToRightHandedSystem
+     * @param convertToRightHandedSystemMap
+     * @param animationSampleRate
      */
-    _GLTFAnimation._CreateNodeAnimationFromAnimationGroups = function (babylonScene, glTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
+    _GLTFAnimation._CreateNodeAnimationFromAnimationGroups = function (babylonScene, glTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystemMap, animationSampleRate) {
         var glTFAnimation;
         if (babylonScene.animationGroups) {
             var animationGroups = babylonScene.animationGroups;
@@ -1160,6 +1163,7 @@ var _GLTFAnimation = /** @class */ (function () {
                         var animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);
                         if (animationInfo) {
                             var babylonTransformNode = target instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["TransformNode"] ? target : target[0];
+                            var convertToRightHandedSystem = convertToRightHandedSystemMap[babylonTransformNode.uniqueId];
                             _GLTFAnimation.AddAnimation("" + animation.name, glTFAnimation, babylonTransformNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate);
                         }
                     }
@@ -1769,7 +1773,6 @@ var _Exporter = /** @class */ (function () {
         this._samplers = [];
         this._animations = [];
         this._imageData = {};
-        this._convertToRightHandedSystem = !this._babylonScene.useRightHandedSystem;
         this._options = options || {};
         this._animationSampleRate = options && options.animationSampleRate ? options.animationSampleRate : 1 / 60;
         this._glTFMaterialExporter = new _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_2__["_GLTFMaterialExporter"](this);
@@ -1962,20 +1965,21 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray The vertex attribute data
      * @param byteOffset The offset to the binary data
      * @param binaryWriter The binary data for the glTF file
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.reorderVertexAttributeDataBasedOnPrimitiveMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
-        if (this._convertToRightHandedSystem && sideOrientation === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].ClockWiseSideOrientation) {
+    _Exporter.prototype.reorderVertexAttributeDataBasedOnPrimitiveMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
+        if (convertToRightHandedSystem && sideOrientation === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].ClockWiseSideOrientation) {
             switch (primitiveMode) {
                 case babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].TriangleFillMode: {
-                    this.reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
+                    this.reorderTriangleFillMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
                     break;
                 }
                 case babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].TriangleStripDrawMode: {
-                    this.reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
+                    this.reorderTriangleStripDrawMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
                     break;
                 }
                 case babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].TriangleFanDrawMode: {
-                    this.reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter);
+                    this.reorderTriangleFanMode(submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem);
                     break;
                 }
             }
@@ -1991,8 +1995,9 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray The vertex attribute data
      * @param byteOffset The offset to the binary data
      * @param binaryWriter The binary data for the glTF file
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.reorderTriangleFillMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
+    _Exporter.prototype.reorderTriangleFillMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
         var vertexBuffer = this.getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
         if (vertexBuffer) {
             var stride = vertexBuffer.byteStride / babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].GetTypeByteLength(vertexBuffer.type);
@@ -2053,7 +2058,7 @@ var _Exporter = /** @class */ (function () {
                         babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Error("Unsupported Vertex Buffer type: " + vertexBufferKind);
                     }
                 }
-                this.writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter);
+                this.writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
             }
         }
         else {
@@ -2070,8 +2075,9 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray The vertex attribute data
      * @param byteOffset The offset to the binary data
      * @param binaryWriter The binary data for the glTF file
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.reorderTriangleStripDrawMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
+    _Exporter.prototype.reorderTriangleStripDrawMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
         var vertexBuffer = this.getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
         if (vertexBuffer) {
             var stride = vertexBuffer.byteStride / babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].GetTypeByteLength(vertexBuffer.type);
@@ -2111,7 +2117,7 @@ var _Exporter = /** @class */ (function () {
                     babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Error("Unsupported Vertex Buffer type: " + vertexBufferKind);
                 }
             }
-            this.writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter);
+            this.writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
         }
         else {
             babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("reorderTriangleStripDrawMode: Vertex buffer kind " + vertexBufferKind + " not present!");
@@ -2127,8 +2133,9 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray The vertex attribute data
      * @param byteOffset The offset to the binary data
      * @param binaryWriter The binary data for the glTF file
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.reorderTriangleFanMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter) {
+    _Exporter.prototype.reorderTriangleFanMode = function (submesh, primitiveMode, sideOrientation, vertexBufferKind, meshAttributeArray, byteOffset, binaryWriter, convertToRightHandedSystem) {
         var vertexBuffer = this.getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh());
         if (vertexBuffer) {
             var stride = vertexBuffer.byteStride / babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].GetTypeByteLength(vertexBuffer.type);
@@ -2170,7 +2177,7 @@ var _Exporter = /** @class */ (function () {
                     babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Error("Unsupported Vertex Buffer type: " + vertexBufferKind);
                 }
             }
-            this.writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter);
+            this.writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);
         }
         else {
             babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("reorderTriangleFanMode: Vertex buffer kind " + vertexBufferKind + " not present!");
@@ -2183,11 +2190,12 @@ var _Exporter = /** @class */ (function () {
      * @param vertexAttributeKind The vertex attribute type
      * @param meshAttributeArray The vertex attribute data
      * @param binaryWriter The writer containing the binary data
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.writeVertexAttributeData = function (vertices, byteOffset, vertexAttributeKind, meshAttributeArray, binaryWriter) {
+    _Exporter.prototype.writeVertexAttributeData = function (vertices, byteOffset, vertexAttributeKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem) {
         for (var _i = 0, vertices_1 = vertices; _i < vertices_1.length; _i++) {
             var vertex = vertices_1[_i];
-            if (this._convertToRightHandedSystem && !(vertexAttributeKind === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind) && !(vertex instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector2"])) {
+            if (convertToRightHandedSystem && !(vertexAttributeKind === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind) && !(vertex instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector2"])) {
                 if (vertex instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"]) {
                     if (vertexAttributeKind === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind) {
                         _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(vertex);
@@ -2223,8 +2231,9 @@ var _Exporter = /** @class */ (function () {
      * @param meshAttributeArray Array containing the attribute data
      * @param binaryWriter The buffer to write the binary data to
      * @param indices Used to specify the order of the vertex data
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, byteStride, binaryWriter) {
+    _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, byteStride, binaryWriter, convertToRightHandedSystem) {
         var stride = byteStride / 4;
         var vertexAttributes = [];
         var index;
@@ -2233,7 +2242,7 @@ var _Exporter = /** @class */ (function () {
                 for (var k = 0, length_2 = meshAttributeArray.length / stride; k < length_2; ++k) {
                     index = k * stride;
                     var vertexData = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(meshAttributeArray, index);
-                    if (this._convertToRightHandedSystem) {
+                    if (convertToRightHandedSystem) {
                         _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(vertexData);
                     }
                     vertexAttributes.push(vertexData.asArray());
@@ -2244,7 +2253,7 @@ var _Exporter = /** @class */ (function () {
                 for (var k = 0, length_3 = meshAttributeArray.length / stride; k < length_3; ++k) {
                     index = k * stride;
                     var vertexData = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(meshAttributeArray, index);
-                    if (this._convertToRightHandedSystem) {
+                    if (convertToRightHandedSystem) {
                         _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(vertexData);
                     }
                     vertexData.normalize();
@@ -2256,7 +2265,7 @@ var _Exporter = /** @class */ (function () {
                 for (var k = 0, length_4 = meshAttributeArray.length / stride; k < length_4; ++k) {
                     index = k * stride;
                     var vertexData = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector4"].FromArray(meshAttributeArray, index);
-                    if (this._convertToRightHandedSystem) {
+                    if (convertToRightHandedSystem) {
                         _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedVector4FromRef(vertexData);
                     }
                     _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._NormalizeTangentFromRef(vertexData);
@@ -2276,7 +2285,7 @@ var _Exporter = /** @class */ (function () {
             case babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind: {
                 for (var k = 0, length_6 = meshAttributeArray.length / stride; k < length_6; ++k) {
                     index = k * stride;
-                    vertexAttributes.push(this._convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]);
+                    vertexAttributes.push(convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]);
                 }
                 break;
             }
@@ -2505,13 +2514,14 @@ var _Exporter = /** @class */ (function () {
      * Sets the TRS for each node
      * @param node glTF Node for storing the transformation data
      * @param babylonTransformNode Babylon mesh used as the source for the transformation data
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.setNodeTransformation = function (node, babylonTransformNode) {
+    _Exporter.prototype.setNodeTransformation = function (node, babylonTransformNode, convertToRightHandedSystem) {
         if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) {
             babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Pivot points are not supported in the glTF serializer");
         }
         if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) {
-            node.translation = this._convertToRightHandedSystem ? _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedPositionVector3(babylonTransformNode.position).asArray() : babylonTransformNode.position.asArray();
+            node.translation = convertToRightHandedSystem ? _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedPositionVector3(babylonTransformNode.position).asArray() : babylonTransformNode.position.asArray();
         }
         if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) {
             node.scale = babylonTransformNode.scaling.asArray();
@@ -2521,7 +2531,7 @@ var _Exporter = /** @class */ (function () {
             rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion);
         }
         if (!(rotationQuaternion.x === 0 && rotationQuaternion.y === 0 && rotationQuaternion.z === 0 && rotationQuaternion.w === 1)) {
-            if (this._convertToRightHandedSystem) {
+            if (convertToRightHandedSystem) {
                 _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(rotationQuaternion);
             }
             node.rotation = rotationQuaternion.normalize().asArray();
@@ -2541,8 +2551,9 @@ var _Exporter = /** @class */ (function () {
      * @param kind Indicates the type of vertices data
      * @param babylonTransformNode The Babylon mesh to get the vertices data from
      * @param binaryWriter The buffer to write the bufferview data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.createBufferViewKind = function (kind, babylonTransformNode, binaryWriter, byteStride) {
+    _Exporter.prototype.createBufferViewKind = function (kind, babylonTransformNode, binaryWriter, byteStride, convertToRightHandedSystem) {
         var bufferMesh = babylonTransformNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Mesh"] ?
             babylonTransformNode : babylonTransformNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["InstancedMesh"] ?
             babylonTransformNode.sourceMesh : null;
@@ -2552,7 +2563,7 @@ var _Exporter = /** @class */ (function () {
                 var byteLength = vertexData.length * 4;
                 var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, kind + " - " + bufferMesh.name);
                 this._bufferViews.push(bufferView);
-                this.writeAttributeData(kind, vertexData, byteStride, binaryWriter);
+                this.writeAttributeData(kind, vertexData, byteStride, binaryWriter, convertToRightHandedSystem);
             }
         }
     };
@@ -2648,8 +2659,9 @@ var _Exporter = /** @class */ (function () {
      * @param mesh glTF Mesh object to store the primitive attribute information
      * @param babylonTransformNode Babylon mesh to get the primitive attribute data from
      * @param binaryWriter Buffer to write the attribute data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
      */
-    _Exporter.prototype.setPrimitiveAttributesAsync = function (mesh, babylonTransformNode, binaryWriter) {
+    _Exporter.prototype.setPrimitiveAttributesAsync = function (mesh, babylonTransformNode, binaryWriter, convertToRightHandedSystem) {
         var promises = [];
         var bufferMesh = null;
         var bufferView;
@@ -2682,7 +2694,7 @@ var _Exporter = /** @class */ (function () {
                     if (attribute.byteStride === 12) {
                         attribute.accessorType = "VEC3" /* VEC3 */;
                     }
-                    this.createBufferViewKind(attributeKind, babylonTransformNode, binaryWriter, attribute.byteStride);
+                    this.createBufferViewKind(attributeKind, babylonTransformNode, binaryWriter, attribute.byteStride, convertToRightHandedSystem);
                     attribute.bufferViewIndex = this._bufferViews.length - 1;
                     vertexAttributeBufferViews[attributeKind] = attribute.bufferViewIndex;
                 }
@@ -2750,7 +2762,7 @@ var _Exporter = /** @class */ (function () {
                                 if (bufferViewIndex != undefined) { // check to see if bufferviewindex has a numeric value assigned.
                                     minMax = { min: null, max: null };
                                     if (attributeKind == babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind) {
-                                        minMax = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, this._convertToRightHandedSystem);
+                                        minMax = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, convertToRightHandedSystem);
                                     }
                                     var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateAccessor(bufferViewIndex, attributeKind + " - " + babylonTransformNode.name, attribute.accessorType, 5126 /* FLOAT */, vertexData.length / stride, 0, minMax.min, minMax.max);
                                     this._accessors.push(accessor);
@@ -2768,7 +2780,7 @@ var _Exporter = /** @class */ (function () {
                     if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
                         var sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;
                         // Only reverse the winding if we have a clockwise winding
-                        if (sideOrientation === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].ClockWiseSideOrientation) {
+                        if (convertToRightHandedSystem && sideOrientation === babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Material"].ClockWiseSideOrientation) {
                             var byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;
                             if (byteOffset == null) {
                                 byteOffset = 0;
@@ -2789,7 +2801,7 @@ var _Exporter = /** @class */ (function () {
                                         if (!byteOffset_1) {
                                             byteOffset_1 = 0;
                                         }
-                                        this.reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter);
+                                        this.reorderVertexAttributeDataBasedOnPrimitiveMode(submesh, primitiveMode, sideOrientation, attribute.kind, vertexData, byteOffset_1, binaryWriter, convertToRightHandedSystem);
                                     }
                                 }
                             }
@@ -2809,6 +2821,32 @@ var _Exporter = /** @class */ (function () {
         });
     };
     /**
+     * Check if the node is used to convert its descendants from right-handed to left-handed
+     * @param node The node to check
+     * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
+     */
+    _Exporter.prototype.isNodeConvertingToLeftHanded = function (node) {
+        if (node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["TransformNode"]) {
+            // Transform
+            var matrix = node.getWorldMatrix();
+            var matrixToLeftHanded = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Compose(new babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"](-1, 1, 1), babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Identity(), babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero());
+            var matrixProduct = matrix.multiply(matrixToLeftHanded);
+            var matrixIdentity = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Matrix"].IdentityReadOnly;
+            for (var i = 0; i < 16; i++) {
+                if (Math.abs(matrixProduct.m[i] - matrixIdentity.m[i]) > babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Epsilon"]) {
+                    return false;
+                }
+            }
+            // Geometry
+            if ((node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Mesh"] && node.geometry !== null) ||
+                (node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["InstancedMesh"] && node.sourceMesh.geometry !== null)) {
+                return false;
+            }
+            return true;
+        }
+        return false;
+    };
+    /**
      * Creates a glTF scene based on the array of meshes
      * Returns the the total byte offset
      * @param babylonScene Babylon scene to get the mesh data from
@@ -2821,6 +2859,32 @@ var _Exporter = /** @class */ (function () {
         var glTFNode;
         var directDescendents;
         var nodes = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__spreadArrays"])(babylonScene.transformNodes, babylonScene.meshes, babylonScene.lights);
+        var rootNodesToLeftHanded = [];
+        this._convertToRightHandedSystemMap = {};
+        // Set default values for all nodes
+        babylonScene.rootNodes.forEach(function (rootNode) {
+            _this._convertToRightHandedSystemMap[rootNode.uniqueId] = !babylonScene.useRightHandedSystem;
+            rootNode.getDescendants(false).forEach(function (descendant) {
+                _this._convertToRightHandedSystemMap[descendant.uniqueId] = !babylonScene.useRightHandedSystem;
+            });
+        });
+        if (!babylonScene.useRightHandedSystem) {
+            // Check if root nodes converting to left-handed are present
+            babylonScene.rootNodes.forEach(function (rootNode) {
+                if (_this.isNodeConvertingToLeftHanded(rootNode)) {
+                    rootNodesToLeftHanded.push(rootNode);
+                    // Exclude the node from list of nodes to export
+                    var indexRootNode = nodes.indexOf(rootNode);
+                    if (indexRootNode !== -1) { // should always be true
+                        nodes.splice(indexRootNode, 1);
+                    }
+                    // Cancel conversion to right handed system
+                    rootNode.getDescendants(false).forEach(function (descendant) {
+                        _this._convertToRightHandedSystemMap[descendant.uniqueId] = false;
+                    });
+                }
+            });
+        }
         return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(babylonScene.materials, "image/png" /* PNG */, true).then(function () {
             return _this.createNodeMapAndAnimationsAsync(babylonScene, nodes, binaryWriter).then(function (nodeMap) {
                 _this._nodeMap = nodeMap;
@@ -2842,12 +2906,13 @@ var _Exporter = /** @class */ (function () {
                                 glTFNode.extras = babylonNode.metadata.gltf.extras;
                             }
                         }
-                        if (!babylonNode.parent) {
+                        if (!babylonNode.parent || rootNodesToLeftHanded.indexOf(babylonNode.parent) !== -1) {
                             if (_this._options.shouldExportNode && !_this._options.shouldExportNode(babylonNode)) {
                                 babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Log("Omitting " + babylonNode.name + " from scene.");
                             }
                             else {
-                                if (_this._convertToRightHandedSystem) {
+                                var convertToRightHandedSystem = _this._convertToRightHandedSystemMap[babylonNode.uniqueId];
+                                if (convertToRightHandedSystem) {
                                     if (glTFNode.translation) {
                                         glTFNode.translation[2] *= -1;
                                         glTFNode.translation[0] *= -1;
@@ -2899,7 +2964,8 @@ var _Exporter = /** @class */ (function () {
         var _loop_1 = function (babylonNode) {
             if (!this_1._options.shouldExportNode || this_1._options.shouldExportNode(babylonNode)) {
                 promiseChain = promiseChain.then(function () {
-                    return _this.createNodeAsync(babylonNode, binaryWriter).then(function (node) {
+                    var convertToRightHandedSystem = _this._convertToRightHandedSystemMap[babylonNode.uniqueId];
+                    return _this.createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem).then(function (node) {
                         var promise = _this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode);
                         if (promise == null) {
                             babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Not exporting node " + babylonNode.name);
@@ -2914,7 +2980,7 @@ var _Exporter = /** @class */ (function () {
                                 nodeIndex = _this._nodes.length - 1;
                                 nodeMap[babylonNode.uniqueId] = nodeIndex;
                                 if (!babylonScene.animationGroups.length && babylonNode.animations.length) {
-                                    _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystem, _this._animationSampleRate);
+                                    _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
                                 }
                             });
                         }
@@ -2940,7 +3006,7 @@ var _Exporter = /** @class */ (function () {
                 }
             });
             if (babylonScene.animationGroups.length) {
-                _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromAnimationGroups(babylonScene, _this._animations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystem, _this._animationSampleRate);
+                _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromAnimationGroups(babylonScene, _this._animations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystemMap, _this._animationSampleRate);
             }
             return nodeMap;
         });
@@ -2949,9 +3015,10 @@ var _Exporter = /** @class */ (function () {
      * Creates a glTF node from a Babylon mesh
      * @param babylonMesh Source Babylon mesh
      * @param binaryWriter Buffer for storing geometry data
+     * @param convertToRightHandedSystem Converts the values to right-handed
      * @returns glTF node
      */
-    _Exporter.prototype.createNodeAsync = function (babylonNode, binaryWriter) {
+    _Exporter.prototype.createNodeAsync = function (babylonNode, binaryWriter, convertToRightHandedSystem) {
         var _this = this;
         return Promise.resolve().then(function () {
             // create node to hold translation/rotation/scale and the mesh
@@ -2963,8 +3030,8 @@ var _Exporter = /** @class */ (function () {
             }
             if (babylonNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__["TransformNode"]) {
                 // Set transformation
-                _this.setNodeTransformation(node, babylonNode);
-                return _this.setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter).then(function () {
+                _this.setNodeTransformation(node, babylonNode, convertToRightHandedSystem);
+                return _this.setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(function () {
                     if (mesh.primitives.length) {
                         _this._meshes.push(mesh);
                         node.mesh = _this._meshes.length - 1;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.js.map


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 54 - 10
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -614,9 +614,11 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          */
         private _nodeMap;
         /**
-         * Specifies if the Babylon scene should be converted to right-handed on export
+         * Specifies if a Babylon node should be converted to right-handed on export
          */
-        _convertToRightHandedSystem: boolean;
+        _convertToRightHandedSystemMap: {
+            [nodeId: number]: boolean;
+        };
         /**
          * Baked animation sample rate
          */
@@ -675,6 +677,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderVertexAttributeDataBasedOnPrimitiveMode;
         /**
@@ -687,6 +690,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleFillMode;
         /**
@@ -699,6 +703,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleStripDrawMode;
         /**
@@ -711,6 +716,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleFanMode;
         /**
@@ -720,6 +726,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * @param vertexAttributeKind The vertex attribute type
          * @param meshAttributeArray The vertex attribute data
          * @param binaryWriter The writer containing the binary data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private writeVertexAttributeData;
         /**
@@ -729,8 +736,9 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * @param meshAttributeArray Array containing the attribute data
          * @param binaryWriter The buffer to write the binary data to
          * @param indices Used to specify the order of the vertex data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
-        writeAttributeData(vertexBufferKind: string, meshAttributeArray: FloatArray, byteStride: number, binaryWriter: _BinaryWriter): void;
+        writeAttributeData(vertexBufferKind: string, meshAttributeArray: FloatArray, byteStride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean): void;
         /**
          * Generates glTF json data
          * @param shouldUseGlb Indicates whether the json should be written for a glb file
@@ -765,6 +773,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * Sets the TRS for each node
          * @param node glTF Node for storing the transformation data
          * @param babylonTransformNode Babylon mesh used as the source for the transformation data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private setNodeTransformation;
         private getVertexBufferFromMesh;
@@ -773,6 +782,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * @param kind Indicates the type of vertices data
          * @param babylonTransformNode The Babylon mesh to get the vertices data from
          * @param binaryWriter The buffer to write the bufferview data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private createBufferViewKind;
         /**
@@ -798,9 +808,16 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * @param mesh glTF Mesh object to store the primitive attribute information
          * @param babylonTransformNode Babylon mesh to get the primitive attribute data from
          * @param binaryWriter Buffer to write the attribute data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private setPrimitiveAttributesAsync;
         /**
+         * Check if the node is used to convert its descendants from right-handed to left-handed
+         * @param node The node to check
+         * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
+         */
+        private isNodeConvertingToLeftHanded;
+        /**
          * Creates a glTF scene based on the array of meshes
          * Returns the the total byte offset
          * @param babylonScene Babylon scene to get the mesh data from
@@ -819,6 +836,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * Creates a glTF node from a Babylon mesh
          * @param babylonMesh Source Babylon mesh
          * @param binaryWriter Buffer for storing geometry data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          * @returns glTF node
          */
         private createNodeAsync;
@@ -971,6 +989,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFAnimation" {
          * @param bufferViews
          * @param accessors
          * @param convertToRightHandedSystem
+         * @param animationSampleRate
          */
         static _CreateNodeAnimationFromNodeAnimations(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
@@ -985,11 +1004,14 @@ declare module "babylonjs-serializers/glTF/2.0/glTFAnimation" {
          * @param binaryWriter
          * @param bufferViews
          * @param accessors
-         * @param convertToRightHandedSystem
+         * @param convertToRightHandedSystemMap
+         * @param animationSampleRate
          */
         static _CreateNodeAnimationFromAnimationGroups(babylonScene: Scene, glTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
-        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
+        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystemMap: {
+            [nodeId: number]: boolean;
+        }, animationSampleRate: number): void;
         private static AddAnimation;
         /**
          * Create a baked animation
@@ -1820,9 +1842,11 @@ declare module BABYLON.GLTF2.Exporter {
          */
         private _nodeMap;
         /**
-         * Specifies if the Babylon scene should be converted to right-handed on export
+         * Specifies if a Babylon node should be converted to right-handed on export
          */
-        _convertToRightHandedSystem: boolean;
+        _convertToRightHandedSystemMap: {
+            [nodeId: number]: boolean;
+        };
         /**
          * Baked animation sample rate
          */
@@ -1881,6 +1905,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderVertexAttributeDataBasedOnPrimitiveMode;
         /**
@@ -1893,6 +1918,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleFillMode;
         /**
@@ -1905,6 +1931,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleStripDrawMode;
         /**
@@ -1917,6 +1944,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray The vertex attribute data
          * @param byteOffset The offset to the binary data
          * @param binaryWriter The binary data for the glTF file
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private reorderTriangleFanMode;
         /**
@@ -1926,6 +1954,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param vertexAttributeKind The vertex attribute type
          * @param meshAttributeArray The vertex attribute data
          * @param binaryWriter The writer containing the binary data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private writeVertexAttributeData;
         /**
@@ -1935,8 +1964,9 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshAttributeArray Array containing the attribute data
          * @param binaryWriter The buffer to write the binary data to
          * @param indices Used to specify the order of the vertex data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
-        writeAttributeData(vertexBufferKind: string, meshAttributeArray: FloatArray, byteStride: number, binaryWriter: _BinaryWriter): void;
+        writeAttributeData(vertexBufferKind: string, meshAttributeArray: FloatArray, byteStride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean): void;
         /**
          * Generates glTF json data
          * @param shouldUseGlb Indicates whether the json should be written for a glb file
@@ -1971,6 +2001,7 @@ declare module BABYLON.GLTF2.Exporter {
          * Sets the TRS for each node
          * @param node glTF Node for storing the transformation data
          * @param babylonTransformNode Babylon mesh used as the source for the transformation data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private setNodeTransformation;
         private getVertexBufferFromMesh;
@@ -1979,6 +2010,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param kind Indicates the type of vertices data
          * @param babylonTransformNode The Babylon mesh to get the vertices data from
          * @param binaryWriter The buffer to write the bufferview data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private createBufferViewKind;
         /**
@@ -2004,9 +2036,16 @@ declare module BABYLON.GLTF2.Exporter {
          * @param mesh glTF Mesh object to store the primitive attribute information
          * @param babylonTransformNode Babylon mesh to get the primitive attribute data from
          * @param binaryWriter Buffer to write the attribute data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
          */
         private setPrimitiveAttributesAsync;
         /**
+         * Check if the node is used to convert its descendants from right-handed to left-handed
+         * @param node The node to check
+         * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise
+         */
+        private isNodeConvertingToLeftHanded;
+        /**
          * Creates a glTF scene based on the array of meshes
          * Returns the the total byte offset
          * @param babylonScene Babylon scene to get the mesh data from
@@ -2025,6 +2064,7 @@ declare module BABYLON.GLTF2.Exporter {
          * Creates a glTF node from a Babylon mesh
          * @param babylonMesh Source Babylon mesh
          * @param binaryWriter Buffer for storing geometry data
+         * @param convertToRightHandedSystem Converts the values to right-handed
          * @returns glTF node
          */
         private createNodeAsync;
@@ -2170,6 +2210,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param bufferViews
          * @param accessors
          * @param convertToRightHandedSystem
+         * @param animationSampleRate
          */
         static _CreateNodeAnimationFromNodeAnimations(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
@@ -2184,11 +2225,14 @@ declare module BABYLON.GLTF2.Exporter {
          * @param binaryWriter
          * @param bufferViews
          * @param accessors
-         * @param convertToRightHandedSystem
+         * @param convertToRightHandedSystemMap
+         * @param animationSampleRate
          */
         static _CreateNodeAnimationFromAnimationGroups(babylonScene: Scene, glTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
-        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
+        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystemMap: {
+            [nodeId: number]: boolean;
+        }, animationSampleRate: number): void;
         private static AddAnimation;
         /**
          * Create a baked animation

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2061 - 674
dist/preview release/viewer/babylon.module.d.ts


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 110 - 78
dist/preview release/viewer/babylon.viewer.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 26 - 10
dist/preview release/viewer/babylonjs.loaders.module.d.ts

@@ -2220,21 +2220,18 @@ declare module "babylonjs-loaders/glTF/index" {
     import * as GLTF2 from "babylonjs-loaders/glTF/2.0/index";
     export { GLTF1, GLTF2 };
 }
-declare module "babylonjs-loaders/OBJ/objFileLoader" {
-    import { Vector2 } from "babylonjs/Maths/math";
-    import { AnimationGroup } from "babylonjs/Animations/animationGroup";
-    import { Skeleton } from "babylonjs/Bones/skeleton";
-    import { IParticleSystem } from "babylonjs/Particles/IParticleSystem";
+declare module "babylonjs-loaders/OBJ/mtlFileLoader" {
     import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
-    import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
-    import { ISceneLoaderPluginAsync, SceneLoaderProgressEvent, ISceneLoaderPluginFactory, ISceneLoaderPlugin } from "babylonjs/Loading/sceneLoader";
-    import { AssetContainer } from "babylonjs/assetContainer";
     import { Scene } from "babylonjs/scene";
     /**
      * Class reading and parsing the MTL file bundled with the obj file.
      */
     export class MTLFileLoader {
         /**
+         * Invert Y-Axis of referenced textures on load
+         */
+        static INVERT_TEXTURE_Y: boolean;
+        /**
          * All material loaded from the mtl will be set here
          */
         materials: StandardMaterial[];
@@ -2261,6 +2258,16 @@ declare module "babylonjs-loaders/OBJ/objFileLoader" {
          */
         private static _getTexture;
     }
+}
+declare module "babylonjs-loaders/OBJ/objFileLoader" {
+    import { Vector2 } from "babylonjs/Maths/math";
+    import { AnimationGroup } from "babylonjs/Animations/animationGroup";
+    import { Skeleton } from "babylonjs/Bones/skeleton";
+    import { IParticleSystem } from "babylonjs/Particles/IParticleSystem";
+    import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
+    import { ISceneLoaderPluginAsync, SceneLoaderProgressEvent, ISceneLoaderPluginFactory, ISceneLoaderPlugin } from "babylonjs/Loading/sceneLoader";
+    import { AssetContainer } from "babylonjs/assetContainer";
+    import { Scene } from "babylonjs/scene";
     /**
      * Options for loading OBJ/MTL files
      */
@@ -2314,7 +2321,8 @@ declare module "babylonjs-loaders/OBJ/objFileLoader" {
         /**
          * Invert Y-Axis of referenced textures on load
          */
-        static INVERT_TEXTURE_Y: boolean;
+        static get INVERT_TEXTURE_Y(): boolean;
+        static set INVERT_TEXTURE_Y(value: boolean);
         /**
          * Include in meshes the vertex colors available in some OBJ files.  This is not part of OBJ standard.
          */
@@ -2455,6 +2463,7 @@ declare module "babylonjs-loaders/OBJ/objFileLoader" {
     }
 }
 declare module "babylonjs-loaders/OBJ/index" {
+    export * from "babylonjs-loaders/OBJ/mtlFileLoader";
     export * from "babylonjs-loaders/OBJ/objFileLoader";
 }
 declare module "babylonjs-loaders/STL/stlFileLoader" {
@@ -4600,6 +4609,10 @@ declare module BABYLON {
      */
     export class MTLFileLoader {
         /**
+         * Invert Y-Axis of referenced textures on load
+         */
+        static INVERT_TEXTURE_Y: boolean;
+        /**
          * All material loaded from the mtl will be set here
          */
         materials: StandardMaterial[];
@@ -4626,6 +4639,8 @@ declare module BABYLON {
          */
         private static _getTexture;
     }
+}
+declare module BABYLON {
     /**
      * Options for loading OBJ/MTL files
      */
@@ -4679,7 +4694,8 @@ declare module BABYLON {
         /**
          * Invert Y-Axis of referenced textures on load
          */
-        static INVERT_TEXTURE_Y: boolean;
+        static get INVERT_TEXTURE_Y(): boolean;
+        static set INVERT_TEXTURE_Y(value: boolean);
         /**
          * Include in meshes the vertex colors available in some OBJ files.  This is not part of OBJ standard.
          */

+ 1 - 0
loaders/src/OBJ/index.ts

@@ -1 +1,2 @@
+export * from "./mtlFileLoader";
 export * from "./objFileLoader";

+ 210 - 0
loaders/src/OBJ/mtlFileLoader.ts

@@ -0,0 +1,210 @@
+import { Nullable } from "babylonjs/types";
+import { Color3 } from "babylonjs/Maths/math";
+import { Texture } from "babylonjs/Materials/Textures/texture";
+import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
+
+import { Scene } from "babylonjs/scene";
+/**
+ * Class reading and parsing the MTL file bundled with the obj file.
+ */
+export class MTLFileLoader {
+   /**
+    * Invert Y-Axis of referenced textures on load
+    */
+   public static INVERT_TEXTURE_Y = true;
+
+    /**
+     * All material loaded from the mtl will be set here
+     */
+    public materials: StandardMaterial[] = [];
+
+    /**
+     * This function will read the mtl file and create each material described inside
+     * This function could be improve by adding :
+     * -some component missing (Ni, Tf...)
+     * -including the specific options available
+     *
+     * @param scene defines the scene the material will be created in
+     * @param data defines the mtl data to parse
+     * @param rootUrl defines the rooturl to use in order to load relative dependencies
+     */
+    public parseMTL(scene: Scene, data: string | ArrayBuffer, rootUrl: string): void {
+        if (data instanceof ArrayBuffer) {
+            return;
+        }
+
+        //Split the lines from the file
+        var lines = data.split('\n');
+        //Space char
+        var delimiter_pattern = /\s+/;
+        //Array with RGB colors
+        var color: number[];
+        //New material
+        var material: Nullable<StandardMaterial> = null;
+
+        //Look at each line
+        for (var i = 0; i < lines.length; i++) {
+            var line = lines[i].trim();
+
+            // Blank line or comment
+            if (line.length === 0 || line.charAt(0) === '#') {
+                continue;
+            }
+
+            //Get the first parameter (keyword)
+            var pos = line.indexOf(' ');
+            var key = (pos >= 0) ? line.substring(0, pos) : line;
+            key = key.toLowerCase();
+
+            //Get the data following the key
+            var value: string = (pos >= 0) ? line.substring(pos + 1).trim() : "";
+
+            //This mtl keyword will create the new material
+            if (key === "newmtl") {
+                //Check if it is the first material.
+                // Materials specifications are described after this keyword.
+                if (material) {
+                    //Add the previous material in the material array.
+                    this.materials.push(material);
+                }
+                //Create a new material.
+                // value is the name of the material read in the mtl file
+                material = new StandardMaterial(value, scene);
+            } else if (key === "kd" && material) {
+                // Diffuse color (color under white light) using RGB values
+
+                //value  = "r g b"
+                color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
+                //color = [r,g,b]
+                //Set tghe color into the material
+                material.diffuseColor = Color3.FromArray(color);
+            } else if (key === "ka" && material) {
+                // Ambient color (color under shadow) using RGB values
+
+                //value = "r g b"
+                color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
+                //color = [r,g,b]
+                //Set tghe color into the material
+                material.ambientColor = Color3.FromArray(color);
+            } else if (key === "ks" && material) {
+                // Specular color (color when light is reflected from shiny surface) using RGB values
+
+                //value = "r g b"
+                color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
+                //color = [r,g,b]
+                //Set the color into the material
+                material.specularColor = Color3.FromArray(color);
+            } else if (key === "ke" && material) {
+                // Emissive color using RGB values
+                color = value.split(delimiter_pattern, 3).map(parseFloat);
+                material.emissiveColor = Color3.FromArray(color);
+            } else if (key === "ns" && material) {
+
+                //value = "Integer"
+                material.specularPower = parseFloat(value);
+            } else if (key === "d" && material) {
+                //d is dissolve for current material. It mean alpha for BABYLON
+                material.alpha = parseFloat(value);
+
+                //Texture
+                //This part can be improved by adding the possible options of texture
+            } else if (key === "map_ka" && material) {
+                // ambient texture map with a loaded image
+                //We must first get the folder of the image
+                material.ambientTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
+            } else if (key === "map_kd" && material) {
+                // Diffuse texture map with a loaded image
+                material.diffuseTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
+            } else if (key === "map_ks" && material) {
+                // Specular texture map with a loaded image
+                //We must first get the folder of the image
+                material.specularTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
+            } else if (key === "map_ns") {
+                //Specular
+                //Specular highlight component
+                //We must first get the folder of the image
+                //
+                //Not supported by BABYLON
+                //
+                //    continue;
+            } else if (key === "map_bump" && material) {
+                //The bump texture
+                material.bumpTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
+            } else if (key === "map_d" && material) {
+                // The dissolve of the material
+                material.opacityTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
+
+                //Options for illumination
+            } else if (key === "illum") {
+                //Illumination
+                if (value === "0") {
+                    //That mean Kd == Kd
+                } else if (value === "1") {
+                    //Color on and Ambient on
+                } else if (value === "2") {
+                    //Highlight on
+                } else if (value === "3") {
+                    //Reflection on and Ray trace on
+                } else if (value === "4") {
+                    //Transparency: Glass on, Reflection: Ray trace on
+                } else if (value === "5") {
+                    //Reflection: Fresnel on and Ray trace on
+                } else if (value === "6") {
+                    //Transparency: Refraction on, Reflection: Fresnel off and Ray trace on
+                } else if (value === "7") {
+                    //Transparency: Refraction on, Reflection: Fresnel on and Ray trace on
+                } else if (value === "8") {
+                    //Reflection on and Ray trace off
+                } else if (value === "9") {
+                    //Transparency: Glass on, Reflection: Ray trace off
+                } else if (value === "10") {
+                    //Casts shadows onto invisible surfaces
+                }
+            } else {
+                // console.log("Unhandled expression at line : " + i +'\n' + "with value : " + line);
+            }
+        }
+        //At the end of the file, add the last material
+        if (material) {
+            this.materials.push(material);
+        }
+    }
+
+    /**
+     * Gets the texture for the material.
+     *
+     * If the material is imported from input file,
+     * We sanitize the url to ensure it takes the textre from aside the material.
+     *
+     * @param rootUrl The root url to load from
+     * @param value The value stored in the mtl
+     * @return The Texture
+     */
+    private static _getTexture(rootUrl: string, value: string, scene: Scene): Nullable<Texture> {
+        if (!value) {
+            return null;
+        }
+
+        var url = rootUrl;
+        // Load from input file.
+        if (rootUrl === "file:") {
+            var lastDelimiter = value.lastIndexOf("\\");
+            if (lastDelimiter === -1) {
+                lastDelimiter = value.lastIndexOf("/");
+            }
+
+            if (lastDelimiter > -1) {
+                url += value.substr(lastDelimiter + 1);
+            }
+            else {
+                url += value;
+            }
+        }
+        // Not from input file.
+        else {
+            url += value;
+        }
+
+        return new Texture(url, scene, false, MTLFileLoader.INVERT_TEXTURE_Y);
+    }
+}

+ 11 - 205
loaders/src/OBJ/objFileLoader.ts

@@ -1,13 +1,11 @@
-import { Nullable, FloatArray, IndicesArray } from "babylonjs/types";
-import { Vector3, Vector2, Color3, Color4 } from "babylonjs/Maths/math";
+import { FloatArray, IndicesArray } from "babylonjs/types";
+import { Vector3, Vector2, Color4 } from "babylonjs/Maths/math";
 import { Tools } from "babylonjs/Misc/tools";
 import { VertexData } from "babylonjs/Meshes/mesh.vertexData";
 import { Geometry } from "babylonjs/Meshes/geometry";
 import { AnimationGroup } from "babylonjs/Animations/animationGroup";
 import { Skeleton } from "babylonjs/Bones/skeleton";
 import { IParticleSystem } from "babylonjs/Particles/IParticleSystem";
-import { Texture } from "babylonjs/Materials/Textures/texture";
-import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
 import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
 import { Mesh } from "babylonjs/Meshes/mesh";
 import { SceneLoader, ISceneLoaderPluginAsync, SceneLoaderProgressEvent, ISceneLoaderPluginFactory, ISceneLoaderPlugin } from "babylonjs/Loading/sceneLoader";
@@ -15,206 +13,7 @@ import { SceneLoader, ISceneLoaderPluginAsync, SceneLoaderProgressEvent, ISceneL
 import { AssetContainer } from "babylonjs/assetContainer";
 import { Scene } from "babylonjs/scene";
 import { WebRequest } from 'babylonjs/Misc/webRequest';
-/**
- * Class reading and parsing the MTL file bundled with the obj file.
- */
-export class MTLFileLoader {
-
-    /**
-     * All material loaded from the mtl will be set here
-     */
-    public materials: StandardMaterial[] = [];
-
-    /**
-     * This function will read the mtl file and create each material described inside
-     * This function could be improve by adding :
-     * -some component missing (Ni, Tf...)
-     * -including the specific options available
-     *
-     * @param scene defines the scene the material will be created in
-     * @param data defines the mtl data to parse
-     * @param rootUrl defines the rooturl to use in order to load relative dependencies
-     */
-    public parseMTL(scene: Scene, data: string | ArrayBuffer, rootUrl: string): void {
-        if (data instanceof ArrayBuffer) {
-            return;
-        }
-
-        //Split the lines from the file
-        var lines = data.split('\n');
-        //Space char
-        var delimiter_pattern = /\s+/;
-        //Array with RGB colors
-        var color: number[];
-        //New material
-        var material: Nullable<StandardMaterial> = null;
-
-        //Look at each line
-        for (var i = 0; i < lines.length; i++) {
-            var line = lines[i].trim();
-
-            // Blank line or comment
-            if (line.length === 0 || line.charAt(0) === '#') {
-                continue;
-            }
-
-            //Get the first parameter (keyword)
-            var pos = line.indexOf(' ');
-            var key = (pos >= 0) ? line.substring(0, pos) : line;
-            key = key.toLowerCase();
-
-            //Get the data following the key
-            var value: string = (pos >= 0) ? line.substring(pos + 1).trim() : "";
-
-            //This mtl keyword will create the new material
-            if (key === "newmtl") {
-                //Check if it is the first material.
-                // Materials specifications are described after this keyword.
-                if (material) {
-                    //Add the previous material in the material array.
-                    this.materials.push(material);
-                }
-                //Create a new material.
-                // value is the name of the material read in the mtl file
-                material = new StandardMaterial(value, scene);
-            } else if (key === "kd" && material) {
-                // Diffuse color (color under white light) using RGB values
-
-                //value  = "r g b"
-                color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
-                //color = [r,g,b]
-                //Set tghe color into the material
-                material.diffuseColor = Color3.FromArray(color);
-            } else if (key === "ka" && material) {
-                // Ambient color (color under shadow) using RGB values
-
-                //value = "r g b"
-                color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
-                //color = [r,g,b]
-                //Set tghe color into the material
-                material.ambientColor = Color3.FromArray(color);
-            } else if (key === "ks" && material) {
-                // Specular color (color when light is reflected from shiny surface) using RGB values
-
-                //value = "r g b"
-                color = <number[]>value.split(delimiter_pattern, 3).map(parseFloat);
-                //color = [r,g,b]
-                //Set the color into the material
-                material.specularColor = Color3.FromArray(color);
-            } else if (key === "ke" && material) {
-                // Emissive color using RGB values
-                color = value.split(delimiter_pattern, 3).map(parseFloat);
-                material.emissiveColor = Color3.FromArray(color);
-            } else if (key === "ns" && material) {
-
-                //value = "Integer"
-                material.specularPower = parseFloat(value);
-            } else if (key === "d" && material) {
-                //d is dissolve for current material. It mean alpha for BABYLON
-                material.alpha = parseFloat(value);
-
-                //Texture
-                //This part can be improved by adding the possible options of texture
-            } else if (key === "map_ka" && material) {
-                // ambient texture map with a loaded image
-                //We must first get the folder of the image
-                material.ambientTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-            } else if (key === "map_kd" && material) {
-                // Diffuse texture map with a loaded image
-                material.diffuseTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-            } else if (key === "map_ks" && material) {
-                // Specular texture map with a loaded image
-                //We must first get the folder of the image
-                material.specularTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-            } else if (key === "map_ns") {
-                //Specular
-                //Specular highlight component
-                //We must first get the folder of the image
-                //
-                //Not supported by BABYLON
-                //
-                //    continue;
-            } else if (key === "map_bump" && material) {
-                //The bump texture
-                material.bumpTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-            } else if (key === "map_d" && material) {
-                // The dissolve of the material
-                material.opacityTexture = MTLFileLoader._getTexture(rootUrl, value, scene);
-
-                //Options for illumination
-            } else if (key === "illum") {
-                //Illumination
-                if (value === "0") {
-                    //That mean Kd == Kd
-                } else if (value === "1") {
-                    //Color on and Ambient on
-                } else if (value === "2") {
-                    //Highlight on
-                } else if (value === "3") {
-                    //Reflection on and Ray trace on
-                } else if (value === "4") {
-                    //Transparency: Glass on, Reflection: Ray trace on
-                } else if (value === "5") {
-                    //Reflection: Fresnel on and Ray trace on
-                } else if (value === "6") {
-                    //Transparency: Refraction on, Reflection: Fresnel off and Ray trace on
-                } else if (value === "7") {
-                    //Transparency: Refraction on, Reflection: Fresnel on and Ray trace on
-                } else if (value === "8") {
-                    //Reflection on and Ray trace off
-                } else if (value === "9") {
-                    //Transparency: Glass on, Reflection: Ray trace off
-                } else if (value === "10") {
-                    //Casts shadows onto invisible surfaces
-                }
-            } else {
-                // console.log("Unhandled expression at line : " + i +'\n' + "with value : " + line);
-            }
-        }
-        //At the end of the file, add the last material
-        if (material) {
-            this.materials.push(material);
-        }
-    }
-
-    /**
-     * Gets the texture for the material.
-     *
-     * If the material is imported from input file,
-     * We sanitize the url to ensure it takes the textre from aside the material.
-     *
-     * @param rootUrl The root url to load from
-     * @param value The value stored in the mtl
-     * @return The Texture
-     */
-    private static _getTexture(rootUrl: string, value: string, scene: Scene): Nullable<Texture> {
-        if (!value) {
-            return null;
-        }
-
-        var url = rootUrl;
-        // Load from input file.
-        if (rootUrl === "file:") {
-            var lastDelimiter = value.lastIndexOf("\\");
-            if (lastDelimiter === -1) {
-                lastDelimiter = value.lastIndexOf("/");
-            }
-
-            if (lastDelimiter > -1) {
-                url += value.substr(lastDelimiter + 1);
-            }
-            else {
-                url += value;
-            }
-        }
-        // Not from input file.
-        else {
-            url += value;
-        }
-
-        return new Texture(url, scene, false, OBJFileLoader.INVERT_TEXTURE_Y);
-    }
-}
+import { MTLFileLoader } from './mtlFileLoader';
 
 type MeshObject = {
     name: string;
@@ -281,7 +80,14 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
     /**
      * Invert Y-Axis of referenced textures on load
      */
-    public static INVERT_TEXTURE_Y = true;
+    public static get INVERT_TEXTURE_Y() {
+        return MTLFileLoader.INVERT_TEXTURE_Y;
+    }
+
+    public static set INVERT_TEXTURE_Y(value: boolean) {
+        MTLFileLoader.INVERT_TEXTURE_Y = value;
+    }
+
     /**
      * Include in meshes the vertex colors available in some OBJ files.  This is not part of OBJ standard.
      */

+ 4 - 2
tests/validation/config.json

@@ -532,12 +532,14 @@
         {
             "title": "GLTF Serializer with Negative World Matrix",
             "playgroundId": "#KX53VK#27",
-            "referenceImage": "glTFSerializerNegativeWorldMatrix.png"
+            "referenceImage": "glTFSerializerNegativeWorldMatrix.png",
+            "errorRatio": 1.1
         },
         {
             "title": "GLTF Serializer with Negative World Matrix (Right Handed)",
             "playgroundId": "#KX53VK#30",
-            "referenceImage": "glTFSerializerNegativeWorldMatrix_Right.png"
+            "referenceImage": "glTFSerializerNegativeWorldMatrix_Right.png",
+            "errorRatio": 1.1
         },
         {
             "title": "GLTF Buggy with Draco Mesh Compression",

+ 4 - 7
tests/validation/validation.js

@@ -6,9 +6,6 @@ var currentScene;
 var config;
 var justOnce;
 
-var threshold = 25;
-var errorRatio = 2.5;
-
 // Overload the random to make it deterministic
 var seed = 100000,
     constant = Math.pow(2, 13) + 1,
@@ -23,7 +20,7 @@ Math.random = function() {
     return seed / maximum;
 }
 
-function compare(renderData, referenceCanvas) {
+function compare(renderData, referenceCanvas, threshold, errorRatio) {
     var width = referenceCanvas.width;
     var height = referenceCanvas.height;
     var size = width * height * 4;
@@ -98,7 +95,7 @@ function saveRenderImage(data, canvas) {
     return screenshotCanvas.toDataURL();
 }
 
-function evaluate(test, resultCanvas, result, renderImage, index, waitRing, done) {
+function evaluate(test, resultCanvas, result, renderImage, waitRing, done) {
     var renderData = getRenderData(canvas, engine);
     var testRes = true;
 
@@ -113,7 +110,7 @@ function evaluate(test, resultCanvas, result, renderImage, index, waitRing, done
 
         // Visual check
         if (!test.onlyVisual) {
-            if (compare(renderData, resultCanvas)) {
+            if (compare(renderData, resultCanvas, test.threshold || 25, test.errorRatio || 2.5)) {
                 result.classList.add("failed");
                 result.innerHTML = "×";
                 testRes = false;
@@ -153,7 +150,7 @@ function processCurrentScene(test, resultCanvas, result, renderImage, index, wai
 
                 if (renderCount === 0) {
                     engine.stopRenderLoop();
-                    evaluate(test, resultCanvas, result, renderImage, index, waitRing, done);
+                    evaluate(test, resultCanvas, result, renderImage, waitRing, done);
                 }
             }
             catch (e) {