David Catuhe 7 lat temu
rodzic
commit
10cfbcad62

Plik diff jest za duży
+ 4286 - 4276
Playground/babylon.d.txt


Plik diff jest za duży
+ 2794 - 2787
dist/preview release/babylon.d.ts


Plik diff jest za duży
+ 42 - 42
dist/preview release/babylon.js


+ 74 - 66
dist/preview release/babylon.max.js

@@ -8561,7 +8561,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.1-beta-5";
+                return "3.1-beta-6";
             },
             enumerable: true,
             configurable: true
@@ -10313,7 +10313,7 @@ var BABYLON;
             }
             if (!fallBack)
                 this._internalTexturesCache.push(texture);
-            var onerror = function () {
+            var onerror = function (message, exception) {
                 if (scene) {
                     scene._removePendingData(texture);
                 }
@@ -10328,7 +10328,7 @@ var BABYLON;
                     _this.createTexture(BABYLON.Tools.fallbackTexture, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
                 }
                 if (onError) {
-                    onError();
+                    onError(message || "Unknown error", exception);
                 }
             };
             var callback = null;
@@ -10368,7 +10368,9 @@ var BABYLON;
                         if (callback) {
                             callback(data);
                         }
-                    }, undefined, scene ? scene.database : undefined, true, onerror);
+                    }, undefined, scene ? scene.database : undefined, true, function (request, exception) {
+                        onerror("Unable to load " + (request ? request.responseURL : url, exception));
+                    });
                 }
                 else {
                     if (callback) {
@@ -13449,6 +13451,7 @@ var BABYLON;
         };
         /**
          * Defines the passed node as the parent of the current node.
+         * The node will remain exactly where it is and its position / rotation will be updated accordingly
          * Returns the TransformNode.
          */
         TransformNode.prototype.setParent = function (node) {
@@ -13467,6 +13470,9 @@ var BABYLON;
                 else {
                     rotation.toEulerAnglesToRef(this.rotation);
                 }
+                this.scaling.x = scale.x;
+                this.scaling.y = scale.y;
+                this.scaling.z = scale.z;
                 this.position.x = position.x;
                 this.position.y = position.y;
                 this.position.z = position.z;
@@ -13475,29 +13481,25 @@ var BABYLON;
                 var rotation = BABYLON.Tmp.Quaternion[0];
                 var position = BABYLON.Tmp.Vector3[0];
                 var scale = BABYLON.Tmp.Vector3[1];
-                var m0 = BABYLON.Tmp.Matrix[0];
-                var m1 = BABYLON.Tmp.Matrix[1];
-                var invParentMatrix = BABYLON.Tmp.Matrix[2];
+                var diffMatrix = BABYLON.Tmp.Matrix[0];
+                var invParentMatrix = BABYLON.Tmp.Matrix[1];
+                this.computeWorldMatrix(true);
                 node.computeWorldMatrix(true);
-                node.getWorldMatrix().decompose(scale, rotation, position);
-                rotation.toRotationMatrix(m0);
-                m1.setTranslation(position);
-                m1.multiplyToRef(m0, m0);
-                m0.invertToRef(invParentMatrix);
-                this.getWorldMatrix().multiplyToRef(invParentMatrix, m0);
-                m0.decompose(scale, rotation, position);
+                node.getWorldMatrix().invertToRef(invParentMatrix);
+                this.getWorldMatrix().multiplyToRef(invParentMatrix, diffMatrix);
+                diffMatrix.decompose(scale, rotation, position);
                 if (this.rotationQuaternion) {
                     this.rotationQuaternion.copyFrom(rotation);
                 }
                 else {
                     rotation.toEulerAnglesToRef(this.rotation);
                 }
-                node.getWorldMatrix().invertToRef(invParentMatrix);
-                this.getWorldMatrix().multiplyToRef(invParentMatrix, m0);
-                m0.decompose(scale, rotation, position);
                 this.position.x = position.x;
                 this.position.y = position.y;
                 this.position.z = position.z;
+                this.scaling.x = scale.x;
+                this.scaling.y = scale.y;
+                this.scaling.z = scale.z;
             }
             this.parent = node;
             return this;
@@ -13805,7 +13807,14 @@ var BABYLON;
             this.onAfterWorldMatrixUpdateObservable.removeCallback(func);
             return this;
         };
