Преглед на файлове

Adding physics helper + texture updated (Inspector)

David Catuhe преди 6 години
родител
ревизия
f0449d6ea5

Файловите разлики са ограничени, защото са твърде много
+ 3699 - 3695
Playground/babylon.d.txt


Файловите разлики са ограничени, защото са твърде много
+ 2508 - 2496
dist/preview release/babylon.d.ts


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/babylon.js


+ 95 - 52
dist/preview release/babylon.max.js

@@ -20293,7 +20293,7 @@ var BABYLON;
             if (this._cache.pivotMatrixUpdated) {
                 return false;
             }
-            if (this.infiniteDistance) {
+            if (this.infiniteDistance !== this._cache.infiniteDistance) {
                 return false;
             }
             if (!this._cache.position.equals(this._position)) {
@@ -20321,6 +20321,7 @@ var BABYLON;
             this._cache.rotation = BABYLON.Vector3.Zero();
             this._cache.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 0);
             this._cache.billboardMode = -1;
+            this._cache.infiniteDistance = false;
         };
         /**
         * Flag the transform node as dirty (Forcing it to update everything)
@@ -20854,6 +20855,7 @@ var BABYLON;
             this._cache.scaling.copyFrom(this.scaling);
             this._cache.pivotMatrixUpdated = false;
             this._cache.billboardMode = this.billboardMode;
+            this._cache.infiniteDistance = this.infiniteDistance;
             this._currentRenderId = this.getScene().getRenderId();
             this._childRenderId = this.getScene().getRenderId();
             this._isDirty = false;
@@ -32482,15 +32484,19 @@ var BABYLON;
          * Update the url (and optional buffer) of this texture if url was null during construction.
          * @param url the url of the texture
          * @param buffer the buffer of the texture (defaults to null)
+         * @param onLoad callback called when the texture is loaded  (defaults to null)
          */
-        Texture.prototype.updateURL = function (url, buffer) {
+        Texture.prototype.updateURL = function (url, buffer, onLoad) {
             if (buffer === void 0) { buffer = null; }
             if (this.url) {
-                throw new Error("URL is already set");
+                this.releaseInternalTexture();
             }
             this.url = url;
             this._buffer = buffer;
             this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+            if (onLoad) {
+                this._delayedOnLoad = onLoad;
+            }
             this.delayLoad();
         };
         /**
@@ -66512,27 +66518,34 @@ var BABYLON;
              */
             function AxesViewer(scene, scaleLines) {
                 if (scaleLines === void 0) { scaleLines = 1; }
-                this._xline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
-                this._yline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
-                this._zline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
                 /**
                  * Gets or sets a number used to scale line length
                  */
                 this.scaleLines = 1;
                 this.scaleLines = scaleLines;
-                this._xmesh = BABYLON.Mesh.CreateLines("xline", this._xline, scene, true);
-                this._ymesh = BABYLON.Mesh.CreateLines("yline", this._yline, scene, true);
-                this._zmesh = BABYLON.Mesh.CreateLines("zline", this._zline, scene, true);
-                this._xmesh.renderingGroupId = 2;
-                this._ymesh.renderingGroupId = 2;
-                this._zmesh.renderingGroupId = 2;
-                this._xmesh.material.checkReadyOnlyOnce = true;
-                this._xmesh.color = new BABYLON.Color3(1, 0, 0);
-                this._ymesh.material.checkReadyOnlyOnce = true;
-                this._ymesh.color = new BABYLON.Color3(0, 1, 0);
-                this._zmesh.material.checkReadyOnlyOnce = true;
-                this._zmesh.color = new BABYLON.Color3(0, 0, 1);
+                var greenColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                greenColoredMaterial.disableLighting = true;
+                greenColoredMaterial.emissiveColor = BABYLON.Color3.Green().scale(0.5);
+                var redColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                redColoredMaterial.disableLighting = true;
+                redColoredMaterial.emissiveColor = BABYLON.Color3.Red().scale(0.5);
+                var blueColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                blueColoredMaterial.disableLighting = true;
+                blueColoredMaterial.emissiveColor = BABYLON.Color3.Blue().scale(0.5);
+                this._xmesh = BABYLON.AxisDragGizmo._CreateArrow(scene, redColoredMaterial);
+                this._ymesh = BABYLON.AxisDragGizmo._CreateArrow(scene, greenColoredMaterial);
+                this._zmesh = BABYLON.AxisDragGizmo._CreateArrow(scene, blueColoredMaterial);
+                this._xmesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._xmesh.scaling.scaleInPlace(4);
+                this._ymesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._ymesh.scaling.scaleInPlace(4);
+                this._zmesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._zmesh.scaling.scaleInPlace(4);
+                AxesViewer._recursiveChangeRenderingGroupId(this._xmesh, 2);
+                AxesViewer._recursiveChangeRenderingGroupId(this._ymesh, 2);
+                AxesViewer._recursiveChangeRenderingGroupId(this._zmesh, 2);
                 this.scene = scene;
+                this.update(new BABYLON.Vector3(), BABYLON.Vector3.Right(), BABYLON.Vector3.Up(), BABYLON.Vector3.Forward());
             }
             Object.defineProperty(AxesViewer.prototype, "xAxisMesh", {
                 /** Gets the mesh used to render x-axis */
@@ -66558,6 +66571,12 @@ var BABYLON;
                 enumerable: true,
                 configurable: true
             });
+            AxesViewer._recursiveChangeRenderingGroupId = function (mesh, id) {
+                mesh.renderingGroupId = id;
+                mesh.getChildMeshes().forEach(function (m) {
+                    AxesViewer._recursiveChangeRenderingGroupId(m, id);
+                });
+            };
             /**
              * Force the viewer to update
              * @param position defines the position of the viewer
@@ -66566,31 +66585,24 @@ var BABYLON;
              * @param zaxis defines the z axis of the viewer
              */
             AxesViewer.prototype.update = function (position, xaxis, yaxis, zaxis) {
-                var scaleLines = this.scaleLines;
                 if (this._xmesh) {
                     this._xmesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), xaxis);
+                    this._xmesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), xaxis));
+                    this._xmesh.rotationQuaternion.normalize();
                 }
                 if (this._ymesh) {
                     this._ymesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), yaxis);
+                    this._ymesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), yaxis));
+                    this._ymesh.rotationQuaternion.normalize();
                 }
                 if (this._zmesh) {
                     this._zmesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), zaxis);
+                    this._zmesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), zaxis));
+                    this._zmesh.rotationQuaternion.normalize();
                 }
