David Catuhe il y a 7 ans
Parent
commit
8d11cb92b3

Fichier diff supprimé car celui-ci est trop grand
+ 5033 - 5024
Playground/babylon.d.txt


Fichier diff supprimé car celui-ci est trop grand
+ 4643 - 4634
dist/preview release/babylon.d.ts


Fichier diff supprimé car celui-ci est trop grand
+ 7 - 7
dist/preview release/babylon.js


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

@@ -89538,7 +89538,6 @@ var BABYLON;
          * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)
          */
         function PointerDragBehavior(options) {
-            this.options = options;
             /**
              * The maximum tolerated angle between the drag plane and dragging pointer rays to trigger pointer events. Set to 0 to allow any angle (default: 0)
              */
@@ -89605,14 +89604,12 @@ var BABYLON;
             this._lineB = new BABYLON.Vector3(0, 0, 0);
             this._localAxis = new BABYLON.Vector3(0, 0, 0);
             this._lookAt = new BABYLON.Vector3(0, 0, 0);
+            this._options = options ? options : {};
             var optionCount = 0;
-            if (options === undefined) {
-                options = {};
-            }
-            if (options.dragAxis) {
+            if (this._options.dragAxis) {
                 optionCount++;
             }
-            if (options.dragPlaneNormal) {
+            if (this._options.dragPlaneNormal) {
                 optionCount++;
             }
             if (optionCount > 1) {
@@ -89691,9 +89688,9 @@ var BABYLON;
                                 _this._updateDragPlanePosition(pointerInfo.pickInfo.ray, pickedPoint);
                             }
                             // depending on the drag mode option drag accordingly
-                            if (_this.options.dragAxis) {
+                            if (_this._options.dragAxis) {
                                 // Convert local drag axis to world
-                                BABYLON.Vector3.TransformCoordinatesToRef(_this.options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix(), _this._worldDragAxis);
+                                BABYLON.Vector3.TransformCoordinatesToRef(_this._options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix(), _this._worldDragAxis);
                                 // Project delta drag from the drag plane onto the drag axis
                                 pickedPoint.subtractToRef(_this.lastDragPosition, _this._tmpVector);
                                 dragLength = BABYLON.Vector3.Dot(_this._tmpVector, _this._worldDragAxis);
@@ -89768,8 +89765,8 @@ var BABYLON;
         // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
         PointerDragBehavior.prototype._updateDragPlanePosition = function (ray, dragPlanePosition) {
             this._pointA.copyFrom(dragPlanePosition);
-            if (this.options.dragAxis) {
-                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragAxis);
+            if (this._options.dragAxis) {
+                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this._options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragAxis);
                 // Calculate plane normal in direction of camera but perpendicular to drag axis
                 this._pointA.addToRef(this._localAxis, this._pointB); // towards drag axis
                 ray.origin.subtractToRef(this._pointA, this._pointC);
@@ -89785,8 +89782,8 @@ var BABYLON;
                 this._pointA.subtractToRef(this._lookAt, this._lookAt);
                 this._dragPlane.lookAt(this._lookAt);
             }
-            else if (this.options.dragPlaneNormal) {
-                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this.options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragPlaneNormal);
+            else if (this._options.dragPlaneNormal) {
+                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this._options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragPlaneNormal);
                 this._dragPlane.position.copyFrom(this._pointA);
                 this._pointA.subtractToRef(this._localAxis, this._lookAt);
                 this._dragPlane.lookAt(this._lookAt);
@@ -89927,9 +89924,9 @@ var BABYLON;
             this._moving = false;
             this._startingOrientation = new BABYLON.Quaternion();
             /**
-             * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 5)
+             * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 3)
              */
-            this.zDragFactor = 5;
+            this.zDragFactor = 3;
             /**
              * If the behavior is currently in a dragging state
              */
@@ -89982,7 +89979,10 @@ var BABYLON;
             this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
                 if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
                     if (!_this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)) {
-                        pickedMesh = pointerInfo.pickInfo.pickedMesh;
+                        if (_this._scene.activeCamera && _this._scene.activeCamera.cameraRigMode == BABYLON.Camera.RIG_MODE_NONE) {
+                            pointerInfo.pickInfo.ray.origin.copyFrom(_this._scene.activeCamera.position);
+                        }
+                        pickedMesh = _this._ownerNode;
                         lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
                         // Set position and orientation of the controller
                         _this._virtualOriginMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);
@@ -90015,14 +90015,18 @@ var BABYLON;
                 }
                 else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
                     if (_this.currentDraggingPointerID == pointerInfo.event.pointerId && _this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray && pickedMesh) {
+                        var zDragFactor = _this.zDragFactor;
+                        if (_this._scene.activeCamera && _this._scene.activeCamera.cameraRigMode == BABYLON.Camera.RIG_MODE_NONE) {
+                            pointerInfo.pickInfo.ray.origin.copyFrom(_this._scene.activeCamera.position);
+                            zDragFactor = 0;
+                        }
                         // Calculate controller drag distance in controller space
                         var originDragDifference = pointerInfo.pickInfo.ray.origin.subtract(lastSixDofOriginPosition);
                         lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
-                        var localOriginDragDifference = BABYLON.Vector3.TransformCoordinates(originDragDifference, BABYLON.Matrix.Invert(_this._virtualOriginMesh.getWorldMatrix().getRotationMatrix()));
+                        var localOriginDragDifference = -BABYLON.Vector3.Dot(originDragDifference, pointerInfo.pickInfo.ray.direction);
                         _this._virtualOriginMesh.addChild(_this._virtualDragMesh);
                         // Determine how much the controller moved to/away towards the dragged object and use this to move the object further when its further away
-                        var zDragDistance = BABYLON.Vector3.Dot(localOriginDragDifference, _this._virtualOriginMesh.position.normalizeToNew());
-                        _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? zDragDistance * _this.zDragFactor : zDragDistance * _this.zDragFactor * _this._virtualDragMesh.position.z;
+                        _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? localOriginDragDifference * _this.zDragFactor : localOriginDragDifference * zDragFactor * _this._virtualDragMesh.position.z;
                         if (_this._virtualDragMesh.position.z < 0) {
                             _this._virtualDragMesh.position.z = 0;
                         }
@@ -90806,6 +90810,7 @@ var BABYLON;
             _this.onDragEndObservable = new BABYLON.Observable();
             // Do not update the gizmo's scale so it has a fixed size to the object its attached to
             _this._updateScale = false;
+            _this._anchorMesh = new BABYLON.AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
             // Create Materials
             var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
             coloredMaterial.disableLighting = true;
@@ -90867,6 +90872,9 @@ var BABYLON;
                         if (!_this.attachedMesh.rotationQuaternion) {
                             _this.attachedMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this.attachedMesh.rotation.y, _this.attachedMesh.rotation.x, _this.attachedMesh.rotation.z);
                         }
+                        if (!_this._anchorMesh.rotationQuaternion) {
+                            _this._anchorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this._anchorMesh.rotation.y, _this._anchorMesh.rotation.x, _this._anchorMesh.rotation.z);
+                        }
                         // Do not allow the object to turn more than a full circle
                         totalTurnAmountOfDrag += projectDist;
                         if (Math.abs(totalTurnAmountOfDrag) <= 2 * Math.PI) {
@@ -90879,7 +90887,10 @@ var BABYLON;
                             else {
                                 BABYLON.Quaternion.RotationYawPitchRollToRef(0, projectDist, 0, _this._tmpQuaternion);
                             }
-                            _this.attachedMesh.rotationQuaternion.multiplyInPlace(_this._tmpQuaternion);
+                            // Rotate around center of bounding box
+                            _this._anchorMesh.addChild(_this.attachedMesh);
+                            _this._anchorMesh.rotationQuaternion.multiplyToRef(_this._tmpQuaternion, _this._anchorMesh.rotationQuaternion);
+                            _this._anchorMesh.removeChild(_this.attachedMesh);
                         }
                     }
                 });
