فهرست منبع

Fix getHierarchyBoundingVectors ordering

Sebastien Vandenberghe 7 سال پیش
والد
کامیت
2194dfb084

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 13839 - 13834
Playground/babylon.d.txt


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 16174 - 16169
dist/preview release/babylon.d.ts


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 27 - 27
dist/preview release/babylon.js


+ 39 - 16
dist/preview release/babylon.max.js

@@ -20307,6 +20307,8 @@ var BABYLON;
          */
         AbstractMesh.prototype.getHierarchyBoundingVectors = function (includeDescendants) {
             if (includeDescendants === void 0) { includeDescendants = true; }
+            // Ensures that all world matrix will be recomputed.
+            this.getScene().incrementRenderId();
             this.computeWorldMatrix(true);
             var min;
             var max;
@@ -25361,21 +25363,23 @@ var BABYLON;
                     }
                     _this._processPointerUp(pickResult, evt, clickInfo);
                     // Sprites
-                    if (_this.spriteManagers.length > 0) {
-                        var spritePickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this._spritePredicate, false, _this.cameraToUseForPointers || undefined);
-                        if (spritePickResult) {
-                            if (spritePickResult.hit && spritePickResult.pickedSprite) {
-                                if (spritePickResult.pickedSprite.actionManager) {
-                                    spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                    if (!clickInfo.ignore) {
+                        if (_this.spriteManagers.length > 0) {
+                            var spritePickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this._spritePredicate, false, _this.cameraToUseForPointers || undefined);
+                            if (spritePickResult) {
+                                if (spritePickResult.hit && spritePickResult.pickedSprite) {
                                     if (spritePickResult.pickedSprite.actionManager) {
-                                        if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < Scene.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < Scene.DragMovementThreshold) {
-                                            spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                        spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                        if (spritePickResult.pickedSprite.actionManager) {
+                                            if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < Scene.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < Scene.DragMovementThreshold) {
+                                                spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                            }
                                         }
                                     }
                                 }
-                            }
-                            if (_this._pickedDownSprite && _this._pickedDownSprite.actionManager && _this._pickedDownSprite !== spritePickResult.pickedSprite) {
-                                _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
+                                if (_this._pickedDownSprite && _this._pickedDownSprite.actionManager && _this._pickedDownSprite !== spritePickResult.pickedSprite) {
+                                    _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
+                                }
                             }
                         }
                     }
@@ -26093,17 +26097,25 @@ var BABYLON;
             this.onNewMeshAddedObservable.notifyObservers(newMesh);
         };
         /**
-         * Remove a mesh for the list of scene's meshes
-         * @param toRemove defines the mesh to remove
-         * @returns the index where the mesh was in the mesh list
-         */
-        Scene.prototype.removeMesh = function (toRemove) {
+           * Remove a mesh for the list of scene's meshes
+           * @param toRemove defines the mesh to remove
+           * @param recursive if all child meshes should also be removed from the scene
+           * @returns the index where the mesh was in the mesh list
+           */
+        Scene.prototype.removeMesh = function (toRemove, recursive) {
+            var _this = this;
+            if (recursive === void 0) { recursive = false; }
             var index = this.meshes.indexOf(toRemove);
             if (index !== -1) {
                 // Remove from the scene if mesh found
                 this.meshes.splice(index, 1);
             }
             this.onMeshRemovedObservable.notifyObservers(toRemove);
+            if (recursive) {
+                toRemove.getChildMeshes().forEach(function (m) {
+                    _this.removeMesh(m);
+                });
+            }
             return index;
         };
         /**
@@ -71347,6 +71359,10 @@ var BABYLON;
              */
             _this._pointingPoseNode = null;
             _this._workingMatrix = BABYLON.Matrix.Identity();
+            /**
+             * @hidden
+             */
+            _this._meshAttachedObservable = new BABYLON.Observable();
             _this.type = BABYLON.Gamepad.POSE_ENABLED;
             _this.controllerType = PoseEnabledControllerType.GENERIC;
             _this.position = BABYLON.Vector3.Zero();
@@ -71421,6 +71437,7 @@ var BABYLON;
             if (!this._mesh.rotationQuaternion) {
                 this._mesh.rotationQuaternion = new BABYLON.Quaternion();
             }
+            this._meshAttachedObservable.notifyObservers(mesh);
         };
         /**
          * Attaches the controllers mesh to a camera
@@ -88008,6 +88025,9 @@ var BABYLON;
                 webVRController.attachToMesh(preloadMesh);
             }
             _this._setLaserPointerParent(webVRController.mesh);
+            _this._meshAttachedObserver = webVRController._meshAttachedObservable.add(function (mesh) {
+                _this._setLaserPointerParent(mesh);
+            });
             return _this;
         }
         VRExperienceHelperControllerGazer.prototype._getForwardRay = function (length) {
@@ -88050,6 +88070,9 @@ var BABYLON;
         VRExperienceHelperControllerGazer.prototype.dispose = function () {
             _super.prototype.dispose.call(this);
             this._laserPointer.dispose();
+            if (this._meshAttachedObserver) {
+                this.webVRController._meshAttachedObservable.remove(this._meshAttachedObserver);
+            }
         };
         return VRExperienceHelperControllerGazer;
     }(VRExperienceHelperGazer));

+ 39 - 16
dist/preview release/babylon.no-module.max.js

@@ -20274,6 +20274,8 @@ var BABYLON;
          */
         AbstractMesh.prototype.getHierarchyBoundingVectors = function (includeDescendants) {
             if (includeDescendants === void 0) { includeDescendants = true; }
+            // Ensures that all world matrix will be recomputed.
+            this.getScene().incrementRenderId();
             this.computeWorldMatrix(true);
             var min;
             var max;
@@ -25328,21 +25330,23 @@ var BABYLON;
                     }
                     _this._processPointerUp(pickResult, evt, clickInfo);
                     // Sprites