-                var point2 = this._xline[1];
-                point2.x = xaxis.x * scaleLines;
-                point2.y = xaxis.y * scaleLines;
-                point2.z = xaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._xline, null, false, this._xmesh);
-                point2 = this._yline[1];
-                point2.x = yaxis.x * scaleLines;
-                point2.y = yaxis.y * scaleLines;
-                point2.z = yaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._yline, null, false, this._ymesh);
-                point2 = this._zline[1];
-                point2.x = zaxis.x * scaleLines;
-                point2.y = zaxis.y * scaleLines;
-                point2.z = zaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._zline, null, false, this._zmesh);
             };
             /** Releases resources */
             AxesViewer.prototype.dispose = function () {
@@ -73770,6 +73782,22 @@ var BABYLON;
             return new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension, createPolynomials);
         };
         /**
+         * Update the url (and optional buffer) of this texture if url was null during construction.
+         * @param url the url of the texture
+         * @param onLoad callback called when the texture is loaded  (defaults to null)
+         */
+        CubeTexture.prototype.updateURL = function (url, onLoad) {
+            if (this.url) {
+                this.releaseInternalTexture();
+            }
+            this.url = url;
+            this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+            if (onLoad) {
+                this._delayedOnLoad = onLoad;
+            }
+            this.delayLoad();
+        };
+        /**
          * Delays loading of the cube texture
          */
         CubeTexture.prototype.delayLoad = function () {
@@ -73784,10 +73812,10 @@ var BABYLON;
             this._texture = this._getFromCache(this.url, this._noMipmap);
             if (!this._texture) {
                 if (this._prefiltered) {
-                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, undefined, undefined, this._format, undefined, this._createPolynomials);
+                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, this._delayedOnLoad, undefined, this._format, undefined, this._createPolynomials);
                 }
                 else {
-                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, undefined, undefined, this._format);
+                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, this._delayedOnLoad, undefined, this._format);
                 }
             }
         };
@@ -103386,20 +103414,7 @@ var BABYLON;
             hoverMaterial.disableLighting = true;
             hoverMaterial.emissiveColor = color.add(new BABYLON.Color3(0.3, 0.3, 0.3));
             // Build mesh on root node
-            var arrow = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
-            var arrowMesh = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameterTop: 0, height: 1.5, diameterBottom: 0.75, tessellation: 96 }, gizmoLayer.utilityLayerScene);
-            var arrowTail = BABYLON.MeshBuilder.CreateLines("yPosMesh", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 1.1, 0)] }, gizmoLayer.utilityLayerScene);
-            arrowTail.color = coloredMaterial.emissiveColor;
-            arrow.addChild(arrowMesh);
-            arrow.addChild(arrowTail);
-            // Position arrow pointing in its drag axis
-            arrowMesh.scaling.scaleInPlace(0.05);
-            arrowMesh.material = coloredMaterial;
-            arrowMesh.rotation.x = Math.PI / 2;
-            arrowMesh.position.z += 0.3;
-            arrowTail.scaling.scaleInPlace(0.26);
-            arrowTail.rotation.x = Math.PI / 2;
-            arrowTail.material = coloredMaterial;
+            var arrow = AxisDragGizmo._CreateArrow(gizmoLayer.utilityLayerScene, coloredMaterial);
             arrow.lookAt(_this._rootMesh.position.subtract(dragAxis));
             arrow.scaling.scaleInPlace(1 / 3);
             _this._rootMesh.addChild(arrow);
@@ -103456,6 +103471,24 @@ var BABYLON;
             });
             return _this;
         }
+        /** @hidden */
+        AxisDragGizmo._CreateArrow = function (scene, material) {
+            var arrow = new BABYLON.AbstractMesh("", scene);
+            var arrowMesh = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameterTop: 0, height: 1.5, diameterBottom: 0.75, tessellation: 96 }, scene);
+            var arrowTail = BABYLON.MeshBuilder.CreateLines("yPosMesh", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 1.1, 0)] }, scene);
+            arrowTail.color = material.emissiveColor;
+            arrow.addChild(arrowMesh);
+            arrow.addChild(arrowTail);
+            // Position arrow pointing in its drag axis
+            arrowMesh.scaling.scaleInPlace(0.05);
+            arrowMesh.material = material;
+            arrowMesh.rotation.x = Math.PI / 2;
+            arrowMesh.position.z += 0.3;
+            arrowTail.scaling.scaleInPlace(0.26);
+            arrowTail.rotation.x = Math.PI / 2;
+            arrowTail.material = material;
+            return arrow;
+        };
         AxisDragGizmo.prototype._attachedMeshChanged = function (value) {
             if (this.dragBehavior) {
                 this.dragBehavior.enabled = value ? true : false;
@@ -104703,6 +104736,10 @@ var BABYLON;
         function GizmoManager(scene) {
             var _this = this;
             this.scene = scene;
+            /** When true, the gizmo will be detached from the current object when a pointer down occurs with an empty picked mesh */
+            this.clearGizmoOnEmptyPointerEvent = false;
+            /** Fires an event when the manager is attached to a mesh */
+            this.onAttachedToMeshObservable = new BABYLON.Observable();
             this._gizmosEnabled = { positionGizmo: false, rotationGizmo: false, scaleGizmo: false, boundingBoxGizmo: false };
             this._pointerObserver = null;
             this._attachedMesh = null;
@@ -104756,11 +104793,15 @@ var BABYLON;
                             }
                         }
                         else {
-                            _this.attachToMesh(null);
+                            if (_this.clearGizmoOnEmptyPointerEvent) {
+                                _this.attachToMesh(null);
+                            }
                         }
                     }
                     else {
-                        _this.attachToMesh(null);
+                        if (_this.clearGizmoOnEmptyPointerEvent) {
+                            _this.attachToMesh(null);
+                        }
                     }
                 }
             });
@@ -104783,6 +104824,7 @@ var BABYLON;
             if (this.boundingBoxGizmoEnabled && this._attachedMesh) {
                 this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
             }
+            this.onAttachedToMeshObservable.notifyObservers(mesh);
         };
         Object.defineProperty(GizmoManager.prototype, "positionGizmoEnabled", {
             get: function () {
@@ -104886,6 +104928,7 @@ var BABYLON;
             this._defaultKeepDepthUtilityLayer.dispose();
             this._defaultUtilityLayer.dispose();
             this.boundingBoxDragBehavior.detach();
+            this.onAttachedToMeshObservable.clear();
         };
         return GizmoManager;
     }());

