rotation handles now include motor range indicators
parent
f77ff74f94
commit
244dcf3893
68
script.js
68
script.js
|
|
@ -8,7 +8,7 @@ const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||||
|
|
||||||
const scene = new THREE.Scene();
|
const scene = new THREE.Scene();
|
||||||
scene.background = new THREE.Color(0x111111);
|
scene.background = new THREE.Color(0xaaaaaa);
|
||||||
|
|
||||||
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
|
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
|
||||||
camera.position.set(2, 2, 2);
|
camera.position.set(2, 2, 2);
|
||||||
|
|
@ -18,7 +18,9 @@ camera.lookAt(0, 0, 0);
|
||||||
scene.add(new THREE.AmbientLight(0xffffff, 0.6));
|
scene.add(new THREE.AmbientLight(0xffffff, 0.6));
|
||||||
const directional = new THREE.DirectionalLight(0xffffff, 0.8);
|
const directional = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||||
directional.position.set(15, 10, 7);
|
directional.position.set(15, 10, 7);
|
||||||
scene.add(directional);
|
const directional2 = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||||
|
directional2.position.set(-15, 10, -7);
|
||||||
|
scene.add(directional2);
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
const controls = new OrbitControls(camera, renderer.domElement);
|
const controls = new OrbitControls(camera, renderer.domElement);
|
||||||
|
|
@ -81,39 +83,63 @@ function createRotationArc(axis, lower, upper, radius = 0.1, segments = 32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRotationSector(axis, lower, upper, radius = 0.1, segments = 64) {
|
function createRotationSector(axis, lower, upper, radius = 0.1, segments = 64) {
|
||||||
const shape = new THREE.Shape();
|
const motorMargin = 0.4; // hardcoded extra range beyond joint limits
|
||||||
shape.moveTo(0, 0);
|
const motorLower = lower - motorMargin;
|
||||||
|
const motorUpper = upper + motorMargin;
|
||||||
|
|
||||||
for (let i = 0; i <= segments; i++) {
|
const redMaterial = new THREE.MeshBasicMaterial({
|
||||||
const angle = lower + (upper - lower) * (i / segments);
|
color: 0xff0000,
|
||||||
shape.lineTo(Math.cos(angle) * radius, Math.sin(angle) * radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
shape.lineTo(0, 0); // close the shape
|
|
||||||
|
|
||||||
const geometry = new THREE.ShapeGeometry(shape);
|
|
||||||
const material = new THREE.MeshBasicMaterial({
|
|
||||||
color: 0x888888, // light gray
|
|
||||||
transparent: true,
|
transparent: true,
|
||||||
opacity: 0.3, // translucent
|
opacity: 0.2,
|
||||||
side: THREE.DoubleSide, // show both sides of the fill
|
side: THREE.DoubleSide,
|
||||||
depthTest: false, // ✅ always on top
|
depthTest: false,
|
||||||
depthWrite: false
|
depthWrite: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const whiteMaterial = new THREE.MeshBasicMaterial({
|
||||||
|
color: 0xffffff,
|
||||||
|
transparent: true,
|
||||||
|
opacity: 0.6,
|
||||||
|
side: THREE.DoubleSide,
|
||||||
|
depthTest: false,
|
||||||
|
depthWrite: false
|
||||||
|
});
|
||||||
|
|
||||||
const mesh = new THREE.Mesh(geometry, material);
|
function createArc(start, end, material) {
|
||||||
|
const shape = new THREE.Shape();
|
||||||
|
shape.moveTo(0, 0);
|
||||||
|
for (let i = 0; i <= segments; i++) {
|
||||||
|
const angle = start + (end - start) * (i / segments);
|
||||||
|
shape.lineTo(Math.cos(angle) * radius, Math.sin(angle) * radius);
|
||||||
|
}
|
||||||
|
shape.lineTo(0, 0);
|
||||||
|
const geometry = new THREE.ShapeGeometry(shape);
|
||||||
|
return new THREE.Mesh(geometry, material);
|
||||||
|
}
|
||||||
|
|
||||||
// Orient the sector to match the axis
|
const redLeft = createArc(motorLower, lower, redMaterial);
|
||||||
|
const whiteArc = createArc(lower, upper, whiteMaterial);
|
||||||
|
const redRight = createArc(upper, motorUpper, redMaterial);
|
||||||
|
|
||||||
|
// Orient all arcs to match the axis
|
||||||
const basis = new THREE.Matrix4();
|
const basis = new THREE.Matrix4();
|
||||||
const up = new THREE.Vector3(0, 0, 1);
|
const up = new THREE.Vector3(0, 0, 1);
|
||||||
const quaternion = new THREE.Quaternion().setFromUnitVectors(up, axis.clone().normalize());
|
const quaternion = new THREE.Quaternion().setFromUnitVectors(up, axis.clone().normalize());
|
||||||
basis.makeRotationFromQuaternion(quaternion);
|
basis.makeRotationFromQuaternion(quaternion);
|
||||||
mesh.applyMatrix4(basis);
|
|
||||||
|
|
||||||
return mesh;
|
redLeft.applyMatrix4(basis);
|
||||||
|
whiteArc.applyMatrix4(basis);
|
||||||
|
redRight.applyMatrix4(basis);
|
||||||
|
|
||||||
|
const group = new THREE.Group();
|
||||||
|
group.add(redLeft);
|
||||||
|
group.add(whiteArc);
|
||||||
|
group.add(redRight);
|
||||||
|
|
||||||
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function createAngleIndicator(axis, angle, radius = 0.1) {
|
function createAngleIndicator(axis, angle, radius = 0.1) {
|
||||||
const dir = new THREE.Vector3(Math.cos(angle), Math.sin(angle), 0).multiplyScalar(radius);
|
const dir = new THREE.Vector3(Math.cos(angle), Math.sin(angle), 0).multiplyScalar(radius);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue