Skip to content
Merged
28 changes: 24 additions & 4 deletions src/extras/gizmo/gizmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ class Gizmo extends EventHandler {
*/
_layer;

/**
* Internal flag to track if a render update is required.
*
* @type {boolean}
* @protected
*/
_renderUpdate = false;

/**
* The graph nodes attached to the gizmo.
*
Expand Down Expand Up @@ -303,7 +311,7 @@ class Gizmo extends EventHandler {
const enabled = state ? this.nodes.length > 0 && cameraDist > DIST_EPSILON : false;
if (enabled !== this.root.enabled) {
this.root.enabled = enabled;
this.fire(Gizmo.EVENT_RENDERUPDATE);
this._renderUpdate = true;
}
}

Expand Down Expand Up @@ -501,7 +509,8 @@ class Gizmo extends EventHandler {

this.root.setLocalPosition(position);
this.fire(Gizmo.EVENT_POSITIONUPDATE, position);
this.fire(Gizmo.EVENT_RENDERUPDATE);

this._renderUpdate = true;
}

/**
Expand All @@ -519,7 +528,8 @@ class Gizmo extends EventHandler {

this.root.setRotation(rotation);
this.fire(Gizmo.EVENT_ROTATIONUPDATE, rotation.getEulerAngles());
this.fire(Gizmo.EVENT_RENDERUPDATE);

this._renderUpdate = true;
}

/**
Expand All @@ -542,7 +552,8 @@ class Gizmo extends EventHandler {

this.root.setLocalScale(this._scale, this._scale, this._scale);
this.fire(Gizmo.EVENT_SCALEUPDATE, this._scale);
this.fire(Gizmo.EVENT_RENDERUPDATE);

this._renderUpdate = true;
}

/**
Expand Down Expand Up @@ -663,6 +674,15 @@ class Gizmo extends EventHandler {
* gizmo.update();
*/
update() {
if (this._renderUpdate) {
this._renderUpdate = false;
this.fire(Gizmo.EVENT_RENDERUPDATE);
}

if (!this.enabled) {
return;
}

this._updatePosition();
this._updateRotation();
this._updateScale();
Expand Down
19 changes: 17 additions & 2 deletions src/extras/gizmo/rotate-gizmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const color = new Color();

// constants
const RING_FACING_EPSILON = 1e-4;
const UPDATE_EPSILON = 1e-6;
const AXES = /** @type {('x' | 'y' | 'z')[]} */ (['x', 'y', 'z']);

/**
Expand Down Expand Up @@ -184,6 +185,14 @@ class RotateGizmo extends TransformGizmo {
*/
_guideAngleLines;

/**
* Internal copy of facing direction to avoid unnecessary updates.
*
* @type {Vec3}
* @private
*/
_facingDir = new Vec3();

/**
* @override
*/
Expand Down Expand Up @@ -489,6 +498,8 @@ class RotateGizmo extends TransformGizmo {
}
q1.setFromAxisAngle(v1, angleDelta);
q1.transformVector(this._guideAngleStart, this._guideAngleEnd);

this._renderUpdate = true;
}

/**
Expand Down Expand Up @@ -552,8 +563,11 @@ class RotateGizmo extends TransformGizmo {
dot = facingDir.dot(this.root.forward);
sector = 1 - Math.abs(dot) > RING_FACING_EPSILON;
this._shapes.z.show(sector ? 'sector' : 'ring');
}

this.fire(TransformGizmo.EVENT_RENDERUPDATE);
if (!facingDir.equalsApprox(this._facingDir, UPDATE_EPSILON)) {
this._facingDir.copy(facingDir);
this._renderUpdate = true;
}
}

Expand Down Expand Up @@ -581,7 +595,8 @@ class RotateGizmo extends TransformGizmo {
}
}
}
this.fire(TransformGizmo.EVENT_RENDERUPDATE);

this._renderUpdate = true;
}

/**
Expand Down
65 changes: 54 additions & 11 deletions src/extras/gizmo/scale-gizmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,23 +422,66 @@ class ScaleGizmo extends TransformGizmo {
const cameraDir = this.cameraDir;

// axes
let dot = cameraDir.dot(this.root.right);
this._shapes.x.entity.enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
let changed = false;
let dot, enabled;
dot = cameraDir.dot(this.root.right);
enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
if (this._shapes.x.entity.enabled !== enabled) {
this._shapes.x.entity.enabled = enabled;
changed = true;
}
dot = cameraDir.dot(this.root.up);
this._shapes.y.entity.enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
if (this._shapes.y.entity.enabled !== enabled) {
this._shapes.y.entity.enabled = enabled;
changed = true;
}
dot = cameraDir.dot(this.root.forward);
this._shapes.z.entity.enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
if (this._shapes.z.entity.enabled !== enabled) {
this._shapes.z.entity.enabled = enabled;
changed = true;
}

// planes
let flipped;
v1.cross(cameraDir, this.root.right);
this._shapes.yz.entity.enabled = 1 - v1.length() > GLANCE_EPSILON;
this._shapes.yz.flipped = this.flipPlanes ? v2.set(0, +(v1.dot(this.root.forward) < 0), +(v1.dot(this.root.up) < 0)) : Vec3.ZERO;
enabled = 1 - v1.length() > GLANCE_EPSILON;
if (this._shapes.yz.entity.enabled !== enabled) {
this._shapes.yz.entity.enabled = enabled;
changed = true;
}
flipped = this.flipPlanes ? v2.set(0, +(v1.dot(this.root.forward) < 0), +(v1.dot(this.root.up) < 0)) : Vec3.ZERO;
if (!this._shapes.yz.flipped.equals(flipped)) {
this._shapes.yz.flipped = flipped;
changed = true;
}
v1.cross(cameraDir, this.root.forward);
this._shapes.xy.entity.enabled = 1 - v1.length() > GLANCE_EPSILON;
this._shapes.xy.flipped = this.flipPlanes ? v2.set(+(v1.dot(this.root.up) < 0), +(v1.dot(this.root.right) > 0), 0) : Vec3.ZERO;
enabled = 1 - v1.length() > GLANCE_EPSILON;
if (this._shapes.xy.entity.enabled !== enabled) {
this._shapes.xy.entity.enabled = enabled;
changed = true;
}
flipped = this.flipPlanes ? v2.set(+(v1.dot(this.root.up) < 0), +(v1.dot(this.root.right) > 0), 0) : Vec3.ZERO;
if (!this._shapes.xy.flipped.equals(flipped)) {
this._shapes.xy.flipped = flipped;
changed = true;
}
v1.cross(cameraDir, this.root.up);
this._shapes.xz.entity.enabled = 1 - v1.length() > GLANCE_EPSILON;
this._shapes.xz.flipped = this.flipPlanes ? v2.set(+(v1.dot(this.root.forward) > 0), 0, +(v1.dot(this.root.right) > 0)) : Vec3.ZERO;
enabled = 1 - v1.length() > GLANCE_EPSILON;
if (this._shapes.xz.entity.enabled !== enabled) {
this._shapes.xz.entity.enabled = enabled;
changed = true;
}
flipped = this.flipPlanes ? v2.set(+(v1.dot(this.root.forward) > 0), 0, +(v1.dot(this.root.right) > 0)) : Vec3.ZERO;
if (!this._shapes.xz.flipped.equals(flipped)) {
this._shapes.xz.flipped = flipped;
changed = true;
}

if (changed) {
this._renderUpdate = true;
}
}

/**
Expand Down Expand Up @@ -471,7 +514,7 @@ class ScaleGizmo extends TransformGizmo {
}
}

this.fire(TransformGizmo.EVENT_RENDERUPDATE);
this._renderUpdate = true;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/extras/gizmo/transform-gizmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ class TransformGizmo extends Gizmo {
}

if (changed) {
this.fire(Gizmo.EVENT_RENDERUPDATE);
this._renderUpdate = true;
}
}

Expand Down
65 changes: 54 additions & 11 deletions src/extras/gizmo/translate-gizmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,23 +402,66 @@ class TranslateGizmo extends TransformGizmo {
const cameraDir = this.cameraDir;

// axes
let dot = cameraDir.dot(this.root.right);
this._shapes.x.entity.enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
let changed = false;
let dot, enabled;
dot = cameraDir.dot(this.root.right);
enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
if (this._shapes.x.entity.enabled !== enabled) {
this._shapes.x.entity.enabled = enabled;
changed = true;
}
dot = cameraDir.dot(this.root.up);
this._shapes.y.entity.enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
if (this._shapes.y.entity.enabled !== enabled) {
this._shapes.y.entity.enabled = enabled;
changed = true;
}
dot = cameraDir.dot(this.root.forward);
this._shapes.z.entity.enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
enabled = 1 - Math.abs(dot) > GLANCE_EPSILON;
if (this._shapes.z.entity.enabled !== enabled) {
this._shapes.z.entity.enabled = enabled;
changed = true;
}

// planes
let flipped;
v1.cross(cameraDir, this.root.right);
this._shapes.yz.entity.enabled = 1 - v1.length() > GLANCE_EPSILON;
this._shapes.yz.flipped = this.flipPlanes ? v2.set(0, +(v1.dot(this.root.forward) < 0), +(v1.dot(this.root.up) < 0)) : Vec3.ZERO;
enabled = 1 - v1.length() > GLANCE_EPSILON;
if (this._shapes.yz.entity.enabled !== enabled) {
this._shapes.yz.entity.enabled = enabled;
changed = true;
}
flipped = this.flipPlanes ? v2.set(0, +(v1.dot(this.root.forward) < 0), +(v1.dot(this.root.up) < 0)) : Vec3.ZERO;
if (!this._shapes.yz.flipped.equals(flipped)) {
this._shapes.yz.flipped = flipped;
changed = true;
}
v1.cross(cameraDir, this.root.forward);
this._shapes.xy.entity.enabled = 1 - v1.length() > GLANCE_EPSILON;
this._shapes.xy.flipped = this.flipPlanes ? v2.set(+(v1.dot(this.root.up) < 0), +(v1.dot(this.root.right) > 0), 0) : Vec3.ZERO;
enabled = 1 - v1.length() > GLANCE_EPSILON;
if (this._shapes.xy.entity.enabled !== enabled) {
this._shapes.xy.entity.enabled = enabled;
changed = true;
}
flipped = this.flipPlanes ? v2.set(+(v1.dot(this.root.up) < 0), +(v1.dot(this.root.right) > 0), 0) : Vec3.ZERO;
if (!this._shapes.xy.flipped.equals(flipped)) {
this._shapes.xy.flipped = flipped;
changed = true;
}
v1.cross(cameraDir, this.root.up);
this._shapes.xz.entity.enabled = 1 - v1.length() > GLANCE_EPSILON;
this._shapes.xz.flipped = this.flipPlanes ? v2.set(+(v1.dot(this.root.forward) > 0), 0, +(v1.dot(this.root.right) > 0)) : Vec3.ZERO;
enabled = 1 - v1.length() > GLANCE_EPSILON;
if (this._shapes.xz.entity.enabled !== enabled) {
this._shapes.xz.entity.enabled = enabled;
changed = true;
}
flipped = this.flipPlanes ? v2.set(+(v1.dot(this.root.forward) > 0), 0, +(v1.dot(this.root.right) > 0)) : Vec3.ZERO;
if (!this._shapes.xz.flipped.equals(flipped)) {
this._shapes.xz.flipped = flipped;
changed = true;
}

if (changed) {
this._renderUpdate = true;
}
}

/**
Expand Down Expand Up @@ -450,7 +493,7 @@ class TranslateGizmo extends TransformGizmo {
}
}

this.fire(TransformGizmo.EVENT_RENDERUPDATE);
this._renderUpdate = true;
}

/**
Expand Down