-                    if (_this.spriteManagers.length > 0) {
-                        var spritePickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this._spritePredicate, false, _this.cameraToUseForPointers || undefined);
-                        if (spritePickResult) {
-                            if (spritePickResult.hit && spritePickResult.pickedSprite) {
-                                if (spritePickResult.pickedSprite.actionManager) {
-                                    spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                    if (!clickInfo.ignore) {
+                        if (_this.spriteManagers.length > 0) {
+                            var spritePickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this._spritePredicate, false, _this.cameraToUseForPointers || undefined);
+                            if (spritePickResult) {
+                                if (spritePickResult.hit && spritePickResult.pickedSprite) {
                                     if (spritePickResult.pickedSprite.actionManager) {
-                                        if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < Scene.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < Scene.DragMovementThreshold) {
-                                            spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                        spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                        if (spritePickResult.pickedSprite.actionManager) {
+                                            if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < Scene.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < Scene.DragMovementThreshold) {
+                                                spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                            }
                                         }
                                     }
                                 }
-                            }
-                            if (_this._pickedDownSprite && _this._pickedDownSprite.actionManager && _this._pickedDownSprite !== spritePickResult.pickedSprite) {
-                                _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
+                                if (_this._pickedDownSprite && _this._pickedDownSprite.actionManager && _this._pickedDownSprite !== spritePickResult.pickedSprite) {
+                                    _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
+                                }
                             }
                         }
                     }
@@ -26060,17 +26064,25 @@ var BABYLON;
             this.onNewMeshAddedObservable.notifyObservers(newMesh);
         };
         /**
-         * Remove a mesh for the list of scene's meshes
-         * @param toRemove defines the mesh to remove
-         * @returns the index where the mesh was in the mesh list
-         */
-        Scene.prototype.removeMesh = function (toRemove) {
+           * Remove a mesh for the list of scene's meshes
+           * @param toRemove defines the mesh to remove
+           * @param recursive if all child meshes should also be removed from the scene
+           * @returns the index where the mesh was in the mesh list
+           */
+        Scene.prototype.removeMesh = function (toRemove, recursive) {
+            var _this = this;
+            if (recursive === void 0) { recursive = false; }
             var index = this.meshes.indexOf(toRemove);
             if (index !== -1) {
                 // Remove from the scene if mesh found
                 this.meshes.splice(index, 1);
             }
             this.onMeshRemovedObservable.notifyObservers(toRemove);
+            if (recursive) {
+                toRemove.getChildMeshes().forEach(function (m) {
+                    _this.removeMesh(m);
+                });
+            }
             return index;
         };
         /**
@@ -71314,6 +71326,10 @@ var BABYLON;
              */
             _this._pointingPoseNode = null;
             _this._workingMatrix = BABYLON.Matrix.Identity();
+            /**
+             * @hidden
+             */
+            _this._meshAttachedObservable = new BABYLON.Observable();
             _this.type = BABYLON.Gamepad.POSE_ENABLED;
             _this.controllerType = PoseEnabledControllerType.GENERIC;
             _this.position = BABYLON.Vector3.Zero();
@@ -71388,6 +71404,7 @@ var BABYLON;
             if (!this._mesh.rotationQuaternion) {
                 this._mesh.rotationQuaternion = new BABYLON.Quaternion();
             }
+            this._meshAttachedObservable.notifyObservers(mesh);
         };
         /**
          * Attaches the controllers mesh to a camera
@@ -87975,6 +87992,9 @@ var BABYLON;
                 webVRController.attachToMesh(preloadMesh);
             }
             _this._setLaserPointerParent(webVRController.mesh);
+            _this._meshAttachedObserver = webVRController._meshAttachedObservable.add(function (mesh) {
+                _this._setLaserPointerParent(mesh);
+            });
             return _this;
         }
         VRExperienceHelperControllerGazer.prototype._getForwardRay = function (length) {
@@ -88017,6 +88037,9 @@ var BABYLON;
         VRExperienceHelperControllerGazer.prototype.dispose = function () {
             _super.prototype.dispose.call(this);
             this._laserPointer.dispose();
+            if (this._meshAttachedObserver) {
+                this.webVRController._meshAttachedObservable.remove(this._meshAttachedObserver);
+            }
         };
         return VRExperienceHelperControllerGazer;
     }(VRExperienceHelperGazer));

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 27 - 27
dist/preview release/babylon.worker.js


+ 39 - 16
dist/preview release/es6.js

@@ -20274,6 +20274,8 @@ var BABYLON;
          */
         AbstractMesh.prototype.getHierarchyBoundingVectors = function (includeDescendants) {
             if (includeDescendants === void 0) { includeDescendants = true; }
+            // Ensures that all world matrix will be recomputed.
+            this.getScene().incrementRenderId();
             this.computeWorldMatrix(true);
             var min;
             var max;
@@ -25328,21 +25330,23 @@ var BABYLON;
                     }
                     _this._processPointerUp(pickResult, evt, clickInfo);
                     // Sprites