-        TransformNode.prototype.clone = function (name, newParent) {
+        /**
+         * Clone the current transform node
+         * Returns the new transform node
+         * @param name Name of the new clone
+         * @param newParent New parent for the clone
+         * @param doNotCloneChildren Do not clone children hierarchy
+         */
+        TransformNode.prototype.clone = function (name, newParent, doNotCloneChildren) {
             var _this = this;
             var result = BABYLON.SerializationHelper.Clone(function () { return new TransformNode(name, _this.getScene()); }, this);
             result.name = name;
@@ -13813,39 +13822,34 @@ var BABYLON;
             if (newParent) {
                 result.parent = newParent;
             }
+            if (!doNotCloneChildren) {
+                // Children
+                var directDescendants = this.getDescendants(true);
+                for (var index = 0; index < directDescendants.length; index++) {
+                    var child = directDescendants[index];
+                    if (child.clone) {
+                        child.clone(name + "." + child.name, result);
+                    }
+                }
+            }
             return result;
         };
-        TransformNode.prototype.serialize = function (serializationObject) {
-            if (serializationObject === void 0) { serializationObject = null; }
-            if (!serializationObject) {
-                serializationObject = {};
-            }
-            serializationObject.name = this.name;
-            serializationObject.id = this.id;
+        TransformNode.prototype.serialize = function (currentSerializationObject) {
+            var serializationObject = BABYLON.SerializationHelper.Serialize(this, currentSerializationObject);
             serializationObject.type = this.getClassName();
+            // Parent
+            if (this.parent) {
+                serializationObject.parentId = this.parent.id;
+            }
             if (BABYLON.Tags && BABYLON.Tags.HasTags(this)) {
                 serializationObject.tags = BABYLON.Tags.GetTags(this);
             }
-            serializationObject.position = this.position.asArray();
-            if (this.rotationQuaternion) {
-                serializationObject.rotationQuaternion = this.rotationQuaternion.asArray();
-            }
-            else if (this.rotation) {
-                serializationObject.rotation = this.rotation.asArray();
-            }
-            serializationObject.scaling = this.scaling.asArray();
             serializationObject.localMatrix = this.getPivotMatrix().asArray();
             serializationObject.isEnabled = this.isEnabled();
-            serializationObject.infiniteDistance = this.infiniteDistance;
-            serializationObject.billboardMode = this.billboardMode;
             // Parent
             if (this.parent) {
                 serializationObject.parentId = this.parent.id;
             }
-            // Metadata
-            if (this.metadata) {
-                serializationObject.metadata = this.metadata;
-            }
             return serializationObject;
         };
         // Statics
@@ -13855,22 +13859,10 @@ var BABYLON;
          * The parameter `rootUrl` is a string, it's the root URL to prefix the `delayLoadingFile` property with
          */
         TransformNode.Parse = function (parsedTransformNode, scene, rootUrl) {
-            var transformNode = new TransformNode(parsedTransformNode.name, scene);
-            transformNode.id = parsedTransformNode.id;
+            var transformNode = BABYLON.SerializationHelper.Parse(function () { return new TransformNode(parsedTransformNode.name, scene); }, parsedTransformNode, scene, rootUrl);
             if (BABYLON.Tags) {
                 BABYLON.Tags.AddTagsTo(transformNode, parsedTransformNode.tags);
             }
-            transformNode.position = BABYLON.Vector3.FromArray(parsedTransformNode.position);
-            if (parsedTransformNode.metadata !== undefined) {
-                transformNode.metadata = parsedTransformNode.metadata;
-            }
-            if (parsedTransformNode.rotationQuaternion) {
-                transformNode.rotationQuaternion = BABYLON.Quaternion.FromArray(parsedTransformNode.rotationQuaternion);
-            }
-            else if (parsedTransformNode.rotation) {
-                transformNode.rotation = BABYLON.Vector3.FromArray(parsedTransformNode.rotation);
-            }
-            transformNode.scaling = BABYLON.Vector3.FromArray(parsedTransformNode.scaling);
             if (parsedTransformNode.localMatrix) {
                 transformNode.setPivotMatrix(BABYLON.Matrix.FromArray(parsedTransformNode.localMatrix));
             }
@@ -13878,8 +13870,6 @@ var BABYLON;
                 transformNode.setPivotMatrix(BABYLON.Matrix.FromArray(parsedTransformNode.pivotMatrix));
             }
             transformNode.setEnabled(parsedTransformNode.isEnabled);
-            transformNode.infiniteDistance = parsedTransformNode.infiniteDistance;
-            transformNode.billboardMode = parsedTransformNode.billboardMode;
             // Parent
             if (parsedTransformNode.parentId) {
                 transformNode._waitingParentId = parsedTransformNode.parentId;
@@ -13887,10 +13877,10 @@ var BABYLON;
             return transformNode;
         };
         /**
-             * Disposes the TransformNode.
-             * By default, all the children are also disposed unless the parameter `doNotRecurse` is set to `true`.
-             * Returns nothing.
-             */
+         * Disposes the TransformNode.
+         * By default, all the children are also disposed unless the parameter `doNotRecurse` is set to `true`.
+         * Returns nothing.
+         */
         TransformNode.prototype.dispose = function (doNotRecurse) {
             // Animations
             this.getScene().stopAnimation(this);
@@ -23103,11 +23093,11 @@ var BABYLON;
                 var index;
                 if (!doNotCloneChildren) {
                     // Children
-                    for (index = 0; index < scene.meshes.length; index++) {
-                        var mesh = scene.meshes[index];
-                        if (mesh.parent === source) {
-                            // doNotCloneChildren is always going to be False
-                            mesh.clone(name + "." + mesh.name, _this, doNotCloneChildren);
+                    var directDescendants = source.getDescendants(true);
+                    for (var index_1 = 0; index_1 < directDescendants.length; index_1++) {
+                        var child = directDescendants[index_1];
+                        if (child.clone) {
+                            child.clone(name + "." + child.name, _this);
                         }
                     }
                 }
@@ -47548,6 +47538,7 @@ var BABYLON;
             _this._matrices = {};
             _this._matrices3x3 = {};
             _this._matrices2x2 = {};
+            _this._vectors2Arrays = {};
             _this._vectors3Arrays = {};
             _this._cachedWorldViewMatrix = new BABYLON.Matrix();
             _this._shaderPath = shaderPath;
@@ -47648,6 +47639,11 @@ var BABYLON;
             this._matrices2x2[name] = value;
             return this;
         };
+        ShaderMaterial.prototype.setArray2 = function (name, value) {
+            this._checkUniform(name);
+            this._vectors2Arrays[name] = value;
+            return this;
+        };
         ShaderMaterial.prototype.setArray3 = function (name, value) {
             this._checkUniform(name);
             this._vectors3Arrays[name] = value;
@@ -47822,6 +47818,10 @@ var BABYLON;
                 for (name in this._matrices2x2) {
                     this._effect.setMatrix2x2(name, this._matrices2x2[name]);
                 }
+                // Vector2Array   
+                for (name in this._vectors2Arrays) {
+                    this._effect.setArray2(name, this._vectors2Arrays[name]);
+                }
                 // Vector3Array   
                 for (name in this._vectors3Arrays) {
                     this._effect.setArray3(name, this._vectors3Arrays[name]);
@@ -47956,6 +47956,11 @@ var BABYLON;
             for (name in this._matrices2x2) {
                 serializationObject.matrices2x2[name] = this._matrices2x2[name];
             }
+            // Vector2Array
+            serializationObject.vectors2Arrays = {};
+            for (name in this._vectors2Arrays) {
+                serializationObject.vectors2Arrays[name] = this._vectors2Arrays[name];
+            }
             // Vector3Array
             serializationObject.vectors3Arrays = {};
             for (name in this._vectors3Arrays) {
@@ -48032,6 +48037,10 @@ var BABYLON;
             for (name in source.matrices2x2) {
                 material.setMatrix2x2(name, source.matrices2x2[name]);
             }
+            // Vector2Array
+            for (name in source.vectors2Arrays) {
+                material.setArray2(name, source.vectors2Arrays[name]);
+            }
             // Vector3Array
             for (name in source.vectors3Arrays) {
                 material.setArray3(name, source.vectors3Arrays[name]);
@@ -72154,10 +72163,9 @@ var BABYLON;
                 });
             }
         };
-        // Little white circle attached to the camera
-        // That will act as the target to look on the floor where to teleport
+        // Gaze support used to point to teleport or to interact with an object
         VRExperienceHelper.prototype._createGazeTracker = function () {
-            this._gazeTracker = BABYLON.Mesh.CreateTorus("gazeTracker", 0.0050, 0.0020, 25, this._scene, false);
+            this._gazeTracker = BABYLON.Mesh.CreateTorus("gazeTracker", 0.0035, 0.0025, 20, this._scene, false);
             this._gazeTracker.bakeCurrentTransformIntoVertices();
             this._gazeTracker.isPickable = false;
             var targetMat = new BABYLON.StandardMaterial("targetMat", this._scene);

Plik diff jest za duży
+ 46 - 46
dist/preview release/babylon.worker.js


Plik diff jest za duży
+ 7672 - 7662
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Plik diff jest za duży
+ 29 - 29
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 74 - 66
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -8561,7 +8561,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.1-beta-5";
+                return "3.1-beta-6";
             },
             enumerable: true,
             configurable: true
@@ -10313,7 +10313,7 @@ var BABYLON;
             }
             if (!fallBack)
                 this._internalTexturesCache.push(texture);
-            var onerror = function () {
+            var onerror = function (message, exception) {
                 if (scene) {
                     scene._removePendingData(texture);
                 }
@@ -10328,7 +10328,7 @@ var BABYLON;
                     _this.createTexture(BABYLON.Tools.fallbackTexture, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
                 }
                 if (onError) {
-                    onError();
+                    onError(message || "Unknown error", exception);
                 }
             };
             var callback = null;
@@ -10368,7 +10368,9 @@ var BABYLON;
                         if (callback) {
                             callback(data);
                         }
-                    }, undefined, scene ? scene.database : undefined, true, onerror);
+                    }, undefined, scene ? scene.database : undefined, true, function (request, exception) {
+                        onerror("Unable to load " + (request ? request.responseURL : url, exception));
+                    });
                 }
                 else {
                     if (callback) {
@@ -13449,6 +13451,7 @@ var BABYLON;
         };
         /**
          * Defines the passed node as the parent of the current node.
+         * The node will remain exactly where it is and its position / rotation will be updated accordingly
          * Returns the TransformNode.
          */
         TransformNode.prototype.setParent = function (node) {
@@ -13467,6 +13470,9 @@ var BABYLON;
                 else {
                     rotation.toEulerAnglesToRef(this.rotation);
                 }
+                this.scaling.x = scale.x;
+                this.scaling.y = scale.y;
+                this.scaling.z = scale.z;
                 this.position.x = position.x;
                 this.position.y = position.y;
                 this.position.z = position.z;
@@ -13475,29 +13481,25 @@ var BABYLON;
                 var rotation = BABYLON.Tmp.Quaternion[0];
                 var position = BABYLON.Tmp.Vector3[0];
                 var scale = BABYLON.Tmp.Vector3[1];
-                var m0 = BABYLON.Tmp.Matrix[0];
-                var m1 = BABYLON.Tmp.Matrix[1];
-                var invParentMatrix = BABYLON.Tmp.Matrix[2];
+                var diffMatrix = BABYLON.Tmp.Matrix[0];
+                var invParentMatrix = BABYLON.Tmp.Matrix[1];
+                this.computeWorldMatrix(true);
                 node.computeWorldMatrix(true);
-                node.getWorldMatrix().decompose(scale, rotation, position);
-                rotation.toRotationMatrix(m0);
-                m1.setTranslation(position);
-                m1.multiplyToRef(m0, m0);
-                m0.invertToRef(invParentMatrix);
-                this.getWorldMatrix().multiplyToRef(invParentMatrix, m0);
-                m0.decompose(scale, rotation, position);
+                node.getWorldMatrix().invertToRef(invParentMatrix);
+                this.getWorldMatrix().multiplyToRef(invParentMatrix, diffMatrix);
+                diffMatrix.decompose(scale, rotation, position);
                 if (this.rotationQuaternion) {
                     this.rotationQuaternion.copyFrom(rotation);
                 }
                 else {
                     rotation.toEulerAnglesToRef(this.rotation);
                 }
-                node.getWorldMatrix().invertToRef(invParentMatrix);
-                this.getWorldMatrix().multiplyToRef(invParentMatrix, m0);
-                m0.decompose(scale, rotation, position);
                 this.position.x = position.x;
                 this.position.y = position.y;
                 this.position.z = position.z;
+                this.scaling.x = scale.x;
+                this.scaling.y = scale.y;
+                this.scaling.z = scale.z;
             }
             this.parent = node;
             return this;
@@ -13805,7 +13807,14 @@ var BABYLON;
             this.onAfterWorldMatrixUpdateObservable.removeCallback(func);
             return this;
         };
