TransformControlsGizmo constructor
TransformControlsGizmo(
- TransformControls controls
Implementation
TransformControlsGizmo(this.controls) : super() {
type = 'TransformControlsGizmo';
// shared materials
var gizmoMaterial = MeshBasicMaterial(
{"depthTest": false, "depthWrite": false, "fog": false, "toneMapped": false, "transparent": true});
var gizmoLineMaterial = LineBasicMaterial(
{"depthTest": false, "depthWrite": false, "fog": false, "toneMapped": false, "transparent": true});
// Make unique material for each axis/color
var matInvisible = gizmoMaterial.clone();
matInvisible.opacity = 0.15;
var matHelper = gizmoLineMaterial.clone();
matHelper.opacity = 0.5;
var matRed = gizmoMaterial.clone();
matRed.color.setHex(0xff0000);
var matGreen = gizmoMaterial.clone();
matGreen.color.setHex(0x00ff00);
var matBlue = gizmoMaterial.clone();
matBlue.color.setHex(0x0000ff);
var matRedTransparent = gizmoMaterial.clone();
matRedTransparent.color.setHex(0xff0000);
matRedTransparent.opacity = 0.5;
var matGreenTransparent = gizmoMaterial.clone();
matGreenTransparent.color.setHex(0x00ff00);
matGreenTransparent.opacity = 0.5;
var matBlueTransparent = gizmoMaterial.clone();
matBlueTransparent.color.setHex(0x0000ff);
matBlueTransparent.opacity = 0.5;
var matWhiteTransparent = gizmoMaterial.clone();
matWhiteTransparent.opacity = 0.25;
var matYellowTransparent = gizmoMaterial.clone();
matYellowTransparent.color.setHex(0xffff00);
matYellowTransparent.opacity = 0.25;
var matYellow = gizmoMaterial.clone();
matYellow.color.setHex(0xffff00);
var matGray = gizmoMaterial.clone();
matGray.color.setHex(0x787878);
// reusable geometry
var arrowGeometry = CylinderGeometry(0, 0.04, 0.1, 12);
arrowGeometry.translate(0, 0.05, 0);
var scaleHandleGeometry = BoxGeometry(0.08, 0.08, 0.08);
scaleHandleGeometry.translate(0, 0.04, 0);
var lineGeometry = BufferGeometry();
lineGeometry.setAttribute('position', Float32BufferAttribute(Float32Array.from([0.0, 0.0, 0.0, 1.0, 0.0, 0.0]), 3));
var lineGeometry2 = CylinderGeometry(0.0075, 0.0075, 0.5, 3);
lineGeometry2.translate(0, 0.25, 0);
circleGeometry(radius, arc) {
var geometry = TorusGeometry(radius, 0.0075, 3, 64, arc * Math.pi * 2);
geometry.rotateY(Math.pi / 2);
geometry.rotateX(Math.pi / 2);
return geometry;
}
// Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position
translateHelperGeometry() {
var geometry = BufferGeometry();
geometry.setAttribute(
'position', Float32BufferAttribute(Float32Array.fromList([0.0, 0.0, 0.0, 1.0, 1.0, 1.0]), 3));
return geometry;
}
// Gizmo definitions - custom hierarchy definitions for setupGizmo() function
var gizmoTranslate = {
"X": [
[
Mesh(arrowGeometry, matRed),
[0.5, 0.0, 0.0],
[0.0, 0.0, -Math.pi / 2]
],
[
Mesh(arrowGeometry, matRed),
[-0.5, 0.0, 0.0],
[0.0, 0.0, Math.pi / 2]
],
[
Mesh(lineGeometry2, matRed),
[0.0, 0.0, 0.0],
[0.0, 0.0, -Math.pi / 2]
]
],
"Y": [
[
Mesh(arrowGeometry, matGreen),
[0, 0.5, 0]
],
[
Mesh(arrowGeometry, matGreen),
[0, -0.5, 0],
[Math.pi, 0, 0]
],
[Mesh(lineGeometry2, matGreen)]
],
"Z": [
[
Mesh(arrowGeometry, matBlue),
[0, 0, 0.5],
[Math.pi / 2, 0, 0]
],
[
Mesh(arrowGeometry, matBlue),
[0, 0, -0.5],
[-Math.pi / 2, 0, 0]
],
[
Mesh(lineGeometry2, matBlue),
null,
[Math.pi / 2, 0, 0]
]
],
"XYZ": [
[
Mesh(OctahedronGeometry(0.1, 0), matWhiteTransparent.clone()),
[0, 0, 0]
]
],
"XY": [
[
Mesh(BoxGeometry(0.15, 0.15, 0.01), matBlueTransparent.clone()),
[0.15, 0.15, 0]
]
],
"YZ": [
[
Mesh(BoxGeometry(0.15, 0.15, 0.01), matRedTransparent.clone()),
[0, 0.15, 0.15],
[0, Math.pi / 2, 0]
]
],
"XZ": [
[
Mesh(BoxGeometry(0.15, 0.15, 0.01), matGreenTransparent.clone()),
[0.15, 0, 0.15],
[-Math.pi / 2, 0, 0]
]
]
};
var pickerTranslate = {
"X": [
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0.3, 0, 0],
[0, 0, -Math.pi / 2]
],
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[-0.3, 0, 0],
[0, 0, Math.pi / 2]
]
],
"Y": [
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0, 0.3, 0]
],
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0, -0.3, 0],
[0, 0, Math.pi]
]
],
"Z": [
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0, 0, 0.3],
[Math.pi / 2, 0, 0]
],
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0, 0, -0.3],
[-Math.pi / 2, 0, 0]
]
],
"XYZ": [
[Mesh(OctahedronGeometry(0.2, 0), matInvisible)]
],
"XY": [
[
Mesh(BoxGeometry(0.2, 0.2, 0.01), matInvisible),
[0.15, 0.15, 0]
]
],
"YZ": [
[
Mesh(BoxGeometry(0.2, 0.2, 0.01), matInvisible),
[0, 0.15, 0.15],
[0, Math.pi / 2, 0]
]
],
"XZ": [
[
Mesh(BoxGeometry(0.2, 0.2, 0.01), matInvisible),
[0.15, 0, 0.15],
[-Math.pi / 2, 0, 0]
]
]
};
var helperTranslate = {
"START": [
[Mesh(OctahedronGeometry(0.01, 2), matHelper), null, null, null, 'helper']
],
"END": [
[Mesh(OctahedronGeometry(0.01, 2), matHelper), null, null, null, 'helper']
],
"DELTA": [
[Line(translateHelperGeometry(), matHelper), null, null, null, 'helper']
],
"X": [
[
Line(lineGeometry, matHelper.clone()),
[-1e3, 0, 0],
null,
[1e6, 1, 1],
'helper'
]
],
"Y": [
[
Line(lineGeometry, matHelper.clone()),
[0, -1e3, 0],
[0, 0, Math.pi / 2],
[1e6, 1, 1],
'helper'
]
],
"Z": [
[
Line(lineGeometry, matHelper.clone()),
[0, 0, -1e3],
[0, -Math.pi / 2, 0],
[1e6, 1, 1],
'helper'
]
]
};
var gizmoRotate = {
"XYZE": [
[
Mesh(circleGeometry(0.5, 1), matGray),
null,
[0, Math.pi / 2, 0]
]
],
"X": [
[Mesh(circleGeometry(0.5, 0.5), matRed)]
],
"Y": [
[
Mesh(circleGeometry(0.5, 0.5), matGreen),
null,
[0, 0, -Math.pi / 2]
]
],
"Z": [
[
Mesh(circleGeometry(0.5, 0.5), matBlue),
null,
[0, Math.pi / 2, 0]
]
],
"E": [
[
Mesh(circleGeometry(0.75, 1), matYellowTransparent),
null,
[0, Math.pi / 2, 0]
]
]
};
var helperRotate = {
"AXIS": [
[
Line(lineGeometry, matHelper.clone()),
[-1e3, 0, 0],
null,
[1e6, 1, 1],
'helper'
]
]
};
var pickerRotate = {
"XYZE": [
[Mesh(SphereGeometry(0.25, 10, 8), matInvisible)]
],
"X": [
[
Mesh(TorusGeometry(0.5, 0.1, 4, 24), matInvisible),
[0, 0, 0],
[0, -Math.pi / 2, -Math.pi / 2]
],
],
"Y": [
[
Mesh(TorusGeometry(0.5, 0.1, 4, 24), matInvisible),
[0, 0, 0],
[Math.pi / 2, 0, 0]
],
],
"Z": [
[
Mesh(TorusGeometry(0.5, 0.1, 4, 24), matInvisible),
[0, 0, 0],
[0, 0, -Math.pi / 2]
],
],
"E": [
[Mesh(TorusGeometry(0.75, 0.1, 2, 24), matInvisible)]
]
};
var gizmoScale = {
"X": [
[
Mesh(scaleHandleGeometry, matRed),
[0.5, 0, 0],
[0, 0, -Math.pi / 2]
],
[
Mesh(lineGeometry2, matRed),
[0, 0, 0],
[0, 0, -Math.pi / 2]
],
[
Mesh(scaleHandleGeometry, matRed),
[-0.5, 0, 0],
[0, 0, Math.pi / 2]
],
],
"Y": [
[
Mesh(scaleHandleGeometry, matGreen),
[0, 0.5, 0]
],
[Mesh(lineGeometry2, matGreen)],
[
Mesh(scaleHandleGeometry, matGreen),
[0, -0.5, 0],
[0, 0, Math.pi]
],
],
"Z": [
[
Mesh(scaleHandleGeometry, matBlue),
[0, 0, 0.5],
[Math.pi / 2, 0, 0]
],
[
Mesh(lineGeometry2, matBlue),
[0, 0, 0],
[Math.pi / 2, 0, 0]
],
[
Mesh(scaleHandleGeometry, matBlue),
[0, 0, -0.5],
[-Math.pi / 2, 0, 0]
]
],
"XY": [
[
Mesh(BoxGeometry(0.15, 0.15, 0.01), matBlueTransparent),
[0.15, 0.15, 0]
]
],
"YZ": [
[
Mesh(BoxGeometry(0.15, 0.15, 0.01), matRedTransparent),
[0, 0.15, 0.15],
[0, Math.pi / 2, 0]
]
],
"XZ": [
[
Mesh(BoxGeometry(0.15, 0.15, 0.01), matGreenTransparent),
[0.15, 0, 0.15],
[-Math.pi / 2, 0, 0]
]
],
"XYZ": [
[Mesh(BoxGeometry(0.1, 0.1, 0.1), matWhiteTransparent.clone())],
]
};
var pickerScale = {
"X": [
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0.3, 0, 0],
[0, 0, -Math.pi / 2]
],
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[-0.3, 0, 0],
[0, 0, Math.pi / 2]
]
],
"Y": [
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0, 0.3, 0]
],
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0, -0.3, 0],
[0, 0, Math.pi]
]
],
"Z": [
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0, 0, 0.3],
[Math.pi / 2, 0, 0]
],
[
Mesh(CylinderGeometry(0.2, 0, 0.6, 4), matInvisible),
[0, 0, -0.3],
[-Math.pi / 2, 0, 0]
]
],
"XY": [
[
Mesh(BoxGeometry(0.2, 0.2, 0.01), matInvisible),
[0.15, 0.15, 0]
],
],
"YZ": [
[
Mesh(BoxGeometry(0.2, 0.2, 0.01), matInvisible),
[0, 0.15, 0.15],
[0, Math.pi / 2, 0]
],
],
"XZ": [
[
Mesh(BoxGeometry(0.2, 0.2, 0.01), matInvisible),
[0.15, 0, 0.15],
[-Math.pi / 2, 0, 0]
],
],
"XYZ": [
[
Mesh(BoxGeometry(0.2, 0.2, 0.2), matInvisible),
[0, 0, 0]
],
]
};
var helperScale = {
"X": [
[
Line(lineGeometry, matHelper.clone()),
[-1e3, 0, 0],
null,
[1e6, 1, 1],
'helper'
]
],
"Y": [
[
Line(lineGeometry, matHelper.clone()),
[0, -1e3, 0],
[0, 0, Math.pi / 2],
[1e6, 1, 1],
'helper'
]
],
"Z": [
[
Line(lineGeometry, matHelper.clone()),
[0, 0, -1e3],
[0, -Math.pi / 2, 0],
[1e6, 1, 1],
'helper'
]
]
};
// Creates an Object3D with gizmos described in custom hierarchy definition.
setupGizmo(gizmoMap) {
var gizmo = Object3D();
for (var name in gizmoMap.keys) {
var len = gizmoMap[name].length;
for (var i = (len - 1); i >= 0; i--) {
var gi = gizmoMap[name][i];
dynamic object;
if (gi.length > 0) {
object = gi[0].clone();
}
List<num>? position;
if (gi.length > 1) {
position = gi[1];
}
List<num>? rotation;
if (gi.length > 2) {
rotation = gi[2];
}
List<num>? scale;
if (gi.length > 3) {
scale = gi[3];
}
dynamic tag;
if (gi.length > 4) {
tag = gi[4];
}
// name and tag properties are essential for picking and updating logic.
object.name = name;
object.tag = tag;
if (position != null) {
object.position.set(position[0].toDouble(), position[1].toDouble(), position[2].toDouble());
}
if (rotation != null) {
object.rotation.set(rotation[0].toDouble(), rotation[1].toDouble(), rotation[2].toDouble());
}
if (scale != null) {
object.scale.set(scale[0].toDouble(), scale[1].toDouble(), scale[2].toDouble());
}
object.updateMatrix();
var tempGeometry = object.geometry.clone();
tempGeometry.applyMatrix4(object.matrix);
object.geometry = tempGeometry;
object.renderOrder = Math.infinity;
object.position.set(0.0, 0.0, 0.0);
object.rotation.set(0.0, 0.0, 0.0);
object.scale.set(1.0, 1.0, 1.0);
gizmo.add(object);
}
}
return gizmo;
}
// Gizmo creation
gizmo['translate'] = setupGizmo(gizmoTranslate);
gizmo['rotate'] = setupGizmo(gizmoRotate);
gizmo['scale'] = setupGizmo(gizmoScale);
picker['translate'] = setupGizmo(pickerTranslate);
picker['rotate'] = setupGizmo(pickerRotate);
picker['scale'] = setupGizmo(pickerScale);
helper['translate'] = setupGizmo(helperTranslate);
helper['rotate'] = setupGizmo(helperRotate);
helper['scale'] = setupGizmo(helperScale);
add(gizmo['translate']);
add(gizmo['rotate']);
add(gizmo['scale']);
add(picker['translate']);
add(picker['rotate']);
add(picker['scale']);
add(helper['translate']);
add(helper['rotate']);
add(helper['scale']);
// Pickers should be hidden always
picker['translate'].visible = false;
picker['rotate'].visible = false;
picker['scale'].visible = false;
}