David Catuhe 7 年之前
父节点
当前提交
406732732b
共有 23 个文件被更改,包括 28216 次插入27996 次删除
  1. 8940 8945
      Playground/babylon.d.txt
  2. 11947 11956
      dist/preview release/babylon.d.ts
  3. 52 52
      dist/preview release/babylon.js
  4. 362 294
      dist/preview release/babylon.max.js
  5. 7 7
      dist/preview release/babylon.worker.js
  6. 4646 4655
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 19 19
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 362 294
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 362 294
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  10. 362 294
      dist/preview release/es6.js
  11. 6 2
      dist/preview release/gui/babylon.gui.d.ts
  12. 24 22
      dist/preview release/gui/babylon.gui.js
  13. 3 3
      dist/preview release/gui/babylon.gui.min.js
  14. 6 2
      dist/preview release/gui/babylon.gui.module.d.ts
  15. 62 24
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  16. 281 362
      dist/preview release/serializers/babylon.glTF2Serializer.js
  17. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  18. 281 362
      dist/preview release/serializers/babylonjs.serializers.js
  19. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  20. 62 24
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  21. 2 23
      dist/preview release/typedocValidationBaseline.json
  22. 66 66
      dist/preview release/viewer/babylon.viewer.js
  23. 362 294
      dist/preview release/viewer/babylon.viewer.max.js

文件差异内容过多而无法显示
+ 8940 - 8945
Playground/babylon.d.txt


文件差异内容过多而无法显示
+ 11947 - 11956
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 52 - 52
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 362 - 294
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 7 - 7
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 4646 - 4655
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


文件差异内容过多而无法显示
+ 19 - 19
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


文件差异内容过多而无法显示
+ 362 - 294
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


文件差异内容过多而无法显示
+ 362 - 294
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


文件差异内容过多而无法显示
+ 362 - 294
dist/preview release/es6.js


+ 6 - 2
dist/preview release/gui/babylon.gui.d.ts

@@ -16,8 +16,12 @@ declare module BABYLON.GUI {
         private _background;
         _rootContainer: Container;
         _lastPickedControl: Control;
-        _lastControlOver: Nullable<Control>;
-        _lastControlDown: Nullable<Control>;
+        _lastControlOver: {
+            [pointerId: number]: Control;
+        };
+        _lastControlDown: {
+            [pointerId: number]: Control;
+        };
         _capturingControl: {
             [pointerId: number]: Control;
         };

+ 24 - 22
dist/preview release/gui/babylon.gui.js

@@ -33,6 +33,8 @@ var BABYLON;
                 var _this = _super.call(this, name, { width: width, height: height }, scene, generateMipMaps, samplingMode, BABYLON.Engine.TEXTUREFORMAT_RGBA) || this;
                 _this._isDirty = false;
                 _this._rootContainer = new GUI.Container("root");
+                _this._lastControlOver = {};
+                _this._lastControlDown = {};
                 _this._capturingControl = {};
                 _this._linkedControls = new Array();
                 _this._isFullscreen = false;
@@ -358,10 +360,10 @@ var BABYLON;
                 }
                 if (!this._rootContainer._processPicking(x, y, type, pointerId, buttonIndex)) {
                     if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
-                        if (this._lastControlOver) {
-                            this._lastControlOver._onPointerOut(this._lastControlOver);
+                        if (this._lastControlOver[pointerId]) {
+                            this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId]);
                         }
-                        this._lastControlOver = null;
+                        delete this._lastControlOver[pointerId];
                     }
                 }
                 this._manageFocus();
@@ -417,17 +419,17 @@ var BABYLON;
                         }
                     }
                     else if (pi.type === BABYLON.PointerEventTypes.POINTERUP) {
-                        if (_this._lastControlDown) {
-                            _this._lastControlDown.forcePointerUp(pointerId);
+                        if (_this._lastControlDown[pointerId]) {
+                            _this._lastControlDown[pointerId].forcePointerUp(pointerId);
                         }
-                        _this._lastControlDown = null;
+                        delete _this._lastControlDown[pointerId];
                         _this.focusedControl = null;
                     }
                     else if (pi.type === BABYLON.PointerEventTypes.POINTERMOVE) {
-                        if (_this._lastControlOver) {
-                            _this._lastControlOver._onPointerOut(_this._lastControlOver);
+                        if (_this._lastControlOver[pointerId]) {
+                            _this._lastControlOver[pointerId]._onPointerOut(_this._lastControlOver[pointerId]);
                         }
-                        _this._lastControlOver = null;
+                        delete _this._lastControlOver[pointerId];
                     }
                 });
                 mesh.enablePointerMoveEvents = supportPointerMove;
