updateMatrixWorld method
void
updateMatrixWorld(
[ - bool force = false
])
override
Implementation
updateMatrixWorld([bool force = false]) {
var space = (this.mode == 'scale')
? 'local'
: this.space; // scale always oriented to local rotation
var quaternion =
(space == 'local') ? this.worldQuaternion : _identityQuaternion;
// Show only gizmos for current transform mode
this.gizmo['translate'].visible = this.mode == 'translate';
this.gizmo['rotate'].visible = this.mode == 'rotate';
this.gizmo['scale'].visible = this.mode == 'scale';
this.helper['translate'].visible = this.mode == 'translate';
this.helper['rotate'].visible = this.mode == 'rotate';
this.helper['scale'].visible = this.mode == 'scale';
var handles = [];
handles.addAll(this.picker[this.mode].children);
handles.addAll(this.gizmo[this.mode].children);
handles.addAll(this.helper[this.mode].children);
// print("TransformControlsGizmo cameraQuaternion ${this.cameraQuaternion.toJSON()} ");
// print("TransformControlsGizmo updateMatrixWorld mode: ${this.mode} handles: ${handles.length} ");
for (var i = 0; i < handles.length; i++) {
var handle = handles[i];
// hide aligned to camera
handle.visible = true;
handle.rotation.set(0.0, 0.0, 0.0);
handle.position.copy(this.worldPosition);
var factor;
if (this.camera! is OrthographicCamera) {
factor = (this.camera!.top - this.camera!.bottom) / this.camera!.zoom;
} else {
factor = this.worldPosition.distanceTo(this.cameraPosition) *
Math.min(
1.9 *
Math.tan(Math.PI * this.camera!.fov / 360) /
this.camera!.zoom,
7);
}
handle.scale.set(1.0, 1.0, 1.0).multiplyScalar(factor * this.size / 4);
// TODO: simplify helpers and consider decoupling from gizmo
if (handle.tag == 'helper') {
handle.visible = false;
if (handle.name == 'AXIS') {
handle.position.copy(this.worldPositionStart);
handle.visible = this.axis != null;
if (this.axis == 'X') {
_tempQuaternion.setFromEuler(_tempEuler.set(0, 0, 0), false);
handle.quaternion.copy(quaternion).multiply(_tempQuaternion);
if (Math.abs(_alignVector
.copy(_unitX)
.applyQuaternion(quaternion)
.dot(this.eye)) >
0.9) {
handle.visible = false;
}
}
if (this.axis == 'Y') {
_tempQuaternion.setFromEuler(
_tempEuler.set(0, 0, Math.PI / 2), false);
handle.quaternion.copy(quaternion).multiply(_tempQuaternion);
if (Math.abs(_alignVector
.copy(_unitY)
.applyQuaternion(quaternion)
.dot(this.eye)) >
0.9) {
handle.visible = false;
}
}
if (this.axis == 'Z') {
_tempQuaternion.setFromEuler(
_tempEuler.set(0, Math.PI / 2, 0), false);
handle.quaternion.copy(quaternion).multiply(_tempQuaternion);
if (Math.abs(_alignVector
.copy(_unitZ)
.applyQuaternion(quaternion)
.dot(this.eye)) >
0.9) {
handle.visible = false;
}
}
if (this.axis == 'XYZE') {
_tempQuaternion.setFromEuler(
_tempEuler.set(0, Math.PI / 2, 0), false);
_alignVector.copy(this.rotationAxis);
handle.quaternion.setFromRotationMatrix(
_lookAtMatrix.lookAt(_zeroVector, _alignVector, _unitY));
handle.quaternion.multiply(_tempQuaternion);
handle.visible = this.dragging;
}
if (this.axis == 'E') {
handle.visible = false;
}
} else if (handle.name == 'START') {
handle.position.copy(this.worldPositionStart);
handle.visible = this.dragging;
} else if (handle.name == 'END') {
handle.position.copy(this.worldPosition);
handle.visible = this.dragging;
} else if (handle.name == 'DELTA') {
handle.position.copy(this.worldPositionStart);
handle.quaternion.copy(this.worldQuaternionStart);
_tempVector
.set(1e-10, 1e-10, 1e-10)
.add(this.worldPositionStart)
.sub(this.worldPosition)
.multiplyScalar(-1);
_tempVector
.applyQuaternion(this.worldQuaternionStart.clone().invert());
handle.scale.copy(_tempVector);
handle.visible = this.dragging;
} else {
handle.quaternion.copy(quaternion);
if (this.dragging) {
handle.position.copy(this.worldPositionStart);
} else {
handle.position.copy(this.worldPosition);
}
if (this.axis != null) {
handle.visible = this.axis!.indexOf(handle.name) != -1;
}
}
// If updating helper, skip rest of the loop
continue;
}
// Align handles to current local or world rotation
handle.quaternion.copy(quaternion);
if (this.mode == 'translate' || this.mode == 'scale') {
// Hide translate and scale axis facing the camera
var AXIS_HIDE_TRESHOLD = 0.99;
var PLANE_HIDE_TRESHOLD = 0.2;
if (handle.name == 'X') {
if (Math.abs(_alignVector
.copy(_unitX)
.applyQuaternion(quaternion)
.dot(this.eye)) >
AXIS_HIDE_TRESHOLD) {
handle.scale.set(1e-10, 1e-10, 1e-10);
handle.visible = false;
}
}
if (handle.name == 'Y') {
if (Math.abs(_alignVector
.copy(_unitY)
.applyQuaternion(quaternion)
.dot(this.eye)) >
AXIS_HIDE_TRESHOLD) {
handle.scale.set(1e-10, 1e-10, 1e-10);
handle.visible = false;
}
}
if (handle.name == 'Z') {
if (Math.abs(_alignVector
.copy(_unitZ)
.applyQuaternion(quaternion)
.dot(this.eye)) >
AXIS_HIDE_TRESHOLD) {
handle.scale.set(1e-10, 1e-10, 1e-10);
handle.visible = false;
}
}
if (handle.name == 'XY') {
var ll = Math.abs(_alignVector
.copy(_unitZ)
.applyQuaternion(quaternion)
.dot(this.eye));
if (ll < PLANE_HIDE_TRESHOLD) {
handle.scale.set(1e-10, 1e-10, 1e-10);
handle.visible = false;
}
}
if (handle.name == 'YZ') {
if (Math.abs(_alignVector
.copy(_unitX)
.applyQuaternion(quaternion)
.dot(this.eye)) <
PLANE_HIDE_TRESHOLD) {
handle.scale.set(1e-10, 1e-10, 1e-10);
handle.visible = false;
}
}
if (handle.name == 'XZ') {
if (Math.abs(_alignVector
.copy(_unitY)
.applyQuaternion(quaternion)
.dot(this.eye)) <
PLANE_HIDE_TRESHOLD) {
handle.scale.set(1e-10, 1e-10, 1e-10);
handle.visible = false;
}
}
} else if (this.mode == 'rotate') {
// Align handles to current local or world rotation
_tempQuaternion2.copy(quaternion);
_alignVector
.copy(this.eye)
.applyQuaternion(_tempQuaternion.copy(quaternion).invert());
if (handle.name.indexOf('E') != -1) {
handle.quaternion.setFromRotationMatrix(
_lookAtMatrix.lookAt(this.eye, _zeroVector, _unitY));
}
if (handle.name == 'X') {
_tempQuaternion.setFromAxisAngle(
_unitX, Math.atan2(-_alignVector.y, _alignVector.z));
_tempQuaternion.multiplyQuaternions(
_tempQuaternion2, _tempQuaternion);
handle.quaternion.copy(_tempQuaternion);
}
if (handle.name == 'Y') {
_tempQuaternion.setFromAxisAngle(
_unitY, Math.atan2(_alignVector.x, _alignVector.z));
_tempQuaternion.multiplyQuaternions(
_tempQuaternion2, _tempQuaternion);
handle.quaternion.copy(_tempQuaternion);
}
if (handle.name == 'Z') {
_tempQuaternion.setFromAxisAngle(
_unitZ, Math.atan2(_alignVector.y, _alignVector.x));
_tempQuaternion.multiplyQuaternions(
_tempQuaternion2, _tempQuaternion);
handle.quaternion.copy(_tempQuaternion);
}
}
// Hide disabled axes
handle.visible =
handle.visible && (handle.name.indexOf('X') == -1 || this.showX);
handle.visible =
handle.visible && (handle.name.indexOf('Y') == -1 || this.showY);
handle.visible =
handle.visible && (handle.name.indexOf('Z') == -1 || this.showZ);
handle.visible = handle.visible &&
(handle.name.indexOf('E') == -1 ||
(this.showX && this.showY && this.showZ));
// highlight selected axis
handle.material.userData["_color"] =
handle.material.userData["_color"] ?? handle.material.color.clone();
handle.material.userData["_opacity"] =
handle.material.userData["_opacity"] ?? handle.material.opacity;
handle.material.color.copy(handle.material.userData["_color"]);
handle.material.opacity = handle.material.userData["_opacity"];
if (this.enabled && this.axis != null) {
if (handle.name == this.axis) {
handle.material.color.setHex(0xffff00);
handle.material.opacity = 1.0;
} else if (this
.axis!
.split('')
.where((a) {
return handle.name == a;
})
.toList()
.length >
0) {
handle.material.color.setHex(0xffff00);
handle.material.opacity = 1.0;
}
}
}
super.updateMatrixWorld(force);
}