+ 95 - 52
dist/preview release/babylon.no-module.max.js

@@ -20260,7 +20260,7 @@ var BABYLON;
             if (this._cache.pivotMatrixUpdated) {
                 return false;
             }
-            if (this.infiniteDistance) {
+            if (this.infiniteDistance !== this._cache.infiniteDistance) {
                 return false;
             }
             if (!this._cache.position.equals(this._position)) {
@@ -20288,6 +20288,7 @@ var BABYLON;
             this._cache.rotation = BABYLON.Vector3.Zero();
             this._cache.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 0);
             this._cache.billboardMode = -1;
+            this._cache.infiniteDistance = false;
         };
         /**
         * Flag the transform node as dirty (Forcing it to update everything)
@@ -20821,6 +20822,7 @@ var BABYLON;
             this._cache.scaling.copyFrom(this.scaling);
             this._cache.pivotMatrixUpdated = false;
             this._cache.billboardMode = this.billboardMode;
+            this._cache.infiniteDistance = this.infiniteDistance;
             this._currentRenderId = this.getScene().getRenderId();
             this._childRenderId = this.getScene().getRenderId();
             this._isDirty = false;
@@ -32449,15 +32451,19 @@ var BABYLON;
          * Update the url (and optional buffer) of this texture if url was null during construction.
          * @param url the url of the texture
          * @param buffer the buffer of the texture (defaults to null)
+         * @param onLoad callback called when the texture is loaded  (defaults to null)
          */
-        Texture.prototype.updateURL = function (url, buffer) {
+        Texture.prototype.updateURL = function (url, buffer, onLoad) {
             if (buffer === void 0) { buffer = null; }
             if (this.url) {
-                throw new Error("URL is already set");
+                this.releaseInternalTexture();
             }
             this.url = url;
             this._buffer = buffer;
             this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+            if (onLoad) {
+                this._delayedOnLoad = onLoad;
+            }
             this.delayLoad();
         };
         /**
@@ -66479,27 +66485,34 @@ var BABYLON;
              */
             function AxesViewer(scene, scaleLines) {
                 if (scaleLines === void 0) { scaleLines = 1; }
-                this._xline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
-                this._yline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
-                this._zline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
                 /**
                  * Gets or sets a number used to scale line length
                  */
                 this.scaleLines = 1;
                 this.scaleLines = scaleLines;
-                this._xmesh = BABYLON.Mesh.CreateLines("xline", this._xline, scene, true);
-                this._ymesh = BABYLON.Mesh.CreateLines("yline", this._yline, scene, true);
-                this._zmesh = BABYLON.Mesh.CreateLines("zline", this._zline, scene, true);
-                this._xmesh.renderingGroupId = 2;
-                this._ymesh.renderingGroupId = 2;
-                this._zmesh.renderingGroupId = 2;
-                this._xmesh.material.checkReadyOnlyOnce = true;
-                this._xmesh.color = new BABYLON.Color3(1, 0, 0);
-                this._ymesh.material.checkReadyOnlyOnce = true;
-                this._ymesh.color = new BABYLON.Color3(0, 1, 0);
-                this._zmesh.material.checkReadyOnlyOnce = true;
-                this._zmesh.color = new BABYLON.Color3(0, 0, 1);
+                var greenColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                greenColoredMaterial.disableLighting = true;
+                greenColoredMaterial.emissiveColor = BABYLON.Color3.Green().scale(0.5);
+                var redColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                redColoredMaterial.disableLighting = true;
+                redColoredMaterial.emissiveColor = BABYLON.Color3.Red().scale(0.5);
+                var blueColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                blueColoredMaterial.disableLighting = true;
+                blueColoredMaterial.emissiveColor = BABYLON.Color3.Blue().scale(0.5);
+                this._xmesh = BABYLON.AxisDragGizmo._CreateArrow(scene, redColoredMaterial);
+                this._ymesh = BABYLON.AxisDragGizmo._CreateArrow(scene, greenColoredMaterial);
+                this._zmesh = BABYLON.AxisDragGizmo._CreateArrow(scene, blueColoredMaterial);
+                this._xmesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._xmesh.scaling.scaleInPlace(4);
+                this._ymesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._ymesh.scaling.scaleInPlace(4);
+                this._zmesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._zmesh.scaling.scaleInPlace(4);
+                AxesViewer._recursiveChangeRenderingGroupId(this._xmesh, 2);
+                AxesViewer._recursiveChangeRenderingGroupId(this._ymesh, 2);
+                AxesViewer._recursiveChangeRenderingGroupId(this._zmesh, 2);
                 this.scene = scene;
+                this.update(new BABYLON.Vector3(), BABYLON.Vector3.Right(), BABYLON.Vector3.Up(), BABYLON.Vector3.Forward());
             }
             Object.defineProperty(AxesViewer.prototype, "xAxisMesh", {
                 /** Gets the mesh used to render x-axis */
@@ -66525,6 +66538,12 @@ var BABYLON;
                 enumerable: true,
                 configurable: true
             });
+            AxesViewer._recursiveChangeRenderingGroupId = function (mesh, id) {
+                mesh.renderingGroupId = id;
+                mesh.getChildMeshes().forEach(function (m) {
+                    AxesViewer._recursiveChangeRenderingGroupId(m, id);
+                });
+            };
             /**
              * Force the viewer to update
              * @param position defines the position of the viewer
@@ -66533,31 +66552,24 @@ var BABYLON;
              * @param zaxis defines the z axis of the viewer
              */
             AxesViewer.prototype.update = function (position, xaxis, yaxis, zaxis) {
-                var scaleLines = this.scaleLines;
                 if (this._xmesh) {
                     this._xmesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), xaxis);
+                    this._xmesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), xaxis));
+                    this._xmesh.rotationQuaternion.normalize();
                 }
                 if (this._ymesh) {
                     this._ymesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), yaxis);
+                    this._ymesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), yaxis));
+                    this._ymesh.rotationQuaternion.normalize();
                 }
                 if (this._zmesh) {
                     this._zmesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), zaxis);
+                    this._zmesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), zaxis));
+                    this._zmesh.rotationQuaternion.normalize();
                 }