@@ -90915,24 +90926,18 @@ var BABYLON;
                         _dragBehavior.onDragObservable.add(function (event) {
                             _this.onDragObservable.notifyObservers({});
                             if (_this.attachedMesh) {
-                                // Current boudning box dimensions
-                                var boundingInfo = _this.attachedMesh.getBoundingInfo().boundingBox;
-                                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(_this.attachedMesh.scaling);
-                                // Get the change in bounding box size/2 and add this to the mesh's position to offset from scaling with center pivot point
                                 var deltaScale = new BABYLON.Vector3(event.dragDistance, event.dragDistance, event.dragDistance);
                                 deltaScale.scaleInPlace(_this._scaleDragSpeed);
-                                var scaleRatio = deltaScale.divide(_this.attachedMesh.scaling).scaleInPlace(0.5);
-                                var moveDirection = boundBoxDimensions.multiply(scaleRatio).multiplyInPlace(dragAxis);
-                                var worldMoveDirection = BABYLON.Vector3.TransformCoordinates(moveDirection, _this.attachedMesh.getWorldMatrix().getRotationMatrix());
-                                // Update scale and position
-                                _this.attachedMesh.scaling.addInPlace(deltaScale);
-                                if (_this.attachedMesh.scaling.x < 0 || _this.attachedMesh.scaling.y < 0 || _this.attachedMesh.scaling.z < 0) {
-                                    _this.attachedMesh.scaling.subtractInPlace(deltaScale);
-                                }
-                                else {
-                                    _this.attachedMesh.getAbsolutePosition().addToRef(worldMoveDirection, _this._tmpVector);
-                                    _this.attachedMesh.setAbsolutePosition(_this._tmpVector);
+                                _this._updateBoundingBox();
+                                // Scale from the position of the opposite corner                   
+                                box.absolutePosition.subtractToRef(_this._anchorMesh.position, _this._tmpVector);
+                                _this._anchorMesh.position.subtractInPlace(_this._tmpVector);
+                                _this._anchorMesh.addChild(_this.attachedMesh);
+                                _this._anchorMesh.scaling.addInPlace(deltaScale);
+                                if (_this._anchorMesh.scaling.x < 0 || _this._anchorMesh.scaling.y < 0 || _this._anchorMesh.scaling.z < 0) {
+                                    _this._anchorMesh.scaling.subtractInPlace(deltaScale);
                                 }
+                                _this._anchorMesh.removeChild(_this.attachedMesh);
                             }
                         });
                         // Selection/deselection
@@ -90978,19 +90983,57 @@ var BABYLON;
             _this._updateBoundingBox();
             return _this;
         }
+        BoundingBoxGizmo.prototype._attachedMeshChanged = function (value) {
+            if (value) {
+                // Reset anchor mesh to match attached mesh's scale
+                // This is needed to avoid invalid box/sphere position on first drag
+                this._anchorMesh.addChild(value);
+                this._anchorMesh.removeChild(value);
+                this._updateBoundingBox();
+            }
+        };
         BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
             this._rotateSpheresParent.getChildMeshes()
                 .concat(this._scaleBoxesParent.getChildMeshes()).forEach(function (m, i) {
                 m.isVisible = (!selectedMesh || m == selectedMesh);
             });
         };
+        BoundingBoxGizmo.prototype._recurseComputeWorld = function (mesh) {
+            var _this = this;
+            mesh.computeWorldMatrix(true);
+            mesh.getChildMeshes().forEach(function (m) {
+                _this._recurseComputeWorld(m);
+            });
+        };
         BoundingBoxGizmo.prototype._updateBoundingBox = function () {
             if (this.attachedMesh) {
-                // Update bounding dimensions/positions
-                var boundingInfo = this.attachedMesh.getBoundingInfo().boundingBox;
-                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(this.attachedMesh.scaling);
-                this._boundingDimensions.copyFrom(boundBoxDimensions);
+                // Rotate based on axis
+                if (!this.attachedMesh.rotationQuaternion) {
+                    this.attachedMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.attachedMesh.rotation.y, this.attachedMesh.rotation.x, this.attachedMesh.rotation.z);
+                }
+                if (!this._anchorMesh.rotationQuaternion) {
+                    this._anchorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this._anchorMesh.rotation.y, this._anchorMesh.rotation.x, this._anchorMesh.rotation.z);
+                }
+                this._anchorMesh.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                // Store original position and reset mesh to origin before computing the bounding box
+                this._tmpQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                this._tmpVector.copyFrom(this.attachedMesh.position);
+                this.attachedMesh.rotationQuaternion.set(0, 0, 0, 1);
+                this.attachedMesh.position.set(0, 0, 0);
+                // Update bounding dimensions/positions   
+                var boundingMinMax = this.attachedMesh.getHierarchyBoundingVectors();
+                boundingMinMax.max.subtractToRef(boundingMinMax.min, this._boundingDimensions);
+                // Update gizmo to match bounding box scaling and rotation
                 this._lineBoundingBox.scaling.copyFrom(this._boundingDimensions);
+                this._lineBoundingBox.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
+                this._rotateSpheresParent.position.copyFrom(this._lineBoundingBox.position);
+                this._scaleBoxesParent.position.copyFrom(this._lineBoundingBox.position);
+                this._lineBoundingBox.computeWorldMatrix();
+                this._anchorMesh.position.copyFrom(this._lineBoundingBox.absolutePosition);
+                // restore position/rotation values
+                this.attachedMesh.rotationQuaternion.copyFrom(this._tmpQuaternion);
+                this.attachedMesh.position.copyFrom(this._tmpVector);
+                this._recurseComputeWorld(this.attachedMesh);
             }
             // Update rotation sphere locations
             var rotateSpheres = this._rotateSpheresParent.getChildMeshes();
@@ -91074,6 +91117,42 @@ var BABYLON;
             this._scaleBoxesParent.dispose();
             _super.prototype.dispose.call(this);
         };
+        /**
+         * Makes a mesh not pickable and wraps the mesh inside of a bounding box mesh that is pickable. (This is useful to avoid picking within complex geometry)
+         * @param mesh the mesh to wrap in the bounding box mesh and make not pickable
+         * @returns the bounding box mesh with the passed in mesh as a child
+         */
+        BoundingBoxGizmo.MakeNotPickableAndWrapInBoundingBox = function (mesh) {
+            var makeNotPickable = function (root) {
+                root.isPickable = false;
+                root.getChildMeshes().forEach(function (c) {
+                    makeNotPickable(c);
+                });
+            };
+            makeNotPickable(mesh);
+            // Reset position to get boudning box from origin with no rotation
+            if (!mesh.rotationQuaternion) {
+                mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z);
+            }
+            var oldPos = mesh.position.clone();
+            var oldRot = mesh.rotationQuaternion.clone();
+            mesh.rotationQuaternion.set(0, 0, 0, 1);
+            mesh.position.set(0, 0, 0);
+            // Update bounding dimensions/positions   
+            var box = BABYLON.MeshBuilder.CreateBox("box", { size: 1 }, mesh.getScene());
+            var boundingMinMax = mesh.getHierarchyBoundingVectors();
+            boundingMinMax.max.subtractToRef(boundingMinMax.min, box.scaling);
+            box.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
+            // Restore original positions
+            mesh.addChild(box);
+            mesh.rotationQuaternion.copyFrom(oldRot);
+            mesh.position.copyFrom(oldPos);
+            // Reverse parenting
+            mesh.removeChild(box);
+            box.addChild(mesh);
+            box.visibility = 0;
+            return box;
+        };
         return BoundingBoxGizmo;
     }(BABYLON.Gizmo));
     BABYLON.BoundingBoxGizmo = BoundingBoxGizmo;