-        TransformNode.prototype.clone = function (name, newParent) {
+        /**
+         * Clone the current transform node
+         * Returns the new transform node
+         * @param name Name of the new clone
+         * @param newParent New parent for the clone
+         * @param doNotCloneChildren Do not clone children hierarchy
+         */
+        TransformNode.prototype.clone = function (name, newParent, doNotCloneChildren) {
             var _this = this;
             var result = BABYLON.SerializationHelper.Clone(function () { return new TransformNode(name, _this.getScene()); }, this);
             result.name = name;
@@ -13813,39 +13822,34 @@ var BABYLON;
             if (newParent) {
                 result.parent = newParent;
             }
+            if (!doNotCloneChildren) {
+                // Children
+                var directDescendants = this.getDescendants(true);
+                for (var index = 0; index < directDescendants.length; index++) {
+                    var child = directDescendants[index];
+                    if (child.clone) {
+                        child.clone(name + "." + child.name, result);
+                    }
+                }
+            }
             return result;
         };
-        TransformNode.prototype.serialize = function (serializationObject) {
-            if (serializationObject === void 0) { serializationObject = null; }
-            if (!serializationObject) {
-                serializationObject = {};
-            }
-            serializationObject.name = this.name;
-            serializationObject.id = this.id;
+        TransformNode.prototype.serialize = function (currentSerializationObject) {
+            var serializationObject = BABYLON.SerializationHelper.Serialize(this, currentSerializationObject);
             serializationObject.type = this.getClassName();
+            // Parent
+            if (this.parent) {
+                serializationObject.parentId = this.parent.id;
+            }
             if (BABYLON.Tags && BABYLON.Tags.HasTags(this)) {
                 serializationObject.tags = BABYLON.Tags.GetTags(this);
             }
-            serializationObject.position = this.position.asArray();
-            if (this.rotationQuaternion) {
-                serializationObject.rotationQuaternion = this.rotationQuaternion.asArray();
-            }
-            else if (this.rotation) {
-                serializationObject.rotation = this.rotation.asArray();
-            }
-            serializationObject.scaling = this.scaling.asArray();
             serializationObject.localMatrix = this.getPivotMatrix().asArray();
             serializationObject.isEnabled = this.isEnabled();
-            serializationObject.infiniteDistance = this.infiniteDistance;
-            serializationObject.billboardMode = this.billboardMode;
             // Parent
             if (this.parent) {
                 serializationObject.parentId = this.parent.id;
             }
-            // Metadata
-            if (this.metadata) {
-                serializationObject.metadata = this.metadata;
-            }
             return serializationObject;
         };
         // Statics
@@ -13855,22 +13859,10 @@ var BABYLON;
          * The parameter `rootUrl` is a string, it's the root URL to prefix the `delayLoadingFile` property with
          */
         TransformNode.Parse = function (parsedTransformNode, scene, rootUrl) {
-            var transformNode = new TransformNode(parsedTransformNode.name, scene);
-            transformNode.id = parsedTransformNode.id;
+            var transformNode = BABYLON.SerializationHelper.Parse(function () { return new TransformNode(parsedTransformNode.name, scene); }, parsedTransformNode, scene, rootUrl);
             if (BABYLON.Tags) {
                 BABYLON.Tags.AddTagsTo(transformNode, parsedTransformNode.tags);
             }
-            transformNode.position = BABYLON.Vector3.FromArray(parsedTransformNode.position);
-            if (parsedTransformNode.metadata !== undefined) {
-                transformNode.metadata = parsedTransformNode.metadata;
-            }
-            if (parsedTransformNode.rotationQuaternion) {
-                transformNode.rotationQuaternion = BABYLON.Quaternion.FromArray(parsedTransformNode.rotationQuaternion);
-            }
-            else if (parsedTransformNode.rotation) {
-                transformNode.rotation = BABYLON.Vector3.FromArray(parsedTransformNode.rotation);
-            }
-            transformNode.scaling = BABYLON.Vector3.FromArray(parsedTransformNode.scaling);
             if (parsedTransformNode.localMatrix) {
                 transformNode.setPivotMatrix(BABYLON.Matrix.FromArray(parsedTransformNode.localMatrix));
             }
@@ -13878,8 +13870,6 @@ var BABYLON;
                 transformNode.setPivotMatrix(BABYLON.Matrix.FromArray(parsedTransformNode.pivotMatrix));
             }
             transformNode.setEnabled(parsedTransformNode.isEnabled);
-            transformNode.infiniteDistance = parsedTransformNode.infiniteDistance;
-            transformNode.billboardMode = parsedTransformNode.billboardMode;
             // Parent
             if (parsedTransformNode.parentId) {
                 transformNode._waitingParentId = parsedTransformNode.parentId;
@@ -13887,10 +13877,10 @@ var BABYLON;
             return transformNode;
         };
         /**
-             * Disposes the TransformNode.
-             * By default, all the children are also disposed unless the parameter `doNotRecurse` is set to `true`.
-             * Returns nothing.
-             */
+         * Disposes the TransformNode.
+         * By default, all the children are also disposed unless the parameter `doNotRecurse` is set to `true`.
+         * Returns nothing.
+         */
         TransformNode.prototype.dispose = function (doNotRecurse) {
             // Animations
             this.getScene().stopAnimation(this);
@@ -23103,11 +23093,11 @@ var BABYLON;
                 var index;
                 if (!doNotCloneChildren) {
                     // Children
-                    for (index = 0; index < scene.meshes.length; index++) {
-                        var mesh = scene.meshes[index];
-                        if (mesh.parent === source) {
-                            // doNotCloneChildren is always going to be False
-                            mesh.clone(name + "." + mesh.name, _this, doNotCloneChildren);
+                    var directDescendants = source.getDescendants(true);
+                    for (var index_1 = 0; index_1 < directDescendants.length; index_1++) {
+                        var child = directDescendants[index_1];
+                        if (child.clone) {
+                            child.clone(name + "." + child.name, _this);
                         }
                     }
                 }
@@ -47394,6 +47384,7 @@ var BABYLON;
             _this._matrices = {};
             _this._matrices3x3 = {};
             _this._matrices2x2 = {};
+            _this._vectors2Arrays = {};
             _this._vectors3Arrays = {};
             _this._cachedWorldViewMatrix = new BABYLON.Matrix();
             _this._shaderPath = shaderPath;
@@ -47494,6 +47485,11 @@ var BABYLON;
             this._matrices2x2[name] = value;
             return this;
         };
+        ShaderMaterial.prototype.setArray2 = function (name, value) {
+            this._checkUniform(name);
+            this._vectors2Arrays[name] = value;
+            return this;
+        };
         ShaderMaterial.prototype.setArray3 = function (name, value) {
             this._checkUniform(name);
             this._vectors3Arrays[name] = value;
@@ -47668,6 +47664,10 @@ var BABYLON;
                 for (name in this._matrices2x2) {
                     this._effect.setMatrix2x2(name, this._matrices2x2[name]);
                 }
+                // Vector2Array   
+                for (name in this._vectors2Arrays) {
+                    this._effect.setArray2(name, this._vectors2Arrays[name]);
+                }
                 // Vector3Array   
                 for (name in this._vectors3Arrays) {
                     this._effect.setArray3(name, this._vectors3Arrays[name]);
@@ -47802,6 +47802,11 @@ var BABYLON;
             for (name in this._matrices2x2) {
                 serializationObject.matrices2x2[name] = this._matrices2x2[name];
             }
+            // Vector2Array
+            serializationObject.vectors2Arrays = {};
+            for (name in this._vectors2Arrays) {
+                serializationObject.vectors2Arrays[name] = this._vectors2Arrays[name];
+            }
             // Vector3Array
             serializationObject.vectors3Arrays = {};
             for (name in this._vectors3Arrays) {
@@ -47878,6 +47883,10 @@ var BABYLON;
             for (name in source.matrices2x2) {
                 material.setMatrix2x2(name, source.matrices2x2[name]);
             }
+            // Vector2Array
+            for (name in source.vectors2Arrays) {
+                material.setArray2(name, source.vectors2Arrays[name]);
+            }
             // Vector3Array
             for (name in source.vectors3Arrays) {
                 material.setArray3(name, source.vectors3Arrays[name]);
@@ -72000,10 +72009,9 @@ var BABYLON;
                 });
             }
         };
-        // Little white circle attached to the camera
-        // That will act as the target to look on the floor where to teleport
+        // Gaze support used to point to teleport or to interact with an object
         VRExperienceHelper.prototype._createGazeTracker = function () {
-            this._gazeTracker = BABYLON.Mesh.CreateTorus("gazeTracker", 0.0050, 0.0020, 25, this._scene, false);
+            this._gazeTracker = BABYLON.Mesh.CreateTorus("gazeTracker", 0.0035, 0.0025, 20, this._scene, false);
             this._gazeTracker.bakeCurrentTransformIntoVertices();
             this._gazeTracker.isPickable = false;
             var targetMat = new BABYLON.StandardMaterial("targetMat", this._scene);

Plik diff jest za duży
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


+ 54 - 54
dist/preview release/inspector/babylon.inspector.js

@@ -1,6 +1,6 @@
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Inspector = (function () {
+    var Inspector = /** @class */ (function () {
         /** The inspector is created with the given engine.
          * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
          * If the parameter 'popup' is true, the inspector is created in another popup.
@@ -606,7 +606,7 @@ var INSPECTOR;
      * Represents a html div element.
      * The div is built when an instance of BasicElement is created.
      */
-    var BasicElement = (function () {
+    var BasicElement = /** @class */ (function () {
         function BasicElement() {
             this._div = INSPECTOR.Helpers.CreateDiv();
         }
@@ -633,7 +633,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Adapter = (function () {
+    var Adapter = /** @class */ (function () {
         function Adapter(obj) {
             this._obj = obj;
         }
@@ -680,7 +680,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var CameraAdapter = (function (_super) {
+    var CameraAdapter = /** @class */ (function (_super) {
         __extends(CameraAdapter, _super);
         function CameraAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -729,7 +729,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PhysicsImpostorAdapter = (function (_super) {
+    var PhysicsImpostorAdapter = /** @class */ (function (_super) {
         __extends(PhysicsImpostorAdapter, _super);
         function PhysicsImpostorAdapter(obj, viewer) {
             var _this = _super.call(this, obj) || this;
@@ -790,7 +790,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var GUIAdapter = (function (_super) {
+    var GUIAdapter = /** @class */ (function (_super) {
         __extends(GUIAdapter, _super);
         function GUIAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -841,7 +841,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var SoundAdapter = (function (_super) {
+    var SoundAdapter = /** @class */ (function (_super) {
         __extends(SoundAdapter, _super);
         function SoundAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -897,7 +897,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var TextureAdapter = (function (_super) {
+    var TextureAdapter = /** @class */ (function (_super) {
         __extends(TextureAdapter, _super);
         function TextureAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -943,7 +943,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var LightAdapter = (function (_super) {
+    var LightAdapter = /** @class */ (function (_super) {
         __extends(LightAdapter, _super);
         function LightAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -994,7 +994,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var MaterialAdapter = (function (_super) {
+    var MaterialAdapter = /** @class */ (function (_super) {
         __extends(MaterialAdapter, _super);
         function MaterialAdapter(obj) {
             return _super.call(this, obj) || this;
@@ -1038,7 +1038,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var MeshAdapter = (function (_super) {
+    var MeshAdapter = /** @class */ (function (_super) {
         __extends(MeshAdapter, _super);
         function MeshAdapter(mesh) {
             return _super.call(this, mesh) || this;
@@ -1145,7 +1145,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var DetailPanel = (function (_super) {
+    var DetailPanel = /** @class */ (function (_super) {
         __extends(DetailPanel, _super);
         function DetailPanel(dr) {
             var _this = _super.call(this) || this;
@@ -1296,7 +1296,7 @@ var INSPECTOR;
     /**
      * A property is a link between a data (string) and an object.
      */
-    var Property = (function () {
+    var Property = /** @class */ (function () {
         function Property(prop, obj) {
             this._property = prop;
             this._obj = obj;
@@ -1344,7 +1344,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PropertyFormatter = (function () {
+    var PropertyFormatter = /** @class */ (function () {
         function PropertyFormatter() {
         }
         /**
@@ -1371,7 +1371,7 @@ var INSPECTOR;
      * If this instance has no link to other instances, its type is ALWAYS a simple one (see above).
      *
      */
-    var PropertyLine = (function () {
+    var PropertyLine = /** @class */ (function () {
         function PropertyLine(prop, parent, level) {
             if (parent === void 0) { parent = null; }
             if (level === void 0) { level = 0; }
@@ -1819,7 +1819,7 @@ var INSPECTOR;
     /**
     * Display a very small div corresponding to the given color
     */
-    var ColorElement = (function (_super) {
+    var ColorElement = /** @class */ (function (_super) {
         __extends(ColorElement, _super);
         // The color as hexadecimal string
         function ColorElement(color) {
@@ -1869,7 +1869,7 @@ var INSPECTOR;
      * Represents a html div element.
      * The div is built when an instance of BasicElement is created.
      */
-    var ColorPickerElement = (function (_super) {
+    var ColorPickerElement = /** @class */ (function (_super) {
         __extends(ColorPickerElement, _super);
         function ColorPickerElement(color, propertyLine) {
             var _this = _super.call(this) || this;
@@ -1939,7 +1939,7 @@ var INSPECTOR;
     * Display a very small div. A new canvas is created, with a new Babylon.js scene, containing only the
     * cube texture in a cube
     */
-    var CubeTextureElement = (function (_super) {
+    var CubeTextureElement = /** @class */ (function (_super) {
         __extends(CubeTextureElement, _super);
         /** The texture given as a parameter should be cube. */
         function CubeTextureElement(tex) {
@@ -2056,7 +2056,7 @@ var INSPECTOR;
     * Display a very small div. A new canvas is created, with a new Babylon.js scene, containing only the
     * cube texture in a cube
     */
-    var HDRCubeTextureElement = (function (_super) {
+    var HDRCubeTextureElement = /** @class */ (function (_super) {
         __extends(HDRCubeTextureElement, _super);
         /** The texture given as a parameter should be cube. */
         function HDRCubeTextureElement(tex) {
@@ -2100,7 +2100,7 @@ var INSPECTOR;
      * A search bar can be used to filter elements in the tree panel.
      * At each keypress on the input, the treepanel will be filtered.
      */
-    var SearchBar = (function (_super) {
+    var SearchBar = /** @class */ (function (_super) {
         __extends(SearchBar, _super);
         function SearchBar(tab) {
             var _this = _super.call(this) || this;
@@ -2146,7 +2146,7 @@ var INSPECTOR;
     /**
     * Display a very small div corresponding to the given texture. On mouse over, display the full image
     */
-    var TextureElement = (function (_super) {
+    var TextureElement = /** @class */ (function (_super) {
         __extends(TextureElement, _super);
         function TextureElement(tex) {
             var _this = _super.call(this) || this;
@@ -2182,7 +2182,7 @@ var INSPECTOR;
     /**
      * Creates a tooltip for the parent of the given html element
      */
-    var Tooltip = (function () {
+    var Tooltip = /** @class */ (function () {
         function Tooltip(elem, tip, attachTo) {
             if (attachTo === void 0) { attachTo = null; }
             var _this = this;
@@ -2204,7 +2204,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Helpers = (function () {
+    var Helpers = /** @class */ (function () {
         function Helpers() {
         }
         /**
@@ -2410,7 +2410,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Scheduler = (function () {
+    var Scheduler = /** @class */ (function () {
         function Scheduler() {
             /** Is this scheduler in pause ? */
             this.pause = false;
@@ -2463,7 +2463,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Tab = (function (_super) {
+    var Tab = /** @class */ (function (_super) {
         __extends(Tab, _super);
         function Tab(tabbar, name) {
             var _this = _super.call(this) || this;
@@ -2545,7 +2545,7 @@ var INSPECTOR;
      * in which properties will be displayed.
      * Both panels are separated by a resize bar
      */
-    var PropertyTab = (function (_super) {
+    var PropertyTab = /** @class */ (function (_super) {
         __extends(PropertyTab, _super);
         function PropertyTab(tabbar, name, insp) {
             var _this = _super.call(this, tabbar, name) || this;
@@ -2689,7 +2689,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var CameraTab = (function (_super) {
+    var CameraTab = /** @class */ (function (_super) {
         __extends(CameraTab, _super);
         function CameraTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Camera', inspector) || this;
@@ -2722,7 +2722,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var GUITab = (function (_super) {
+    var GUITab = /** @class */ (function (_super) {
         __extends(GUITab, _super);
         function GUITab(tabbar, inspector) {
             return _super.call(this, tabbar, 'GUI', inspector) || this;
@@ -2777,7 +2777,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PhysicsTab = (function (_super) {
+    var PhysicsTab = /** @class */ (function (_super) {
         __extends(PhysicsTab, _super);
         function PhysicsTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Physics', inspector) || this;
@@ -2817,7 +2817,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var SoundTab = (function (_super) {
+    var SoundTab = /** @class */ (function (_super) {
         __extends(SoundTab, _super);
         function SoundTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Audio', inspector) || this;
@@ -2854,7 +2854,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var TextureTab = (function (_super) {
+    var TextureTab = /** @class */ (function (_super) {
         __extends(TextureTab, _super);
         function TextureTab(tabbar, inspector) {
             var _this = _super.call(this, tabbar, 'Textures') || this;
@@ -3027,7 +3027,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var LightTab = (function (_super) {
+    var LightTab = /** @class */ (function (_super) {
         __extends(LightTab, _super);
         function LightTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Light', inspector) || this;
@@ -3060,7 +3060,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var MaterialTab = (function (_super) {
+    var MaterialTab = /** @class */ (function (_super) {
         __extends(MaterialTab, _super);
         function MaterialTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Material', inspector) || this;
@@ -3094,7 +3094,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var MeshTab = (function (_super) {
+    var MeshTab = /** @class */ (function (_super) {
         __extends(MeshTab, _super);
         function MeshTab(tabbar, inspector) {
             return _super.call(this, tabbar, 'Mesh', inspector) || this;
@@ -3183,7 +3183,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var SceneTab = (function (_super) {
+    var SceneTab = /** @class */ (function (_super) {
         __extends(SceneTab, _super);
         function SceneTab(tabbar, insp) {
             var _this = _super.call(this, tabbar, 'Scene') || this;
@@ -3374,7 +3374,7 @@ var INSPECTOR;
      * - hook all console.log call and display them in this panel (and in the browser console as well)
      * - display all Babylon logs (called with Tools.Log...)
      */
-    var ConsoleTab = (function (_super) {
+    var ConsoleTab = /** @class */ (function (_super) {
         __extends(ConsoleTab, _super);
         function ConsoleTab(tabbar, insp) {
             var _this = _super.call(this, tabbar, 'Console') || this;
@@ -3508,7 +3508,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var StatsTab = (function (_super) {
+    var StatsTab = /** @class */ (function (_super) {
         __extends(StatsTab, _super);
         function StatsTab(tabbar, insp) {
             var _this = _super.call(this, tabbar, 'Stats') || this;
@@ -3850,7 +3850,7 @@ var INSPECTOR;
      * A tab bar will contains each view the inspector can have : Canvas2D, Meshes...
      * The default active tab is the first one of the list.
      */
-    var TabBar = (function (_super) {
+    var TabBar = /** @class */ (function (_super) {
         __extends(TabBar, _super);
         function TabBar(inspector, initialTab) {
             var _this = _super.call(this) || this;
@@ -4057,7 +4057,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var AbstractTool = (function () {
+    var AbstractTool = /** @class */ (function () {
         function AbstractTool(icon, parent, inspector, tooltip) {
             var _this = this;
             this._inspector = inspector;
@@ -4107,7 +4107,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PauseScheduleTool = (function (_super) {
+    var PauseScheduleTool = /** @class */ (function (_super) {
         __extends(PauseScheduleTool, _super);
         function PauseScheduleTool(parent, inspector) {
             var _this = _super.call(this, 'fa-pause', parent, inspector, 'Pause the automatic update of properties') || this;
@@ -4143,7 +4143,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PickTool = (function (_super) {
+    var PickTool = /** @class */ (function (_super) {
         __extends(PickTool, _super);
         function PickTool(parent, inspector) {
             var _this = _super.call(this, 'fa-mouse-pointer', parent, inspector, 'Select a mesh in the scene') || this;
@@ -4206,7 +4206,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var PopupTool = (function (_super) {
+    var PopupTool = /** @class */ (function (_super) {
         __extends(PopupTool, _super);
         function PopupTool(parent, inspector) {
             return _super.call(this, 'fa-external-link', parent, inspector, 'Open the inspector in a popup') || this;
@@ -4232,7 +4232,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var RefreshTool = (function (_super) {
+    var RefreshTool = /** @class */ (function (_super) {
         __extends(RefreshTool, _super);
         function RefreshTool(parent, inspector) {
             return _super.call(this, 'fa-refresh', parent, inspector, 'Refresh the current tab') || this;
@@ -4258,7 +4258,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var LabelTool = (function (_super) {
+    var LabelTool = /** @class */ (function (_super) {
         __extends(LabelTool, _super);
         function LabelTool(parent, inspector) {
             var _this = _super.call(this, 'fa-tags', parent, inspector, 'Display mesh names on the canvas') || this;
@@ -4378,7 +4378,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var Toolbar = (function (_super) {
+    var Toolbar = /** @class */ (function (_super) {
         __extends(Toolbar, _super);
         function Toolbar(inspector) {
             var _this = _super.call(this) || this;
@@ -4444,7 +4444,7 @@ var INSPECTOR;
     /**
      * Removes the inspector panel
      */
-    var DisposeTool = (function (_super) {
+    var DisposeTool = /** @class */ (function (_super) {
         __extends(DisposeTool, _super);
         function DisposeTool(parent, inspector) {
             return _super.call(this, 'fa-times', parent, inspector, 'Close the inspector panel') || this;
@@ -4470,7 +4470,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var TreeItem = (function (_super) {
+    var TreeItem = /** @class */ (function (_super) {
         __extends(TreeItem, _super);
         function TreeItem(tab, obj) {
             var _this = _super.call(this) || this;
@@ -4634,7 +4634,7 @@ var INSPECTOR;
 
 var INSPECTOR;
 (function (INSPECTOR) {
-    var AbstractTreeTool = (function () {
+    var AbstractTreeTool = /** @class */ (function () {
         function AbstractTreeTool() {
             /** Is the tool enabled ? */
             this._on = false;
@@ -4679,7 +4679,7 @@ var INSPECTOR;
     /**
      * Checkbox to display/hide the primitive
      */
-    var BoundingBox = (function (_super) {
+    var BoundingBox = /** @class */ (function (_super) {
         __extends(BoundingBox, _super);
         function BoundingBox(obj) {
             var _this = _super.call(this) || this;
@@ -4726,7 +4726,7 @@ var INSPECTOR;
     /**
      *
      */
-    var CameraPOV = (function (_super) {
+    var CameraPOV = /** @class */ (function (_super) {
         __extends(CameraPOV, _super);
         function CameraPOV(camera) {
             var _this = _super.call(this) || this;
@@ -4770,7 +4770,7 @@ var INSPECTOR;
     /**
      *
      */
-    var SoundInteractions = (function (_super) {
+    var SoundInteractions = /** @class */ (function (_super) {
         __extends(SoundInteractions, _super);
         function SoundInteractions(playSound) {
             var _this = _super.call(this) || this;
@@ -4817,7 +4817,7 @@ var INSPECTOR;
     /**
      * Checkbox to display/hide the primitive
      */
-    var Checkbox = (function (_super) {
+    var Checkbox = /** @class */ (function (_super) {
         __extends(Checkbox, _super);
         function Checkbox(obj) {
             var _this = _super.call(this) || this;
@@ -4867,7 +4867,7 @@ var __extends = (this && this.__extends) || (function () {
 })();
 var INSPECTOR;
 (function (INSPECTOR) {
-    var DebugArea = (function (_super) {
+    var DebugArea = /** @class */ (function (_super) {
         __extends(DebugArea, _super);
         function DebugArea(obj) {
             var _this = _super.call(this) || this;
@@ -4907,7 +4907,7 @@ var INSPECTOR;
     /**
      * Checkbox to display/hide the primitive
      */
-    var Info = (function (_super) {
+    var Info = /** @class */ (function (_super) {
         __extends(Info, _super);
         function Info(obj) {
             var _this = _super.call(this) || this;

Plik diff jest za duży
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


Plik diff jest za duży
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.min.js


+ 8 - 6
src/Engine/babylon.engine.ts

@@ -563,7 +563,7 @@
         }
 
         public static get Version(): string {
-            return "3.1-beta-5";
+            return "3.1-beta-6";
         }
 
         // Updatable statics so stick with vars here
@@ -2986,7 +2986,7 @@
          * @returns {WebGLTexture} for assignment back into BABYLON.Texture
          */
         public createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<Scene>, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,
-            onLoad: Nullable<() => void> = null, onError: Nullable<() => void> = null,
+            onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null,
             buffer: Nullable<ArrayBuffer | HTMLImageElement> = null, fallBack: Nullable<InternalTexture> = null, format: Nullable<number> = null): InternalTexture {
             var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
             var fromData = url.substr(0, 5) === "data:";
@@ -3028,7 +3028,7 @@
 
             if (!fallBack) this._internalTexturesCache.push(texture);
 
-            var onerror = () => {
+            var onerror = (message?: string, exception?: any) => {
                 if (scene) {
                     scene._removePendingData(texture);
                 }
@@ -3045,7 +3045,7 @@
                 }
 
                 if (onError) {
-                    onError();
+                    onError(message || "Unknown error", exception);
                 }
             };
 
@@ -3091,7 +3091,9 @@
                         if (callback) {
                             callback(data);
                         }
-                    }, undefined, scene ? scene.database : undefined, true, onerror);
+                    }, undefined, scene ? scene.database : undefined, true, (request?: XMLHttpRequest, exception?: any) => {
+                        onerror("Unable to load " + (request ? request.responseURL : url, exception));
+                    });
                 } else {
                     if (callback) {
                         callback(buffer);
@@ -4065,7 +4067,7 @@
                     if (!noMipmap) {
                         gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
                     }
-                    
+
                     this.setCubeMapTextureParams(gl, !noMipmap);
 
                     texture.width = width;

+ 25 - 25
src/Engine/babylon.nullEngine.ts

@@ -6,12 +6,12 @@
 
         public textureSize = 512;
     }
-   
+
     /**
      * The null engine class provides support for headless version of babylon.js.
      * This can be used in server side scenario or for testing purposes
      */
-    export class NullEngine extends Engine {  
+    export class NullEngine extends Engine {
         private _options: NullEngineOptions;
 
         public constructor(options: NullEngineOptions = new NullEngineOptions()) {
@@ -69,14 +69,14 @@
             // Wrappers
             if (typeof URL === "undefined") {
                 (<any>URL) = {
-                    createObjectURL: function() {},
-                    revokeObjectURL: function() {}
+                    createObjectURL: function () { },
+                    revokeObjectURL: function () { }
                 }
             }
 
             if (typeof Blob === "undefined") {
-                (<any>Blob) = function() {};         
-            }   
+                (<any>Blob) = function () { };
+            }
         }
 
         public createVertexBuffer(vertices: FloatArray): WebGLBuffer {
@@ -144,11 +144,11 @@
                 effect.onBind(effect);
             }
             effect.onBindObservable.notifyObservers(effect);
-        }   
-        
+        }
+
         public setState(culling: boolean, zOffset: number = 0, force?: boolean, reverseSide = false): void {
-        }        
-        
+        }
+
         public setIntArray(uniform: WebGLUniformLocation, array: Int32Array): void {
         }
 
@@ -229,7 +229,7 @@
                 this.setDepthWrite(mode === Engine.ALPHA_DISABLE);
             }
             this._alphaMode = mode;
-        }        
+        }
 
         public bindBuffers(vertexBuffers: { [key: string]: VertexBuffer; }, indexBuffer: WebGLBuffer, effect: Effect): void {
         }
@@ -262,9 +262,9 @@
             return {};
         }
 
-        public createTexture(urlArg: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: Nullable<() => void> = null, onError: Nullable<() => void> = null, buffer: Nullable<ArrayBuffer | HTMLImageElement> = null, fallBack?: InternalTexture, format?: number): InternalTexture {
+        public createTexture(urlArg: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null, buffer: Nullable<ArrayBuffer | HTMLImageElement> = null, fallBack?: InternalTexture, format?: number): InternalTexture {
             var texture = new InternalTexture(this, InternalTexture.DATASOURCE_URL);
-            var url = String(urlArg); 
+            var url = String(urlArg);
 
             texture.url = url;
             texture.generateMipMaps = !noMipmap;
@@ -273,12 +273,12 @@
             texture.baseWidth = this._options.textureSize;
             texture.baseHeight = this._options.textureSize;
             texture.width = this._options.textureSize;
-            texture.height = this._options.textureSize;  
-            if (format) {          
-                texture.format = format;    
+            texture.height = this._options.textureSize;
+            if (format) {
+                texture.format = format;
             }
 
-            texture.isReady = true;            
+            texture.isReady = true;
 
             if (onLoad) {
                 onLoad();
@@ -322,12 +322,12 @@
             texture._generateDepthBuffer = fullOptions.generateDepthBuffer;
             texture._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;
             return texture;
-        }     
-        
+        }
+
         public updateTextureSamplingMode(samplingMode: number, texture: InternalTexture): void {
             texture.samplingMode = samplingMode;
-        }      
-        
+        }
+
         public bindFramebuffer(texture: InternalTexture, faceIndex?: number, requiredWidth?: number, requiredHeight?: number, forceFullscreenViewport?: boolean): void {
             if (this._currentRenderTarget) {
                 this.unBindFramebuffer(this._currentRenderTarget);
@@ -336,7 +336,7 @@
             this._currentFramebuffer = texture._MSAAFramebuffer ? texture._MSAAFramebuffer : texture._framebuffer;
             if (this._cachedViewport && !forceFullscreenViewport) {
                 this.setViewport(this._cachedViewport, requiredWidth, requiredHeight);
-            } 
+            }
         }
 
         public unBindFramebuffer(texture: InternalTexture, disableGenerateMipMaps = false, onBeforeUnbind?: () => void): void {
@@ -354,7 +354,7 @@
         public createDynamicVertexBuffer(vertices: FloatArray): WebGLBuffer {
             var vbo = {
                 capacity: 1,
-                references: 1,                
+                references: 1,
                 is32Bits: false
             }
 
@@ -365,7 +365,7 @@
         }
 
         public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, offset?: number, count?: number): void {
-        }        
+        }
 
         public _bindTextureDirectly(target: number, texture: InternalTexture): void {
             if (this._activeTexturesCache[this._activeTextureChannel] !== texture) {
@@ -389,6 +389,6 @@
             }
 
             return false;
-        }        
+        }
     }
 }

+ 13 - 13
src/Mesh/babylon.mesh.ts

@@ -197,12 +197,12 @@
                 var index: number;
                 if (!doNotCloneChildren) {
                     // Children
-                    for (index = 0; index < scene.meshes.length; index++) {
-                        var mesh = scene.meshes[index];
+                    let directDescendants = source.getDescendants(true);
+                    for (let index = 0; index < directDescendants.length; index++) {
+                        var child = directDescendants[index];
 
-                        if (mesh.parent === source) {
-                            // doNotCloneChildren is always going to be False
-                            mesh.clone(name + "." + mesh.name, this, doNotCloneChildren);
+                        if ((<any>child).clone) {
+                            (<any>child).clone(name + "." + child.name, this);
                         }
                     }
                 }
@@ -372,7 +372,7 @@
             } else {
                 let boundingInfo = this.getBoundingInfo();
 
-                bSphere =  boundingInfo.boundingSphere;
+                bSphere = boundingInfo.boundingSphere;
             }
 
             var distanceToCamera = bSphere.centerWorld.subtract(camera.globalPosition).length();
@@ -523,7 +523,7 @@
                 return false;
             }
             return this._geometry.isVertexBufferUpdatable(kind);
-        }        
+        }
         /**
          * Returns a string : the list of existing `kinds` of Vertex Data for this mesh.  
          * Possible `kind` values :
@@ -1195,7 +1195,7 @@
 
                 let visibleInstancesForSubMesh = batch.visibleInstances[subMesh._id];
 
-                if (visibleInstancesForSubMesh) {                
+                if (visibleInstancesForSubMesh) {
                     for (var instanceIndex = 0; instanceIndex < visibleInstancesForSubMesh.length; instanceIndex++) {
                         var instance = visibleInstancesForSubMesh[instanceIndex];
 
@@ -2101,7 +2101,7 @@
 
             // Physics
             //TODO implement correct serialization for physics impostors.
-            
+
             let impostor = this.getPhysicsImpostor();
             if (impostor) {
                 serializationObject.physicsMass = impostor.getParam("mass");
@@ -2181,7 +2181,7 @@
                 for (var index = 0; index < morphTargetManager.numInfluencers; index++) {
                     var morphTarget = morphTargetManager.getActiveTarget(index);
 
-                    const positions = morphTarget.getPositions(); 
+                    const positions = morphTarget.getPositions();
                     if (!positions) {
                         Tools.Error("Invalid morph target. Target must have positions.");
                         return;
@@ -3106,7 +3106,7 @@
 
             var matricesIndicesData = this.getVerticesData(VertexBuffer.MatricesIndicesKind);
             var matricesWeightsData = this.getVerticesData(VertexBuffer.MatricesWeightsKind);
-            
+
             if (!matricesWeightsData || !matricesIndicesData) {
                 return this;
             }
@@ -3117,7 +3117,7 @@
 
             if (!matricesWeightsExtraData || !matricesIndicesExtraData) {
                 return this;
-            }            
+            }
 
             var skeletonMatrices = skeleton.getTransformMatrices(this);
 
@@ -3171,7 +3171,7 @@
         public static MinMax(meshes: AbstractMesh[]): { min: Vector3; max: Vector3 } {
             var minVector: Nullable<Vector3> = null;
             var maxVector: Nullable<Vector3> = null;
-            
+
             meshes.forEach(function (mesh, index, array) {
                 let boundingInfo = mesh.getBoundingInfo();
 

+ 39 - 50
src/Mesh/babylon.transformNode.ts

@@ -443,7 +443,6 @@ module BABYLON {
          */
         public setParent(node: Nullable<TransformNode>): TransformNode {
 
-            this.computeWorldMatrix(true);
             if (node == null) {
                 var rotation = Tmp.Quaternion[0];
                 var position = Tmp.Vector3[0];
@@ -452,6 +451,7 @@ module BABYLON {
                 if (this.parent && (<TransformNode>this.parent).computeWorldMatrix) {
                     (<TransformNode>this.parent).computeWorldMatrix(true);
                 }
+                this.computeWorldMatrix(true);
                 this.getWorldMatrix().decompose(scale, rotation, position);
 
                 if (this.rotationQuaternion) {
@@ -460,6 +460,10 @@ module BABYLON {
                     rotation.toEulerAnglesToRef(this.rotation);
                 }
 
+                this.scaling.x = scale.x;
+                this.scaling.y = scale.y;
+                this.scaling.z = scale.z;
+
                 this.position.x = position.x;
                 this.position.y = position.y;
                 this.position.z = position.z;
@@ -470,7 +474,9 @@ module BABYLON {
                 var diffMatrix = Tmp.Matrix[0];
                 var invParentMatrix = Tmp.Matrix[1];
 
+                this.computeWorldMatrix(true);
                 node.computeWorldMatrix(true);
+
                 node.getWorldMatrix().invertToRef(invParentMatrix);
                 this.getWorldMatrix().multiplyToRef(invParentMatrix, diffMatrix);
                 diffMatrix.decompose(scale, rotation, position);
@@ -835,7 +841,14 @@ module BABYLON {
             return this;
         }
 
-        public clone(name: string, newParent: Node): Nullable<TransformNode> {
+        /**
+         * Clone the current transform node
+         * Returns the new transform node
+         * @param name Name of the new clone
+         * @param newParent New parent for the clone
+         * @param doNotCloneChildren Do not clone children hierarchy
+         */
+        public clone(name: string, newParent: Node, doNotCloneChildren?: boolean): Nullable<TransformNode> {
             var result = SerializationHelper.Clone(() => new TransformNode(name, this.getScene()), this);
 
             result.name = name;
@@ -845,48 +858,43 @@ module BABYLON {
                 result.parent = newParent;
             }
 
-            return result;
-        }
+            if (!doNotCloneChildren) {
+                // Children
+                let directDescendants = this.getDescendants(true);
+                for (let index = 0; index < directDescendants.length; index++) {
+                    var child = directDescendants[index];
 
-        public serialize(serializationObject: any = null): any {
-            if (!serializationObject) {
-                serializationObject = {};
+                    if ((<any>child).clone) {
+                        (<any>child).clone(name + "." + child.name, result);
+                    }
+                }
             }
 
-            serializationObject.name = this.name;
-            serializationObject.id = this.id;
+            return result;
+        }
+
+        public serialize(currentSerializationObject?: any): any {
+            let serializationObject = SerializationHelper.Serialize(this, currentSerializationObject);
             serializationObject.type = this.getClassName();
 
-            if (Tags && Tags.HasTags(this)) {
-                serializationObject.tags = Tags.GetTags(this);
+            // Parent
+            if (this.parent) {
+                serializationObject.parentId = this.parent.id;
             }
 
-            serializationObject.position = this.position.asArray();
-
-            if (this.rotationQuaternion) {
-                serializationObject.rotationQuaternion = this.rotationQuaternion.asArray();
-            } else if (this.rotation) {
-                serializationObject.rotation = this.rotation.asArray();
+            if (Tags && Tags.HasTags(this)) {
+                serializationObject.tags = Tags.GetTags(this);
             }
 
-            serializationObject.scaling = this.scaling.asArray();
             serializationObject.localMatrix = this.getPivotMatrix().asArray();
 
             serializationObject.isEnabled = this.isEnabled();
-            serializationObject.infiniteDistance = this.infiniteDistance;
-
-            serializationObject.billboardMode = this.billboardMode;
 
             // Parent
             if (this.parent) {
                 serializationObject.parentId = this.parent.id;
             }
 
-            // Metadata
-            if (this.metadata) {
-                serializationObject.metadata = this.metadata;
-            }
-
             return serializationObject;
         }
 
@@ -897,28 +905,12 @@ module BABYLON {
          * The parameter `rootUrl` is a string, it's the root URL to prefix the `delayLoadingFile` property with
          */
         public static Parse(parsedTransformNode: any, scene: Scene, rootUrl: string): TransformNode {
-            var transformNode = new TransformNode(parsedTransformNode.name, scene);
-
-            transformNode.id = parsedTransformNode.id;
+            var transformNode = SerializationHelper.Parse(() => new TransformNode(parsedTransformNode.name, scene), parsedTransformNode, scene, rootUrl);
 
             if (Tags) {
                 Tags.AddTagsTo(transformNode, parsedTransformNode.tags);
             }
 
-            transformNode.position = Vector3.FromArray(parsedTransformNode.position);
-
-            if (parsedTransformNode.metadata !== undefined) {
-                transformNode.metadata = parsedTransformNode.metadata;
-            }
-
-            if (parsedTransformNode.rotationQuaternion) {
-                transformNode.rotationQuaternion = Quaternion.FromArray(parsedTransformNode.rotationQuaternion);
-            } else if (parsedTransformNode.rotation) {
-                transformNode.rotation = Vector3.FromArray(parsedTransformNode.rotation);
-            }
-
-            transformNode.scaling = Vector3.FromArray(parsedTransformNode.scaling);
-
             if (parsedTransformNode.localMatrix) {
                 transformNode.setPivotMatrix(Matrix.FromArray(parsedTransformNode.localMatrix));
             } else if (parsedTransformNode.pivotMatrix) {
@@ -926,9 +918,6 @@ module BABYLON {
             }
 
             transformNode.setEnabled(parsedTransformNode.isEnabled);
-            transformNode.infiniteDistance = parsedTransformNode.infiniteDistance;
-
-            transformNode.billboardMode = parsedTransformNode.billboardMode;
 
             // Parent
             if (parsedTransformNode.parentId) {
@@ -939,10 +928,10 @@ module BABYLON {
         }
 
         /**
-             * Disposes the TransformNode.  
-             * By default, all the children are also disposed unless the parameter `doNotRecurse` is set to `true`.  
-             * Returns nothing.  
-             */
+         * Disposes the TransformNode.  
+         * By default, all the children are also disposed unless the parameter `doNotRecurse` is set to `true`.  
+         * Returns nothing.  
+         */
         public dispose(doNotRecurse?: boolean): void {
             // Animations
             this.getScene().stopAnimation(this);