-                var point2 = this._xline[1];
-                point2.x = xaxis.x * scaleLines;
-                point2.y = xaxis.y * scaleLines;
-                point2.z = xaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._xline, null, false, this._xmesh);
-                point2 = this._yline[1];
-                point2.x = yaxis.x * scaleLines;
-                point2.y = yaxis.y * scaleLines;
-                point2.z = yaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._yline, null, false, this._ymesh);
-                point2 = this._zline[1];
-                point2.x = zaxis.x * scaleLines;
-                point2.y = zaxis.y * scaleLines;
-                point2.z = zaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._zline, null, false, this._zmesh);
             };
             /** Releases resources */
             AxesViewer.prototype.dispose = function () {
@@ -73737,6 +73749,22 @@ var BABYLON;
             return new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension, createPolynomials);
         };
         /**
+         * Update the url (and optional buffer) of this texture if url was null during construction.
+         * @param url the url of the texture
+         * @param onLoad callback called when the texture is loaded  (defaults to null)
+         */
+        CubeTexture.prototype.updateURL = function (url, onLoad) {
+            if (this.url) {
+                this.releaseInternalTexture();
+            }
+            this.url = url;
+            this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+            if (onLoad) {
+                this._delayedOnLoad = onLoad;
+            }
+            this.delayLoad();
+        };
+        /**
          * Delays loading of the cube texture
          */
         CubeTexture.prototype.delayLoad = function () {
@@ -73751,10 +73779,10 @@ var BABYLON;
             this._texture = this._getFromCache(this.url, this._noMipmap);
             if (!this._texture) {
                 if (this._prefiltered) {
-                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, undefined, undefined, this._format, undefined, this._createPolynomials);
+                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, this._delayedOnLoad, undefined, this._format, undefined, this._createPolynomials);
                 }
                 else {
-                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, undefined, undefined, this._format);
+                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, this._delayedOnLoad, undefined, this._format);
                 }
             }
         };
@@ -103353,20 +103381,7 @@ var BABYLON;
             hoverMaterial.disableLighting = true;
             hoverMaterial.emissiveColor = color.add(new BABYLON.Color3(0.3, 0.3, 0.3));
             // Build mesh on root node
-            var arrow = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
-            var arrowMesh = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameterTop: 0, height: 1.5, diameterBottom: 0.75, tessellation: 96 }, gizmoLayer.utilityLayerScene);
-            var arrowTail = BABYLON.MeshBuilder.CreateLines("yPosMesh", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 1.1, 0)] }, gizmoLayer.utilityLayerScene);
-            arrowTail.color = coloredMaterial.emissiveColor;
-            arrow.addChild(arrowMesh);
-            arrow.addChild(arrowTail);
-            // Position arrow pointing in its drag axis
-            arrowMesh.scaling.scaleInPlace(0.05);
-            arrowMesh.material = coloredMaterial;
-            arrowMesh.rotation.x = Math.PI / 2;
-            arrowMesh.position.z += 0.3;
-            arrowTail.scaling.scaleInPlace(0.26);
-            arrowTail.rotation.x = Math.PI / 2;
-            arrowTail.material = coloredMaterial;
+            var arrow = AxisDragGizmo._CreateArrow(gizmoLayer.utilityLayerScene, coloredMaterial);
             arrow.lookAt(_this._rootMesh.position.subtract(dragAxis));
             arrow.scaling.scaleInPlace(1 / 3);
             _this._rootMesh.addChild(arrow);
@@ -103423,6 +103438,24 @@ var BABYLON;
             });
             return _this;
         }
+        /** @hidden */
+        AxisDragGizmo._CreateArrow = function (scene, material) {
+            var arrow = new BABYLON.AbstractMesh("", scene);
+            var arrowMesh = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameterTop: 0, height: 1.5, diameterBottom: 0.75, tessellation: 96 }, scene);
+            var arrowTail = BABYLON.MeshBuilder.CreateLines("yPosMesh", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 1.1, 0)] }, scene);
+            arrowTail.color = material.emissiveColor;
+            arrow.addChild(arrowMesh);
+            arrow.addChild(arrowTail);
+            // Position arrow pointing in its drag axis
+            arrowMesh.scaling.scaleInPlace(0.05);
+            arrowMesh.material = material;
+            arrowMesh.rotation.x = Math.PI / 2;
+            arrowMesh.position.z += 0.3;
+            arrowTail.scaling.scaleInPlace(0.26);
+            arrowTail.rotation.x = Math.PI / 2;
+            arrowTail.material = material;
+            return arrow;
+        };
         AxisDragGizmo.prototype._attachedMeshChanged = function (value) {
             if (this.dragBehavior) {
                 this.dragBehavior.enabled = value ? true : false;
@@ -104670,6 +104703,10 @@ var BABYLON;
         function GizmoManager(scene) {
             var _this = this;
             this.scene = scene;
+            /** When true, the gizmo will be detached from the current object when a pointer down occurs with an empty picked mesh */
+            this.clearGizmoOnEmptyPointerEvent = false;
+            /** Fires an event when the manager is attached to a mesh */
+            this.onAttachedToMeshObservable = new BABYLON.Observable();
             this._gizmosEnabled = { positionGizmo: false, rotationGizmo: false, scaleGizmo: false, boundingBoxGizmo: false };
             this._pointerObserver = null;
             this._attachedMesh = null;
@@ -104723,11 +104760,15 @@ var BABYLON;
                             }
                         }
                         else {
-                            _this.attachToMesh(null);
+                            if (_this.clearGizmoOnEmptyPointerEvent) {
+                                _this.attachToMesh(null);
+                            }
                         }
                     }
                     else {
-                        _this.attachToMesh(null);
+                        if (_this.clearGizmoOnEmptyPointerEvent) {
+                            _this.attachToMesh(null);
+                        }
                     }
                 }
             });
@@ -104750,6 +104791,7 @@ var BABYLON;
             if (this.boundingBoxGizmoEnabled && this._attachedMesh) {
                 this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
             }
+            this.onAttachedToMeshObservable.notifyObservers(mesh);
         };
         Object.defineProperty(GizmoManager.prototype, "positionGizmoEnabled", {
             get: function () {
@@ -104853,6 +104895,7 @@ var BABYLON;
             this._defaultKeepDepthUtilityLayer.dispose();
             this._defaultUtilityLayer.dispose();
             this.boundingBoxDragBehavior.detach();
+            this.onAttachedToMeshObservable.clear();
         };
         return GizmoManager;
     }());

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/babylon.worker.js


+ 95 - 52
dist/preview release/es6.js

@@ -20260,7 +20260,7 @@ var BABYLON;
             if (this._cache.pivotMatrixUpdated) {
                 return false;
             }