@@ -93862,7 +93941,7 @@ var BABYLON;
                     this._enableInteractionOnController(this.rightController);
                 }
                 this.raySelectionPredicate = function (mesh) {
-                    return mesh.isVisible;
+                    return mesh.isVisible && mesh.isPickable;
                 };
                 this.meshSelectionPredicate = function (mesh) {
                     return true;

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

@@ -89505,7 +89505,6 @@ var BABYLON;
          * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)
          */
         function PointerDragBehavior(options) {
-            this.options = options;
             /**
              * The maximum tolerated angle between the drag plane and dragging pointer rays to trigger pointer events. Set to 0 to allow any angle (default: 0)
              */
@@ -89572,14 +89571,12 @@ var BABYLON;
             this._lineB = new BABYLON.Vector3(0, 0, 0);
             this._localAxis = new BABYLON.Vector3(0, 0, 0);
             this._lookAt = new BABYLON.Vector3(0, 0, 0);
+            this._options = options ? options : {};
             var optionCount = 0;
-            if (options === undefined) {
-                options = {};
-            }
-            if (options.dragAxis) {
+            if (this._options.dragAxis) {
                 optionCount++;
             }
-            if (options.dragPlaneNormal) {
+            if (this._options.dragPlaneNormal) {
                 optionCount++;
             }
             if (optionCount > 1) {
@@ -89658,9 +89655,9 @@ var BABYLON;
                                 _this._updateDragPlanePosition(pointerInfo.pickInfo.ray, pickedPoint);
                             }
                             // depending on the drag mode option drag accordingly
-                            if (_this.options.dragAxis) {
+                            if (_this._options.dragAxis) {
                                 // Convert local drag axis to world
-                                BABYLON.Vector3.TransformCoordinatesToRef(_this.options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix(), _this._worldDragAxis);
+                                BABYLON.Vector3.TransformCoordinatesToRef(_this._options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix(), _this._worldDragAxis);
                                 // Project delta drag from the drag plane onto the drag axis
                                 pickedPoint.subtractToRef(_this.lastDragPosition, _this._tmpVector);
                                 dragLength = BABYLON.Vector3.Dot(_this._tmpVector, _this._worldDragAxis);
@@ -89735,8 +89732,8 @@ var BABYLON;
         // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
         PointerDragBehavior.prototype._updateDragPlanePosition = function (ray, dragPlanePosition) {
             this._pointA.copyFrom(dragPlanePosition);
-            if (this.options.dragAxis) {
-                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragAxis);
+            if (this._options.dragAxis) {
+                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this._options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragAxis);
                 // Calculate plane normal in direction of camera but perpendicular to drag axis
                 this._pointA.addToRef(this._localAxis, this._pointB); // towards drag axis
                 ray.origin.subtractToRef(this._pointA, this._pointC);
@@ -89752,8 +89749,8 @@ var BABYLON;
                 this._pointA.subtractToRef(this._lookAt, this._lookAt);
                 this._dragPlane.lookAt(this._lookAt);
             }
-            else if (this.options.dragPlaneNormal) {
-                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this.options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragPlaneNormal);
+            else if (this._options.dragPlaneNormal) {
+                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this._options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragPlaneNormal);
                 this._dragPlane.position.copyFrom(this._pointA);
                 this._pointA.subtractToRef(this._localAxis, this._lookAt);
                 this._dragPlane.lookAt(this._lookAt);
@@ -89894,9 +89891,9 @@ var BABYLON;
             this._moving = false;
             this._startingOrientation = new BABYLON.Quaternion();
             /**
-             * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 5)
+             * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 3)
              */
-            this.zDragFactor = 5;
+            this.zDragFactor = 3;
             /**
              * If the behavior is currently in a dragging state
              */
@@ -89949,7 +89946,10 @@ var BABYLON;
             this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
                 if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
                     if (!_this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)) {
-                        pickedMesh = pointerInfo.pickInfo.pickedMesh;
+                        if (_this._scene.activeCamera && _this._scene.activeCamera.cameraRigMode == BABYLON.Camera.RIG_MODE_NONE) {
+                            pointerInfo.pickInfo.ray.origin.copyFrom(_this._scene.activeCamera.position);
+                        }
+                        pickedMesh = _this._ownerNode;
                         lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
                         // Set position and orientation of the controller
                         _this._virtualOriginMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);
@@ -89982,14 +89982,18 @@ var BABYLON;
                 }
                 else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
                     if (_this.currentDraggingPointerID == pointerInfo.event.pointerId && _this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray && pickedMesh) {
+                        var zDragFactor = _this.zDragFactor;
+                        if (_this._scene.activeCamera && _this._scene.activeCamera.cameraRigMode == BABYLON.Camera.RIG_MODE_NONE) {
+                            pointerInfo.pickInfo.ray.origin.copyFrom(_this._scene.activeCamera.position);
+                            zDragFactor = 0;
+                        }
                         // Calculate controller drag distance in controller space
                         var originDragDifference = pointerInfo.pickInfo.ray.origin.subtract(lastSixDofOriginPosition);
                         lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
-                        var localOriginDragDifference = BABYLON.Vector3.TransformCoordinates(originDragDifference, BABYLON.Matrix.Invert(_this._virtualOriginMesh.getWorldMatrix().getRotationMatrix()));
+                        var localOriginDragDifference = -BABYLON.Vector3.Dot(originDragDifference, pointerInfo.pickInfo.ray.direction);
                         _this._virtualOriginMesh.addChild(_this._virtualDragMesh);
                         // Determine how much the controller moved to/away towards the dragged object and use this to move the object further when its further away
-                        var zDragDistance = BABYLON.Vector3.Dot(localOriginDragDifference, _this._virtualOriginMesh.position.normalizeToNew());
-                        _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? zDragDistance * _this.zDragFactor : zDragDistance * _this.zDragFactor * _this._virtualDragMesh.position.z;
+                        _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? localOriginDragDifference * _this.zDragFactor : localOriginDragDifference * zDragFactor * _this._virtualDragMesh.position.z;
                         if (_this._virtualDragMesh.position.z < 0) {
                             _this._virtualDragMesh.position.z = 0;
                         }
@@ -90773,6 +90777,7 @@ var BABYLON;
             _this.onDragEndObservable = new BABYLON.Observable();
             // Do not update the gizmo's scale so it has a fixed size to the object its attached to
             _this._updateScale = false;
+            _this._anchorMesh = new BABYLON.AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
             // Create Materials
             var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
             coloredMaterial.disableLighting = true;
@@ -90834,6 +90839,9 @@ var BABYLON;
                         if (!_this.attachedMesh.rotationQuaternion) {
                             _this.attachedMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this.attachedMesh.rotation.y, _this.attachedMesh.rotation.x, _this.attachedMesh.rotation.z);
                         }
+                        if (!_this._anchorMesh.rotationQuaternion) {
+                            _this._anchorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this._anchorMesh.rotation.y, _this._anchorMesh.rotation.x, _this._anchorMesh.rotation.z);
+                        }
                         // Do not allow the object to turn more than a full circle
                         totalTurnAmountOfDrag += projectDist;
                         if (Math.abs(totalTurnAmountOfDrag) <= 2 * Math.PI) {
@@ -90846,7 +90854,10 @@ var BABYLON;
                             else {
                                 BABYLON.Quaternion.RotationYawPitchRollToRef(0, projectDist, 0, _this._tmpQuaternion);
                             }
-                            _this.attachedMesh.rotationQuaternion.multiplyInPlace(_this._tmpQuaternion);
+                            // Rotate around center of bounding box
+                            _this._anchorMesh.addChild(_this.attachedMesh);
+                            _this._anchorMesh.rotationQuaternion.multiplyToRef(_this._tmpQuaternion, _this._anchorMesh.rotationQuaternion);
+                            _this._anchorMesh.removeChild(_this.attachedMesh);
                         }
                     }
                 });
