From 182340dafa1425a62cb770c660dfa75aac4572fc Mon Sep 17 00:00:00 2001 From: KPal <48248865+kpal81xd@users.noreply.github.com> Date: Fri, 24 May 2024 12:43:06 +0100 Subject: [PATCH] Added orthogonal facing translation to gizmo (#6607) --- .../src/examples/misc/gizmos.controls.mjs | 4 +- src/extras/gizmo/axis-shapes.js | 51 ++++++++++++++++++- src/extras/gizmo/transform-gizmo.js | 15 ++++-- src/extras/gizmo/translate-gizmo.js | 40 +++++++++++++-- 4 files changed, 100 insertions(+), 10 deletions(-) diff --git a/examples/src/examples/misc/gizmos.controls.mjs b/examples/src/examples/misc/gizmos.controls.mjs index 55290ff0879..02f3f9fe198 100644 --- a/examples/src/examples/misc/gizmos.controls.mjs +++ b/examples/src/examples/misc/gizmos.controls.mjs @@ -123,7 +123,7 @@ export function controls({ observer, ReactPCUI, React, jsx, fragment }) { precision: 2 }) ), - type === 'scale' && + (type === 'translate' || type === 'scale') && jsx( LabelGroup, { text: 'Center Tolerance' }, @@ -223,7 +223,7 @@ export function controls({ observer, ReactPCUI, React, jsx, fragment }) { link: { observer, path: 'gizmo.axisPlaneGap' } }) ), - type === 'scale' && + (type === 'translate' || type === 'scale') && jsx( LabelGroup, { text: 'Center Size' }, diff --git a/src/extras/gizmo/axis-shapes.js b/src/extras/gizmo/axis-shapes.js index 4c3155d96df..8c797da7ba3 100644 --- a/src/extras/gizmo/axis-shapes.js +++ b/src/extras/gizmo/axis-shapes.js @@ -15,6 +15,7 @@ import { BoxGeometry } from '../../scene/geometry/box-geometry.js'; import { CylinderGeometry } from '../../scene/geometry/cylinder-geometry.js'; import { ConeGeometry } from '../../scene/geometry/cone-geometry.js'; import { PlaneGeometry } from '../../scene/geometry/plane-geometry.js'; +import { SphereGeometry } from '../../scene/geometry/sphere-geometry.js'; import { TorusGeometry } from '../../scene/geometry/torus-geometry.js'; // constants @@ -32,6 +33,7 @@ const GEOMETRIES = { cone: ConeGeometry, cylinder: CylinderGeometry, plane: PlaneGeometry, + sphere: SphereGeometry, torus: TorusGeometry }; @@ -690,4 +692,51 @@ class AxisPlane extends AxisShape { } } -export { AxisShape, AxisArrow, AxisBoxCenter, AxisBoxLine, AxisDisk, AxisPlane }; +class AxisSphereCenter extends AxisShape { + _size = 0.12; + + _tolerance = 0.05; + + constructor(device, options = {}) { + super(device, options); + + this.triData = [ + new TriData(new SphereGeometry(), 2) + ]; + + this._createCenter(); + } + + _createCenter() { + this._createRoot('sphereCenter'); + this._updateTransform(); + + // box + this._addRenderShadowMesh(this.entity, 'sphere'); + } + + set size(value) { + this._size = value ?? 1; + this._updateTransform(); + } + + get size() { + return this._size; + } + + set tolerance(value) { + this._tolerance = value; + this._updateTransform(); + } + + get tolerance() { + return this._tolerance; + } + + _updateTransform() { + // intersect/render + this.entity.setLocalScale(this._size, this._size, this._size); + } +} + +export { AxisShape, AxisArrow, AxisBoxCenter, AxisBoxLine, AxisDisk, AxisPlane, AxisSphereCenter }; diff --git a/src/extras/gizmo/transform-gizmo.js b/src/extras/gizmo/transform-gizmo.js index fea4c1d4be9..ed00fc27b5d 100644 --- a/src/extras/gizmo/transform-gizmo.js +++ b/src/extras/gizmo/transform-gizmo.js @@ -182,6 +182,15 @@ class TransformGizmo extends Gizmo { face: COLOR_YELLOW.clone() }; + /** + * Internal gizmo starting rotation in world space. + * + * @type {Vec3} + * @protected + */ + _rootStartPos = new Vec3(); + + /** * Internal gizmo starting rotation in world space. * @@ -321,6 +330,7 @@ class TransformGizmo extends Gizmo { this._selectedAxis = this._getAxis(meshInstance); this._selectedIsPlane = this._getIsPlane(meshInstance); + this._rootStartPos.copy(this.root.getPosition()); this._rootStartRot.copy(this.root.getRotation()); const pointInfo = this._screenToPoint(x, y); this._selectionStartPoint.copy(pointInfo.point); @@ -518,9 +528,8 @@ class TransformGizmo extends Gizmo { _createPlane(axis, isFacing, isLine) { const cameraPos = this._camera.entity.getPosition(); - const gizmoPos = this.root.getPosition(); - const facingDir = tmpV1.sub2(cameraPos, gizmoPos).normalize(); + const facingDir = tmpV1.sub2(cameraPos, this._rootStartPos).normalize(); const normal = tmpP1.normal.set(0, 0, 0); if (isFacing) { @@ -538,7 +547,7 @@ class TransformGizmo extends Gizmo { } } - return tmpP1.setFromPointNormal(gizmoPos, normal); + return tmpP1.setFromPointNormal(this._rootStartPos, normal); } _projectToAxis(point, axis) { diff --git a/src/extras/gizmo/translate-gizmo.js b/src/extras/gizmo/translate-gizmo.js index 28b7bc34577..39843fe1c7f 100644 --- a/src/extras/gizmo/translate-gizmo.js +++ b/src/extras/gizmo/translate-gizmo.js @@ -1,7 +1,7 @@ import { Vec3 } from '../../core/math/vec3.js'; import { Quat } from '../../core/math/quat.js'; -import { AxisArrow, AxisPlane } from './axis-shapes.js'; +import { AxisArrow, AxisPlane, AxisSphereCenter } from './axis-shapes.js'; import { GIZMO_LOCAL } from './gizmo.js'; import { TransformGizmo } from "./transform-gizmo.js"; @@ -17,6 +17,12 @@ const tmpQ1 = new Quat(); */ class TranslateGizmo extends TransformGizmo { _shapes = { + face: new AxisSphereCenter(this._device, { + axis: 'face', + layers: [this._layer.id], + defaultColor: this._meshColors.axis.xyz, + hoverColor: this._meshColors.hover.xyz + }), yz: new AxisPlane(this._device, { axis: 'x', flipAxis: 'y', @@ -223,6 +229,32 @@ class TranslateGizmo extends TransformGizmo { return this._shapes.yz.gap; } + /** + * Axis center size. + * + * @type {number} + */ + set axisCenterSize(value) { + this._shapes.face.size = value; + } + + get axisCenterSize() { + return this._shapes.face.size; + } + + /** + * Axis center tolerance. + * + * @type {number} + */ + set axisCenterTolerance(value) { + this._shapes.face.tolerance = value; + } + + get axisCenterTolerance() { + return this._shapes.face.tolerance; + } + _setArrowProp(prop, value) { this._shapes.x[prop] = value; this._shapes.y[prop] = value; @@ -248,7 +280,7 @@ class TranslateGizmo extends TransformGizmo { const node = this.nodes[i]; if (this._coordSpace === GIZMO_LOCAL) { tmpV1.copy(pointDelta); - node.parent.getWorldTransform().getScale(tmpV2); + node.parent?.getWorldTransform().getScale(tmpV2); tmpV2.x = 1 / tmpV2.x; tmpV2.y = 1 / tmpV2.y; tmpV2.z = 1 / tmpV2.z; @@ -270,7 +302,7 @@ class TranslateGizmo extends TransformGizmo { const isPlane = this._selectedIsPlane; const ray = this._createRay(mouseWPos); - const plane = this._createPlane(axis, false, !isPlane); + const plane = this._createPlane(axis, axis === 'face', !isPlane); const point = new Vec3(); const angle = 0; @@ -280,7 +312,7 @@ class TranslateGizmo extends TransformGizmo { // rotate point back to world coords tmpQ1.copy(this._rootStartRot).invert().transformVector(point, point); - if (!isPlane) { + if (!isPlane && axis !== 'face') { this._projectToAxis(point, axis); }