-            if (this.infiniteDistance) {
+            if (this.infiniteDistance !== this._cache.infiniteDistance) {
                 return false;
             }
             if (!this._cache.position.equals(this._position)) {
@@ -20288,6 +20288,7 @@ var BABYLON;
             this._cache.rotation = BABYLON.Vector3.Zero();
             this._cache.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 0);
             this._cache.billboardMode = -1;
+            this._cache.infiniteDistance = false;
         };
         /**
         * Flag the transform node as dirty (Forcing it to update everything)
@@ -20821,6 +20822,7 @@ var BABYLON;
             this._cache.scaling.copyFrom(this.scaling);
             this._cache.pivotMatrixUpdated = false;
             this._cache.billboardMode = this.billboardMode;
+            this._cache.infiniteDistance = this.infiniteDistance;
             this._currentRenderId = this.getScene().getRenderId();
             this._childRenderId = this.getScene().getRenderId();
             this._isDirty = false;
@@ -32449,15 +32451,19 @@ var BABYLON;
          * Update the url (and optional buffer) of this texture if url was null during construction.
          * @param url the url of the texture
          * @param buffer the buffer of the texture (defaults to null)
+         * @param onLoad callback called when the texture is loaded  (defaults to null)
          */
-        Texture.prototype.updateURL = function (url, buffer) {
+        Texture.prototype.updateURL = function (url, buffer, onLoad) {
             if (buffer === void 0) { buffer = null; }
             if (this.url) {
-                throw new Error("URL is already set");
+                this.releaseInternalTexture();
             }
             this.url = url;
             this._buffer = buffer;
             this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+            if (onLoad) {
+                this._delayedOnLoad = onLoad;
+            }
             this.delayLoad();
         };
         /**
@@ -66479,27 +66485,34 @@ var BABYLON;
              */
             function AxesViewer(scene, scaleLines) {
                 if (scaleLines === void 0) { scaleLines = 1; }
-                this._xline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
-                this._yline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
-                this._zline = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
                 /**
                  * Gets or sets a number used to scale line length
                  */
                 this.scaleLines = 1;
                 this.scaleLines = scaleLines;
-                this._xmesh = BABYLON.Mesh.CreateLines("xline", this._xline, scene, true);
-                this._ymesh = BABYLON.Mesh.CreateLines("yline", this._yline, scene, true);
-                this._zmesh = BABYLON.Mesh.CreateLines("zline", this._zline, scene, true);
-                this._xmesh.renderingGroupId = 2;
-                this._ymesh.renderingGroupId = 2;
-                this._zmesh.renderingGroupId = 2;
-                this._xmesh.material.checkReadyOnlyOnce = true;
-                this._xmesh.color = new BABYLON.Color3(1, 0, 0);
-                this._ymesh.material.checkReadyOnlyOnce = true;
-                this._ymesh.color = new BABYLON.Color3(0, 1, 0);
-                this._zmesh.material.checkReadyOnlyOnce = true;
-                this._zmesh.color = new BABYLON.Color3(0, 0, 1);
+                var greenColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                greenColoredMaterial.disableLighting = true;
+                greenColoredMaterial.emissiveColor = BABYLON.Color3.Green().scale(0.5);
+                var redColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                redColoredMaterial.disableLighting = true;
+                redColoredMaterial.emissiveColor = BABYLON.Color3.Red().scale(0.5);
+                var blueColoredMaterial = new BABYLON.StandardMaterial("", scene);
+                blueColoredMaterial.disableLighting = true;
+                blueColoredMaterial.emissiveColor = BABYLON.Color3.Blue().scale(0.5);
+                this._xmesh = BABYLON.AxisDragGizmo._CreateArrow(scene, redColoredMaterial);
+                this._ymesh = BABYLON.AxisDragGizmo._CreateArrow(scene, greenColoredMaterial);
+                this._zmesh = BABYLON.AxisDragGizmo._CreateArrow(scene, blueColoredMaterial);
+                this._xmesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._xmesh.scaling.scaleInPlace(4);
+                this._ymesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._ymesh.scaling.scaleInPlace(4);
+                this._zmesh.rotationQuaternion = new BABYLON.Quaternion();
+                this._zmesh.scaling.scaleInPlace(4);
+                AxesViewer._recursiveChangeRenderingGroupId(this._xmesh, 2);
+                AxesViewer._recursiveChangeRenderingGroupId(this._ymesh, 2);
+                AxesViewer._recursiveChangeRenderingGroupId(this._zmesh, 2);
                 this.scene = scene;
+                this.update(new BABYLON.Vector3(), BABYLON.Vector3.Right(), BABYLON.Vector3.Up(), BABYLON.Vector3.Forward());
             }
             Object.defineProperty(AxesViewer.prototype, "xAxisMesh", {
                 /** Gets the mesh used to render x-axis */
@@ -66525,6 +66538,12 @@ var BABYLON;
                 enumerable: true,
                 configurable: true
             });
+            AxesViewer._recursiveChangeRenderingGroupId = function (mesh, id) {
+                mesh.renderingGroupId = id;
+                mesh.getChildMeshes().forEach(function (m) {
+                    AxesViewer._recursiveChangeRenderingGroupId(m, id);
+                });
+            };
             /**
              * Force the viewer to update
              * @param position defines the position of the viewer
@@ -66533,31 +66552,24 @@ var BABYLON;
              * @param zaxis defines the z axis of the viewer
              */
             AxesViewer.prototype.update = function (position, xaxis, yaxis, zaxis) {
-                var scaleLines = this.scaleLines;
                 if (this._xmesh) {
                     this._xmesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), xaxis);
+                    this._xmesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), xaxis));
+                    this._xmesh.rotationQuaternion.normalize();
                 }
                 if (this._ymesh) {
                     this._ymesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), yaxis);
+                    this._ymesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), yaxis));
+                    this._ymesh.rotationQuaternion.normalize();
                 }
                 if (this._zmesh) {
                     this._zmesh.position.copyFrom(position);
+                    var cross = BABYLON.Vector3.Cross(BABYLON.Vector3.Forward(), zaxis);
+                    this._zmesh.rotationQuaternion.set(cross.x, cross.y, cross.z, 1 + BABYLON.Vector3.Dot(BABYLON.Vector3.Forward(), zaxis));
+                    this._zmesh.rotationQuaternion.normalize();
                 }