@@ -90882,24 +90893,18 @@ var BABYLON;
                         _dragBehavior.onDragObservable.add(function (event) {
                             _this.onDragObservable.notifyObservers({});
                             if (_this.attachedMesh) {
-                                // Current boudning box dimensions
-                                var boundingInfo = _this.attachedMesh.getBoundingInfo().boundingBox;
-                                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(_this.attachedMesh.scaling);
-                                // Get the change in bounding box size/2 and add this to the mesh's position to offset from scaling with center pivot point
                                 var deltaScale = new BABYLON.Vector3(event.dragDistance, event.dragDistance, event.dragDistance);
                                 deltaScale.scaleInPlace(_this._scaleDragSpeed);
-                                var scaleRatio = deltaScale.divide(_this.attachedMesh.scaling).scaleInPlace(0.5);
-                                var moveDirection = boundBoxDimensions.multiply(scaleRatio).multiplyInPlace(dragAxis);
-                                var worldMoveDirection = BABYLON.Vector3.TransformCoordinates(moveDirection, _this.attachedMesh.getWorldMatrix().getRotationMatrix());
-                                // Update scale and position
-                                _this.attachedMesh.scaling.addInPlace(deltaScale);
-                                if (_this.attachedMesh.scaling.x < 0 || _this.attachedMesh.scaling.y < 0 || _this.attachedMesh.scaling.z < 0) {
-                                    _this.attachedMesh.scaling.subtractInPlace(deltaScale);
-                                }
-                                else {
-                                    _this.attachedMesh.getAbsolutePosition().addToRef(worldMoveDirection, _this._tmpVector);
-                                    _this.attachedMesh.setAbsolutePosition(_this._tmpVector);
+                                _this._updateBoundingBox();
+                                // Scale from the position of the opposite corner                   
+                                box.absolutePosition.subtractToRef(_this._anchorMesh.position, _this._tmpVector);
+                                _this._anchorMesh.position.subtractInPlace(_this._tmpVector);
+                                _this._anchorMesh.addChild(_this.attachedMesh);
+                                _this._anchorMesh.scaling.addInPlace(deltaScale);
+                                if (_this._anchorMesh.scaling.x < 0 || _this._anchorMesh.scaling.y < 0 || _this._anchorMesh.scaling.z < 0) {
+                                    _this._anchorMesh.scaling.subtractInPlace(deltaScale);
                                 }
+                                _this._anchorMesh.removeChild(_this.attachedMesh);
                             }
                         });
                         // Selection/deselection
@@ -90945,19 +90950,57 @@ var BABYLON;
             _this._updateBoundingBox();
             return _this;
         }
+        BoundingBoxGizmo.prototype._attachedMeshChanged = function (value) {
+            if (value) {
+                // Reset anchor mesh to match attached mesh's scale
+                // This is needed to avoid invalid box/sphere position on first drag
+                this._anchorMesh.addChild(value);
+                this._anchorMesh.removeChild(value);
+                this._updateBoundingBox();
+            }
+        };
         BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
             this._rotateSpheresParent.getChildMeshes()
                 .concat(this._scaleBoxesParent.getChildMeshes()).forEach(function (m, i) {
                 m.isVisible = (!selectedMesh || m == selectedMesh);
             });
         };
+        BoundingBoxGizmo.prototype._recurseComputeWorld = function (mesh) {
+            var _this = this;
+            mesh.computeWorldMatrix(true);
+            mesh.getChildMeshes().forEach(function (m) {
+                _this._recurseComputeWorld(m);
+            });
+        };
         BoundingBoxGizmo.prototype._updateBoundingBox = function () {
             if (this.attachedMesh) {
-                // Update bounding dimensions/positions
-                var boundingInfo = this.attachedMesh.getBoundingInfo().boundingBox;
-                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(this.attachedMesh.scaling);
-                this._boundingDimensions.copyFrom(boundBoxDimensions);
+                // Rotate based on axis
+                if (!this.attachedMesh.rotationQuaternion) {
+                    this.attachedMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.attachedMesh.rotation.y, this.attachedMesh.rotation.x, this.attachedMesh.rotation.z);
+                }
+                if (!this._anchorMesh.rotationQuaternion) {
+                    this._anchorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this._anchorMesh.rotation.y, this._anchorMesh.rotation.x, this._anchorMesh.rotation.z);
+                }
+                this._anchorMesh.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                // Store original position and reset mesh to origin before computing the bounding box
+                this._tmpQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                this._tmpVector.copyFrom(this.attachedMesh.position);
+                this.attachedMesh.rotationQuaternion.set(0, 0, 0, 1);
+                this.attachedMesh.position.set(0, 0, 0);
+                // Update bounding dimensions/positions   
+                var boundingMinMax = this.attachedMesh.getHierarchyBoundingVectors();
+                boundingMinMax.max.subtractToRef(boundingMinMax.min, this._boundingDimensions);
+                // Update gizmo to match bounding box scaling and rotation
                 this._lineBoundingBox.scaling.copyFrom(this._boundingDimensions);
+                this._lineBoundingBox.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
+                this._rotateSpheresParent.position.copyFrom(this._lineBoundingBox.position);
+                this._scaleBoxesParent.position.copyFrom(this._lineBoundingBox.position);
+                this._lineBoundingBox.computeWorldMatrix();
+                this._anchorMesh.position.copyFrom(this._lineBoundingBox.absolutePosition);
+                // restore position/rotation values
+                this.attachedMesh.rotationQuaternion.copyFrom(this._tmpQuaternion);
+                this.attachedMesh.position.copyFrom(this._tmpVector);
+                this._recurseComputeWorld(this.attachedMesh);
             }
             // Update rotation sphere locations
             var rotateSpheres = this._rotateSpheresParent.getChildMeshes();
@@ -91041,6 +91084,42 @@ var BABYLON;
             this._scaleBoxesParent.dispose();
             _super.prototype.dispose.call(this);
         };
+        /**
+         * Makes a mesh not pickable and wraps the mesh inside of a bounding box mesh that is pickable. (This is useful to avoid picking within complex geometry)
+         * @param mesh the mesh to wrap in the bounding box mesh and make not pickable
+         * @returns the bounding box mesh with the passed in mesh as a child
+         */
+        BoundingBoxGizmo.MakeNotPickableAndWrapInBoundingBox = function (mesh) {
+            var makeNotPickable = function (root) {
+                root.isPickable = false;
+                root.getChildMeshes().forEach(function (c) {
+                    makeNotPickable(c);
+                });
+            };
+            makeNotPickable(mesh);
+            // Reset position to get boudning box from origin with no rotation
+            if (!mesh.rotationQuaternion) {
+                mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z);
+            }
+            var oldPos = mesh.position.clone();
+            var oldRot = mesh.rotationQuaternion.clone();
+            mesh.rotationQuaternion.set(0, 0, 0, 1);
+            mesh.position.set(0, 0, 0);
+            // Update bounding dimensions/positions   
+            var box = BABYLON.MeshBuilder.CreateBox("box", { size: 1 }, mesh.getScene());
+            var boundingMinMax = mesh.getHierarchyBoundingVectors();
+            boundingMinMax.max.subtractToRef(boundingMinMax.min, box.scaling);
+            box.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
+            // Restore original positions
+            mesh.addChild(box);
+            mesh.rotationQuaternion.copyFrom(oldRot);
+            mesh.position.copyFrom(oldPos);
+            // Reverse parenting
+            mesh.removeChild(box);
+            box.addChild(mesh);
+            box.visibility = 0;
+            return box;
+        };
         return BoundingBoxGizmo;
     }(BABYLON.Gizmo));
     BABYLON.BoundingBoxGizmo = BoundingBoxGizmo;
