Преглед изворни кода

add uniform scaling to scale gizmo

Trevor Baron пре 7 година
родитељ
комит
8435d3295e

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

@@ -91,6 +91,7 @@
 - Added ACES ToneMapping to the image processing to help getting more parity with other engines ([sebavan](http://www.github.com/sebavan))
 - Added Image Processing to the particle system to allow consistency in one pass forward rendering scenes ([sebavan](http://www.github.com/sebavan))
 - Added ignoreChildren field to bounding box to save performance when using heavily nested meshes ([TrevorDev](https://github.com/TrevorDev))
+- Add uniform scaling drag support to scale gizmo ([TrevorDev](https://github.com/TrevorDev))
 
 ### glTF Loader
 

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

@@ -3,6 +3,7 @@ module BABYLON {
      * Single axis scale gizmo
      */
     export class AxisScaleGizmo extends Gizmo {
+        private _coloredMaterial:StandardMaterial;
         /**
          * Drag behavior responsible for the gizmos dragging interactions
          */
@@ -18,6 +19,10 @@ module BABYLON {
          */
         public onSnapObservable = new Observable<{snapDistance:number}>();
         /**
+         * If the scaling operation should be done on all axis (default: false)
+         */
+        public uniformScaling = false;
+        /**
          * Creates an AxisScaleGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
          * @param dragAxis The axis which the gizmo will be able to scale on
@@ -27,9 +32,9 @@ module BABYLON {
             super(gizmoLayer);
             
             // Create Material
-            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
-            coloredMaterial.disableLighting = true;
-            coloredMaterial.emissiveColor = color;
+            this._coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            this._coloredMaterial.disableLighting = true;
+            this._coloredMaterial.emissiveColor = color;
 
             var hoverMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
             hoverMaterial.disableLighting = true;
@@ -39,18 +44,18 @@ module BABYLON {
             var arrow = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene)
             var arrowMesh = BABYLON.MeshBuilder.CreateBox("yPosMesh", {size: 0.4}, gizmoLayer.utilityLayerScene);
             var arrowTail = BABYLON.MeshBuilder.CreateLines("yPosMesh", {points: [new Vector3(0, 0, 0), new Vector3(0, 1.5, 0)]}, gizmoLayer.utilityLayerScene);
-            arrowTail.color = coloredMaterial.emissiveColor;
+            arrowTail.color = this._coloredMaterial.emissiveColor;
             arrow.addChild(arrowMesh);
             arrow.addChild(arrowTail);
 
             // Position arrow pointing in its drag axis
             arrowMesh.scaling.scaleInPlace(0.1);
-            arrowMesh.material = coloredMaterial;
+            arrowMesh.material = this._coloredMaterial;
             arrowMesh.rotation.x = Math.PI/2;
             arrowMesh.position.z+=0.3;
             arrowTail.scaling.scaleInPlace(0.2);
             arrowTail.rotation.x = Math.PI/2;
-            arrowTail.material = coloredMaterial;
+            arrowTail.material = this._coloredMaterial;
             arrow.lookAt(this._rootMesh.position.subtract(dragAxis));
             this._rootMesh.addChild(arrow);
 
@@ -67,14 +72,22 @@ module BABYLON {
                     // Snapping logic
                     var snapped = false;
                     var dragSteps = 0;
+                    if(this.uniformScaling){
+                        this.attachedMesh.scaling.normalizeToRef(tmpVector)
+                        if(tmpVector.y < 0){
+                            tmpVector.scaleInPlace(-1);
+                        }
+                    }else{
+                        tmpVector.copyFrom(dragAxis)
+                    }
                     if(this.snapDistance == 0){
-                        dragAxis.scaleToRef(event.dragDistance, tmpVector);
+                        tmpVector.scaleToRef(event.dragDistance, tmpVector);
                     }else{
                         currentSnapDragDistance+=event.dragDistance;
                         if(Math.abs(currentSnapDragDistance)>this.snapDistance){
                             dragSteps = Math.floor(currentSnapDragDistance/this.snapDistance);
                             currentSnapDragDistance = currentSnapDragDistance % this.snapDistance;
-                            dragAxis.scaleToRef(this.snapDistance*dragSteps, tmpVector);
+                            tmpVector.scaleToRef(this.snapDistance*dragSteps, tmpVector);
                             snapped = true;
                         }else{
                             tmpVector.scaleInPlace(0);
@@ -95,7 +108,7 @@ module BABYLON {
                     return;
                 }
                 var isHovered = pointerInfo.pickInfo && (this._rootMesh.getChildMeshes().indexOf(<Mesh>pointerInfo.pickInfo.pickedMesh) != -1);
-                var material = isHovered ? hoverMaterial : coloredMaterial;
+                var material = isHovered ? hoverMaterial : this._coloredMaterial;
                 this._rootMesh.getChildMeshes().forEach((m)=>{
                     m.material = material;
                     if((<LinesMesh>m).color){
@@ -120,5 +133,23 @@ module BABYLON {
             this.dragBehavior.detach();
             super.dispose();
         }
+
+        /**
+         * Disposes and replaces the current meshes in the gizmo with the specified mesh
+         * @param mesh The mesh to replace the default mesh of the gizmo
+         * @param useGizmoMaterial If the gizmo's default material should be used (default: false)
+         */
+        public setCustomMesh(mesh:Mesh, useGizmoMaterial:boolean = false){
+            super.setCustomMesh(mesh);
+            if(useGizmoMaterial){
+                this._rootMesh.getChildMeshes().forEach((m)=>{
+                    m.material = this._coloredMaterial;
+                    if((<LinesMesh>m).color){
+                        (<LinesMesh>m).color = this._coloredMaterial.emissiveColor
+                    }
+                });
+                this._customMeshSet = false;
+            }
+        }
     }
 }

+ 18 - 0
src/Gizmos/babylon.scaleGizmo.ts

@@ -16,11 +16,18 @@ module BABYLON {
          */
         public zGizmo:AxisScaleGizmo;
 
+        /**
+         * @hidden
+         * Internal gizmo used to scale all axis equally
+         */
+        private _uniformGizmo:AxisScaleGizmo;
+
         public set attachedMesh(mesh:Nullable<AbstractMesh>){
             if(this.xGizmo){
                 this.xGizmo.attachedMesh = mesh;
                 this.yGizmo.attachedMesh = mesh;
                 this.zGizmo.attachedMesh = mesh;
+                this._uniformGizmo.attachedMesh = mesh;
             }
         }
         /**
@@ -32,6 +39,15 @@ module BABYLON {
             this.xGizmo = new AxisScaleGizmo(new Vector3(1,0,0), BABYLON.Color3.Green().scale(0.5), gizmoLayer);
             this.yGizmo = new AxisScaleGizmo(new Vector3(0,1,0), BABYLON.Color3.Red().scale(0.5), gizmoLayer);
             this.zGizmo = new AxisScaleGizmo(new Vector3(0,0,1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer);
+
+            // Create uniform scale gizmo
+            this._uniformGizmo = new AxisScaleGizmo(new Vector3(0,1,0), BABYLON.Color3.Yellow().scale(0.5), gizmoLayer);
+            this._uniformGizmo.updateGizmoRotationToMatchAttachedMesh = false;
+            this._uniformGizmo.uniformScaling = true
+            var octahedron = BABYLON.Mesh.CreatePolyhedron("", {type: 1}, this._uniformGizmo.gizmoLayer.utilityLayerScene);
+            octahedron.scaling.scaleInPlace(0.02);
+            this._uniformGizmo.setCustomMesh(octahedron, true);
+            
             this.attachedMesh = null;
         }
 
@@ -54,6 +70,7 @@ module BABYLON {
                 this.xGizmo.snapDistance = value;
                 this.yGizmo.snapDistance = value;
                 this.zGizmo.snapDistance = value;
+                this._uniformGizmo.snapDistance = value;
             }
         }
         public get snapDistance(){
@@ -67,6 +84,7 @@ module BABYLON {
             this.xGizmo.dispose();
             this.yGizmo.dispose();
             this.zGizmo.dispose();
+            this._uniformGizmo.dispose();
         }
     }
 }