-                    if (_this.spriteManagers.length > 0) {
-                        var spritePickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this._spritePredicate, false, _this.cameraToUseForPointers || undefined);
-                        if (spritePickResult) {
-                            if (spritePickResult.hit && spritePickResult.pickedSprite) {
-                                if (spritePickResult.pickedSprite.actionManager) {
-                                    spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                    if (!clickInfo.ignore) {
+                        if (_this.spriteManagers.length > 0) {
+                            var spritePickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this._spritePredicate, false, _this.cameraToUseForPointers || undefined);
+                            if (spritePickResult) {
+                                if (spritePickResult.hit && spritePickResult.pickedSprite) {
                                     if (spritePickResult.pickedSprite.actionManager) {
-                                        if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < Scene.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < Scene.DragMovementThreshold) {
-                                            spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                        spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                        if (spritePickResult.pickedSprite.actionManager) {
+                                            if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < Scene.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < Scene.DragMovementThreshold) {
+                                                spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                            }
                                         }
                                     }
                                 }
-                            }
-                            if (_this._pickedDownSprite && _this._pickedDownSprite.actionManager && _this._pickedDownSprite !== spritePickResult.pickedSprite) {
-                                _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
+                                if (_this._pickedDownSprite && _this._pickedDownSprite.actionManager && _this._pickedDownSprite !== spritePickResult.pickedSprite) {
+                                    _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
+                                }
                             }
                         }
                     }
@@ -26060,17 +26064,25 @@ var BABYLON;
             this.onNewMeshAddedObservable.notifyObservers(newMesh);
         };
         /**
-         * Remove a mesh for the list of scene's meshes
-         * @param toRemove defines the mesh to remove
-         * @returns the index where the mesh was in the mesh list
-         */
-        Scene.prototype.removeMesh = function (toRemove) {
+           * Remove a mesh for the list of scene's meshes
+           * @param toRemove defines the mesh to remove
+           * @param recursive if all child meshes should also be removed from the scene
+           * @returns the index where the mesh was in the mesh list
+           */
+        Scene.prototype.removeMesh = function (toRemove, recursive) {
+            var _this = this;
+            if (recursive === void 0) { recursive = false; }
             var index = this.meshes.indexOf(toRemove);
             if (index !== -1) {
                 // Remove from the scene if mesh found
                 this.meshes.splice(index, 1);
             }
             this.onMeshRemovedObservable.notifyObservers(toRemove);
+            if (recursive) {
+                toRemove.getChildMeshes().forEach(function (m) {
+                    _this.removeMesh(m);
+                });
+            }
             return index;
         };
         /**
@@ -71314,6 +71326,10 @@ var BABYLON;
              */
             _this._pointingPoseNode = null;
             _this._workingMatrix = BABYLON.Matrix.Identity();
+            /**
+             * @hidden
+             */
+            _this._meshAttachedObservable = new BABYLON.Observable();
             _this.type = BABYLON.Gamepad.POSE_ENABLED;
             _this.controllerType = PoseEnabledControllerType.GENERIC;
             _this.position = BABYLON.Vector3.Zero();
@@ -71388,6 +71404,7 @@ var BABYLON;
             if (!this._mesh.rotationQuaternion) {
                 this._mesh.rotationQuaternion = new BABYLON.Quaternion();
             }
+            this._meshAttachedObservable.notifyObservers(mesh);
         };
         /**
          * Attaches the controllers mesh to a camera
@@ -87975,6 +87992,9 @@ var BABYLON;
                 webVRController.attachToMesh(preloadMesh);
             }
             _this._setLaserPointerParent(webVRController.mesh);
+            _this._meshAttachedObserver = webVRController._meshAttachedObservable.add(function (mesh) {
+                _this._setLaserPointerParent(mesh);
+            });
             return _this;
         }
         VRExperienceHelperControllerGazer.prototype._getForwardRay = function (length) {
@@ -88017,6 +88037,9 @@ var BABYLON;
         VRExperienceHelperControllerGazer.prototype.dispose = function () {
             _super.prototype.dispose.call(this);
             this._laserPointer.dispose();
+            if (this._meshAttachedObserver) {
+                this.webVRController._meshAttachedObservable.remove(this._meshAttachedObserver);
+            }
         };
         return VRExperienceHelperControllerGazer;
     }(VRExperienceHelperGazer));

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 32 - 32
dist/preview release/viewer/babylon.viewer.js


+ 39 - 16
dist/preview release/viewer/babylon.viewer.max.js

@@ -20395,6 +20395,8 @@ var BABYLON;
          */
         AbstractMesh.prototype.getHierarchyBoundingVectors = function (includeDescendants) {
             if (includeDescendants === void 0) { includeDescendants = true; }
+            // Ensures that all world matrix will be recomputed.
+            this.getScene().incrementRenderId();
             this.computeWorldMatrix(true);
             var min;
             var max;
@@ -25449,21 +25451,23 @@ var BABYLON;
                     }
                     _this._processPointerUp(pickResult, evt, clickInfo);
                     // Sprites
