updateMatrixWorld method
void
updateMatrixWorld(
[ - bool force = false
])
override
Implementation
@override
updateMatrixWorld([bool force = false]) {
var space = (mode == 'scale') ? 'local' : this.space; // scale always oriented to local rotation
var quaternion = (space == 'local') ? worldQuaternion : _identityQuaternion;
// Show only gizmos for current transform mode
gizmo['translate'].visible = mode == 'translate';
gizmo['rotate'].visible = mode == 'rotate';
gizmo['scale'].visible = mode == 'scale';
helper['translate'].visible = mode == 'translate';
helper['rotate'].visible = mode == 'rotate';
helper['scale'].visible = mode == 'scale';
var handles = [];
handles.addAll(picker[mode].children);
handles.addAll(gizmo[mode].children);
handles.addAll(helper[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(worldPosition);
var factor;
if (camera! is OrthographicCamera) {
factor = (camera!.top - camera!.bottom) / camera!.zoom;
} else {
factor = worldPosition.distanceTo(cameraPosition) *
Math.min(1.9 * Math.tan(Math.pi * camera!.fov / 360) / camera!.zoom, 7);
}
handle.scale.set(1.0, 1.0, 1.0).multiplyScalar(factor * size / 4);
// TODO: simplify helpers and consider decoupling from gizmo
if (handle.tag == 'helper') {
handle.visible = false;
if (handle.name == 'AXIS') {
handle.position.copy(worldPositionStart);
handle.visible = axis != null;
if (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(eye)) > 0.9) {
handle.visible = false;
}
}
if (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(eye)) > 0.9) {
handle.visible = false;
}
}
if (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(eye)) > 0.9) {
handle.visible = false;
}
}
if (axis == 'XYZE') {
_tempQuaternion.setFromEuler(_tempEuler.set(0, Math.pi / 2, 0), false);
_alignVector.copy(rotationAxis);
handle.quaternion.setFromRotationMatrix(_lookAtMatrix.lookAt(_zeroVector, _alignVector, _unitY));
handle.quaternion.multiply(_tempQuaternion);
handle.visible = dragging;
}
if (axis == 'E') {
handle.visible = false;
}
} else if (handle.name == 'START') {
handle.position.copy(worldPositionStart);
handle.visible = dragging;
} else if (handle.name == 'END') {
handle.position.copy(worldPosition);
handle.visible = dragging;
} else if (handle.name == 'DELTA') {
handle.position.copy(worldPositionStart);
handle.quaternion.copy(worldQuaternionStart);
_tempVector.set(1e-10, 1e-10, 1e-10).add(worldPositionStart).sub(worldPosition).multiplyScalar(-1);
_tempVector.applyQuaternion(worldQuaternionStart.clone().invert());
handle.scale.copy(_tempVector);
handle.visible = dragging;
} else {
handle.quaternion.copy(quaternion);
if (dragging) {
handle.position.copy(worldPositionStart);
} else {
handle.position.copy(worldPosition);
}
if (axis != null) {
handle.visible = axis!.contains(handle.name);
}
}
// If updating helper, skip rest of the loop
continue;
}
// Align handles to current local or world rotation
handle.quaternion.copy(quaternion);
if (mode == 'translate' || mode == 'scale') {
// Hide translate and scale axis facing the camera
var axisHideThreshold = 0.99;
var planeHideThreshold = 0.2;
if (handle.name == 'X') {
if (Math.abs(_alignVector.copy(_unitX).applyQuaternion(quaternion).dot(eye)) > axisHideThreshold) {
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(eye)) > axisHideThreshold) {
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(eye)) > axisHideThreshold) {
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(eye));
if (ll < planeHideThreshold) {
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(eye)) < planeHideThreshold) {
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(eye)) < planeHideThreshold) {
handle.scale.set(1e-10, 1e-10, 1e-10);
handle.visible = false;
}
}
} else if (mode == 'rotate') {
// Align handles to current local or world rotation
_tempQuaternion2.copy(quaternion);
_alignVector.copy(eye).applyQuaternion(_tempQuaternion.copy(quaternion).invert());
if (handle.name.indexOf('E') != -1) {
handle.quaternion.setFromRotationMatrix(_lookAtMatrix.lookAt(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 || showX);
handle.visible = handle.visible && (handle.name.indexOf('Y') == -1 || showY);
handle.visible = handle.visible && (handle.name.indexOf('Z') == -1 || showZ);
handle.visible = handle.visible && (handle.name.indexOf('E') == -1 || (showX && showY && 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 (enabled && axis != null) {
if (handle.name == axis) {
handle.material.color.setHex(0xffff00);
handle.material.opacity = 1.0;
} else if (axis?.split('').where((a) => handle.name == a).toList().isNotEmpty == true) {
handle.material.color.setHex(0xffff00);
handle.material.opacity = 1.0;
}
}
}
super.updateMatrixWorld(force);
}