@@ -93829,7 +93908,7 @@ var BABYLON;
                     this._enableInteractionOnController(this.rightController);
                 }
                 this.raySelectionPredicate = function (mesh) {
-                    return mesh.isVisible;
+                    return mesh.isVisible && mesh.isPickable;
                 };
                 this.meshSelectionPredicate = function (mesh) {
                     return true;

Fichier diff supprimé car celui-ci est trop grand
+ 7 - 7
dist/preview release/babylon.worker.js


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

@@ -89505,7 +89505,6 @@ var BABYLON;
          * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)
          */
         function PointerDragBehavior(options) {
-            this.options = options;
             /**
              * The maximum tolerated angle between the drag plane and dragging pointer rays to trigger pointer events. Set to 0 to allow any angle (default: 0)
              */
@@ -89572,14 +89571,12 @@ var BABYLON;
             this._lineB = new BABYLON.Vector3(0, 0, 0);
             this._localAxis = new BABYLON.Vector3(0, 0, 0);
             this._lookAt = new BABYLON.Vector3(0, 0, 0);
+            this._options = options ? options : {};
             var optionCount = 0;
-            if (options === undefined) {
-                options = {};
-            }
-            if (options.dragAxis) {
+            if (this._options.dragAxis) {
                 optionCount++;
             }
-            if (options.dragPlaneNormal) {
+            if (this._options.dragPlaneNormal) {
                 optionCount++;
             }
             if (optionCount > 1) {
@@ -89658,9 +89655,9 @@ var BABYLON;
                                 _this._updateDragPlanePosition(pointerInfo.pickInfo.ray, pickedPoint);
                             }
                             // depending on the drag mode option drag accordingly
-                            if (_this.options.dragAxis) {
+                            if (_this._options.dragAxis) {
                                 // Convert local drag axis to world
-                                BABYLON.Vector3.TransformCoordinatesToRef(_this.options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix(), _this._worldDragAxis);
+                                BABYLON.Vector3.TransformCoordinatesToRef(_this._options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix(), _this._worldDragAxis);
                                 // Project delta drag from the drag plane onto the drag axis
                                 pickedPoint.subtractToRef(_this.lastDragPosition, _this._tmpVector);
                                 dragLength = BABYLON.Vector3.Dot(_this._tmpVector, _this._worldDragAxis);
@@ -89735,8 +89732,8 @@ var BABYLON;
         // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
         PointerDragBehavior.prototype._updateDragPlanePosition = function (ray, dragPlanePosition) {
             this._pointA.copyFrom(dragPlanePosition);
-            if (this.options.dragAxis) {
-                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragAxis);
+            if (this._options.dragAxis) {
+                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this._options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragAxis);
                 // Calculate plane normal in direction of camera but perpendicular to drag axis
                 this._pointA.addToRef(this._localAxis, this._pointB); // towards drag axis
                 ray.origin.subtractToRef(this._pointA, this._pointC);
@@ -89752,8 +89749,8 @@ var BABYLON;
                 this._pointA.subtractToRef(this._lookAt, this._lookAt);
                 this._dragPlane.lookAt(this._lookAt);
             }
-            else if (this.options.dragPlaneNormal) {
-                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this.options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragPlaneNormal);
+            else if (this._options.dragPlaneNormal) {
+                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this._options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragPlaneNormal);
                 this._dragPlane.position.copyFrom(this._pointA);
                 this._pointA.subtractToRef(this._localAxis, this._lookAt);
                 this._dragPlane.lookAt(this._lookAt);
@@ -89894,9 +89891,9 @@ var BABYLON;
             this._moving = false;
             this._startingOrientation = new BABYLON.Quaternion();
             /**
-             * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 5)
+             * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 3)
              */
-            this.zDragFactor = 5;
+            this.zDragFactor = 3;
             /**
              * If the behavior is currently in a dragging state
              */
@@ -89949,7 +89946,10 @@ var BABYLON;
             this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
                 if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
                     if (!_this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)) {
-                        pickedMesh = pointerInfo.pickInfo.pickedMesh;
+                        if (_this._scene.activeCamera && _this._scene.activeCamera.cameraRigMode == BABYLON.Camera.RIG_MODE_NONE) {
+                            pointerInfo.pickInfo.ray.origin.copyFrom(_this._scene.activeCamera.position);
+                        }
+                        pickedMesh = _this._ownerNode;
                         lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
                         // Set position and orientation of the controller
                         _this._virtualOriginMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);
@@ -89982,14 +89982,18 @@ var BABYLON;
                 }
                 else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
                     if (_this.currentDraggingPointerID == pointerInfo.event.pointerId && _this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray && pickedMesh) {
+                        var zDragFactor = _this.zDragFactor;
+                        if (_this._scene.activeCamera && _this._scene.activeCamera.cameraRigMode == BABYLON.Camera.RIG_MODE_NONE) {
+                            pointerInfo.pickInfo.ray.origin.copyFrom(_this._scene.activeCamera.position);
+                            zDragFactor = 0;
+                        }
                         // Calculate controller drag distance in controller space
                         var originDragDifference = pointerInfo.pickInfo.ray.origin.subtract(lastSixDofOriginPosition);
                         lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
-                        var localOriginDragDifference = BABYLON.Vector3.TransformCoordinates(originDragDifference, BABYLON.Matrix.Invert(_this._virtualOriginMesh.getWorldMatrix().getRotationMatrix()));
+                        var localOriginDragDifference = -BABYLON.Vector3.Dot(originDragDifference, pointerInfo.pickInfo.ray.direction);
                         _this._virtualOriginMesh.addChild(_this._virtualDragMesh);
                         // Determine how much the controller moved to/away towards the dragged object and use this to move the object further when its further away
-                        var zDragDistance = BABYLON.Vector3.Dot(localOriginDragDifference, _this._virtualOriginMesh.position.normalizeToNew());
-                        _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? zDragDistance * _this.zDragFactor : zDragDistance * _this.zDragFactor * _this._virtualDragMesh.position.z;
+                        _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? localOriginDragDifference * _this.zDragFactor : localOriginDragDifference * zDragFactor * _this._virtualDragMesh.position.z;
                         if (_this._virtualDragMesh.position.z < 0) {
                             _this._virtualDragMesh.position.z = 0;
                         }
@@ -90773,6 +90777,7 @@ var BABYLON;
             _this.onDragEndObservable = new BABYLON.Observable();
             // Do not update the gizmo's scale so it has a fixed size to the object its attached to
             _this._updateScale = false;
+            _this._anchorMesh = new BABYLON.AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
             // Create Materials
             var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
             coloredMaterial.disableLighting = true;
@@ -90834,6 +90839,9 @@ var BABYLON;
                         if (!_this.attachedMesh.rotationQuaternion) {
                             _this.attachedMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this.attachedMesh.rotation.y, _this.attachedMesh.rotation.x, _this.attachedMesh.rotation.z);
                         }
+                        if (!_this._anchorMesh.rotationQuaternion) {
+                            _this._anchorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this._anchorMesh.rotation.y, _this._anchorMesh.rotation.x, _this._anchorMesh.rotation.z);
+                        }
                         // Do not allow the object to turn more than a full circle
                         totalTurnAmountOfDrag += projectDist;
                         if (Math.abs(totalTurnAmountOfDrag) <= 2 * Math.PI) {
@@ -90846,7 +90854,10 @@ var BABYLON;
                             else {
                                 BABYLON.Quaternion.RotationYawPitchRollToRef(0, projectDist, 0, _this._tmpQuaternion);
                             }
-                            _this.attachedMesh.rotationQuaternion.multiplyInPlace(_this._tmpQuaternion);
+                            // Rotate around center of bounding box
+                            _this._anchorMesh.addChild(_this.attachedMesh);
+                            _this._anchorMesh.rotationQuaternion.multiplyToRef(_this._tmpQuaternion, _this._anchorMesh.rotationQuaternion);
+                            _this._anchorMesh.removeChild(_this.attachedMesh);
                         }
                     }
                 });