-                var point2 = this._xline[1];
-                point2.x = xaxis.x * scaleLines;
-                point2.y = xaxis.y * scaleLines;
-                point2.z = xaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._xline, null, false, this._xmesh);
-                point2 = this._yline[1];
-                point2.x = yaxis.x * scaleLines;
-                point2.y = yaxis.y * scaleLines;
-                point2.z = yaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._yline, null, false, this._ymesh);
-                point2 = this._zline[1];
-                point2.x = zaxis.x * scaleLines;
-                point2.y = zaxis.y * scaleLines;
-                point2.z = zaxis.z * scaleLines;
-                BABYLON.Mesh.CreateLines("", this._zline, null, false, this._zmesh);
             };
             /** Releases resources */
             AxesViewer.prototype.dispose = function () {
@@ -73737,6 +73749,22 @@ var BABYLON;
             return new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension, createPolynomials);
         };
         /**
+         * Update the url (and optional buffer) of this texture if url was null during construction.
+         * @param url the url of the texture
+         * @param onLoad callback called when the texture is loaded  (defaults to null)
+         */
+        CubeTexture.prototype.updateURL = function (url, onLoad) {
+            if (this.url) {
+                this.releaseInternalTexture();
+            }
+            this.url = url;
+            this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
+            if (onLoad) {
+                this._delayedOnLoad = onLoad;
+            }
+            this.delayLoad();
+        };
+        /**
          * Delays loading of the cube texture
          */
         CubeTexture.prototype.delayLoad = function () {
@@ -73751,10 +73779,10 @@ var BABYLON;
             this._texture = this._getFromCache(this.url, this._noMipmap);
             if (!this._texture) {
                 if (this._prefiltered) {
-                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, undefined, undefined, this._format, undefined, this._createPolynomials);
+                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, this._delayedOnLoad, undefined, this._format, undefined, this._createPolynomials);
                 }
                 else {
-                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, undefined, undefined, this._format);
+                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, this._delayedOnLoad, undefined, this._format);
                 }
             }
         };
@@ -103353,20 +103381,7 @@ var BABYLON;
             hoverMaterial.disableLighting = true;
             hoverMaterial.emissiveColor = color.add(new BABYLON.Color3(0.3, 0.3, 0.3));
             // Build mesh on root node
-            var arrow = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
-            var arrowMesh = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameterTop: 0, height: 1.5, diameterBottom: 0.75, tessellation: 96 }, gizmoLayer.utilityLayerScene);
-            var arrowTail = BABYLON.MeshBuilder.CreateLines("yPosMesh", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 1.1, 0)] }, gizmoLayer.utilityLayerScene);
-            arrowTail.color = coloredMaterial.emissiveColor;
-            arrow.addChild(arrowMesh);
-            arrow.addChild(arrowTail);
-            // Position arrow pointing in its drag axis
-            arrowMesh.scaling.scaleInPlace(0.05);
-            arrowMesh.material = coloredMaterial;
-            arrowMesh.rotation.x = Math.PI / 2;
-            arrowMesh.position.z += 0.3;
-            arrowTail.scaling.scaleInPlace(0.26);
-            arrowTail.rotation.x = Math.PI / 2;
-            arrowTail.material = coloredMaterial;
+            var arrow = AxisDragGizmo._CreateArrow(gizmoLayer.utilityLayerScene, coloredMaterial);
             arrow.lookAt(_this._rootMesh.position.subtract(dragAxis));
             arrow.scaling.scaleInPlace(1 / 3);
             _this._rootMesh.addChild(arrow);
@@ -103423,6 +103438,24 @@ var BABYLON;
             });
             return _this;
         }
+        /** @hidden */
+        AxisDragGizmo._CreateArrow = function (scene, material) {
+            var arrow = new BABYLON.AbstractMesh("", scene);
+            var arrowMesh = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", { diameterTop: 0, height: 1.5, diameterBottom: 0.75, tessellation: 96 }, scene);
+            var arrowTail = BABYLON.MeshBuilder.CreateLines("yPosMesh", { points: [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 1.1, 0)] }, scene);
+            arrowTail.color = material.emissiveColor;
+            arrow.addChild(arrowMesh);
+            arrow.addChild(arrowTail);
+            // Position arrow pointing in its drag axis
+            arrowMesh.scaling.scaleInPlace(0.05);
+            arrowMesh.material = material;
+            arrowMesh.rotation.x = Math.PI / 2;
+            arrowMesh.position.z += 0.3;
+            arrowTail.scaling.scaleInPlace(0.26);
+            arrowTail.rotation.x = Math.PI / 2;
+            arrowTail.material = material;
+            return arrow;
+        };
         AxisDragGizmo.prototype._attachedMeshChanged = function (value) {
             if (this.dragBehavior) {
                 this.dragBehavior.enabled = value ? true : false;
@@ -104670,6 +104703,10 @@ var BABYLON;
         function GizmoManager(scene) {
             var _this = this;
             this.scene = scene;
+            /** When true, the gizmo will be detached from the current object when a pointer down occurs with an empty picked mesh */
+            this.clearGizmoOnEmptyPointerEvent = false;
+            /** Fires an event when the manager is attached to a mesh */
+            this.onAttachedToMeshObservable = new BABYLON.Observable();
             this._gizmosEnabled = { positionGizmo: false, rotationGizmo: false, scaleGizmo: false, boundingBoxGizmo: false };
             this._pointerObserver = null;
             this._attachedMesh = null;
@@ -104723,11 +104760,15 @@ var BABYLON;
                             }
                         }
                         else {
-                            _this.attachToMesh(null);
+                            if (_this.clearGizmoOnEmptyPointerEvent) {
+                                _this.attachToMesh(null);
+                            }
                         }
                     }
                     else {
-                        _this.attachToMesh(null);
+                        if (_this.clearGizmoOnEmptyPointerEvent) {
+                            _this.attachToMesh(null);
+                        }
                     }
                 }
             });
@@ -104750,6 +104791,7 @@ var BABYLON;
             if (this.boundingBoxGizmoEnabled && this._attachedMesh) {
                 this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
             }
+            this.onAttachedToMeshObservable.notifyObservers(mesh);
         };
         Object.defineProperty(GizmoManager.prototype, "positionGizmoEnabled", {
             get: function () {
@@ -104853,6 +104895,7 @@ var BABYLON;
             this._defaultKeepDepthUtilityLayer.dispose();
             this._defaultUtilityLayer.dispose();
             this.boundingBoxDragBehavior.detach();
+            this.onAttachedToMeshObservable.clear();
         };
         return GizmoManager;
     }());

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js.map


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 3 - 2
inspector/src/components/actionTabs/lines/fileButtonLineComponent.tsx

