Skip to content

Commit

Permalink
Gizmo uniform scaling update (#5999)
Browse files Browse the repository at this point in the history
* changed logic for uniform scaling

* fixed uniform directino projections

* copy entity direction vectors for uniform scale calculation
  • Loading branch information
kpal81xd authored and Martin Valigursky committed Jan 29, 2024
1 parent c8f41ce commit 7877ac6
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 22 deletions.
33 changes: 13 additions & 20 deletions extras/gizmo/scale-gizmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import { AxisBoxCenter, AxisBoxLine, AxisPlane } from './axis-shapes.js';
import { GIZMO_LOCAL } from './gizmo.js';
import { TransformGizmo } from "./transform-gizmo.js";

// temporary variables
const tmpV1 = new Vec3();

/**
* Scaling gizmo.
*
Expand Down Expand Up @@ -87,13 +84,6 @@ class ScaleGizmo extends TransformGizmo {
*/
_nodeScales = new Map();

/**
* State for if uniform scaling is enabled for planes. Defaults to true.
*
* @type {boolean}
*/
uniform = true;

/**
* @override
*/
Expand All @@ -119,21 +109,11 @@ class ScaleGizmo extends TransformGizmo {
});

this.on('transform:move', (pointDelta) => {
const axis = this._selectedAxis;
const isPlane = this._selectedIsPlane;
if (this.snap) {
pointDelta.mulScalar(1 / this.snapIncrement);
pointDelta.round();
pointDelta.mulScalar(this.snapIncrement);
}
if (this.uniform && isPlane) {
tmpV1.set(Math.abs(pointDelta.x), Math.abs(pointDelta.y), Math.abs(pointDelta.z));
tmpV1[axis] = 0;
const v = tmpV1.length();
tmpV1.set(v * Math.sign(pointDelta.x), v * Math.sign(pointDelta.y), v * Math.sign(pointDelta.z));
tmpV1[axis] = 1;
pointDelta.copy(tmpV1);
}
this._setNodeScales(pointDelta);
});

Expand All @@ -150,6 +130,19 @@ class ScaleGizmo extends TransformGizmo {
return this._coordSpace;
}

/**
* Uniform scaling state for planes.
*
* @type {boolean}
*/
set uniform(value) {
this._useUniformScaling = value ?? true;
}

get uniform() {
return this._useUniformScaling;
}

/**
* Axis gap.
*
Expand Down
42 changes: 40 additions & 2 deletions extras/gizmo/transform-gizmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Gizmo } from "./gizmo.js";
// temporary variables
const tmpV1 = new Vec3();
const tmpV2 = new Vec3();
const tmpV3 = new Vec3();
const tmpQ1 = new Quat();

const pointDelta = new Vec3();
Expand Down Expand Up @@ -281,6 +282,14 @@ class TransformGizmo extends Gizmo {
*/
_isRotation = false;

/**
* Internal state if transform should use uniform scaling.
*
* @type {boolean}
* @protected
*/
_useUniformScaling = false;

/**
* Internal state for if the gizmo is being dragged.
*
Expand Down Expand Up @@ -499,6 +508,7 @@ class TransformGizmo extends Gizmo {
const axis = this._selectedAxis;
const isPlane = this._selectedIsPlane;
const isRotation = this._isRotation;
const isUniform = this._useUniformScaling && isPlane;
const isAllAxes = axis === 'xyz';
const isFacing = axis === 'face';

Expand All @@ -510,7 +520,7 @@ class TransformGizmo extends Gizmo {
this._camera.entity.getWorldTransform().transformVector(tmpV1.set(0, 0, -1), rayDir);
}

if (isAllAxes || isFacing) {
if (isUniform || isAllAxes || isFacing) {
// all axes so set normal to plane facing camera
planeNormal.copy(rayOrigin).sub(gizmoPos).normalize();
} else {
Expand All @@ -537,7 +547,35 @@ class TransformGizmo extends Gizmo {
point.sub(gizmoPos);
}

if (isAllAxes) {
if (isUniform) {
// calculate point distance from gizmo
tmpV1.copy(point).sub(gizmoPos).normalize();

// calculate projecion vector for scale direction
switch (axis) {
case 'x':
tmpV2.copy(this.root.up);
tmpV3.copy(this.root.forward).mulScalar(-1);
break;
case 'y':
tmpV2.copy(this.root.right);
tmpV3.copy(this.root.forward).mulScalar(-1);
break;
case 'z':
tmpV2.copy(this.root.up);
tmpV3.copy(this.root.right);
break;
default:
tmpV2.set(0, 0, 0);
tmpV3.set(0, 0, 0);
break;
}
tmpV2.add(tmpV3).normalize();

const v = point.sub(gizmoPos).length() * tmpV1.dot(tmpV2);
point.set(v, v, v);
point[axis] = 1;
} else if (isAllAxes) {
// calculate point distance from gizmo
tmpV1.copy(point).sub(gizmoPos).normalize();
tmpV2.copy(this._camera.entity.up).add(this._camera.entity.right).normalize();
Expand Down

0 comments on commit 7877ac6

Please sign in to comment.