-                    if (_this.spriteManagers.length > 0) {
-                        var spritePickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this._spritePredicate, false, _this.cameraToUseForPointers || undefined);
-                        if (spritePickResult) {
-                            if (spritePickResult.hit && spritePickResult.pickedSprite) {
-                                if (spritePickResult.pickedSprite.actionManager) {
-                                    spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                    if (!clickInfo.ignore) {
+                        if (_this.spriteManagers.length > 0) {
+                            var spritePickResult = _this.pickSprite(_this._unTranslatedPointerX, _this._unTranslatedPointerY, _this._spritePredicate, false, _this.cameraToUseForPointers || undefined);
+                            if (spritePickResult) {
+                                if (spritePickResult.hit && spritePickResult.pickedSprite) {
                                     if (spritePickResult.pickedSprite.actionManager) {
-                                        if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < Scene.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < Scene.DragMovementThreshold) {
-                                            spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                        spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickUpTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                        if (spritePickResult.pickedSprite.actionManager) {
+                                            if (Math.abs(_this._startingPointerPosition.x - _this._pointerX) < Scene.DragMovementThreshold && Math.abs(_this._startingPointerPosition.y - _this._pointerY) < Scene.DragMovementThreshold) {
+                                                spritePickResult.pickedSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, BABYLON.ActionEvent.CreateNewFromSprite(spritePickResult.pickedSprite, _this, evt));
+                                            }
                                         }
                                     }
                                 }
-                            }
-                            if (_this._pickedDownSprite && _this._pickedDownSprite.actionManager && _this._pickedDownSprite !== spritePickResult.pickedSprite) {
-                                _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
+                                if (_this._pickedDownSprite && _this._pickedDownSprite.actionManager && _this._pickedDownSprite !== spritePickResult.pickedSprite) {
+                                    _this._pickedDownSprite.actionManager.processTrigger(BABYLON.ActionManager.OnPickOutTrigger, BABYLON.ActionEvent.CreateNewFromSprite(_this._pickedDownSprite, _this, evt));
+                                }
                             }
                         }
                     }
@@ -26181,17 +26185,25 @@ var BABYLON;
             this.onNewMeshAddedObservable.notifyObservers(newMesh);
         };
         /**
-         * Remove a mesh for the list of scene's meshes
-         * @param toRemove defines the mesh to remove
-         * @returns the index where the mesh was in the mesh list
-         */
-        Scene.prototype.removeMesh = function (toRemove) {
+           * Remove a mesh for the list of scene's meshes
+           * @param toRemove defines the mesh to remove
+           * @param recursive if all child meshes should also be removed from the scene
+           * @returns the index where the mesh was in the mesh list
+           */
+        Scene.prototype.removeMesh = function (toRemove, recursive) {
+            var _this = this;
+            if (recursive === void 0) { recursive = false; }
             var index = this.meshes.indexOf(toRemove);
             if (index !== -1) {
                 // Remove from the scene if mesh found
                 this.meshes.splice(index, 1);
             }
             this.onMeshRemovedObservable.notifyObservers(toRemove);
+            if (recursive) {
+                toRemove.getChildMeshes().forEach(function (m) {
+                    _this.removeMesh(m);
+                });
+            }
             return index;
         };
         /**
@@ -71435,6 +71447,10 @@ var BABYLON;
              */
             _this._pointingPoseNode = null;
             _this._workingMatrix = BABYLON.Matrix.Identity();
+            /**
+             * @hidden
+             */
+            _this._meshAttachedObservable = new BABYLON.Observable();
             _this.type = BABYLON.Gamepad.POSE_ENABLED;
             _this.controllerType = PoseEnabledControllerType.GENERIC;
             _this.position = BABYLON.Vector3.Zero();
@@ -71509,6 +71525,7 @@ var BABYLON;
             if (!this._mesh.rotationQuaternion) {
                 this._mesh.rotationQuaternion = new BABYLON.Quaternion();
             }
+            this._meshAttachedObservable.notifyObservers(mesh);
         };
         /**
          * Attaches the controllers mesh to a camera
@@ -88096,6 +88113,9 @@ var BABYLON;
                 webVRController.attachToMesh(preloadMesh);
             }
             _this._setLaserPointerParent(webVRController.mesh);
+            _this._meshAttachedObserver = webVRController._meshAttachedObservable.add(function (mesh) {
+                _this._setLaserPointerParent(mesh);
+            });
             return _this;
         }
         VRExperienceHelperControllerGazer.prototype._getForwardRay = function (length) {
@@ -88138,6 +88158,9 @@ var BABYLON;
         VRExperienceHelperControllerGazer.prototype.dispose = function () {
             _super.prototype.dispose.call(this);
             this._laserPointer.dispose();
+            if (this._meshAttachedObserver) {
+                this.webVRController._meshAttachedObservable.remove(this._meshAttachedObserver);
+            }
         };
         return VRExperienceHelperControllerGazer;
     }(VRExperienceHelperGazer));

+ 3 - 0
src/Mesh/babylon.abstractMesh.ts

@@ -1059,6 +1059,9 @@
          * @returns the new bounding vectors
          */
         public getHierarchyBoundingVectors(includeDescendants = true): { min: Vector3, max: Vector3 } {
+            // Ensures that all world matrix will be recomputed.
+            this.getScene().incrementRenderId();
+
             this.computeWorldMatrix(true);
 
             let min: Vector3;