@@ -456,15 +458,15 @@ var BABYLON;
             };
             AdvancedDynamicTexture.prototype._attachToOnPointerOut = function (scene) {
                 var _this = this;
-                this._canvasPointerOutObserver = scene.getEngine().onCanvasPointerOutObservable.add(function () {
-                    if (_this._lastControlOver) {
-                        _this._lastControlOver._onPointerOut(_this._lastControlOver);
+                this._canvasPointerOutObserver = scene.getEngine().onCanvasPointerOutObservable.add(function (pointerEvent) {
+                    if (_this._lastControlOver[pointerEvent.pointerId]) {
+                        _this._lastControlOver[pointerEvent.pointerId]._onPointerOut(_this._lastControlOver[pointerEvent.pointerId]);
                     }
-                    _this._lastControlOver = null;
-                    if (_this._lastControlDown) {
-                        _this._lastControlDown.forcePointerUp();
+                    delete _this._lastControlOver[pointerEvent.pointerId];
+                    if (_this._lastControlDown[pointerEvent.pointerId]) {
+                        _this._lastControlDown[pointerEvent.pointerId].forcePointerUp();
                     }
-                    _this._lastControlDown = null;
+                    delete _this._lastControlDown[pointerEvent.pointerId];
                 });
             };
             // Statics
@@ -1726,27 +1728,27 @@ var BABYLON;
                 this._dummyVector2.copyFromFloats(x, y);
                 if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
                     this._onPointerMove(this, this._dummyVector2);
-                    var previousControlOver = this._host._lastControlOver;
+                    var previousControlOver = this._host._lastControlOver[pointerId];
                     if (previousControlOver && previousControlOver !== this) {
                         previousControlOver._onPointerOut(this);
                     }
                     if (previousControlOver !== this) {
                         this._onPointerEnter(this);
                     }
-                    this._host._lastControlOver = this;
+                    this._host._lastControlOver[pointerId] = this;
                     return true;
                 }
                 if (type === BABYLON.PointerEventTypes.POINTERDOWN) {
                     this._onPointerDown(this, this._dummyVector2, pointerId, buttonIndex);
-                    this._host._lastControlDown = this;
+                    this._host._lastControlDown[pointerId] = this;
                     this._host._lastPickedControl = this;
                     return true;
                 }
                 if (type === BABYLON.PointerEventTypes.POINTERUP) {
-                    if (this._host._lastControlDown) {
-                        this._host._lastControlDown._onPointerUp(this, this._dummyVector2, pointerId, buttonIndex);
+                    if (this._host._lastControlDown[pointerId]) {
+                        this._host._lastControlDown[pointerId]._onPointerUp(this, this._dummyVector2, pointerId, buttonIndex);
                     }
-                    this._host._lastControlDown = null;
+                    delete this._host._lastControlDown[pointerId];
                     return true;
                 }
                 return false;

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/gui/babylon.gui.min.js


+ 6 - 2
dist/preview release/gui/babylon.gui.module.d.ts

@@ -22,8 +22,12 @@ declare module BABYLON.GUI {
         private _background;
         _rootContainer: Container;
         _lastPickedControl: Control;
-        _lastControlOver: Nullable<Control>;
-        _lastControlDown: Nullable<Control>;
+        _lastControlOver: {
+            [pointerId: number]: Control;
+        };
+        _lastControlDown: {
+            [pointerId: number]: Control;
+        };
         _capturingControl: {
             [pointerId: number]: Control;
         };

+ 62 - 24
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -100,6 +100,18 @@ declare module BABYLON.GLTF2 {
          */
         private imageData;
         /**
+         * Stores a map of the unique id of a node to its index in the node array.
+         */
+        private nodeMap;
+        /**
+         * Stores the binary buffer used to store geometry data.
+         */
+        private binaryBuffer;
+        /**
+         * Specifies if the Babylon scene should be converted to right-handed on export.
+         */
+        private convertToRightHandedSystem;
+        /**
          * Creates a glTF Exporter instance, which can accept optional exporter options.
          * @param babylonScene - Babylon scene object
          * @param options - Options to modify the behavior of the exporter.
@@ -117,26 +129,42 @@ declare module BABYLON.GLTF2 {
         private createBufferView(bufferIndex, byteOffset, byteLength, byteStride?, name?);
         /**
          * Creates an accessor based on the supplied arguments
-         * @param bufferviewIndex
-         * @param name
-         * @param type
-         * @param componentType
-         * @param count
-         * @param min
-         * @param max
+         * @param bufferviewIndex - The index of the bufferview referenced by this accessor.
+         * @param name - The name of the accessor.
+         * @param type - The type of the accessor.
+         * @param componentType - The datatype of components in the attribute.
+         * @param count - The number of attributes referenced by this accessor.
+         * @param byteOffset - The offset relative to the start of the bufferView in bytes.
+         * @param min - Minimum value of each component in this attribute.
+         * @param max - Maximum value of each component in this attribute.
          * @returns - accessor for glTF
          */
-        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset?, min?, max?);
+        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset, min, max);
         /**
-         * Calculates the minimum and maximum values of an array of floats, based on stride
-         * @param buff - Data to check for min and max values.
-         * @param vertexStart - Start offset to calculate min and max values.
+         * Calculates the minimum and maximum values of an array of position floats.
+         * @param positions - Positions array of a mesh.
+         * @param vertexStart - Starting vertex offset to calculate min and max values.
          * @param vertexCount - Number of vertices to check for min and max values.
-         * @param stride - Offset between consecutive attributes.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          * @returns - min number array and max number array.
          */
-        private calculateMinMax(buff, vertexStart, vertexCount, stride, useRightHandedSystem);
+        private calculateMinMaxPositions(positions, vertexStart, vertexCount);
+        /**
+         * Converts a vector3 array to right-handed.
+         * @param vector - vector3 Array to convert to right-handed.
+         * @returns - right-handed Vector3 array.
+         */
+        private static GetRightHandedVector3(vector);
+        /**
+         * Converts a vector4 array to right-handed.
+         * @param vector - vector4 Array to convert to right-handed.
+         * @returns - right-handed vector4 array.
+         */
+        private static GetRightHandedVector4(vector);
+        /**
+         * Converts a quaternion to right-handed.
+         * @param quaternion - Source quaternion to convert to right-handed.
+         */
+        private static GetRightHandedQuaternion(quaternion);
         /**
          * Writes mesh attribute data to a data buffer.
          * Returns the bytelength of the data.
@@ -145,10 +173,9 @@ declare module BABYLON.GLTF2 {
          * @param strideSize - Represents the offset between consecutive attributes
          * @param byteOffset - The offset to start counting bytes from.
          * @param dataBuffer - The buffer to write the binary data to.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer);
         /**
          * Generates glTF json data
          * @param shouldUseGlb - Indicates whether the json should be written for a glb file.
@@ -185,38 +212,49 @@ declare module BABYLON.GLTF2 {
          * Sets the TRS for each node
          * @param node - glTF Node for storing the transformation data.
          * @param babylonMesh - Babylon mesh used as the source for the transformation data.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          */
-        private setNodeTransformation(node, babylonMesh, useRightHandedSystem);
+        private setNodeTransformation(node, babylonMesh);
         /**
          * Creates a bufferview based on the vertices type for the Babylon mesh
          * @param kind - Indicates the type of vertices data.
          * @param babylonMesh - The Babylon mesh to get the vertices data from.
          * @param byteOffset - The offset from the buffer to start indexing from.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          * @param dataBuffer - The buffer to write the bufferview data to.
          * @returns bytelength of the bufferview data.
          */
-        private createBufferViewKind(kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+        private createBufferViewKind(kind, babylonMesh, byteOffset, dataBuffer);
         /**
          * Sets data for the primitive attributes of each submesh
          * @param mesh - glTF Mesh object to store the primitive attribute information.
          * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
          * @param byteOffset - The offset in bytes of the buffer data.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          * @param dataBuffer - Buffer to write the attribute data to.
          * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
          */
-        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
         /**
          * 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.
          * @param byteOffset - Offset to start from in bytes.
-         * @param dataBuffer - Buffer to write geometry data to.
          * @returns bytelength + byteoffset
          */
-        private createScene(babylonScene, byteOffset, dataBuffer);
+        private createScene(babylonScene, byteOffset);
+        /**
+         * Creates a mapping of Node unique id to node index
+         * @param scene - Babylon Scene.
+         * @param byteOffset - The initial byte offset.
+         * @returns - Node mapping of unique id to index.
+         */
+        private createNodeMap(scene, byteOffset);
+        /**
+         * Creates a glTF node from a Babylon mesh.
+         * @param babylonMesh - Source Babylon mesh.
+         * @param byteOffset - The initial byte offset.
+         * @param dataBuffer - Buffer for storing geometry data.
+         * @returns - Object containing an INode and byteoffset.
+         */
+        private createNode(babylonMesh, byteOffset, dataBuffer);
     }
 }
 

+ 281 - 362
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -80,12 +80,10 @@ var BABYLON;
                 this.materials = new Array();
                 this.textures = new Array();
                 this.imageData = {};
-                if (options !== undefined) {
+                this.convertToRightHandedSystem = !this.babylonScene.useRightHandedSystem;
+                if (options) {
                     this.options = options;
                 }
-                var totalByteLength = 0;
-                totalByteLength = this.createScene(this.babylonScene, totalByteLength, null);
-                this.totalByteLength = totalByteLength;
             }
             /**
              * Creates a buffer view based on teh supplied arguments
@@ -98,7 +96,7 @@ var BABYLON;
              */
             _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, byteStride, name) {
                 var bufferview = { buffer: bufferIndex, byteLength: byteLength };
-                if (byteOffset > 0) {
+                if (byteOffset) {
                     bufferview.byteOffset = byteOffset;
                 }
                 if (name) {
@@ -111,13 +109,14 @@ var BABYLON;
             };
             /**
              * Creates an accessor based on the supplied arguments
-             * @param bufferviewIndex
-             * @param name
-             * @param type
-             * @param componentType
-             * @param count
-             * @param min
-             * @param max
+             * @param bufferviewIndex - The index of the bufferview referenced by this accessor.
+             * @param name - The name of the accessor.
+             * @param type - The type of the accessor.
+             * @param componentType - The datatype of components in the attribute.
+             * @param count - The number of attributes referenced by this accessor.
+             * @param byteOffset - The offset relative to the start of the bufferView in bytes.
+             * @param min - Minimum value of each component in this attribute.
+             * @param max - Maximum value of each component in this attribute.
              * @returns - accessor for glTF
              */
             _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, byteOffset, min, max) {
@@ -134,40 +133,60 @@ var BABYLON;
                 return accessor;
             };
             /**
-             * Calculates the minimum and maximum values of an array of floats, based on stride
-             * @param buff - Data to check for min and max values.
-             * @param vertexStart - Start offset to calculate min and max values.
+             * Calculates the minimum and maximum values of an array of position floats.
+             * @param positions - Positions array of a mesh.
+             * @param vertexStart - Starting vertex offset to calculate min and max values.
              * @param vertexCount - Number of vertices to check for min and max values.
-             * @param stride - Offset between consecutive attributes.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              * @returns - min number array and max number array.
              */
-            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, stride, useRightHandedSystem) {
+            _Exporter.prototype.calculateMinMaxPositions = function (positions, vertexStart, vertexCount) {
                 var min = [Infinity, Infinity, Infinity];
                 var max = [-Infinity, -Infinity, -Infinity];
+                var positionStrideSize = 3;
                 var end = vertexStart + vertexCount;
-                if (vertexCount > 0) {
+                if (vertexCount) {
                     for (var i = vertexStart; i < end; ++i) {
-                        var index = stride * i;
-                        var scale = 1;
-                        for (var j = 0; j < stride; ++j) {
-                            if (j === (stride - 1) && !useRightHandedSystem) {
-                                scale = -1;
-                            }
-                            var num = scale * buff[index];
+                        var indexOffset = positionStrideSize * i;
+                        var position = new BABYLON.Vector3(positions[indexOffset], positions[indexOffset + 1], positions[indexOffset + 2]);
+                        var vector = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(position).asArray() : position.asArray();
+                        for (var j = 0; j < positionStrideSize; ++j) {
+                            var num = vector[j];
                             if (num < min[j]) {
                                 min[j] = num;
                             }
                             if (num > max[j]) {
                                 max[j] = num;
                             }
-                            ++index;
+                            ++indexOffset;
                         }
                     }
                 }
                 return { min: min, max: max };
             };
             /**
+             * Converts a vector3 array to right-handed.
+             * @param vector - vector3 Array to convert to right-handed.
+             * @returns - right-handed Vector3 array.
+             */
+            _Exporter.GetRightHandedVector3 = function (vector) {
+                return new BABYLON.Vector3(vector.x, vector.y, -vector.z);
+            };
+            /**
+             * Converts a vector4 array to right-handed.
+             * @param vector - vector4 Array to convert to right-handed.
+             * @returns - right-handed vector4 array.
+             */
+            _Exporter.GetRightHandedVector4 = function (vector) {
+                return new BABYLON.Vector4(vector.x, vector.y, -vector.z, -vector.w);
+            };
+            /**
+             * Converts a quaternion to right-handed.
+             * @param quaternion - Source quaternion to convert to right-handed.
+             */
+            _Exporter.GetRightHandedQuaternion = function (quaternion) {
+                return new BABYLON.Quaternion(-quaternion.x, -quaternion.y, quaternion.z, quaternion.w);
+            };
+            /**
              * Writes mesh attribute data to a data buffer.
              * Returns the bytelength of the data.
              * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
@@ -175,112 +194,35 @@ var BABYLON;
              * @param strideSize - Represents the offset between consecutive attributes
              * @param byteOffset - The offset to start counting bytes from.
              * @param dataBuffer - The buffer to write the binary data to.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer) {
                 var byteOff = byteOffset;
-                var start = 0;
                 var end = meshAttributeArray.length / strideSize;
                 var byteLength = 0;
-                switch (vertexBufferKind) {
-                    case BABYLON.VertexBuffer.PositionKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                            if (useRightHandedSystem) {
-                                dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
-                            }
-                            else {
-                                dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
-                            }
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
-                    }
-                    case BABYLON.VertexBuffer.NormalKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                            if (useRightHandedSystem) {
-                                dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
-                            }
-                            else {
-                                dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
-                            }
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
-                    }
-                    case BABYLON.VertexBuffer.TangentKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                            if (useRightHandedSystem) {
-                                dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
-                            }
-                            else {
-                                dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
-                            }
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
+                for (var k = 0; k < end; ++k) {
+                    var index = k * strideSize;
+                    var vector = [];
+                    if (vertexBufferKind === BABYLON.VertexBuffer.PositionKind || vertexBufferKind === BABYLON.VertexBuffer.NormalKind) {
+                        var vertexData = new BABYLON.Vector3(meshAttributeArray[index], meshAttributeArray[index + 1], meshAttributeArray[index + 2]);
+                        vector = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(vertexData).asArray() : vertexData.asArray();
                     }
-                    case BABYLON.VertexBuffer.ColorKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
+                    else if (vertexBufferKind === BABYLON.VertexBuffer.TangentKind || vertexBufferKind === BABYLON.VertexBuffer.ColorKind) {
+                        var vertexData = new BABYLON.Vector4(meshAttributeArray[index], meshAttributeArray[index + 1], meshAttributeArray[index + 2], meshAttributeArray[index + 3]);
+                        vector = (this.convertToRightHandedSystem && !(vertexBufferKind === BABYLON.VertexBuffer.ColorKind)) ? _Exporter.GetRightHandedVector4(vertexData).asArray() : vertexData.asArray();
                     }
-                    case BABYLON.VertexBuffer.UVKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
+                    else if (vertexBufferKind === BABYLON.VertexBuffer.UVKind || vertexBufferKind === BABYLON.VertexBuffer.UV2Kind) {
+                        vector = [meshAttributeArray[index], meshAttributeArray[index + 1]];
                     }
-                    case BABYLON.VertexBuffer.UV2Kind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
+                    else {
+                        BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
                     }
-                    default: {
-                        throw new Error("Unsupported vertex buffer type: " + vertexBufferKind);
+                    for (var i = 0; i < vector.length; ++i) {
+                        dataBuffer.setFloat32(byteOff, vector[i], true);
+                        byteOff += 4;
                     }
                 }
+                byteLength = meshAttributeArray.length * 4;
                 return byteLength;
             };
             /**
@@ -295,32 +237,32 @@ var BABYLON;
                 var glTF = {
                     asset: this.asset
                 };
-                if (buffer.byteLength > 0) {
+                if (buffer.byteLength) {
                     glTF.buffers = [buffer];
                 }
-                if (this.nodes && this.nodes.length !== 0) {
+                if (this.nodes && this.nodes.length) {
                     glTF.nodes = this.nodes;
                 }
-                if (this.meshes && this.meshes.length !== 0) {
+                if (this.meshes && this.meshes.length) {
                     glTF.meshes = this.meshes;
                 }
-                if (this.scenes && this.scenes.length !== 0) {
+                if (this.scenes && this.scenes.length) {
                     glTF.scenes = this.scenes;
                     glTF.scene = 0;
                 }
-                if (this.bufferViews && this.bufferViews.length !== 0) {
+                if (this.bufferViews && this.bufferViews.length) {
                     glTF.bufferViews = this.bufferViews;
                 }
-                if (this.accessors && this.accessors.length !== 0) {
+                if (this.accessors && this.accessors.length) {
                     glTF.accessors = this.accessors;
                 }
-                if (this.materials && this.materials.length !== 0) {
+                if (this.materials && this.materials.length) {
                     glTF.materials = this.materials;
                 }
-                if (this.textures && this.textures.length !== 0) {
+                if (this.textures && this.textures.length) {
                     glTF.textures = this.textures;
                 }
-                if (this.images && this.images.length !== 0) {
+                if (this.images && this.images.length) {
                     if (!shouldUseGlb) {
                         glTF.images = this.images;
                     }
@@ -331,7 +273,7 @@ var BABYLON;
                         var byteOffset = this.totalByteLength;
                         for (var i = 0; i < imageLength; ++i) {
                             var image = this.images[i];
-                            if (image.uri !== undefined) {
+                            if (image.uri) {
                                 var imageData = this.imageData[image.uri];
                                 var imageName = image.uri.split('.')[0] + " image";
                                 var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
@@ -359,15 +301,15 @@ var BABYLON;
              * @returns - GLTFData with glTF file data.
              */
             _Exporter.prototype._generateGLTF = function (glTFPrefix) {
-                var jsonText = this.generateJSON(false, glTFPrefix, true);
                 var binaryBuffer = this.generateBinary();
+                var jsonText = this.generateJSON(false, glTFPrefix, true);
                 var bin = new Blob([binaryBuffer], { type: 'application/octet-stream' });
                 var glTFFileName = glTFPrefix + '.gltf';
                 var glTFBinFile = glTFPrefix + '.bin';
                 var container = new BABYLON._GLTFData();
                 container.glTFFiles[glTFFileName] = jsonText;
                 container.glTFFiles[glTFBinFile] = bin;
-                if (this.imageData !== null) {
+                if (this.imageData) {
                     for (var image in this.imageData) {
                         container.glTFFiles[image] = new Blob([this.imageData[image].data], { type: this.imageData[image].mimeType });
                     }
@@ -380,10 +322,8 @@ var BABYLON;
              */
             _Exporter.prototype.generateBinary = function () {
                 var byteOffset = 0;
-                var binaryBuffer = new ArrayBuffer(this.totalByteLength);
-                var dataBuffer = new DataView(binaryBuffer);
-                byteOffset = this.createScene(this.babylonScene, byteOffset, dataBuffer);
-                return binaryBuffer;
+                byteOffset = this.createScene(this.babylonScene, byteOffset);
+                return this.binaryBuffer;
             };
             /**
              * Pads the number to a multiple of 4
@@ -402,8 +342,8 @@ var BABYLON;
              * @returns - object with glb filename as key and data as value
              */
             _Exporter.prototype._generateGLB = function (glTFPrefix) {
-                var jsonText = this.generateJSON(true);
                 var binaryBuffer = this.generateBinary();
+                var jsonText = this.generateJSON(true);
                 var glbFileName = glTFPrefix + '.glb';
                 var headerLength = 12;
                 var chunkLengthPrefix = 8;
@@ -469,36 +409,20 @@ var BABYLON;
              * Sets the TRS for each node
              * @param node - glTF Node for storing the transformation data.
              * @param babylonMesh - Babylon mesh used as the source for the transformation data.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              */
-            _Exporter.prototype.setNodeTransformation = function (node, babylonMesh, useRightHandedSystem) {
+            _Exporter.prototype.setNodeTransformation = function (node, babylonMesh) {
                 if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
-                    if (useRightHandedSystem) {
-                        node.translation = babylonMesh.position.asArray();
-                    }
-                    else {
-                        node.translation = [babylonMesh.position.x, babylonMesh.position.y, -babylonMesh.position.z];
-                    }
+                    node.translation = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(babylonMesh.position).asArray() : babylonMesh.position.asArray();
                 }
                 if (!(babylonMesh.scaling.x === 1 && babylonMesh.scaling.y === 1 && babylonMesh.scaling.z === 1)) {
-                    if (useRightHandedSystem) {
-                        node.scale = babylonMesh.scaling.asArray();
-                    }
-                    else {
-                        node.scale = [babylonMesh.scaling.x, babylonMesh.scaling.y, -babylonMesh.scaling.z];
-                    }
+                    node.scale = babylonMesh.scaling.asArray();
                 }
                 var rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(babylonMesh.rotation.y, babylonMesh.rotation.x, babylonMesh.rotation.z);
                 if (babylonMesh.rotationQuaternion) {
                     rotationQuaternion = rotationQuaternion.multiply(babylonMesh.rotationQuaternion);
                 }
                 if (!(rotationQuaternion.x === 0 && rotationQuaternion.y === 0 && rotationQuaternion.z === 0 && rotationQuaternion.w === 1)) {
-                    if (useRightHandedSystem) {
-                        node.rotation = rotationQuaternion.asArray();
-                    }
-                    else {
-                        node.rotation = [-rotationQuaternion.x, -rotationQuaternion.y, rotationQuaternion.z, rotationQuaternion.w];
-                    }
+                    node.rotation = this.convertToRightHandedSystem ? _Exporter.GetRightHandedQuaternion(rotationQuaternion).asArray() : rotationQuaternion.asArray();
                 }
             };
             /**
@@ -506,11 +430,10 @@ var BABYLON;
              * @param kind - Indicates the type of vertices data.
              * @param babylonMesh - The Babylon mesh to get the vertices data from.
              * @param byteOffset - The offset from the buffer to start indexing from.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              * @param dataBuffer - The buffer to write the bufferview data to.
              * @returns bytelength of the bufferview data.
              */
-            _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+            _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, dataBuffer) {
                 var bufferMesh = null;
                 var byteLength = 0;
                 if (babylonMesh instanceof BABYLON.Mesh) {
@@ -519,62 +442,29 @@ var BABYLON;
                 else if (babylonMesh instanceof BABYLON.InstancedMesh) {
                     bufferMesh = babylonMesh.sourceMesh;
                 }
-                if (bufferMesh !== null) {
+                if (bufferMesh) {
                     var vertexBuffer = null;
                     var vertexBufferOffset = null;
                     var vertexData = null;
                     var vertexStrideSize = null;
-                    if (bufferMesh.getVerticesDataKinds().indexOf(kind) > -1) {
+                    if (bufferMesh.isVerticesDataPresent(kind)) {
                         vertexBuffer = bufferMesh.getVertexBuffer(kind);
-                        vertexBufferOffset = vertexBuffer.getOffset();
-                        vertexData = vertexBuffer.getData();
-                        vertexStrideSize = vertexBuffer.getStrideSize();
-                        if (dataBuffer && vertexData) {
-                            byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
-                            byteOffset += byteLength;
-                        }
-                        else {
-                            var bufferViewName = null;
-                            switch (kind) {
-                                case BABYLON.VertexBuffer.PositionKind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "Position - " + bufferMesh.name;
-                                    break;
-                                }
-                                case BABYLON.VertexBuffer.NormalKind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "Normal - " + bufferMesh.name;
-                                    break;
-                                }
-                                case BABYLON.VertexBuffer.TangentKind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "Tangent - " + bufferMesh.name;
-                                    break;
-                                }
-                                case BABYLON.VertexBuffer.ColorKind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "Color - " + bufferMesh.name;
-                                    break;
+                        if (vertexBuffer) {
+                            vertexBufferOffset = vertexBuffer.getOffset();
+                            vertexData = vertexBuffer.getData();
+                            if (vertexData) {
+                                vertexStrideSize = vertexBuffer.getStrideSize();
+                                if (dataBuffer && vertexData) {
+                                    byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer);
+                                    byteOffset += byteLength;
                                 }
-                                case BABYLON.VertexBuffer.UVKind: {
+                                else {
                                     byteLength = vertexData.length * 4;
-                                    bufferViewName = "TexCoord 0 - " + bufferMesh.name;
-                                    break;
-                                }
-                                case BABYLON.VertexBuffer.UV2Kind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "TexCoord 1 - " + bufferMesh.name;
-                                    break;
-                                }
-                                default: {
-                                    BABYLON.Tools.Warn("Unsupported VertexBuffer kind: " + kind);
+                                    var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, kind + " - " + bufferMesh.name);
+                                    byteOffset += byteLength;
+                                    this.bufferViews.push(bufferView);
                                 }
                             }
-                            if (bufferViewName !== null) {
-                                var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, bufferViewName);
-                                byteOffset += byteLength;
-                                this.bufferViews.push(bufferView);
-                            }
                         }
                     }
                 }
@@ -585,11 +475,10 @@ var BABYLON;
              * @param mesh - glTF Mesh object to store the primitive attribute information.
              * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
              * @param byteOffset - The offset in bytes of the buffer data.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              * @param dataBuffer - Buffer to write the attribute data to.
              * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
              */
-            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, dataBuffer) {
                 var bufferMesh = null;
                 if (babylonMesh instanceof BABYLON.Mesh) {
                     bufferMesh = babylonMesh;
@@ -597,147 +486,134 @@ var BABYLON;
                 else if (babylonMesh instanceof BABYLON.InstancedMesh) {
                     bufferMesh = babylonMesh.sourceMesh;
                 }
-                var positionBufferViewIndex = null;
-                var normalBufferViewIndex = null;
-                var colorBufferViewIndex = null;
-                var tangentBufferViewIndex = null;
-                var texCoord0BufferViewIndex = null;
-                var texCoord1BufferViewIndex = null;
+                var attributeData = [
+                    { kind: BABYLON.VertexBuffer.PositionKind, accessorType: "VEC3" /* VEC3 */ },
+                    { kind: BABYLON.VertexBuffer.NormalKind, accessorType: "VEC3" /* VEC3 */ },
+                    { kind: BABYLON.VertexBuffer.ColorKind, accessorType: "VEC4" /* VEC4 */ },
+                    { kind: BABYLON.VertexBuffer.TangentKind, accessorType: "VEC4" /* VEC4 */ },
+                    { kind: BABYLON.VertexBuffer.UVKind, accessorType: "VEC2" /* VEC2 */ },
+                    { kind: BABYLON.VertexBuffer.UV2Kind, accessorType: "VEC2" /* VEC2 */ },
+                ];
                 var indexBufferViewIndex = null;
-                if (bufferMesh !== null) {
+                if (bufferMesh) {
                     // For each BabylonMesh, create bufferviews for each 'kind'
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.PositionKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        positionBufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.NormalKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        normalBufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.ColorKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        colorBufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.TangentKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        colorBufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UVKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        texCoord0BufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UV2Kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        texCoord1BufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.getTotalIndices() > 0) {
-                        var indices = bufferMesh.getIndices();
-                        if (dataBuffer) {
-                            var end = indices.length;
-                            var byteOff = byteOffset;
-                            for (var k = 0; k < end; ++k) {
-                                dataBuffer.setUint32(byteOff, indices[k], true);
-                                byteOff += 4;
-                            }
-                            byteOffset = byteOff;
-                        }
-                        else {
-                            var byteLength = indices.length * 4;
-                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferView);
-                            indexBufferViewIndex = this.bufferViews.length - 1;
+                    for (var _i = 0, attributeData_1 = attributeData; _i < attributeData_1.length; _i++) {
+                        var attribute = attributeData_1[_i];
+                        var attributeKind = attribute.kind;
+                        if (bufferMesh.isVerticesDataPresent(attributeKind)) {
+                            byteOffset += this.createBufferViewKind(attributeKind, babylonMesh, byteOffset, dataBuffer);
+                            attribute.bufferViewIndex = this.bufferViews.length - 1;
                         }
                     }
-                }
-                // go through all mesh primitives (submeshes)
-                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
-                    var submesh = babylonMesh.subMeshes[j];
-                    var meshPrimitive = { attributes: {} };
-                    if (bufferMesh !== null) {
-                        // Create a bufferview storing all the positions
-                        if (!dataBuffer) {
-                            // Loop through each attribute of the submesh (mesh primitive)
-                            if (positionBufferViewIndex !== null) {
-                                var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
-                                var positions = positionVertexBuffer.getData();
-                                var positionStrideSize = positionVertexBuffer.getStrideSize();
-                                // Create accessor
-                                var result = this.calculateMinMax(positions, 0, positions.length / positionStrideSize, positionStrideSize, useRightHandedSystem);
-                                var accessor = this.createAccessor(positionBufferViewIndex, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, positions.length / positionStrideSize, 0, result.min, result.max);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                            }
-                            if (normalBufferViewIndex !== null) {
-                                var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
-                                var normals = normalVertexBuffer.getData();
-                                var normalStrideSize = normalVertexBuffer.getStrideSize();
-                                // Create accessor
-                                var accessor = this.createAccessor(normalBufferViewIndex, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, normals.length / normalStrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
-                            }
-                            if (tangentBufferViewIndex !== null) {
-                                var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
-                                var tangents = tangentVertexBuffer.getData();
-                                var tangentStrideSize = tangentVertexBuffer.getStrideSize();
-                                // Create accessor
-                                var accessor = this.createAccessor(tangentBufferViewIndex, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, tangents.length / tangentStrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                            }
-                            if (colorBufferViewIndex !== null) {
-                                var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
-                                var colors = colorVertexBuffer.getData();
-                                var colorStrideSize = colorVertexBuffer.getStrideSize();
-                                // Create accessor
-                                var accessor = this.createAccessor(colorBufferViewIndex, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, colors.length / colorStrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                            }
-                            if (texCoord0BufferViewIndex !== null) {
-                                // Create accessor
-                                var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
-                                var texCoord0s = texCoord0VertexBuffer.getData();
-                                var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
-                                var accessor = this.createAccessor(texCoord0BufferViewIndex, "Texture Coords 0", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord0s.length / texCoord0StrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                            }
-                            if (texCoord1BufferViewIndex !== null) {
-                                // Create accessor
-                                var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
-                                var texCoord1s = texCoord1VertexBuffer.getData();
-                                var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
-                                var accessor = this.createAccessor(texCoord1BufferViewIndex, "Texture Coords 1", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord1s.length / texCoord1StrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                    if (bufferMesh.getTotalIndices()) {
+                        var indices = bufferMesh.getIndices();
+                        if (indices) {
+                            if (dataBuffer) {
+                                var end = indices.length;
+                                var byteOff = byteOffset;
+                                for (var k = 0; k < end; ++k) {
+                                    dataBuffer.setUint32(byteOff, indices[k], true);
+                                    byteOff += 4;
+                                }
+                                byteOffset = byteOff;
                             }
-                            if (indexBufferViewIndex) {
-                                // Create accessor
-                                var accessor = this.createAccessor(indexBufferViewIndex, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4);
-                                this.accessors.push(accessor);
-                                meshPrimitive.indices = this.accessors.length - 1;
+                            else {
+                                var byteLength = indices.length * 4;
+                                var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
+                                byteOffset += byteLength;
+                                this.bufferViews.push(bufferView);
+                                indexBufferViewIndex = this.bufferViews.length - 1;
                             }
                         }
-                        if (bufferMesh.material) {
-                            if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                                var materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
-                                meshPrimitive.material = materialIndex;
+                    }
+                    if (babylonMesh.subMeshes) {
+                        // go through all mesh primitives (submeshes)
+                        for (var _a = 0, _b = babylonMesh.subMeshes; _a < _b.length; _a++) {
+                            var submesh = _b[_a];
+                            var meshPrimitive = { attributes: {} };
+                            // Create a bufferview storing all the positions
+                            if (!dataBuffer) {
+                                for (var _c = 0, attributeData_2 = attributeData; _c < attributeData_2.length; _c++) {
+                                    var attribute = attributeData_2[_c];
+                                    var attributeKind = attribute.kind;
+                                    if (bufferMesh.isVerticesDataPresent(attributeKind)) {
+                                        var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
+                                        if (vertexBuffer) {
+                                            var bufferData = vertexBuffer.getData();
+                                            if (bufferData) {
+                                                var strideSize = vertexBuffer.getStrideSize();
+                                                var minMax = void 0;
+                                                var min = null;
+                                                var max = null;
+                                                var bufferViewIndex = attribute.bufferViewIndex;
+                                                if (bufferViewIndex != undefined) {
+                                                    if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
+                                                        minMax = this.calculateMinMaxPositions(bufferData, 0, bufferData.length / strideSize);
+                                                        min = minMax.min;
+                                                        max = minMax.max;
+                                                    }
+                                                    var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, bufferData.length / strideSize, 0, min, max);
+                                                    this.accessors.push(accessor);
+                                                    switch (attributeKind) {
+                                                        case BABYLON.VertexBuffer.PositionKind: {
+                                                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.NormalKind: {
+                                                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.ColorKind: {
+                                                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.TangentKind: {
+                                                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.UVKind: {
+                                                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.UV2Kind: {
+                                                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        default: {
+                                                            BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                                if (indexBufferViewIndex) {
+                                    // Create accessor
+                                    var accessor = this.createAccessor(indexBufferViewIndex, "indices - " + babylonMesh.name, "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4, null, null);
+                                    this.accessors.push(accessor);
+                                    meshPrimitive.indices = this.accessors.length - 1;
+                                }
                             }
-                            else if (bufferMesh.material instanceof BABYLON.MultiMaterial) {
-                                var babylonMultiMaterial = bufferMesh.material;
-                                var material = babylonMultiMaterial.subMaterials[submesh.materialIndex];
-                                if (material !== null) {
-                                    var materialIndex = babylonMesh.getScene().materials.indexOf(material);
+                            if (bufferMesh.material) {
+                                if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
+                                    var materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
                                     meshPrimitive.material = materialIndex;
                                 }
+                                else if (bufferMesh.material instanceof BABYLON.MultiMaterial) {
+                                    var babylonMultiMaterial = bufferMesh.material;
+                                    var material = babylonMultiMaterial.subMaterials[submesh.materialIndex];
+                                    if (material) {
+                                        var materialIndex = babylonMesh.getScene().materials.indexOf(material);
+                                        meshPrimitive.material = materialIndex;
+                                    }
+                                }
+                                else {
+                                    BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
+                                }
                             }
-                            else {
-                                BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
-                            }
+                            mesh.primitives.push(meshPrimitive);
                         }
-                        mesh.primitives.push(meshPrimitive);
                     }
                 }
                 return byteOffset;
@@ -747,47 +623,90 @@ var BABYLON;
              * Returns the the total byte offset.
              * @param babylonScene - Babylon scene to get the mesh data from.
              * @param byteOffset - Offset to start from in bytes.
-             * @param dataBuffer - Buffer to write geometry data to.
              * @returns bytelength + byteoffset
              */
-            _Exporter.prototype.createScene = function (babylonScene, byteOffset, dataBuffer) {
-                if (babylonScene.meshes.length > 0) {
+            _Exporter.prototype.createScene = function (babylonScene, byteOffset) {
+                if (babylonScene.meshes.length) {
                     var babylonMeshes = babylonScene.meshes;
                     var scene = { nodes: new Array() };
-                    if (dataBuffer == null) {
-                        GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
-                    }
+                    GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
+                    var result = this.createNodeMap(babylonScene, byteOffset);
+                    this.nodeMap = result.nodeMap;
+                    this.totalByteLength = result.byteOffset;
+                    this.binaryBuffer = new ArrayBuffer(this.totalByteLength);
+                    var dataBuffer = new DataView(this.binaryBuffer);
                     for (var i = 0; i < babylonMeshes.length; ++i) {
                         if (this.options &&
-                            this.options.shouldExportMesh !== undefined &&
+                            this.options.shouldExportMesh != undefined &&
                             !this.options.shouldExportMesh(babylonMeshes[i])) {
                             continue;
                         }
                         else {
-                            // create node to hold translation/rotation/scale and the mesh
-                            var node = { mesh: -1 };
                             var babylonMesh = babylonMeshes[i];
-                            var useRightHandedSystem = babylonMesh.getScene().useRightHandedSystem;
-                            // Set transformation
-                            this.setNodeTransformation(node, babylonMesh, useRightHandedSystem);
-                            // create mesh
-                            var mesh = { primitives: new Array() };
-                            mesh.primitives = [];
-                            byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                            // go through all mesh primitives (submeshes)
-                            this.meshes.push(mesh);
-                            node.mesh = this.meshes.length - 1;
-                            if (babylonMesh.name) {
-                                node.name = babylonMesh.name;
+                            // Build Hierarchy with the node map.
+                            var glTFNodeIndex = this.nodeMap[babylonMesh.uniqueId];
+                            var glTFNode = this.nodes[glTFNodeIndex];
+                            if (!babylonMesh.parent) {
+                                scene.nodes.push(glTFNodeIndex);
                             }
-                            this.nodes.push(node);
-                            scene.nodes.push(this.nodes.length - 1);
+                            var directDescendents = babylonMesh.getDescendants(true);
+                            if (!glTFNode.children && directDescendents && directDescendents.length) {
+                                glTFNode.children = [];
+                                for (var _i = 0, directDescendents_1 = directDescendents; _i < directDescendents_1.length; _i++) {
+                                    var descendent = directDescendents_1[_i];
+                                    glTFNode.children.push(this.nodeMap[descendent.uniqueId]);
+                                }
+                            }
+                            var mesh = { primitives: new Array() };
+                            byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
                         }
                     }
                     this.scenes.push(scene);
                 }
                 return byteOffset;
             };
+            /**
+             * Creates a mapping of Node unique id to node index
+             * @param scene - Babylon Scene.
+             * @param byteOffset - The initial byte offset.
+             * @returns - Node mapping of unique id to index.
+             */
+            _Exporter.prototype.createNodeMap = function (scene, byteOffset) {
+                var nodeMap = {};
+                for (var _i = 0, _a = scene.meshes; _i < _a.length; _i++) {
+                    var babylonMesh = _a[_i];
+                    var result = this.createNode(babylonMesh, byteOffset, null);
+                    this.nodes.push(result.node);
+                    nodeMap[babylonMesh.uniqueId] = this.nodes.length - 1;
+                    byteOffset = result.byteOffset;
+                }
+                return { nodeMap: nodeMap, byteOffset: byteOffset };
+            };
+            /**
+             * Creates a glTF node from a Babylon mesh.
+             * @param babylonMesh - Source Babylon mesh.
+             * @param byteOffset - The initial byte offset.
+             * @param dataBuffer - Buffer for storing geometry data.
+             * @returns - Object containing an INode and byteoffset.
+             */
+            _Exporter.prototype.createNode = function (babylonMesh, byteOffset, dataBuffer) {
+                // create node to hold translation/rotation/scale and the mesh
+                var node = {};
+                if (babylonMesh.name) {
+                    node.name = babylonMesh.name;
+                }
+                // Set transformation
+                this.setNodeTransformation(node, babylonMesh);
+                // create mesh
+                var mesh = { primitives: new Array() };
+                mesh.primitives = [];
+                byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
+                if (mesh.primitives.length) {
+                    this.meshes.push(mesh);
+                    node.mesh = this.meshes.length - 1;
+                }
+                return { node: node, byteOffset: byteOffset };
+            };
             return _Exporter;
         }());
         GLTF2._Exporter = _Exporter;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 281 - 362
dist/preview release/serializers/babylonjs.serializers.js

@@ -224,12 +224,10 @@ var BABYLON;
                 this.materials = new Array();
                 this.textures = new Array();
                 this.imageData = {};
-                if (options !== undefined) {
+                this.convertToRightHandedSystem = !this.babylonScene.useRightHandedSystem;
+                if (options) {
                     this.options = options;
                 }
-                var totalByteLength = 0;
-                totalByteLength = this.createScene(this.babylonScene, totalByteLength, null);
-                this.totalByteLength = totalByteLength;
             }
             /**
              * Creates a buffer view based on teh supplied arguments
@@ -242,7 +240,7 @@ var BABYLON;
              */
             _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, byteStride, name) {
                 var bufferview = { buffer: bufferIndex, byteLength: byteLength };
-                if (byteOffset > 0) {
+                if (byteOffset) {
                     bufferview.byteOffset = byteOffset;
                 }
                 if (name) {
@@ -255,13 +253,14 @@ var BABYLON;
             };
             /**
              * Creates an accessor based on the supplied arguments
-             * @param bufferviewIndex
-             * @param name
-             * @param type
-             * @param componentType
-             * @param count
-             * @param min
-             * @param max
+             * @param bufferviewIndex - The index of the bufferview referenced by this accessor.
+             * @param name - The name of the accessor.
+             * @param type - The type of the accessor.
+             * @param componentType - The datatype of components in the attribute.
+             * @param count - The number of attributes referenced by this accessor.
+             * @param byteOffset - The offset relative to the start of the bufferView in bytes.
+             * @param min - Minimum value of each component in this attribute.
+             * @param max - Maximum value of each component in this attribute.
              * @returns - accessor for glTF
              */
             _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, byteOffset, min, max) {
@@ -278,40 +277,60 @@ var BABYLON;
                 return accessor;
             };
             /**
-             * Calculates the minimum and maximum values of an array of floats, based on stride
-             * @param buff - Data to check for min and max values.
-             * @param vertexStart - Start offset to calculate min and max values.
+             * Calculates the minimum and maximum values of an array of position floats.
+             * @param positions - Positions array of a mesh.
+             * @param vertexStart - Starting vertex offset to calculate min and max values.
              * @param vertexCount - Number of vertices to check for min and max values.
-             * @param stride - Offset between consecutive attributes.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              * @returns - min number array and max number array.
              */
-            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, stride, useRightHandedSystem) {
+            _Exporter.prototype.calculateMinMaxPositions = function (positions, vertexStart, vertexCount) {
                 var min = [Infinity, Infinity, Infinity];
                 var max = [-Infinity, -Infinity, -Infinity];
+                var positionStrideSize = 3;
                 var end = vertexStart + vertexCount;
-                if (vertexCount > 0) {
+                if (vertexCount) {
                     for (var i = vertexStart; i < end; ++i) {
-                        var index = stride * i;
-                        var scale = 1;
-                        for (var j = 0; j < stride; ++j) {
-                            if (j === (stride - 1) && !useRightHandedSystem) {
-                                scale = -1;
-                            }
-                            var num = scale * buff[index];
+                        var indexOffset = positionStrideSize * i;
+                        var position = new BABYLON.Vector3(positions[indexOffset], positions[indexOffset + 1], positions[indexOffset + 2]);
+                        var vector = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(position).asArray() : position.asArray();
+                        for (var j = 0; j < positionStrideSize; ++j) {
+                            var num = vector[j];
                             if (num < min[j]) {
                                 min[j] = num;
                             }
                             if (num > max[j]) {
                                 max[j] = num;
                             }
-                            ++index;
+                            ++indexOffset;
                         }
                     }
                 }
                 return { min: min, max: max };
             };
             /**
+             * Converts a vector3 array to right-handed.
+             * @param vector - vector3 Array to convert to right-handed.
+             * @returns - right-handed Vector3 array.
+             */
+            _Exporter.GetRightHandedVector3 = function (vector) {
+                return new BABYLON.Vector3(vector.x, vector.y, -vector.z);
+            };
+            /**
+             * Converts a vector4 array to right-handed.
+             * @param vector - vector4 Array to convert to right-handed.
+             * @returns - right-handed vector4 array.
+             */
+            _Exporter.GetRightHandedVector4 = function (vector) {
+                return new BABYLON.Vector4(vector.x, vector.y, -vector.z, -vector.w);
+            };
+            /**
+             * Converts a quaternion to right-handed.
+             * @param quaternion - Source quaternion to convert to right-handed.
+             */
+            _Exporter.GetRightHandedQuaternion = function (quaternion) {
+                return new BABYLON.Quaternion(-quaternion.x, -quaternion.y, quaternion.z, quaternion.w);
+            };
+            /**
              * Writes mesh attribute data to a data buffer.
              * Returns the bytelength of the data.
              * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
@@ -319,112 +338,35 @@ var BABYLON;
              * @param strideSize - Represents the offset between consecutive attributes
              * @param byteOffset - The offset to start counting bytes from.
              * @param dataBuffer - The buffer to write the binary data to.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer) {
                 var byteOff = byteOffset;
-                var start = 0;
                 var end = meshAttributeArray.length / strideSize;
                 var byteLength = 0;
-                switch (vertexBufferKind) {
-                    case BABYLON.VertexBuffer.PositionKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                            if (useRightHandedSystem) {
-                                dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
-                            }
-                            else {
-                                dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
-                            }
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
-                    }
-                    case BABYLON.VertexBuffer.NormalKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                            if (useRightHandedSystem) {
-                                dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
-                            }
-                            else {
-                                dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
-                            }
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
-                    }
-                    case BABYLON.VertexBuffer.TangentKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                            if (useRightHandedSystem) {
-                                dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
-                            }
-                            else {
-                                dataBuffer.setFloat32(byteOff, -meshAttributeArray[index + 2], true);
-                            }
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
+                for (var k = 0; k < end; ++k) {
+                    var index = k * strideSize;
+                    var vector = [];
+                    if (vertexBufferKind === BABYLON.VertexBuffer.PositionKind || vertexBufferKind === BABYLON.VertexBuffer.NormalKind) {
+                        var vertexData = new BABYLON.Vector3(meshAttributeArray[index], meshAttributeArray[index + 1], meshAttributeArray[index + 2]);
+                        vector = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(vertexData).asArray() : vertexData.asArray();
                     }
-                    case BABYLON.VertexBuffer.ColorKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 2], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
+                    else if (vertexBufferKind === BABYLON.VertexBuffer.TangentKind || vertexBufferKind === BABYLON.VertexBuffer.ColorKind) {
+                        var vertexData = new BABYLON.Vector4(meshAttributeArray[index], meshAttributeArray[index + 1], meshAttributeArray[index + 2], meshAttributeArray[index + 3]);
+                        vector = (this.convertToRightHandedSystem && !(vertexBufferKind === BABYLON.VertexBuffer.ColorKind)) ? _Exporter.GetRightHandedVector4(vertexData).asArray() : vertexData.asArray();
                     }
-                    case BABYLON.VertexBuffer.UVKind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
+                    else if (vertexBufferKind === BABYLON.VertexBuffer.UVKind || vertexBufferKind === BABYLON.VertexBuffer.UV2Kind) {
+                        vector = [meshAttributeArray[index], meshAttributeArray[index + 1]];
                     }
-                    case BABYLON.VertexBuffer.UV2Kind: {
-                        for (var k = start; k < end; ++k) {
-                            var index = k * strideSize;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
-                            byteOff += 4;
-                            dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
-                            byteOff += 4;
-                        }
-                        byteLength = meshAttributeArray.length * 4;
-                        break;
+                    else {
+                        BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
                     }
-                    default: {
-                        throw new Error("Unsupported vertex buffer type: " + vertexBufferKind);
+                    for (var i = 0; i < vector.length; ++i) {
+                        dataBuffer.setFloat32(byteOff, vector[i], true);
+                        byteOff += 4;
                     }
                 }
+                byteLength = meshAttributeArray.length * 4;
                 return byteLength;
             };
             /**
@@ -439,32 +381,32 @@ var BABYLON;
                 var glTF = {
                     asset: this.asset
                 };
-                if (buffer.byteLength > 0) {
+                if (buffer.byteLength) {
                     glTF.buffers = [buffer];
                 }
-                if (this.nodes && this.nodes.length !== 0) {
+                if (this.nodes && this.nodes.length) {
                     glTF.nodes = this.nodes;
                 }
-                if (this.meshes && this.meshes.length !== 0) {
+                if (this.meshes && this.meshes.length) {
                     glTF.meshes = this.meshes;
                 }
-                if (this.scenes && this.scenes.length !== 0) {
+                if (this.scenes && this.scenes.length) {
                     glTF.scenes = this.scenes;
                     glTF.scene = 0;
                 }
-                if (this.bufferViews && this.bufferViews.length !== 0) {
+                if (this.bufferViews && this.bufferViews.length) {
                     glTF.bufferViews = this.bufferViews;
                 }
-                if (this.accessors && this.accessors.length !== 0) {
+                if (this.accessors && this.accessors.length) {
                     glTF.accessors = this.accessors;
                 }
-                if (this.materials && this.materials.length !== 0) {
+                if (this.materials && this.materials.length) {
                     glTF.materials = this.materials;
                 }
-                if (this.textures && this.textures.length !== 0) {
+                if (this.textures && this.textures.length) {
                     glTF.textures = this.textures;
                 }
-                if (this.images && this.images.length !== 0) {
+                if (this.images && this.images.length) {
                     if (!shouldUseGlb) {
                         glTF.images = this.images;
                     }
@@ -475,7 +417,7 @@ var BABYLON;
                         var byteOffset = this.totalByteLength;
                         for (var i = 0; i < imageLength; ++i) {
                             var image = this.images[i];
-                            if (image.uri !== undefined) {
+                            if (image.uri) {
                                 var imageData = this.imageData[image.uri];
                                 var imageName = image.uri.split('.')[0] + " image";
                                 var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
@@ -503,15 +445,15 @@ var BABYLON;
              * @returns - GLTFData with glTF file data.
              */
             _Exporter.prototype._generateGLTF = function (glTFPrefix) {
-                var jsonText = this.generateJSON(false, glTFPrefix, true);
                 var binaryBuffer = this.generateBinary();
+                var jsonText = this.generateJSON(false, glTFPrefix, true);
                 var bin = new Blob([binaryBuffer], { type: 'application/octet-stream' });
                 var glTFFileName = glTFPrefix + '.gltf';
                 var glTFBinFile = glTFPrefix + '.bin';
                 var container = new BABYLON._GLTFData();
                 container.glTFFiles[glTFFileName] = jsonText;
                 container.glTFFiles[glTFBinFile] = bin;
-                if (this.imageData !== null) {
+                if (this.imageData) {
                     for (var image in this.imageData) {
                         container.glTFFiles[image] = new Blob([this.imageData[image].data], { type: this.imageData[image].mimeType });
                     }
@@ -524,10 +466,8 @@ var BABYLON;
              */
             _Exporter.prototype.generateBinary = function () {
                 var byteOffset = 0;
-                var binaryBuffer = new ArrayBuffer(this.totalByteLength);
-                var dataBuffer = new DataView(binaryBuffer);
-                byteOffset = this.createScene(this.babylonScene, byteOffset, dataBuffer);
-                return binaryBuffer;
+                byteOffset = this.createScene(this.babylonScene, byteOffset);
+                return this.binaryBuffer;
             };
             /**
              * Pads the number to a multiple of 4
@@ -546,8 +486,8 @@ var BABYLON;
              * @returns - object with glb filename as key and data as value
              */
             _Exporter.prototype._generateGLB = function (glTFPrefix) {
-                var jsonText = this.generateJSON(true);
                 var binaryBuffer = this.generateBinary();
+                var jsonText = this.generateJSON(true);
                 var glbFileName = glTFPrefix + '.glb';
                 var headerLength = 12;
                 var chunkLengthPrefix = 8;
@@ -613,36 +553,20 @@ var BABYLON;
              * Sets the TRS for each node
              * @param node - glTF Node for storing the transformation data.
              * @param babylonMesh - Babylon mesh used as the source for the transformation data.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              */
-            _Exporter.prototype.setNodeTransformation = function (node, babylonMesh, useRightHandedSystem) {
+            _Exporter.prototype.setNodeTransformation = function (node, babylonMesh) {
                 if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
-                    if (useRightHandedSystem) {
-                        node.translation = babylonMesh.position.asArray();
-                    }
-                    else {
-                        node.translation = [babylonMesh.position.x, babylonMesh.position.y, -babylonMesh.position.z];
-                    }
+                    node.translation = this.convertToRightHandedSystem ? _Exporter.GetRightHandedVector3(babylonMesh.position).asArray() : babylonMesh.position.asArray();
                 }
                 if (!(babylonMesh.scaling.x === 1 && babylonMesh.scaling.y === 1 && babylonMesh.scaling.z === 1)) {
-                    if (useRightHandedSystem) {
-                        node.scale = babylonMesh.scaling.asArray();
-                    }
-                    else {
-                        node.scale = [babylonMesh.scaling.x, babylonMesh.scaling.y, -babylonMesh.scaling.z];
-                    }
+                    node.scale = babylonMesh.scaling.asArray();
                 }
                 var rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(babylonMesh.rotation.y, babylonMesh.rotation.x, babylonMesh.rotation.z);
                 if (babylonMesh.rotationQuaternion) {
                     rotationQuaternion = rotationQuaternion.multiply(babylonMesh.rotationQuaternion);
                 }
                 if (!(rotationQuaternion.x === 0 && rotationQuaternion.y === 0 && rotationQuaternion.z === 0 && rotationQuaternion.w === 1)) {
-                    if (useRightHandedSystem) {
-                        node.rotation = rotationQuaternion.asArray();
-                    }
-                    else {
-                        node.rotation = [-rotationQuaternion.x, -rotationQuaternion.y, rotationQuaternion.z, rotationQuaternion.w];
-                    }
+                    node.rotation = this.convertToRightHandedSystem ? _Exporter.GetRightHandedQuaternion(rotationQuaternion).asArray() : rotationQuaternion.asArray();
                 }
             };
             /**
@@ -650,11 +574,10 @@ var BABYLON;
              * @param kind - Indicates the type of vertices data.
              * @param babylonMesh - The Babylon mesh to get the vertices data from.
              * @param byteOffset - The offset from the buffer to start indexing from.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              * @param dataBuffer - The buffer to write the bufferview data to.
              * @returns bytelength of the bufferview data.
              */
-            _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+            _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, dataBuffer) {
                 var bufferMesh = null;
                 var byteLength = 0;
                 if (babylonMesh instanceof BABYLON.Mesh) {
@@ -663,62 +586,29 @@ var BABYLON;
                 else if (babylonMesh instanceof BABYLON.InstancedMesh) {
                     bufferMesh = babylonMesh.sourceMesh;
                 }
-                if (bufferMesh !== null) {
+                if (bufferMesh) {
                     var vertexBuffer = null;
                     var vertexBufferOffset = null;
                     var vertexData = null;
                     var vertexStrideSize = null;
-                    if (bufferMesh.getVerticesDataKinds().indexOf(kind) > -1) {
+                    if (bufferMesh.isVerticesDataPresent(kind)) {
                         vertexBuffer = bufferMesh.getVertexBuffer(kind);
-                        vertexBufferOffset = vertexBuffer.getOffset();
-                        vertexData = vertexBuffer.getData();
-                        vertexStrideSize = vertexBuffer.getStrideSize();
-                        if (dataBuffer && vertexData) {
-                            byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
-                            byteOffset += byteLength;
-                        }
-                        else {
-                            var bufferViewName = null;
-                            switch (kind) {
-                                case BABYLON.VertexBuffer.PositionKind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "Position - " + bufferMesh.name;
-                                    break;
-                                }
-                                case BABYLON.VertexBuffer.NormalKind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "Normal - " + bufferMesh.name;
-                                    break;
-                                }
-                                case BABYLON.VertexBuffer.TangentKind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "Tangent - " + bufferMesh.name;
-                                    break;
-                                }
-                                case BABYLON.VertexBuffer.ColorKind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "Color - " + bufferMesh.name;
-                                    break;
+                        if (vertexBuffer) {
+                            vertexBufferOffset = vertexBuffer.getOffset();
+                            vertexData = vertexBuffer.getData();
+                            if (vertexData) {
+                                vertexStrideSize = vertexBuffer.getStrideSize();
+                                if (dataBuffer && vertexData) {
+                                    byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer);
+                                    byteOffset += byteLength;
                                 }
-                                case BABYLON.VertexBuffer.UVKind: {
+                                else {
                                     byteLength = vertexData.length * 4;
-                                    bufferViewName = "TexCoord 0 - " + bufferMesh.name;
-                                    break;
-                                }
-                                case BABYLON.VertexBuffer.UV2Kind: {
-                                    byteLength = vertexData.length * 4;
-                                    bufferViewName = "TexCoord 1 - " + bufferMesh.name;
-                                    break;
-                                }
-                                default: {
-                                    BABYLON.Tools.Warn("Unsupported VertexBuffer kind: " + kind);
+                                    var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, kind + " - " + bufferMesh.name);
+                                    byteOffset += byteLength;
+                                    this.bufferViews.push(bufferView);
                                 }
                             }
-                            if (bufferViewName !== null) {
-                                var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, bufferViewName);
-                                byteOffset += byteLength;
-                                this.bufferViews.push(bufferView);
-                            }
                         }
                     }
                 }
@@ -729,11 +619,10 @@ var BABYLON;
              * @param mesh - glTF Mesh object to store the primitive attribute information.
              * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
              * @param byteOffset - The offset in bytes of the buffer data.
-             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              * @param dataBuffer - Buffer to write the attribute data to.
              * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
              */
-            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, dataBuffer) {
                 var bufferMesh = null;
                 if (babylonMesh instanceof BABYLON.Mesh) {
                     bufferMesh = babylonMesh;
@@ -741,147 +630,134 @@ var BABYLON;
                 else if (babylonMesh instanceof BABYLON.InstancedMesh) {
                     bufferMesh = babylonMesh.sourceMesh;
                 }
-                var positionBufferViewIndex = null;
-                var normalBufferViewIndex = null;
-                var colorBufferViewIndex = null;
-                var tangentBufferViewIndex = null;
-                var texCoord0BufferViewIndex = null;
-                var texCoord1BufferViewIndex = null;
+                var attributeData = [
+                    { kind: BABYLON.VertexBuffer.PositionKind, accessorType: "VEC3" /* VEC3 */ },
+                    { kind: BABYLON.VertexBuffer.NormalKind, accessorType: "VEC3" /* VEC3 */ },
+                    { kind: BABYLON.VertexBuffer.ColorKind, accessorType: "VEC4" /* VEC4 */ },
+                    { kind: BABYLON.VertexBuffer.TangentKind, accessorType: "VEC4" /* VEC4 */ },
+                    { kind: BABYLON.VertexBuffer.UVKind, accessorType: "VEC2" /* VEC2 */ },
+                    { kind: BABYLON.VertexBuffer.UV2Kind, accessorType: "VEC2" /* VEC2 */ },
+                ];
                 var indexBufferViewIndex = null;
-                if (bufferMesh !== null) {
+                if (bufferMesh) {
                     // For each BabylonMesh, create bufferviews for each 'kind'
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.PositionKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        positionBufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.NormalKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        normalBufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.ColorKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        colorBufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.TangentKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        colorBufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UVKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        texCoord0BufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UV2Kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                        texCoord1BufferViewIndex = this.bufferViews.length - 1;
-                    }
-                    if (bufferMesh.getTotalIndices() > 0) {
-                        var indices = bufferMesh.getIndices();
-                        if (dataBuffer) {
-                            var end = indices.length;
-                            var byteOff = byteOffset;
-                            for (var k = 0; k < end; ++k) {
-                                dataBuffer.setUint32(byteOff, indices[k], true);
-                                byteOff += 4;
-                            }
-                            byteOffset = byteOff;
-                        }
-                        else {
-                            var byteLength = indices.length * 4;
-                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferView);
-                            indexBufferViewIndex = this.bufferViews.length - 1;
+                    for (var _i = 0, attributeData_1 = attributeData; _i < attributeData_1.length; _i++) {
+                        var attribute = attributeData_1[_i];
+                        var attributeKind = attribute.kind;
+                        if (bufferMesh.isVerticesDataPresent(attributeKind)) {
+                            byteOffset += this.createBufferViewKind(attributeKind, babylonMesh, byteOffset, dataBuffer);
+                            attribute.bufferViewIndex = this.bufferViews.length - 1;
                         }
                     }
-                }
-                // go through all mesh primitives (submeshes)
-                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
-                    var submesh = babylonMesh.subMeshes[j];
-                    var meshPrimitive = { attributes: {} };
-                    if (bufferMesh !== null) {
-                        // Create a bufferview storing all the positions
-                        if (!dataBuffer) {
-                            // Loop through each attribute of the submesh (mesh primitive)
-                            if (positionBufferViewIndex !== null) {
-                                var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
-                                var positions = positionVertexBuffer.getData();
-                                var positionStrideSize = positionVertexBuffer.getStrideSize();
-                                // Create accessor
-                                var result = this.calculateMinMax(positions, 0, positions.length / positionStrideSize, positionStrideSize, useRightHandedSystem);
-                                var accessor = this.createAccessor(positionBufferViewIndex, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, positions.length / positionStrideSize, 0, result.min, result.max);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                            }
-                            if (normalBufferViewIndex !== null) {
-                                var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
-                                var normals = normalVertexBuffer.getData();
-                                var normalStrideSize = normalVertexBuffer.getStrideSize();
-                                // Create accessor
-                                var accessor = this.createAccessor(normalBufferViewIndex, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, normals.length / normalStrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
-                            }
-                            if (tangentBufferViewIndex !== null) {
-                                var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
-                                var tangents = tangentVertexBuffer.getData();
-                                var tangentStrideSize = tangentVertexBuffer.getStrideSize();
-                                // Create accessor
-                                var accessor = this.createAccessor(tangentBufferViewIndex, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, tangents.length / tangentStrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                            }
-                            if (colorBufferViewIndex !== null) {
-                                var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
-                                var colors = colorVertexBuffer.getData();
-                                var colorStrideSize = colorVertexBuffer.getStrideSize();
-                                // Create accessor
-                                var accessor = this.createAccessor(colorBufferViewIndex, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, colors.length / colorStrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                            }
-                            if (texCoord0BufferViewIndex !== null) {
-                                // Create accessor
-                                var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
-                                var texCoord0s = texCoord0VertexBuffer.getData();
-                                var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
-                                var accessor = this.createAccessor(texCoord0BufferViewIndex, "Texture Coords 0", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord0s.length / texCoord0StrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                            }
-                            if (texCoord1BufferViewIndex !== null) {
-                                // Create accessor
-                                var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
-                                var texCoord1s = texCoord1VertexBuffer.getData();
-                                var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
-                                var accessor = this.createAccessor(texCoord1BufferViewIndex, "Texture Coords 1", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord1s.length / texCoord1StrideSize);
-                                this.accessors.push(accessor);
-                                meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                    if (bufferMesh.getTotalIndices()) {
+                        var indices = bufferMesh.getIndices();
+                        if (indices) {
+                            if (dataBuffer) {
+                                var end = indices.length;
+                                var byteOff = byteOffset;
+                                for (var k = 0; k < end; ++k) {
+                                    dataBuffer.setUint32(byteOff, indices[k], true);
+                                    byteOff += 4;
+                                }
+                                byteOffset = byteOff;
                             }
-                            if (indexBufferViewIndex) {
-                                // Create accessor
-                                var accessor = this.createAccessor(indexBufferViewIndex, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4);
-                                this.accessors.push(accessor);
-                                meshPrimitive.indices = this.accessors.length - 1;
+                            else {
+                                var byteLength = indices.length * 4;
+                                var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
+                                byteOffset += byteLength;
+                                this.bufferViews.push(bufferView);
+                                indexBufferViewIndex = this.bufferViews.length - 1;
                             }
                         }
-                        if (bufferMesh.material) {
-                            if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                                var materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
-                                meshPrimitive.material = materialIndex;
+                    }
+                    if (babylonMesh.subMeshes) {
+                        // go through all mesh primitives (submeshes)
+                        for (var _a = 0, _b = babylonMesh.subMeshes; _a < _b.length; _a++) {
+                            var submesh = _b[_a];
+                            var meshPrimitive = { attributes: {} };
+                            // Create a bufferview storing all the positions
+                            if (!dataBuffer) {
+                                for (var _c = 0, attributeData_2 = attributeData; _c < attributeData_2.length; _c++) {
+                                    var attribute = attributeData_2[_c];
+                                    var attributeKind = attribute.kind;
+                                    if (bufferMesh.isVerticesDataPresent(attributeKind)) {
+                                        var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
+                                        if (vertexBuffer) {
+                                            var bufferData = vertexBuffer.getData();
+                                            if (bufferData) {
+                                                var strideSize = vertexBuffer.getStrideSize();
+                                                var minMax = void 0;
+                                                var min = null;
+                                                var max = null;
+                                                var bufferViewIndex = attribute.bufferViewIndex;
+                                                if (bufferViewIndex != undefined) {
+                                                    if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
+                                                        minMax = this.calculateMinMaxPositions(bufferData, 0, bufferData.length / strideSize);
+                                                        min = minMax.min;
+                                                        max = minMax.max;
+                                                    }
+                                                    var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, bufferData.length / strideSize, 0, min, max);
+                                                    this.accessors.push(accessor);
+                                                    switch (attributeKind) {
+                                                        case BABYLON.VertexBuffer.PositionKind: {
+                                                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.NormalKind: {
+                                                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.ColorKind: {
+                                                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.TangentKind: {
+                                                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.UVKind: {
+                                                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        case BABYLON.VertexBuffer.UV2Kind: {
+                                                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                            break;
+                                                        }
+                                                        default: {
+                                                            BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                                if (indexBufferViewIndex) {
+                                    // Create accessor
+                                    var accessor = this.createAccessor(indexBufferViewIndex, "indices - " + babylonMesh.name, "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4, null, null);
+                                    this.accessors.push(accessor);
+                                    meshPrimitive.indices = this.accessors.length - 1;
+                                }
                             }
-                            else if (bufferMesh.material instanceof BABYLON.MultiMaterial) {
-                                var babylonMultiMaterial = bufferMesh.material;
-                                var material = babylonMultiMaterial.subMaterials[submesh.materialIndex];
-                                if (material !== null) {
-                                    var materialIndex = babylonMesh.getScene().materials.indexOf(material);
+                            if (bufferMesh.material) {
+                                if (bufferMesh.material instanceof BABYLON.StandardMaterial || bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
+                                    var materialIndex = babylonMesh.getScene().materials.indexOf(bufferMesh.material);
                                     meshPrimitive.material = materialIndex;
                                 }
+                                else if (bufferMesh.material instanceof BABYLON.MultiMaterial) {
+                                    var babylonMultiMaterial = bufferMesh.material;
+                                    var material = babylonMultiMaterial.subMaterials[submesh.materialIndex];
+                                    if (material) {
+                                        var materialIndex = babylonMesh.getScene().materials.indexOf(material);
+                                        meshPrimitive.material = materialIndex;
+                                    }
+                                }
+                                else {
+                                    BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
+                                }
                             }
-                            else {
-                                BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
-                            }
+                            mesh.primitives.push(meshPrimitive);
                         }
-                        mesh.primitives.push(meshPrimitive);
                     }
                 }
                 return byteOffset;
@@ -891,47 +767,90 @@ var BABYLON;
              * Returns the the total byte offset.
              * @param babylonScene - Babylon scene to get the mesh data from.
              * @param byteOffset - Offset to start from in bytes.
-             * @param dataBuffer - Buffer to write geometry data to.
              * @returns bytelength + byteoffset
              */
-            _Exporter.prototype.createScene = function (babylonScene, byteOffset, dataBuffer) {
-                if (babylonScene.meshes.length > 0) {
+            _Exporter.prototype.createScene = function (babylonScene, byteOffset) {
+                if (babylonScene.meshes.length) {
                     var babylonMeshes = babylonScene.meshes;
                     var scene = { nodes: new Array() };
-                    if (dataBuffer == null) {
-                        GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
-                    }
+                    GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
+                    var result = this.createNodeMap(babylonScene, byteOffset);
+                    this.nodeMap = result.nodeMap;
+                    this.totalByteLength = result.byteOffset;
+                    this.binaryBuffer = new ArrayBuffer(this.totalByteLength);
+                    var dataBuffer = new DataView(this.binaryBuffer);
                     for (var i = 0; i < babylonMeshes.length; ++i) {
                         if (this.options &&
-                            this.options.shouldExportMesh !== undefined &&
+                            this.options.shouldExportMesh != undefined &&
                             !this.options.shouldExportMesh(babylonMeshes[i])) {
                             continue;
                         }
                         else {
-                            // create node to hold translation/rotation/scale and the mesh
-                            var node = { mesh: -1 };
                             var babylonMesh = babylonMeshes[i];
-                            var useRightHandedSystem = babylonMesh.getScene().useRightHandedSystem;
-                            // Set transformation
-                            this.setNodeTransformation(node, babylonMesh, useRightHandedSystem);
-                            // create mesh
-                            var mesh = { primitives: new Array() };
-                            mesh.primitives = [];
-                            byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
-                            // go through all mesh primitives (submeshes)
-                            this.meshes.push(mesh);
-                            node.mesh = this.meshes.length - 1;
-                            if (babylonMesh.name) {
-                                node.name = babylonMesh.name;
+                            // Build Hierarchy with the node map.
+                            var glTFNodeIndex = this.nodeMap[babylonMesh.uniqueId];
+                            var glTFNode = this.nodes[glTFNodeIndex];
+                            if (!babylonMesh.parent) {
+                                scene.nodes.push(glTFNodeIndex);
                             }
-                            this.nodes.push(node);
-                            scene.nodes.push(this.nodes.length - 1);
+                            var directDescendents = babylonMesh.getDescendants(true);
+                            if (!glTFNode.children && directDescendents && directDescendents.length) {
+                                glTFNode.children = [];
+                                for (var _i = 0, directDescendents_1 = directDescendents; _i < directDescendents_1.length; _i++) {
+                                    var descendent = directDescendents_1[_i];
+                                    glTFNode.children.push(this.nodeMap[descendent.uniqueId]);
+                                }
+                            }
+                            var mesh = { primitives: new Array() };
+                            byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
                         }
                     }
                     this.scenes.push(scene);
                 }
                 return byteOffset;
             };
+            /**
+             * Creates a mapping of Node unique id to node index
+             * @param scene - Babylon Scene.
+             * @param byteOffset - The initial byte offset.
+             * @returns - Node mapping of unique id to index.
+             */
+            _Exporter.prototype.createNodeMap = function (scene, byteOffset) {
+                var nodeMap = {};
+                for (var _i = 0, _a = scene.meshes; _i < _a.length; _i++) {
+                    var babylonMesh = _a[_i];
+                    var result = this.createNode(babylonMesh, byteOffset, null);
+                    this.nodes.push(result.node);
+                    nodeMap[babylonMesh.uniqueId] = this.nodes.length - 1;
+                    byteOffset = result.byteOffset;
+                }
+                return { nodeMap: nodeMap, byteOffset: byteOffset };
+            };
+            /**
+             * Creates a glTF node from a Babylon mesh.
+             * @param babylonMesh - Source Babylon mesh.
+             * @param byteOffset - The initial byte offset.
+             * @param dataBuffer - Buffer for storing geometry data.
+             * @returns - Object containing an INode and byteoffset.
+             */
+            _Exporter.prototype.createNode = function (babylonMesh, byteOffset, dataBuffer) {
+                // create node to hold translation/rotation/scale and the mesh
+                var node = {};
+                if (babylonMesh.name) {
+                    node.name = babylonMesh.name;
+                }
+                // Set transformation
+                this.setNodeTransformation(node, babylonMesh);
+                // create mesh
+                var mesh = { primitives: new Array() };
+                mesh.primitives = [];
+                byteOffset = this.setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
+                if (mesh.primitives.length) {
+                    this.meshes.push(mesh);
+                    node.mesh = this.meshes.length - 1;
+                }
+                return { node: node, byteOffset: byteOffset };
+            };
             return _Exporter;
         }());
         GLTF2._Exporter = _Exporter;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 62 - 24
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -363,6 +363,18 @@ declare module BABYLON.GLTF2 {
          */
         private imageData;
         /**
+         * Stores a map of the unique id of a node to its index in the node array.
+         */
+        private nodeMap;
+        /**
+         * Stores the binary buffer used to store geometry data.
+         */
+        private binaryBuffer;
+        /**
+         * Specifies if the Babylon scene should be converted to right-handed on export.
+         */
+        private convertToRightHandedSystem;
+        /**
          * Creates a glTF Exporter instance, which can accept optional exporter options.
          * @param babylonScene - Babylon scene object
          * @param options - Options to modify the behavior of the exporter.
@@ -380,26 +392,42 @@ declare module BABYLON.GLTF2 {
         private createBufferView(bufferIndex, byteOffset, byteLength, byteStride?, name?);
         /**
          * Creates an accessor based on the supplied arguments
-         * @param bufferviewIndex
-         * @param name
-         * @param type
-         * @param componentType
-         * @param count
-         * @param min
-         * @param max
+         * @param bufferviewIndex - The index of the bufferview referenced by this accessor.
+         * @param name - The name of the accessor.
+         * @param type - The type of the accessor.
+         * @param componentType - The datatype of components in the attribute.
+         * @param count - The number of attributes referenced by this accessor.
+         * @param byteOffset - The offset relative to the start of the bufferView in bytes.
+         * @param min - Minimum value of each component in this attribute.
+         * @param max - Maximum value of each component in this attribute.
          * @returns - accessor for glTF
          */
-        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset?, min?, max?);
+        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset, min, max);
         /**
-         * Calculates the minimum and maximum values of an array of floats, based on stride
-         * @param buff - Data to check for min and max values.
-         * @param vertexStart - Start offset to calculate min and max values.
+         * Calculates the minimum and maximum values of an array of position floats.
+         * @param positions - Positions array of a mesh.
+         * @param vertexStart - Starting vertex offset to calculate min and max values.
          * @param vertexCount - Number of vertices to check for min and max values.
-         * @param stride - Offset between consecutive attributes.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          * @returns - min number array and max number array.
          */
-        private calculateMinMax(buff, vertexStart, vertexCount, stride, useRightHandedSystem);
+        private calculateMinMaxPositions(positions, vertexStart, vertexCount);
+        /**
+         * Converts a vector3 array to right-handed.
+         * @param vector - vector3 Array to convert to right-handed.
+         * @returns - right-handed Vector3 array.
+         */
+        private static GetRightHandedVector3(vector);
+        /**
+         * Converts a vector4 array to right-handed.
+         * @param vector - vector4 Array to convert to right-handed.
+         * @returns - right-handed vector4 array.
+         */
+        private static GetRightHandedVector4(vector);
+        /**
+         * Converts a quaternion to right-handed.
+         * @param quaternion - Source quaternion to convert to right-handed.
+         */
+        private static GetRightHandedQuaternion(quaternion);
         /**
          * Writes mesh attribute data to a data buffer.
          * Returns the bytelength of the data.
@@ -408,10 +436,9 @@ declare module BABYLON.GLTF2 {
          * @param strideSize - Represents the offset between consecutive attributes
          * @param byteOffset - The offset to start counting bytes from.
          * @param dataBuffer - The buffer to write the binary data to.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer);
         /**
          * Generates glTF json data
          * @param shouldUseGlb - Indicates whether the json should be written for a glb file.
@@ -448,38 +475,49 @@ declare module BABYLON.GLTF2 {
          * Sets the TRS for each node
          * @param node - glTF Node for storing the transformation data.
          * @param babylonMesh - Babylon mesh used as the source for the transformation data.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          */
-        private setNodeTransformation(node, babylonMesh, useRightHandedSystem);
+        private setNodeTransformation(node, babylonMesh);
         /**
          * Creates a bufferview based on the vertices type for the Babylon mesh
          * @param kind - Indicates the type of vertices data.
          * @param babylonMesh - The Babylon mesh to get the vertices data from.
          * @param byteOffset - The offset from the buffer to start indexing from.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          * @param dataBuffer - The buffer to write the bufferview data to.
          * @returns bytelength of the bufferview data.
          */
-        private createBufferViewKind(kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+        private createBufferViewKind(kind, babylonMesh, byteOffset, dataBuffer);
         /**
          * Sets data for the primitive attributes of each submesh
          * @param mesh - glTF Mesh object to store the primitive attribute information.
          * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
          * @param byteOffset - The offset in bytes of the buffer data.
-         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          * @param dataBuffer - Buffer to write the attribute data to.
          * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
          */
-        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
         /**
          * 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.
          * @param byteOffset - Offset to start from in bytes.
-         * @param dataBuffer - Buffer to write geometry data to.
          * @returns bytelength + byteoffset
          */
-        private createScene(babylonScene, byteOffset, dataBuffer);
+        private createScene(babylonScene, byteOffset);
+        /**
+         * Creates a mapping of Node unique id to node index
+         * @param scene - Babylon Scene.
+         * @param byteOffset - The initial byte offset.
+         * @returns - Node mapping of unique id to index.
+         */
+        private createNodeMap(scene, byteOffset);
+        /**
+         * Creates a glTF node from a Babylon mesh.
+         * @param babylonMesh - Source Babylon mesh.
+         * @param byteOffset - The initial byte offset.
+         * @param dataBuffer - Buffer for storing geometry data.
+         * @returns - Object containing an INode and byteoffset.
+         */
+        private createNode(babylonMesh, byteOffset, dataBuffer);
     }
 }
 

+ 2 - 23
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 7241,
+  "errors": 7238,
   "babylon.typedoc.json": {
-    "errors": 7241,
+    "errors": 7238,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {
@@ -28539,37 +28539,16 @@
         "simulatePointerDown": {
           "Comments": {
             "MissingReturn": true
-          },
-          "Parameter": {
-            "pickResult": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
           }
         },
         "simulatePointerMove": {
           "Comments": {
             "MissingReturn": true
-          },
-          "Parameter": {
-            "pickResult": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
           }
         },
         "simulatePointerUp": {
           "Comments": {
             "MissingReturn": true
-          },
-          "Parameter": {
-            "pickResult": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
           }
         },
         "sortLightsByPriority": {

文件差异内容过多而无法显示
+ 66 - 66
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 362 - 294
dist/preview release/viewer/babylon.viewer.max.js