Explorar el Código

do not remove parent when adding bounding box

Trevor Baron hace 6 años
padre
commit
7c23af8834

+ 2 - 1
dist/preview release/what's new.md

@@ -131,7 +131,8 @@
 - Update physics position using absolutePosition instead of pivotPosition ([TrevorDev](https://github.com/TrevorDev))
 - Disable camera arrow key controls when the Command key is selected on Mac OS ([kcoley](https://github.com/kcoley))
 - Viewer should not set receiveShadows on an instanced mesh ([TrevorDev](https://github.com/TrevorDev))
-- Updated comment in TransformNode.rotationQuaternion to include undefined as one of the potential return values ([nathankmiller](https://github.com/nathankmiller))
+- Updated comment in TransformNode.rotationQuaternion to include undefined as one of the potential return values ([nathankmiller](https://github.com/nathankmiller)
+- Attaching a BoundingBoxGizmo on a child should not remove its parent ([TrevorDev](https://github.com/TrevorDev)))
 
 ### Core Engine
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))

+ 8 - 4
src/Behaviors/Mesh/babylon.sixDofDragBehavior.ts

@@ -208,11 +208,15 @@ module BABYLON {
                         tmpQuaternion.multiplyToRef(this._startingOrientation, tmpQuaternion);
                         // Slowly move mesh to avoid jitter
                         var oldParent = pickedMesh.parent;
-                        pickedMesh.setParent(null);
-                        Quaternion.SlerpToRef(pickedMesh.rotationQuaternion!, tmpQuaternion, this.dragDeltaRatio, pickedMesh.rotationQuaternion!);
-                        pickedMesh.setParent(oldParent);
-                        BoundingBoxGizmo._RestorePivotPoint(pickedMesh);
+
+                        // Only rotate the mesh if it's parent has uniform scaling
+                        if (!oldParent || ((oldParent as Mesh).scaling && !BoundingBoxGizmo._isNonUniform((oldParent as Mesh).scaling))) {
+                            pickedMesh.setParent(null);
+                            Quaternion.SlerpToRef(pickedMesh.rotationQuaternion!, tmpQuaternion, this.dragDeltaRatio, pickedMesh.rotationQuaternion!);
+                            pickedMesh.setParent(oldParent);
+                        }
                     }
+                    BoundingBoxGizmo._RestorePivotPoint(pickedMesh);
                 }
             });
         }

+ 54 - 1
src/Gizmos/babylon.boundingBoxGizmo.ts

@@ -106,6 +106,30 @@ module BABYLON {
         }
 
         /**
+         * @hidden
+         * Due to float precisiion, scale of a mesh may be uniform but float values are off by a small fraction
+         * Check if uniform within 3 decimal places to account for this
+         */
+        public static _isNonUniform(vec: Vector3) {
+            let absX = Math.abs(Math.round(vec.x * 1000) / 1000);
+            let absY = Math.abs(Math.round(vec.y * 1000) / 1000);
+            if (absX !== absY) {
+                return true;
+            }
+
+            let absZ = Math.abs(Math.round(vec.z * 1000) / 1000);
+            if (absX !== absZ) {
+                return true;
+            }
+
+            if (absY !== absZ) {
+                return true;
+            }
+
+            return false;
+        }
+
+        /**
          * Creates an BoundingBoxGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
          * @param color The color of the gizmo
@@ -171,6 +195,11 @@ module BABYLON {
                 _dragBehavior.onDragObservable.add((event) => {
                     this.onRotationSphereDragObservable.notifyObservers({});
                     if (this.attachedMesh) {
+                        var originalParent = this.attachedMesh.parent;
+                        if (originalParent && ((originalParent as Mesh).scaling && BoundingBoxGizmo._isNonUniform((originalParent as Mesh).scaling))) {
+                            Tools.Warn("BoundingBoxGizmo controls are not supported on child meshes with non-uniform parent scaling");
+                            return;
+                        }
                         BoundingBoxGizmo._RemoveAndStorePivotPoint(this.attachedMesh);
 
                         var worldDragDirection = startingTurnDirection;
@@ -208,6 +237,7 @@ module BABYLON {
                             this._anchorMesh.addChild(this.attachedMesh);
                             this._anchorMesh.rotationQuaternion!.multiplyToRef(this._tmpQuaternion, this._anchorMesh.rotationQuaternion!);
                             this._anchorMesh.removeChild(this.attachedMesh);
+                            this.attachedMesh.setParent(originalParent);
                         }
                         this.updateBoundingBox();
 
@@ -248,6 +278,11 @@ module BABYLON {
                         _dragBehavior.onDragObservable.add((event) => {
                             this.onScaleBoxDragObservable.notifyObservers({});
                             if (this.attachedMesh) {
+                                var originalParent = this.attachedMesh.parent;
+                                if (originalParent && ((originalParent as Mesh).scaling && BoundingBoxGizmo._isNonUniform((originalParent as Mesh).scaling))) {
+                                    Tools.Warn("BoundingBoxGizmo controls are not supported on child meshes with non-uniform parent scaling");
+                                    return;
+                                }
                                 BoundingBoxGizmo._RemoveAndStorePivotPoint(this.attachedMesh);
                                 var relativeDragDistance = (event.dragDistance / this._boundingDimensions.length()) * this._anchorMesh.scaling.length();
                                 var deltaScale = new Vector3(relativeDragDistance, relativeDragDistance, relativeDragDistance);
@@ -274,7 +309,7 @@ module BABYLON {
                                     this._anchorMesh.scaling.subtractInPlace(deltaScale);
                                 }
                                 this._anchorMesh.removeChild(this.attachedMesh);
-
+                                this.attachedMesh.setParent(originalParent);
                                 BoundingBoxGizmo._RestorePivotPoint(this.attachedMesh);
                             }
                             this._updateDummy();
@@ -339,10 +374,15 @@ module BABYLON {
                 // Reset anchor mesh to match attached mesh's scale
                 // This is needed to avoid invalid box/sphere position on first drag
                 BoundingBoxGizmo._RemoveAndStorePivotPoint(value);
+                var originalParent = value.parent;
                 this._anchorMesh.addChild(value);
                 this._anchorMesh.removeChild(value);
+                value.setParent(originalParent);
                 BoundingBoxGizmo._RestorePivotPoint(value);
                 this.updateBoundingBox();
+                value.getChildMeshes(false).forEach((m) => {
+                    m.markAsDirty("scaling");
+                });
 
                 this.gizmoLayer.utilityLayerScene.onAfterRenderObservable.addOnce(() => {
                     this._updateDummy();
@@ -363,6 +403,8 @@ module BABYLON {
         public updateBoundingBox() {
             if (this.attachedMesh) {
                 BoundingBoxGizmo._RemoveAndStorePivotPoint(this.attachedMesh);
+                var originalParent = this.attachedMesh.parent;
+                this.attachedMesh.setParent(null);
                 this._update();
                 // Rotate based on axis
                 if (!this.attachedMesh.rotationQuaternion) {
@@ -394,6 +436,7 @@ module BABYLON {
                 // restore position/rotation values
                 this.attachedMesh.rotationQuaternion.copyFrom(this._tmpQuaternion);
                 this.attachedMesh.position.copyFrom(this._tmpVector);
+                this.attachedMesh.setParent(originalParent);
             }
 
             this._updateRotationSpheres();
@@ -476,6 +519,16 @@ module BABYLON {
             });
         }
 
+        /**
+         * Enables/disables scaling
+         * @param enable if scaling should be enabled
+         */
+        public setEnabledScaling(enable: boolean) {
+            this._scaleBoxesParent.getChildMeshes().forEach((m, i) => {
+                m.setEnabled(enable);
+            });
+        }
+
         private _updateDummy() {
             if (this._dragMesh) {
                 this._dragMesh.position.copyFrom(this._lineBoundingBox.getAbsolutePosition());