@@ -90882,24 +90893,18 @@ var BABYLON;
                         _dragBehavior.onDragObservable.add(function (event) {
                             _this.onDragObservable.notifyObservers({});
                             if (_this.attachedMesh) {
-                                // Current boudning box dimensions
-                                var boundingInfo = _this.attachedMesh.getBoundingInfo().boundingBox;
-                                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(_this.attachedMesh.scaling);
-                                // Get the change in bounding box size/2 and add this to the mesh's position to offset from scaling with center pivot point
                                 var deltaScale = new BABYLON.Vector3(event.dragDistance, event.dragDistance, event.dragDistance);
                                 deltaScale.scaleInPlace(_this._scaleDragSpeed);
-                                var scaleRatio = deltaScale.divide(_this.attachedMesh.scaling).scaleInPlace(0.5);
-                                var moveDirection = boundBoxDimensions.multiply(scaleRatio).multiplyInPlace(dragAxis);
-                                var worldMoveDirection = BABYLON.Vector3.TransformCoordinates(moveDirection, _this.attachedMesh.getWorldMatrix().getRotationMatrix());
-                                // Update scale and position
-                                _this.attachedMesh.scaling.addInPlace(deltaScale);
-                                if (_this.attachedMesh.scaling.x < 0 || _this.attachedMesh.scaling.y < 0 || _this.attachedMesh.scaling.z < 0) {
-                                    _this.attachedMesh.scaling.subtractInPlace(deltaScale);
-                                }
-                                else {
-                                    _this.attachedMesh.getAbsolutePosition().addToRef(worldMoveDirection, _this._tmpVector);
-                                    _this.attachedMesh.setAbsolutePosition(_this._tmpVector);
+                                _this._updateBoundingBox();
+                                // Scale from the position of the opposite corner                   
+                                box.absolutePosition.subtractToRef(_this._anchorMesh.position, _this._tmpVector);
+                                _this._anchorMesh.position.subtractInPlace(_this._tmpVector);
+                                _this._anchorMesh.addChild(_this.attachedMesh);
+                                _this._anchorMesh.scaling.addInPlace(deltaScale);
+                                if (_this._anchorMesh.scaling.x < 0 || _this._anchorMesh.scaling.y < 0 || _this._anchorMesh.scaling.z < 0) {
+                                    _this._anchorMesh.scaling.subtractInPlace(deltaScale);
                                 }
+                                _this._anchorMesh.removeChild(_this.attachedMesh);
                             }
                         });
                         // Selection/deselection
@@ -90945,19 +90950,57 @@ var BABYLON;
             _this._updateBoundingBox();
             return _this;
         }
+        BoundingBoxGizmo.prototype._attachedMeshChanged = function (value) {
+            if (value) {
+                // Reset anchor mesh to match attached mesh's scale
+                // This is needed to avoid invalid box/sphere position on first drag
+                this._anchorMesh.addChild(value);
+                this._anchorMesh.removeChild(value);
+                this._updateBoundingBox();
+            }
+        };
         BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
             this._rotateSpheresParent.getChildMeshes()
                 .concat(this._scaleBoxesParent.getChildMeshes()).forEach(function (m, i) {
                 m.isVisible = (!selectedMesh || m == selectedMesh);
             });
         };
+        BoundingBoxGizmo.prototype._recurseComputeWorld = function (mesh) {
+            var _this = this;
+            mesh.computeWorldMatrix(true);
+            mesh.getChildMeshes().forEach(function (m) {
+                _this._recurseComputeWorld(m);
+            });
+        };
         BoundingBoxGizmo.prototype._updateBoundingBox = function () {
             if (this.attachedMesh) {
-                // Update bounding dimensions/positions
-                var boundingInfo = this.attachedMesh.getBoundingInfo().boundingBox;
-                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(this.attachedMesh.scaling);
-                this._boundingDimensions.copyFrom(boundBoxDimensions);
+                // Rotate based on axis
+                if (!this.attachedMesh.rotationQuaternion) {
+                    this.attachedMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.attachedMesh.rotation.y, this.attachedMesh.rotation.x, this.attachedMesh.rotation.z);
+                }
+                if (!this._anchorMesh.rotationQuaternion) {
+                    this._anchorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this._anchorMesh.rotation.y, this._anchorMesh.rotation.x, this._anchorMesh.rotation.z);
+                }
+                this._anchorMesh.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                // Store original position and reset mesh to origin before computing the bounding box
+                this._tmpQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                this._tmpVector.copyFrom(this.attachedMesh.position);
+                this.attachedMesh.rotationQuaternion.set(0, 0, 0, 1);
+                this.attachedMesh.position.set(0, 0, 0);
+                // Update bounding dimensions/positions   
+                var boundingMinMax = this.attachedMesh.getHierarchyBoundingVectors();
+                boundingMinMax.max.subtractToRef(boundingMinMax.min, this._boundingDimensions);
+                // Update gizmo to match bounding box scaling and rotation
                 this._lineBoundingBox.scaling.copyFrom(this._boundingDimensions);
+                this._lineBoundingBox.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
+                this._rotateSpheresParent.position.copyFrom(this._lineBoundingBox.position);
+                this._scaleBoxesParent.position.copyFrom(this._lineBoundingBox.position);
+                this._lineBoundingBox.computeWorldMatrix();
+                this._anchorMesh.position.copyFrom(this._lineBoundingBox.absolutePosition);
+                // restore position/rotation values
+                this.attachedMesh.rotationQuaternion.copyFrom(this._tmpQuaternion);
+                this.attachedMesh.position.copyFrom(this._tmpVector);
+                this._recurseComputeWorld(this.attachedMesh);
             }
             // Update rotation sphere locations
             var rotateSpheres = this._rotateSpheresParent.getChildMeshes();
@@ -91041,6 +91084,42 @@ var BABYLON;
             this._scaleBoxesParent.dispose();
             _super.prototype.dispose.call(this);
         };
+        /**
+         * Makes a mesh not pickable and wraps the mesh inside of a bounding box mesh that is pickable. (This is useful to avoid picking within complex geometry)
+         * @param mesh the mesh to wrap in the bounding box mesh and make not pickable
+         * @returns the bounding box mesh with the passed in mesh as a child
+         */
+        BoundingBoxGizmo.MakeNotPickableAndWrapInBoundingBox = function (mesh) {
+            var makeNotPickable = function (root) {
+                root.isPickable = false;
+                root.getChildMeshes().forEach(function (c) {
+                    makeNotPickable(c);
+                });
+            };
+            makeNotPickable(mesh);
+            // Reset position to get boudning box from origin with no rotation
+            if (!mesh.rotationQuaternion) {
+                mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z);
+            }
+            var oldPos = mesh.position.clone();
+            var oldRot = mesh.rotationQuaternion.clone();
+            mesh.rotationQuaternion.set(0, 0, 0, 1);
+            mesh.position.set(0, 0, 0);
+            // Update bounding dimensions/positions   
+            var box = BABYLON.MeshBuilder.CreateBox("box", { size: 1 }, mesh.getScene());
+            var boundingMinMax = mesh.getHierarchyBoundingVectors();
+            boundingMinMax.max.subtractToRef(boundingMinMax.min, box.scaling);
+            box.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
+            // Restore original positions
+            mesh.addChild(box);
+            mesh.rotationQuaternion.copyFrom(oldRot);
+            mesh.position.copyFrom(oldPos);
+            // Reverse parenting
+            mesh.removeChild(box);
+            box.addChild(mesh);
+            box.visibility = 0;
+            return box;
+        };
         return BoundingBoxGizmo;
     }(BABYLON.Gizmo));
     BABYLON.BoundingBoxGizmo = BoundingBoxGizmo;
