瀏覽代碼

Merge pull request #4569 from TrevorDev/improveGizmoDefaultLook

Improve gizmo default look
Trevor Baron 7 年之前
父節點
當前提交
8b156f9533

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

@@ -43,8 +43,8 @@
 - AssetsManager tasks will only run when their state is INIT. It is now possible to remove a task from the assets manager ([RaananW](https://github.com/RaananW))
 - Added sprite isVisible field ([TrevorDev](https://github.com/TrevorDev))
 - EnvironmentHelper will recreate ground and skybox meshes if force-disposed ([RaananW](https://github.com/RaananW))
-- Added viewport caching mecanism in engine ([sebavan](http://www.github.com/sebavan))
-- Added unpackFlipY caching mecanism in engine ([sebavan](http://www.github.com/sebavan))
+- Added viewport caching mechanism in engine ([sebavan](http://www.github.com/sebavan))
+- Added unpackFlipY caching mechanism in engine ([sebavan](http://www.github.com/sebavan))
 - Added rebind optimization of video texture ([sebavan](http://www.github.com/sebavan))
 - Fix Background Material effect caching ([sebavan](http://www.github.com/sebavan))
 - Prevent texture ```getSize``` to generate garbage collection ([sebavan](http://www.github.com/sebavan))

+ 28 - 8
src/Gizmos/babylon.axisDragGizmo.ts

@@ -4,6 +4,7 @@ module BABYLON {
      */
     export class AxisDragGizmo extends Gizmo {
         private _dragBehavior:PointerDragBehavior;
+        private _pointerObserver:Nullable<Observer<PointerInfo>> = null;
         /**
          * Creates an AxisDragGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
@@ -12,31 +13,37 @@ module BABYLON {
          */
         constructor(gizmoLayer:UtilityLayerRenderer, dragAxis:Vector3, color:Color3){
             super(gizmoLayer);
-            this.updateGizmoRotationToMatchAttachedMesh = false;
             
             // Create Material
             var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
             coloredMaterial.disableLighting = true;
             coloredMaterial.emissiveColor = color;
 
+            var hoverMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            hoverMaterial.disableLighting = true;
+            hoverMaterial.emissiveColor = color.add(new Color3(0.2,0.2,0.2));
+
             // Build mesh on root node
+            var arrow = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
             var arrowMesh = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", {diameterTop:0, height: 2, tessellation: 96}, gizmoLayer.utilityLayerScene);
-            var arrowTail = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", {diameter:0.03, height: 0.2, tessellation: 96}, gizmoLayer.utilityLayerScene);
-            this._rootMesh.addChild(arrowMesh);
-            this._rootMesh.addChild(arrowTail);
+            var arrowTail = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", {diameter:0.015, height: 0.3, tessellation: 96}, gizmoLayer.utilityLayerScene);
+            arrow.addChild(arrowMesh);
+            arrow.addChild(arrowTail);
 
             // Position arrow pointing in its drag axis
-            arrowMesh.scaling.scaleInPlace(0.1);
+            arrowMesh.scaling.scaleInPlace(0.05);
             arrowMesh.material = coloredMaterial;
             arrowMesh.rotation.x = Math.PI/2;
             arrowMesh.position.z+=0.3;
             arrowTail.rotation.x = Math.PI/2;
             arrowTail.material = coloredMaterial;
-            arrowTail.position.z+=0.2;
-            this._rootMesh.lookAt(this._rootMesh.position.subtract(dragAxis));
+            arrowTail.position.z+=0.15;
+            arrow.lookAt(this._rootMesh.position.subtract(dragAxis));
+
+            this._rootMesh.addChild(arrow)
 
             // Add drag behavior to handle events when the gizmo is dragged
-            this._dragBehavior = new PointerDragBehavior({dragAxis: new BABYLON.Vector3(0,0,1)});
+            this._dragBehavior = new PointerDragBehavior({dragAxis: dragAxis});
             this._dragBehavior.moveAttached = false;
             this._rootMesh.addBehavior(this._dragBehavior);
             this._dragBehavior.onDragObservable.add((event)=>{
@@ -47,6 +54,18 @@ module BABYLON {
                     this.attachedMesh.position.addInPlace(event.delta);
                 }
             })
+
+            this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo, eventState)=>{
+                if(pointerInfo.pickInfo && (this._rootMesh.getChildMeshes().indexOf(<Mesh>pointerInfo.pickInfo.pickedMesh) != -1)){
+                    this._rootMesh.getChildMeshes().forEach((m)=>{
+                        m.material = hoverMaterial;
+                    });
+                }else{
+                    this._rootMesh.getChildMeshes().forEach((m)=>{
+                        m.material = coloredMaterial;
+                    });
+                }
+            });
         }
         protected _onInteractionsEnabledChanged(value:boolean){
             this._dragBehavior.enabled = value;
@@ -55,6 +74,7 @@ module BABYLON {
          * Disposes of the gizmo
          */
         public dispose(){
+            this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
             this._dragBehavior.detach();
             super.dispose();
         } 

+ 44 - 9
src/Gizmos/babylon.axisScaleGizmo.ts

@@ -4,6 +4,7 @@ module BABYLON {
      */
     export class AxisScaleGizmo extends Gizmo {
         private _dragBehavior:PointerDragBehavior;
+        private _pointerObserver:Nullable<Observer<PointerInfo>> = null;
         /**
          * Creates an AxisScaleGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
@@ -12,18 +13,22 @@ module BABYLON {
          */
         constructor(gizmoLayer:UtilityLayerRenderer, dragAxis:Vector3, color:Color3){
             super(gizmoLayer);
-            this.updateGizmoRotationToMatchAttachedMesh=false;
             
             // Create Material
             var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
             coloredMaterial.disableLighting = true;
             coloredMaterial.emissiveColor = color;
 
+            var hoverMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            hoverMaterial.disableLighting = true;
+            hoverMaterial.emissiveColor = color.add(new Color3(0.2,0.2,0.2));
+
             // Build mesh on root node
-            var arrowMesh = BABYLON.MeshBuilder.CreateBox("yPosMesh", {size: 1}, gizmoLayer.utilityLayerScene);
-            var arrowTail = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", {diameter:0.03, height: 0.2, tessellation: 96}, gizmoLayer.utilityLayerScene);
-            this._rootMesh.addChild(arrowMesh);
-            this._rootMesh.addChild(arrowTail);
+            var arrow = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene)
+            var arrowMesh = BABYLON.MeshBuilder.CreateBox("yPosMesh", {size: 0.5}, gizmoLayer.utilityLayerScene);
+            var arrowTail = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", {diameter:0.015, height: 0.3, tessellation: 96}, gizmoLayer.utilityLayerScene);
+            arrow.addChild(arrowMesh);
+            arrow.addChild(arrowTail);
 
             // Position arrow pointing in its drag axis
             arrowMesh.scaling.scaleInPlace(0.1);
@@ -32,22 +37,51 @@ module BABYLON {
             arrowMesh.position.z+=0.3;
             arrowTail.rotation.x = Math.PI/2;
             arrowTail.material = coloredMaterial;
-            arrowTail.position.z+=0.2;
-            this._rootMesh.lookAt(this._rootMesh.position.subtract(dragAxis));
+            arrowTail.position.z+=0.15;
+            arrow.lookAt(this._rootMesh.position.subtract(dragAxis));
+            this._rootMesh.addChild(arrow);
 
             // Add drag behavior to handle events when the gizmo is dragged
-            this._dragBehavior = new PointerDragBehavior({dragAxis: new BABYLON.Vector3(0,0,1)});
+            this._dragBehavior = new PointerDragBehavior({dragAxis: dragAxis});
             this._dragBehavior.moveAttached = false;
             this._rootMesh.addBehavior(this._dragBehavior);
 
+            var tmpVector = new Vector3();
             this._dragBehavior.onDragObservable.add((event)=>{
                 if(!this.interactionsEnabled){
                     return;
                 }
                 if(this.attachedMesh){
-                    this.attachedMesh.scaling.addInPlace(event.delta);
+                    dragAxis.scaleToRef(event.dragDistance, tmpVector);
+                    var invertCount = 0;
+                    if(this.attachedMesh.scaling["x"] < 0){
+                        invertCount++;
+                    }
+                    if(this.attachedMesh.scaling["y"] < 0){
+                        invertCount++;
+                    }
+                    if(this.attachedMesh.scaling["z"] < 0){
+                        invertCount++;
+                    }
+                    if(invertCount % 2 == 0){
+                        this.attachedMesh.scaling.addInPlace(tmpVector);
+                    }else{
+                        this.attachedMesh.scaling.subtractInPlace(tmpVector);
+                    }
                 }
             })
+
+            this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo, eventState)=>{
+                if(pointerInfo.pickInfo && (this._rootMesh.getChildMeshes().indexOf(<Mesh>pointerInfo.pickInfo.pickedMesh) != -1)){
+                    this._rootMesh.getChildMeshes().forEach((m)=>{
+                        m.material = hoverMaterial;
+                    });
+                }else{
+                    this._rootMesh.getChildMeshes().forEach((m)=>{
+                        m.material = coloredMaterial;
+                    });
+                }
+            });
         }
         
         protected _onInteractionsEnabledChanged(value:boolean){
@@ -58,6 +92,7 @@ module BABYLON {
          * Disposes of the gizmo
          */
         public dispose(){
+            this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
             this._dragBehavior.detach();
             super.dispose();
         } 

+ 41 - 13
src/Gizmos/babylon.planeRotationGizmo.ts

@@ -4,6 +4,7 @@ module BABYLON {
      */
     export class PlaneRotationGizmo extends Gizmo {
         private _dragBehavior:PointerDragBehavior;
+        private _pointerObserver:Nullable<Observer<PointerInfo>> = null;
         /**
          * Creates a PlaneRotationGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
@@ -12,25 +13,30 @@ module BABYLON {
          */
         constructor(gizmoLayer:UtilityLayerRenderer, planeNormal:Vector3, color:Color3){
             super(gizmoLayer);
-            this.updateGizmoRotationToMatchAttachedMesh=false;
             
             // Create Material
             var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
             coloredMaterial.disableLighting = true;
             coloredMaterial.emissiveColor = color;
+            
+            var hoverMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            hoverMaterial.disableLighting = true;
+            hoverMaterial.emissiveColor = color.add(new Color3(0.2,0.2,0.2));
 
             // Build mesh on root node
-            var rotationMesh = BABYLON.Mesh.CreateTorus("torus", 3, 0.3, 20, gizmoLayer.utilityLayerScene, false);
-            this._rootMesh.addChild(rotationMesh);
-
+            var parentMesh = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
+            var rotationMesh = BABYLON.Mesh.CreateTorus("torus", 3, 0.15, 20, gizmoLayer.utilityLayerScene, false);
+            
             // Position arrow pointing in its drag axis
             rotationMesh.scaling.scaleInPlace(0.1);
             rotationMesh.material = coloredMaterial;
             rotationMesh.rotation.x = Math.PI/2;
-            this._rootMesh.lookAt(this._rootMesh.position.subtract(planeNormal));
-
+            parentMesh.addChild(rotationMesh);
+            parentMesh.lookAt(this._rootMesh.position.subtract(planeNormal));
+            
+            this._rootMesh.addChild(parentMesh);
             // Add drag behavior to handle events when the gizmo is dragged
-            this._dragBehavior = new PointerDragBehavior({dragPlaneNormal: new Vector3(0,0,1)});
+            this._dragBehavior = new PointerDragBehavior({dragPlaneNormal: planeNormal});
             this._dragBehavior.moveAttached = false;
             this._rootMesh.addBehavior(this._dragBehavior);
 
@@ -43,6 +49,9 @@ module BABYLON {
                 lastDragPosition = e.dragPlanePoint;
             })
 
+            var rotationMatrix = new Matrix();
+            var planeNormalTowardsCamera = new Vector3();
+            var localPlaneNormalTowardsCamera = new Vector3();
             this._dragBehavior.onDragObservable.add((event)=>{
                 if(!this.interactionsEnabled){
                     return;
@@ -57,28 +66,46 @@ module BABYLON {
                     var cross = Vector3.Cross(newVector,originalVector);
                     var dot = Vector3.Dot(newVector,originalVector);
                     var angle = Math.atan2(cross.length(), dot);
-                    var up = planeNormal.clone();
+                    planeNormalTowardsCamera.copyFrom(planeNormal);
+                    localPlaneNormalTowardsCamera.copyFrom(planeNormal);
+                    if(this.updateGizmoRotationToMatchAttachedMesh){
+                        this.attachedMesh.rotationQuaternion.toRotationMatrix(rotationMatrix);
+                        localPlaneNormalTowardsCamera = Vector3.TransformCoordinates(planeNormalTowardsCamera, rotationMatrix);
+                    }
                     // Flip up vector depending on which side the camera is on
                     if(gizmoLayer.utilityLayerScene.activeCamera){
                         var camVec = gizmoLayer.utilityLayerScene.activeCamera.position.subtract(this.attachedMesh.position);
-                        if(Vector3.Dot(camVec, up) > 0){
-                            up.scaleInPlace(-1);
+                        if(Vector3.Dot(camVec, localPlaneNormalTowardsCamera) > 0){
+                            planeNormalTowardsCamera.scaleInPlace(-1);
+                            localPlaneNormalTowardsCamera.scaleInPlace(-1);
                         }
                     }
-                    var halfCircleSide = Vector3.Dot(up, cross) > 0.0;
+                    var halfCircleSide = Vector3.Dot(localPlaneNormalTowardsCamera, cross) > 0.0;
                     if (halfCircleSide) angle = -angle;
                     
 
                     // Convert angle and axis to quaternion (http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm)
                     var quaternionCoefficient = Math.sin(angle/2)
-                    var amountToRotate = new BABYLON.Quaternion(up.x*quaternionCoefficient,up.y*quaternionCoefficient,up.z*quaternionCoefficient,Math.cos(angle/2));
+                    var amountToRotate = new BABYLON.Quaternion(planeNormalTowardsCamera.x*quaternionCoefficient,planeNormalTowardsCamera.y*quaternionCoefficient,planeNormalTowardsCamera.z*quaternionCoefficient,Math.cos(angle/2));
 
                     // Rotate selected mesh quaternion over fixed axis
-                    amountToRotate.multiplyToRef(this.attachedMesh.rotationQuaternion,this.attachedMesh.rotationQuaternion);
+                    this.attachedMesh.rotationQuaternion.multiplyToRef(amountToRotate,this.attachedMesh.rotationQuaternion);
 
                     lastDragPosition = event.dragPlanePoint;
                 }
             })
+
+            this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo, eventState)=>{
+                if(pointerInfo.pickInfo && (this._rootMesh.getChildMeshes().indexOf(<Mesh>pointerInfo.pickInfo.pickedMesh) != -1)){
+                    this._rootMesh.getChildMeshes().forEach((m)=>{
+                        m.material = hoverMaterial;
+                    });
+                }else{
+                    this._rootMesh.getChildMeshes().forEach((m)=>{
+                        m.material = coloredMaterial;
+                    });
+                }
+            });
         }
 
         protected _onInteractionsEnabledChanged(value:boolean){
@@ -89,6 +116,7 @@ module BABYLON {
          * Disposes of the gizmo
          */
         public dispose(){
+            this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
             this._dragBehavior.detach();
             super.dispose();
         } 

+ 14 - 3
src/Gizmos/babylon.positionGizmo.ts

@@ -18,9 +18,9 @@ module BABYLON {
          */
         constructor(gizmoLayer:UtilityLayerRenderer){
             super(gizmoLayer);
-            this._xDrag = new AxisDragGizmo(gizmoLayer, new Vector3(1,0,0), BABYLON.Color3.FromHexString("#00b894"));
-            this._yDrag = new AxisDragGizmo(gizmoLayer, new Vector3(0,1,0), BABYLON.Color3.FromHexString("#d63031"));
-            this._zDrag = new AxisDragGizmo(gizmoLayer, new Vector3(0,0,1), BABYLON.Color3.FromHexString("#0984e3"));
+            this._xDrag = new AxisDragGizmo(gizmoLayer, new Vector3(1,0,0), BABYLON.Color3.Green().scale(0.5));
+            this._yDrag = new AxisDragGizmo(gizmoLayer, new Vector3(0,1,0), BABYLON.Color3.Red().scale(0.5));
+            this._zDrag = new AxisDragGizmo(gizmoLayer, new Vector3(0,0,1), BABYLON.Color3.Blue().scale(0.5));
         }
 
         protected _onInteractionsEnabledChanged(value:boolean){
@@ -28,6 +28,17 @@ module BABYLON {
             this._yDrag.interactionsEnabled = value
             this._zDrag.interactionsEnabled = value
         }
+
+        public set updateGizmoRotationToMatchAttachedMesh(value:boolean){
+            if(this._xDrag){
+                this._xDrag.updateGizmoRotationToMatchAttachedMesh = value;
+                this._yDrag.updateGizmoRotationToMatchAttachedMesh = value;
+                this._zDrag.updateGizmoRotationToMatchAttachedMesh = value;
+            }
+        }
+        public get updateGizmoRotationToMatchAttachedMesh(){
+            return this._xDrag.updateGizmoRotationToMatchAttachedMesh;
+        }
         
         /**
          * Disposes of the gizmo

+ 14 - 3
src/Gizmos/babylon.rotationGizmo.ts

@@ -18,9 +18,9 @@ module BABYLON {
          */
         constructor(gizmoLayer:UtilityLayerRenderer){
             super(gizmoLayer);
-            this._xDrag = new PlaneRotationGizmo(gizmoLayer, new Vector3(1,0,0), BABYLON.Color3.FromHexString("#00b894"));
-            this._yDrag = new PlaneRotationGizmo(gizmoLayer, new Vector3(0,1,0), BABYLON.Color3.FromHexString("#d63031"));
-            this._zDrag = new PlaneRotationGizmo(gizmoLayer, new Vector3(0,0,1), BABYLON.Color3.FromHexString("#0984e3"));
+            this._xDrag = new PlaneRotationGizmo(gizmoLayer, new Vector3(1,0,0), BABYLON.Color3.Green().scale(0.5));
+            this._yDrag = new PlaneRotationGizmo(gizmoLayer, new Vector3(0,1,0), BABYLON.Color3.Red().scale(0.5));
+            this._zDrag = new PlaneRotationGizmo(gizmoLayer, new Vector3(0,0,1), BABYLON.Color3.Blue().scale(0.5));
         }
 
         protected _onInteractionsEnabledChanged(value:boolean){
@@ -29,6 +29,17 @@ module BABYLON {
             this._zDrag.interactionsEnabled = value
         }
 
+        public set updateGizmoRotationToMatchAttachedMesh(value:boolean){
+            if(this._xDrag){
+                this._xDrag.updateGizmoRotationToMatchAttachedMesh = value;
+                this._yDrag.updateGizmoRotationToMatchAttachedMesh = value;
+                this._zDrag.updateGizmoRotationToMatchAttachedMesh = value;
+            }
+        }
+        public get updateGizmoRotationToMatchAttachedMesh(){
+            return this._xDrag.updateGizmoRotationToMatchAttachedMesh;
+        }
+
         /**
          * Disposes of the gizmo
          */

+ 14 - 3
src/Gizmos/babylon.scaleGizmo.ts

@@ -18,9 +18,9 @@ module BABYLON {
          */
         constructor(gizmoLayer:UtilityLayerRenderer){
             super(gizmoLayer);
-            this._xDrag = new AxisScaleGizmo(gizmoLayer, new Vector3(1,0,0), BABYLON.Color3.FromHexString("#00b894"));
-            this._yDrag = new AxisScaleGizmo(gizmoLayer, new Vector3(0,1,0), BABYLON.Color3.FromHexString("#d63031"));
-            this._zDrag = new AxisScaleGizmo(gizmoLayer, new Vector3(0,0,1), BABYLON.Color3.FromHexString("#0984e3"));
+            this._xDrag = new AxisScaleGizmo(gizmoLayer, new Vector3(1,0,0), BABYLON.Color3.Green().scale(0.5));
+            this._yDrag = new AxisScaleGizmo(gizmoLayer, new Vector3(0,1,0), BABYLON.Color3.Red().scale(0.5));
+            this._zDrag = new AxisScaleGizmo(gizmoLayer, new Vector3(0,0,1), BABYLON.Color3.Blue().scale(0.5));
         }
 
         protected _onInteractionsEnabledChanged(value:boolean){
@@ -29,6 +29,17 @@ module BABYLON {
             this._zDrag.interactionsEnabled = value
         }
 
+        public set updateGizmoRotationToMatchAttachedMesh(value:boolean){
+            if(this._xDrag){
+                this._xDrag.updateGizmoRotationToMatchAttachedMesh = value;
+                this._yDrag.updateGizmoRotationToMatchAttachedMesh = value;
+                this._zDrag.updateGizmoRotationToMatchAttachedMesh = value;
+            }
+        }
+        public get updateGizmoRotationToMatchAttachedMesh(){
+            return this._xDrag.updateGizmoRotationToMatchAttachedMesh;
+        }
+
         /**
          * Disposes of the gizmo
          */