@@ -2,7 +2,8 @@ import * as React from "react";
 
 interface IFileButtonLineComponentProps {
     label: string,
-    onClick: (file: File) => void
+    onClick: (file: File) => void,
+    accept: string
 }
 
 export class FileButtonLineComponent extends React.Component<IFileButtonLineComponentProps> {
@@ -23,7 +24,7 @@ export class FileButtonLineComponent extends React.Component<IFileButtonLineComp
                 <label htmlFor="file-upload" className="file-upload">
                     {this.props.label}
                 </label>
-                <input id="file-upload" type="file" accept=".dds, .env" onChange={evt => this.onChange(evt)} />
+                <input id="file-upload" type="file" accept={this.props.accept} onChange={evt => this.onChange(evt)} />
             </div>
         );
     }

+ 26 - 1
inspector/src/components/actionTabs/tabs/debugTabComponent.tsx

@@ -6,13 +6,13 @@ import { GridPropertyGridComponent } from "./propertyGrids/gridPropertyGridCompo
 
 export class DebugTabComponent extends PaneComponent {
     private _skeletonViewersEnabled = false;
+    private _physicsViewersEnabled = false;
     private _skeletonViewers = new Array<BABYLON.Debug.SkeletonViewer>();
 
     constructor(props: IPaneComponentProps) {
         super(props);
     }
 
-
     componentWillMount() {
         const scene = this.props.scene;
 
@@ -20,6 +20,10 @@ export class DebugTabComponent extends PaneComponent {
             return;
         }
 
+        if (!scene.metadata) {
+            scene.metadata = {};
+        }
+
         for (var mesh of scene.meshes) {
             if (mesh.skeleton && mesh.metadata && mesh.metadata.skeletonViewer) {
                 this._skeletonViewers.push(mesh.metadata.skeletonViewer);
@@ -27,6 +31,7 @@ export class DebugTabComponent extends PaneComponent {
         }
 
         this._skeletonViewersEnabled = (this._skeletonViewers.length > 0);
+        this._physicsViewersEnabled = scene.metadata.physicsViewer != null;
     }
 
     componentWillUnmount() {
@@ -68,6 +73,25 @@ export class DebugTabComponent extends PaneComponent {
         }
     }
 
+    switchPhysicsViewers() {
+        this._physicsViewersEnabled = !this._physicsViewersEnabled;
+        const scene = this.props.scene;
+
+        if (this._physicsViewersEnabled) {
+            const physicsViewer = new BABYLON.Debug.PhysicsViewer(scene);
+            scene.metadata.physicsViewer = physicsViewer;
+
+            for (var mesh of scene.meshes) {
+                if (mesh.physicsImpostor) {
+                    physicsViewer.showImpostor(mesh.physicsImpostor);
+                }
+            }
+        } else {
+            scene.metadata.physicsViewer.dispose();
+            scene.metadata.physicsViewer = null;
+        }
+    }
+
     render() {
         const scene = this.props.scene;
 
@@ -80,6 +104,7 @@ export class DebugTabComponent extends PaneComponent {
                 <LineContainerComponent title="HELPERS">
                     <GridPropertyGridComponent scene={scene} />
                     <CheckBoxLineComponent label="Bones" isSelected={() => this._skeletonViewersEnabled} onSelect={() => this.switchSkeletonViewers()} />
+                    <CheckBoxLineComponent label="Physics" isSelected={() => this._physicsViewersEnabled} onSelect={() => this.switchPhysicsViewers()} />
                 </LineContainerComponent>
                 <LineContainerComponent title="TEXTURE CHANNELS">
                     <CheckBoxLineComponent label="Diffuse" isSelected={() => BABYLON.StandardMaterial.DiffuseTextureEnabled} onSelect={() => BABYLON.StandardMaterial.DiffuseTextureEnabled = !BABYLON.StandardMaterial.DiffuseTextureEnabled} />

+ 19 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/texturePropertyGridComponent.tsx

@@ -1,5 +1,5 @@
 import * as React from "react";
-import { Texture, Observable } from "babylonjs";
+import { Texture, CubeTexture, Observable } from "babylonjs";
 import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { SliderLineComponent } from "../../../lines/sliderLineComponent";
@@ -9,6 +9,7 @@ import { TextureLineComponent } from "../../../lines/textureLineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { AdvancedDynamicTexture } from "babylonjs-gui";
 import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
+import { FileButtonLineComponent } from "../../../lines/fileButtonLineComponent";
 
 interface ITexturePropertyGridComponentProps {
     texture: Texture,
@@ -20,6 +21,21 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
         super(props);
     }
 
+    updateTexture(file: File) {
+        const texture = this.props.texture;
+        BABYLON.Tools.ReadFile(file, (data) => {
+            var blob = new Blob([data], { type: "octet/stream" });
+            var url = URL.createObjectURL(blob);
+
+            if (texture.isCube) {
+                (texture as CubeTexture).updateURL(url, () => this.forceUpdate());
+            } else {
+                texture.updateURL(url, null, () => this.forceUpdate());
+            }
+
+        }, undefined, true);
+    }
+
     render() {
         const texture = this.props.texture;
         const adtTexture = texture instanceof AdvancedDynamicTexture ? texture as AdvancedDynamicTexture : null;
@@ -34,6 +50,7 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
             <div className="pane">
                 <LineContainerComponent title="PREVIEW">
                     <TextureLineComponent texture={texture} width={256} height={256} />
+                    <FileButtonLineComponent label="Replace texture" onClick={(file) => this.updateTexture(file)} accept=".jpg, .png, .tga" />
                 </LineContainerComponent>
                 <LineContainerComponent title="GENERAL">
                     <TextLineComponent label="Has alpha" value={texture.hasAlpha ? "Yes" : "No"} />
@@ -43,7 +60,7 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
                     <TextLineComponent label="Has mipmaps" value={!texture.noMipmap ? "Yes" : "No"} />
                     <SliderLineComponent label="UV set" target={texture} propertyName="coordinatesIndex" minimum={0} maximum={3} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {
-                        texture.updateSamplingMode && 
+                        texture.updateSamplingMode &&
                         <OptionsLineComponent label="Sampling" options={samplingMode} target={texture} noDirectUpdate={true} propertyName="samplingMode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={value => texture.updateSamplingMode(value)} />
                     }
                 </LineContainerComponent>

+ 33 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx

@@ -108,6 +108,30 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
         this.props.onSelectionChangedObservable.notifyObservers(mesh.material)
     }
 
+    convertPhysicsTypeToString(): string {
+        const mesh = this.props.mesh;
+        switch (mesh.physicsImpostor!.type) {
+            case BABYLON.PhysicsImpostor.NoImpostor:
+                return "No impostor";
+            case BABYLON.PhysicsImpostor.SphereImpostor:
+                return "Sphere";
+            case BABYLON.PhysicsImpostor.BoxImpostor:
+                return "Box";
+            case BABYLON.PhysicsImpostor.PlaneImpostor:
+                return "Plane";
+            case BABYLON.PhysicsImpostor.MeshImpostor:
+                return "Mesh";
+            case BABYLON.PhysicsImpostor.CylinderImpostor:
+                return "Cylinder";
+            case BABYLON.PhysicsImpostor.ParticleImpostor:
+                return "Particle";
+            case BABYLON.PhysicsImpostor.HeightmapImpostor:
+                return "Heightmap";
+        }
+
+        return "Unknown";
+    }
+
     render() {
         const mesh = this.props.mesh;
         const scene = mesh.getScene();
@@ -177,6 +201,15 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
                     <TextLineComponent label="has matrix weights" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind) ? "Yes" : "No"} />
                     <TextLineComponent label="has matrix indices" value={mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) ? "Yes" : "No"} />
                 </LineContainerComponent>
+                {
+                    mesh.physicsImpostor != null &&
+                    <LineContainerComponent title="PHYSICS" closed={true}>
+                        <FloatLineComponent label="Mass" target={mesh.physicsImpostor} propertyName="mass" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <FloatLineComponent label="Friction" target={mesh.physicsImpostor} propertyName="friction" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <FloatLineComponent label="Restitution" target={mesh.physicsImpostor} propertyName="restitution" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <TextLineComponent label="Type" value={this.convertPhysicsTypeToString()} />
+                    </LineContainerComponent>
+                }
                 <LineContainerComponent title="DEBUG" closed={true}>
                     <CheckBoxLineComponent label="Show bounding box" target={mesh} propertyName="showBoundingBox" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {

+ 1 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/scenePropertyGridComponent.tsx

@@ -92,7 +92,7 @@ export class ScenePropertyGridComponent extends React.Component<IScenePropertyGr
                         scene.environmentTexture &&
                         <TextureLinkLineComponent label="Env. texture" texture={scene.environmentTexture} onSelectionChangedObservable={this.props.onSelectionChangedObservable} />
                     }
-                    <FileButtonLineComponent label="Update environment texture" onClick={(file) => this.updateEnvironmentTexture(file)} />
+                    <FileButtonLineComponent label="Update environment texture" onClick={(file) => this.updateEnvironmentTexture(file)} accept=".dds, .env" />
                     <FogPropertyGridComponent scene={scene} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
             </div>

+ 24 - 2
src/Materials/Textures/babylon.cubeTexture.ts

@@ -3,6 +3,8 @@ module BABYLON {
      * Class for creating a cube texture
      */
     export class CubeTexture extends BaseTexture {
+        private _delayedOnLoad: Nullable<() => void>;
+
         /**
          * The url of the texture
          */
@@ -190,6 +192,26 @@ module BABYLON {
         }
 
         /**
+         * Update the url (and optional buffer) of this texture if url was null during construction.
+         * @param url the url of the texture
+         * @param onLoad callback called when the texture is loaded  (defaults to null)
+         */
+        public updateURL(url: string, onLoad?: () => void): void {
+            if (this.url) {
+                this.releaseInternalTexture();
+            }
+
+            this.url = url;
+            this.delayLoadState = Engine.DELAYLOADSTATE_NOTLOADED;
+
+            if (onLoad) {
+                this._delayedOnLoad = onLoad;
+            }
+
+            this.delayLoad();
+        }
+
+        /**
          * Delays loading of the cube texture
          */
         public delayLoad(): void {
@@ -207,10 +229,10 @@ module BABYLON {
 
             if (!this._texture) {
                 if (this._prefiltered) {
-                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, undefined, undefined, this._format, undefined, this._createPolynomials);
+                    this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, this._delayedOnLoad, undefined, this._format, undefined, this._createPolynomials);
                 }
                 else {
-                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, undefined, undefined, this._format);
+                    this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, this._delayedOnLoad, undefined, this._format);
                 }
             }
         }

+ 8 - 2
src/Materials/Textures/babylon.texture.ts

@@ -293,15 +293,21 @@ module BABYLON {
          * Update the url (and optional buffer) of this texture if url was null during construction.
          * @param url the url of the texture
          * @param buffer the buffer of the texture (defaults to null)
+         * @param onLoad callback called when the texture is loaded  (defaults to null)
          */
-        public updateURL(url: string, buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob> = null): void {
+        public updateURL(url: string, buffer: Nullable<string | ArrayBuffer | HTMLImageElement | Blob> = null, onLoad?: () => void): void {
             if (this.url) {
-                throw new Error("URL is already set");
+                this.releaseInternalTexture();
             }
 
             this.url = url;
             this._buffer = buffer;
             this.delayLoadState = Engine.DELAYLOADSTATE_NOTLOADED;
+
+            if (onLoad) {
+                this._delayedOnLoad = onLoad;
+            }
+
             this.delayLoad();
         }
 

+ 4 - 2
src/Mesh/babylon.transformNode.ts

@@ -232,7 +232,7 @@ module BABYLON {
                 return false;
             }
 
-            if (this.infiniteDistance) {
+            if (this.infiniteDistance !== this._cache.infiniteDistance) {
                 return false;
             }
 
@@ -267,6 +267,7 @@ module BABYLON {
             this._cache.rotation = Vector3.Zero();
             this._cache.rotationQuaternion = new Quaternion(0, 0, 0, 0);
             this._cache.billboardMode = -1;
+            this._cache.infiniteDistance = false;
         }
 
         /**
@@ -478,7 +479,7 @@ module BABYLON {
                     parentRotationMatrix.invert();
                     rotationMatrix.multiplyToRef(parentRotationMatrix, rotationMatrix);
                     this.rotationQuaternion.fromRotationMatrix(rotationMatrix);
-                }else {
+                } else {
                     // Get local rotation matrix of the looking object
                     var quaternionRotation = Tmp.Quaternion[0];
                     Quaternion.FromEulerVectorToRef(this.rotation, quaternionRotation);
@@ -843,6 +844,7 @@ module BABYLON {
             this._cache.scaling.copyFrom(this.scaling);
             this._cache.pivotMatrixUpdated = false;
             this._cache.billboardMode = this.billboardMode;
+            this._cache.infiniteDistance = this.infiniteDistance;
             this._currentRenderId = this.getScene().getRenderId();
             this._childRenderId = this.getScene().getRenderId();
             this._isDirty = false;