@@ -93829,7 +93908,7 @@ var BABYLON;
                     this._enableInteractionOnController(this.rightController);
                 }
                 this.raySelectionPredicate = function (mesh) {
-                    return mesh.isVisible;
+                    return mesh.isVisible && mesh.isPickable;
                 };
                 this.meshSelectionPredicate = function (mesh) {
                     return true;

Fichier diff supprimé car celui-ci est trop grand
+ 15 - 15
dist/preview release/viewer/babylon.viewer.js


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

@@ -89626,7 +89626,6 @@ var BABYLON;
          * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)
          */
         function PointerDragBehavior(options) {
-            this.options = options;
             /**
              * The maximum tolerated angle between the drag plane and dragging pointer rays to trigger pointer events. Set to 0 to allow any angle (default: 0)
              */
@@ -89693,14 +89692,12 @@ var BABYLON;
             this._lineB = new BABYLON.Vector3(0, 0, 0);
             this._localAxis = new BABYLON.Vector3(0, 0, 0);
             this._lookAt = new BABYLON.Vector3(0, 0, 0);
+            this._options = options ? options : {};
             var optionCount = 0;
-            if (options === undefined) {
-                options = {};
-            }
-            if (options.dragAxis) {
+            if (this._options.dragAxis) {
                 optionCount++;
             }
-            if (options.dragPlaneNormal) {
+            if (this._options.dragPlaneNormal) {
                 optionCount++;
             }
             if (optionCount > 1) {
@@ -89779,9 +89776,9 @@ var BABYLON;
                                 _this._updateDragPlanePosition(pointerInfo.pickInfo.ray, pickedPoint);
                             }
                             // depending on the drag mode option drag accordingly
-                            if (_this.options.dragAxis) {
+                            if (_this._options.dragAxis) {
                                 // Convert local drag axis to world
-                                BABYLON.Vector3.TransformCoordinatesToRef(_this.options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix(), _this._worldDragAxis);
+                                BABYLON.Vector3.TransformCoordinatesToRef(_this._options.dragAxis, _this._attachedNode.getWorldMatrix().getRotationMatrix(), _this._worldDragAxis);
                                 // Project delta drag from the drag plane onto the drag axis
                                 pickedPoint.subtractToRef(_this.lastDragPosition, _this._tmpVector);
                                 dragLength = BABYLON.Vector3.Dot(_this._tmpVector, _this._worldDragAxis);
@@ -89856,8 +89853,8 @@ var BABYLON;
         // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
         PointerDragBehavior.prototype._updateDragPlanePosition = function (ray, dragPlanePosition) {
             this._pointA.copyFrom(dragPlanePosition);
-            if (this.options.dragAxis) {
-                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this.options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragAxis);
+            if (this._options.dragAxis) {
+                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this._options.dragAxis, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragAxis);
                 // Calculate plane normal in direction of camera but perpendicular to drag axis
                 this._pointA.addToRef(this._localAxis, this._pointB); // towards drag axis
                 ray.origin.subtractToRef(this._pointA, this._pointC);
@@ -89873,8 +89870,8 @@ var BABYLON;
                 this._pointA.subtractToRef(this._lookAt, this._lookAt);
                 this._dragPlane.lookAt(this._lookAt);
             }
-            else if (this.options.dragPlaneNormal) {
-                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this.options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this.options.dragPlaneNormal);
+            else if (this._options.dragPlaneNormal) {
+                this.useObjectOrienationForDragging ? BABYLON.Vector3.TransformCoordinatesToRef(this._options.dragPlaneNormal, this._attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragPlaneNormal);
                 this._dragPlane.position.copyFrom(this._pointA);
                 this._pointA.subtractToRef(this._localAxis, this._lookAt);
                 this._dragPlane.lookAt(this._lookAt);
@@ -90015,9 +90012,9 @@ var BABYLON;
             this._moving = false;
             this._startingOrientation = new BABYLON.Quaternion();
             /**
-             * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 5)
+             * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 3)
              */
-            this.zDragFactor = 5;
+            this.zDragFactor = 3;
             /**
              * If the behavior is currently in a dragging state
              */
@@ -90070,7 +90067,10 @@ var BABYLON;
             this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
                 if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
                     if (!_this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)) {
-                        pickedMesh = pointerInfo.pickInfo.pickedMesh;
+                        if (_this._scene.activeCamera && _this._scene.activeCamera.cameraRigMode == BABYLON.Camera.RIG_MODE_NONE) {
+                            pointerInfo.pickInfo.ray.origin.copyFrom(_this._scene.activeCamera.position);
+                        }
+                        pickedMesh = _this._ownerNode;
                         lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
                         // Set position and orientation of the controller
                         _this._virtualOriginMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);
@@ -90103,14 +90103,18 @@ var BABYLON;
                 }
                 else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
                     if (_this.currentDraggingPointerID == pointerInfo.event.pointerId && _this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray && pickedMesh) {
+                        var zDragFactor = _this.zDragFactor;
+                        if (_this._scene.activeCamera && _this._scene.activeCamera.cameraRigMode == BABYLON.Camera.RIG_MODE_NONE) {
+                            pointerInfo.pickInfo.ray.origin.copyFrom(_this._scene.activeCamera.position);
+                            zDragFactor = 0;
+                        }
                         // Calculate controller drag distance in controller space
                         var originDragDifference = pointerInfo.pickInfo.ray.origin.subtract(lastSixDofOriginPosition);
                         lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
-                        var localOriginDragDifference = BABYLON.Vector3.TransformCoordinates(originDragDifference, BABYLON.Matrix.Invert(_this._virtualOriginMesh.getWorldMatrix().getRotationMatrix()));
+                        var localOriginDragDifference = -BABYLON.Vector3.Dot(originDragDifference, pointerInfo.pickInfo.ray.direction);
                         _this._virtualOriginMesh.addChild(_this._virtualDragMesh);
                         // Determine how much the controller moved to/away towards the dragged object and use this to move the object further when its further away
-                        var zDragDistance = BABYLON.Vector3.Dot(localOriginDragDifference, _this._virtualOriginMesh.position.normalizeToNew());
-                        _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? zDragDistance * _this.zDragFactor : zDragDistance * _this.zDragFactor * _this._virtualDragMesh.position.z;
+                        _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? localOriginDragDifference * _this.zDragFactor : localOriginDragDifference * zDragFactor * _this._virtualDragMesh.position.z;
                         if (_this._virtualDragMesh.position.z < 0) {
                             _this._virtualDragMesh.position.z = 0;
                         }
@@ -90894,6 +90898,7 @@ var BABYLON;
             _this.onDragEndObservable = new BABYLON.Observable();
             // Do not update the gizmo's scale so it has a fixed size to the object its attached to
             _this._updateScale = false;
+            _this._anchorMesh = new BABYLON.AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
             // Create Materials
             var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
             coloredMaterial.disableLighting = true;
@@ -90955,6 +90960,9 @@ var BABYLON;
                         if (!_this.attachedMesh.rotationQuaternion) {
                             _this.attachedMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this.attachedMesh.rotation.y, _this.attachedMesh.rotation.x, _this.attachedMesh.rotation.z);
                         }
+                        if (!_this._anchorMesh.rotationQuaternion) {
+                            _this._anchorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(_this._anchorMesh.rotation.y, _this._anchorMesh.rotation.x, _this._anchorMesh.rotation.z);
+                        }
                         // Do not allow the object to turn more than a full circle
                         totalTurnAmountOfDrag += projectDist;
                         if (Math.abs(totalTurnAmountOfDrag) <= 2 * Math.PI) {
@@ -90967,7 +90975,10 @@ var BABYLON;
                             else {
                                 BABYLON.Quaternion.RotationYawPitchRollToRef(0, projectDist, 0, _this._tmpQuaternion);
                             }
-                            _this.attachedMesh.rotationQuaternion.multiplyInPlace(_this._tmpQuaternion);
+                            // Rotate around center of bounding box
+                            _this._anchorMesh.addChild(_this.attachedMesh);
+                            _this._anchorMesh.rotationQuaternion.multiplyToRef(_this._tmpQuaternion, _this._anchorMesh.rotationQuaternion);
+                            _this._anchorMesh.removeChild(_this.attachedMesh);
                         }
                     }
                 });
@@ -91003,24 +91014,18 @@ var BABYLON;
                         _dragBehavior.onDragObservable.add(function (event) {
                             _this.onDragObservable.notifyObservers({});
                             if (_this.attachedMesh) {
-                                // Current boudning box dimensions
-                                var boundingInfo = _this.attachedMesh.getBoundingInfo().boundingBox;
-                                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(_this.attachedMesh.scaling);
-                                // Get the change in bounding box size/2 and add this to the mesh's position to offset from scaling with center pivot point
                                 var deltaScale = new BABYLON.Vector3(event.dragDistance, event.dragDistance, event.dragDistance);
                                 deltaScale.scaleInPlace(_this._scaleDragSpeed);
-                                var scaleRatio = deltaScale.divide(_this.attachedMesh.scaling).scaleInPlace(0.5);
-                                var moveDirection = boundBoxDimensions.multiply(scaleRatio).multiplyInPlace(dragAxis);
-                                var worldMoveDirection = BABYLON.Vector3.TransformCoordinates(moveDirection, _this.attachedMesh.getWorldMatrix().getRotationMatrix());
-                                // Update scale and position
-                                _this.attachedMesh.scaling.addInPlace(deltaScale);
-                                if (_this.attachedMesh.scaling.x < 0 || _this.attachedMesh.scaling.y < 0 || _this.attachedMesh.scaling.z < 0) {
-                                    _this.attachedMesh.scaling.subtractInPlace(deltaScale);
-                                }
-                                else {
-                                    _this.attachedMesh.getAbsolutePosition().addToRef(worldMoveDirection, _this._tmpVector);
-                                    _this.attachedMesh.setAbsolutePosition(_this._tmpVector);
+                                _this._updateBoundingBox();
+                                // Scale from the position of the opposite corner                   
+                                box.absolutePosition.subtractToRef(_this._anchorMesh.position, _this._tmpVector);
+                                _this._anchorMesh.position.subtractInPlace(_this._tmpVector);
+                                _this._anchorMesh.addChild(_this.attachedMesh);
+                                _this._anchorMesh.scaling.addInPlace(deltaScale);
+                                if (_this._anchorMesh.scaling.x < 0 || _this._anchorMesh.scaling.y < 0 || _this._anchorMesh.scaling.z < 0) {
+                                    _this._anchorMesh.scaling.subtractInPlace(deltaScale);
                                 }
+                                _this._anchorMesh.removeChild(_this.attachedMesh);
                             }
                         });
                         // Selection/deselection
@@ -91066,19 +91071,57 @@ var BABYLON;
             _this._updateBoundingBox();
             return _this;
         }
+        BoundingBoxGizmo.prototype._attachedMeshChanged = function (value) {
+            if (value) {
+                // Reset anchor mesh to match attached mesh's scale
+                // This is needed to avoid invalid box/sphere position on first drag
+                this._anchorMesh.addChild(value);
+                this._anchorMesh.removeChild(value);
+                this._updateBoundingBox();
+            }
+        };
         BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
             this._rotateSpheresParent.getChildMeshes()
                 .concat(this._scaleBoxesParent.getChildMeshes()).forEach(function (m, i) {
                 m.isVisible = (!selectedMesh || m == selectedMesh);
             });
         };
