Selaa lähdekoodia

Merge pull request #4770 from TrevorDev/utilityLayerFixes

Utility layer fixes
David Catuhe 7 vuotta sitten
vanhempi
commit
17de25b83f

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

@@ -25,7 +25,7 @@
   - Added support for life time gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#lifetime)
   - Added support for angular speed gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#rotation)
   - Added support for noise textures. [Doc](http://doc.babylonjs.com/babylon101/particles#noise-texture)
-- Added SceneComponent to help decoupling Scene from its components ([sebavan](http://www.github.com/sebavan))
+- Added SceneComponent to help decoupling Scene from its components. ([sebavan](http://www.github.com/sebavan))
 - Playground can now be used with TypeScript directly!. [Demo](https://www.babylonjs-playground.com/ts.html) ([Deltakosh](https://github.com/deltakosh), [NasimiAsl](https://github.com/NasimiAsl))
 - New GUI control: [InputPassword](https://doc.babylonjs.com/how_to/gui#inputpassword) ([theom](https://github.com/theom))
 - Added dead key support and before key add observable to InputText. [Doc](https://doc.babylonjs.com/how_to/gui#using-onbeforekeyaddobservable-for-extended-keyboard-layouts-and-input-masks)([theom](https://github.com/theom))

+ 26 - 15
src/Gizmos/babylon.boundingBoxGizmo.ts

@@ -119,6 +119,9 @@ module BABYLON {
 
                         // project drag delta on to the resulting drag axis and rotate based on that
                         var projectDist = -Vector3.Dot(dragAxis, event.delta);
+                        
+                        // Make rotation relative to size of mesh.
+                        projectDist = (projectDist / this._boundingDimensions.length())*this._anchorMesh.scaling.length();
 
                         // Rotate based on axis
                         if (!this.attachedMesh.rotationQuaternion) {
@@ -178,8 +181,9 @@ module BABYLON {
                         box.addBehavior(_dragBehavior);
                         _dragBehavior.onDragObservable.add((event) => {
                             this.onDragObservable.notifyObservers({});
-                            if (this.attachedMesh) {
-                                var deltaScale = new Vector3(event.dragDistance, event.dragDistance, event.dragDistance);
+                            if(this.attachedMesh){
+                                var relativeDragDistance = (event.dragDistance / this._boundingDimensions.length())*this._anchorMesh.scaling.length();
+                                var deltaScale = new Vector3(relativeDragDistance,relativeDragDistance,relativeDragDistance);
                                 deltaScale.scaleInPlace(this._scaleDragSpeed);
                                 this.updateBoundingBox();
 
@@ -266,8 +270,9 @@ module BABYLON {
         /**
          * Updates the bounding box information for the Gizmo
          */
-        public updateBoundingBox() {
-            if (this.attachedMesh) {
+        public updateBoundingBox(){
+            this._update();
+            if(this.attachedMesh){             
                 // Rotate based on axis
                 if (!this.attachedMesh.rotationQuaternion) {
                     this.attachedMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(this.attachedMesh.rotation.y, this.attachedMesh.rotation.x, this.attachedMesh.rotation.z);
@@ -300,7 +305,7 @@ module BABYLON {
                 this.attachedMesh.position.copyFrom(this._tmpVector);
                 this._recurseComputeWorld(this.attachedMesh);
             }
-
+            
             // Update rotation sphere locations
             var rotateSpheres = this._rotateSpheresParent.getChildMeshes();
             for (var i = 0; i < 3; i++) {
@@ -322,7 +327,10 @@ module BABYLON {
                             rotateSpheres[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
                             rotateSpheres[index].lookAt(Vector3.Cross(Vector3.Forward(), rotateSpheres[index].position.normalizeToNew()).normalizeToNew().add(rotateSpheres[index].position));
                         }
-                        if (this.fixedDragMeshScreenSize) {
+                        if(this.fixedDragMeshScreenSize){
+                            this._rootMesh.computeWorldMatrix();
+                            this._rotateSpheresParent.computeWorldMatrix();
+                            rotateSpheres[index].computeWorldMatrix();
                             rotateSpheres[index].absolutePosition.subtractToRef(this.gizmoLayer.utilityLayerScene.activeCamera!.position, this._tmpVector);
                             var distanceFromCamera = this.rotationSphereSize * this._tmpVector.length() / this.fixedDragMeshScreenSizeDistanceFactor;
                             rotateSpheres[index].scaling.set(distanceFromCamera, distanceFromCamera, distanceFromCamera);
@@ -332,17 +340,20 @@ module BABYLON {
                     }
                 }
             }
-
+            
             // Update scale box locations
             var scaleBoxes = this._scaleBoxesParent.getChildMeshes();
-            for (var i = 0; i < 2; i++) {
-                for (var j = 0; j < 2; j++) {
-                    for (var k = 0; k < 2; k++) {
-                        var index = ((i * 4) + (j * 2)) + k;
-                        if (scaleBoxes[index]) {
-                            scaleBoxes[index].position.set(this._boundingDimensions.x * i, this._boundingDimensions.y * j, this._boundingDimensions.z * k);
-                            scaleBoxes[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
-                            if (this.fixedDragMeshScreenSize) {
+            for(var i=0;i<2;i++){
+                for(var j=0;j<2;j++){
+                    for(var k=0;k<2;k++){
+                        var index= ((i*4)+(j*2))+k;
+                        if(scaleBoxes[index]){
+                            scaleBoxes[index].position.set(this._boundingDimensions.x*i,this._boundingDimensions.y*j,this._boundingDimensions.z*k);
+                            scaleBoxes[index].position.addInPlace(new BABYLON.Vector3(-this._boundingDimensions.x/2,-this._boundingDimensions.y/2,-this._boundingDimensions.z/2));
+                            if(this.fixedDragMeshScreenSize){
+                                this._rootMesh.computeWorldMatrix();
+                                this._scaleBoxesParent.computeWorldMatrix();
+                                scaleBoxes[index].computeWorldMatrix();
                                 scaleBoxes[index].absolutePosition.subtractToRef(this.gizmoLayer.utilityLayerScene.activeCamera!.position, this._tmpVector);
                                 var distanceFromCamera = this.scaleBoxSize * this._tmpVector.length() / this.fixedDragMeshScreenSizeDistanceFactor;
                                 scaleBoxes[index].scaling.set(distanceFromCamera, distanceFromCamera, distanceFromCamera);

+ 42 - 33
src/Gizmos/babylon.gizmo.ts

@@ -66,46 +66,55 @@ module BABYLON {
          */
         constructor(/** The utility layer the gizmo will be added to */ public gizmoLayer:UtilityLayerRenderer=UtilityLayerRenderer.DefaultUtilityLayer){
             this._rootMesh = new BABYLON.Mesh("gizmoRootNode",gizmoLayer.utilityLayerScene);
-            var tempVector = new Vector3();
             this._beforeRenderObserver = this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.add(()=>{
-                if(this.attachedMesh){
-                    if(this.updateGizmoRotationToMatchAttachedMesh){
-                        if(!this._rootMesh.rotationQuaternion){
-                            this._rootMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(this._rootMesh.rotation.y, this._rootMesh.rotation.x, this._rootMesh.rotation.z);
-                        }
+                this._update();
+            })
+            this.attachedMesh = null;
+        }
+
+        private _tempVector = new Vector3();
+        /**
+         * @hidden
+         * Updates the gizmo to match the attached mesh's position/rotation
+         */
+        protected _update(){
+            if(this.attachedMesh){
+                if(this.updateGizmoRotationToMatchAttachedMesh){
+                    if(!this._rootMesh.rotationQuaternion){
+                        this._rootMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(this._rootMesh.rotation.y, this._rootMesh.rotation.x, this._rootMesh.rotation.z);
+                    }
 
-                        // Remove scaling before getting rotation matrix to get rotation matrix unmodified by scale
-                        tempVector.copyFrom(this.attachedMesh.scaling);
-                        if(this.attachedMesh.scaling.x < 0){
-                            this.attachedMesh.scaling.x *= -1;
-                        }
-                        if(this.attachedMesh.scaling.y < 0){
-                            this.attachedMesh.scaling.y *= -1;
-                        }
-                        if(this.attachedMesh.scaling.z < 0){
-                            this.attachedMesh.scaling.z *= -1;
-                        }
-                        this.attachedMesh.computeWorldMatrix().getRotationMatrixToRef(this._tmpMatrix);
-                        this.attachedMesh.scaling.copyFrom(tempVector);
-                        this.attachedMesh.computeWorldMatrix();
-                        Quaternion.FromRotationMatrixToRef(this._tmpMatrix, this._rootMesh.rotationQuaternion);
+                    // Remove scaling before getting rotation matrix to get rotation matrix unmodified by scale
+                    this._tempVector.copyFrom(this.attachedMesh.scaling);
+                    if(this.attachedMesh.scaling.x < 0){
+                        this.attachedMesh.scaling.x *= -1;
                     }
-                    if(this.updateGizmoPositionToMatchAttachedMesh){
-                        this._rootMesh.position.copyFrom(this.attachedMesh.absolutePosition);
+                    if(this.attachedMesh.scaling.y < 0){
+                        this.attachedMesh.scaling.y *= -1;
                     }
-                    if(this._updateScale && this.gizmoLayer.utilityLayerScene.activeCamera && this.attachedMesh){
-                        var cameraPosition = this.gizmoLayer.utilityLayerScene.activeCamera.position;
-                        if((<WebVRFreeCamera>this.gizmoLayer.utilityLayerScene.activeCamera).devicePosition){
-                            cameraPosition = (<WebVRFreeCamera>this.gizmoLayer.utilityLayerScene.activeCamera).devicePosition;
-                        }
-                        this._rootMesh.position.subtractToRef(cameraPosition, tempVector);
-                        var dist = tempVector.length()/this._scaleFactor;
-                        this._rootMesh.scaling.set(dist, dist, dist);
+                    if(this.attachedMesh.scaling.z < 0){
+                        this.attachedMesh.scaling.z *= -1;
                     }
+                    this.attachedMesh.computeWorldMatrix().getRotationMatrixToRef(this._tmpMatrix);
+                    this.attachedMesh.scaling.copyFrom(this._tempVector);
+                    this.attachedMesh.computeWorldMatrix();
+                    Quaternion.FromRotationMatrixToRef(this._tmpMatrix, this._rootMesh.rotationQuaternion);
                 }
-            })
-            this.attachedMesh = null;
+                if(this.updateGizmoPositionToMatchAttachedMesh){
+                    this._rootMesh.position.copyFrom(this.attachedMesh.absolutePosition);
+                }
+                if(this._updateScale && this.gizmoLayer.utilityLayerScene.activeCamera && this.attachedMesh){
+                    var cameraPosition = this.gizmoLayer.utilityLayerScene.activeCamera.position;
+                    if((<WebVRFreeCamera>this.gizmoLayer.utilityLayerScene.activeCamera).devicePosition){
+                        cameraPosition = (<WebVRFreeCamera>this.gizmoLayer.utilityLayerScene.activeCamera).devicePosition;
+                    }
+                    this._rootMesh.position.subtractToRef(cameraPosition, this._tempVector);
+                    var dist = this._tempVector.length()/this._scaleFactor;
+                    this._rootMesh.scaling.set(dist, dist, dist);
+                }
+            }
         }
+
         /**
          * Disposes of the gizmo
          */

+ 8 - 5
src/Rendering/babylon.utilityLayerRenderer.ts

@@ -72,11 +72,11 @@ module BABYLON {
             this.utilityLayerScene = new BABYLON.Scene(originalScene.getEngine());
             this.utilityLayerScene._allowPostProcessClear = false;
             originalScene.getEngine().scenes.pop();
-
+      
             // Detach controls on utility scene, events will be fired by logic below to handle picking priority
             this.utilityLayerScene.detachControl();
             this._originalPointerObserver = originalScene.onPrePointerObservable.add((prePointerInfo, eventState) => {
-
+                
                 if (!this.processAllEvents) {
                     if (prePointerInfo.type !== BABYLON.PointerEventTypes.POINTERMOVE
                         && prePointerInfo.type !== BABYLON.PointerEventTypes.POINTERUP
@@ -109,7 +109,7 @@ module BABYLON {
                     }
                     return;
                 }
-
+                
                 if(this.utilityLayerScene.autoClearDepthAndStencil){
                     // If this layer is an overlay, check if this layer was hit and if so, skip pointer events for the main scene
                     if(utilityScenePick && utilityScenePick.hit){
@@ -135,10 +135,13 @@ module BABYLON {
                             } else if (prePointerInfo.type === BABYLON.PointerEventTypes.POINTERDOWN) {
                                 this._pointerCaptures[pointerEvent.pointerId] = true;
                             } 
-                        } else if (!this._pointerCaptures[pointerEvent.pointerId] && (utilityScenePick.distance < originalScenePick.distance || originalScenePick.distance === 0)){
+                        } else if (!this._pointerCaptures[pointerEvent.pointerId] && (utilityScenePick.distance < originalScenePick.distance || originalScenePick.distance === 0)){  
                             // We pick something in utility scene or the pick in utility is closer than the one in main scene
                             this._notifyObservers(prePointerInfo, utilityScenePick, pointerEvent);
-                            prePointerInfo.skipOnPointerObservable = utilityScenePick.distance > 0;
+                            // If a previous utility layer set this, do not unset this
+                            if(!prePointerInfo.skipOnPointerObservable){
+                                prePointerInfo.skipOnPointerObservable = utilityScenePick.distance > 0;
+                            }
                         } else if (!this._pointerCaptures[pointerEvent.pointerId] && (utilityScenePick.distance > originalScenePick.distance)) {
                             // We have a pick in both scenes but main is closer than utility