+        BoundingBoxGizmo.prototype._recurseComputeWorld = function (mesh) {
+            var _this = this;
+            mesh.computeWorldMatrix(true);
+            mesh.getChildMeshes().forEach(function (m) {
+                _this._recurseComputeWorld(m);
+            });
+        };
         BoundingBoxGizmo.prototype._updateBoundingBox = function () {
             if (this.attachedMesh) {
-                // Update bounding dimensions/positions
-                var boundingInfo = this.attachedMesh.getBoundingInfo().boundingBox;
-                var boundBoxDimensions = boundingInfo.maximum.subtract(boundingInfo.minimum).multiplyInPlace(this.attachedMesh.scaling);
-                this._boundingDimensions.copyFrom(boundBoxDimensions);
+                // Rotate based on axis
+                if (!this.attachedMesh.rotationQuaternion) {
+                    this.attachedMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.attachedMesh.rotation.y, this.attachedMesh.rotation.x, this.attachedMesh.rotation.z);
+                }
+                if (!this._anchorMesh.rotationQuaternion) {
+                    this._anchorMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this._anchorMesh.rotation.y, this._anchorMesh.rotation.x, this._anchorMesh.rotation.z);
+                }
+                this._anchorMesh.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                // Store original position and reset mesh to origin before computing the bounding box
+                this._tmpQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
+                this._tmpVector.copyFrom(this.attachedMesh.position);
+                this.attachedMesh.rotationQuaternion.set(0, 0, 0, 1);
+                this.attachedMesh.position.set(0, 0, 0);
+                // Update bounding dimensions/positions   
+                var boundingMinMax = this.attachedMesh.getHierarchyBoundingVectors();
+                boundingMinMax.max.subtractToRef(boundingMinMax.min, this._boundingDimensions);
+                // Update gizmo to match bounding box scaling and rotation
                 this._lineBoundingBox.scaling.copyFrom(this._boundingDimensions);
+                this._lineBoundingBox.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
+                this._rotateSpheresParent.position.copyFrom(this._lineBoundingBox.position);
+                this._scaleBoxesParent.position.copyFrom(this._lineBoundingBox.position);
+                this._lineBoundingBox.computeWorldMatrix();
+                this._anchorMesh.position.copyFrom(this._lineBoundingBox.absolutePosition);
+                // restore position/rotation values
+                this.attachedMesh.rotationQuaternion.copyFrom(this._tmpQuaternion);
+                this.attachedMesh.position.copyFrom(this._tmpVector);
+                this._recurseComputeWorld(this.attachedMesh);
             }
             // Update rotation sphere locations
             var rotateSpheres = this._rotateSpheresParent.getChildMeshes();
@@ -91162,6 +91205,42 @@ var BABYLON;
             this._scaleBoxesParent.dispose();
             _super.prototype.dispose.call(this);
         };
+        /**
+         * Makes a mesh not pickable and wraps the mesh inside of a bounding box mesh that is pickable. (This is useful to avoid picking within complex geometry)
+         * @param mesh the mesh to wrap in the bounding box mesh and make not pickable
+         * @returns the bounding box mesh with the passed in mesh as a child
+         */
+        BoundingBoxGizmo.MakeNotPickableAndWrapInBoundingBox = function (mesh) {
+            var makeNotPickable = function (root) {
+                root.isPickable = false;
+                root.getChildMeshes().forEach(function (c) {
+                    makeNotPickable(c);
+                });
+            };
+            makeNotPickable(mesh);
+            // Reset position to get boudning box from origin with no rotation
+            if (!mesh.rotationQuaternion) {
+                mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z);
+            }
+            var oldPos = mesh.position.clone();
+            var oldRot = mesh.rotationQuaternion.clone();
+            mesh.rotationQuaternion.set(0, 0, 0, 1);
+            mesh.position.set(0, 0, 0);
+            // Update bounding dimensions/positions   
+            var box = BABYLON.MeshBuilder.CreateBox("box", { size: 1 }, mesh.getScene());
+            var boundingMinMax = mesh.getHierarchyBoundingVectors();
+            boundingMinMax.max.subtractToRef(boundingMinMax.min, box.scaling);
+            box.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
+            // Restore original positions
+            mesh.addChild(box);
+            mesh.rotationQuaternion.copyFrom(oldRot);
+            mesh.position.copyFrom(oldPos);
+            // Reverse parenting
+            mesh.removeChild(box);
+            box.addChild(mesh);
+            box.visibility = 0;
+            return box;
+        };
         return BoundingBoxGizmo;
     }(BABYLON.Gizmo));
     BABYLON.BoundingBoxGizmo = BoundingBoxGizmo;
@@ -93950,7 +94029,7 @@ var BABYLON;
                     this._enableInteractionOnController(this.rightController);
                 }
                 this.raySelectionPredicate = function (mesh) {
-                    return mesh.isVisible;
+                    return mesh.isVisible && mesh.isPickable;
                 };
                 this.meshSelectionPredicate = function (mesh) {
                     return true;