73 lines
2.7 KiB
JavaScript
73 lines
2.7 KiB
JavaScript
import * as THREE from 'three';
|
|
|
|
export function createRotationSector(axis, lower, upper, radius = 0.1, segments = 64) {
|
|
const motorMargin = 0.4;
|
|
const motorLower = lower - motorMargin;
|
|
const motorUpper = upper + motorMargin;
|
|
|
|
const redMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.2, side: THREE.DoubleSide, depthTest: false, depthWrite: false });
|
|
const whiteMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.6, side: THREE.DoubleSide, depthTest: false, depthWrite: false });
|
|
|
|
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);
|
|
return new THREE.Mesh(new THREE.ShapeGeometry(shape), material);
|
|
}
|
|
|
|
const redLeft = createArc(motorLower, lower, redMaterial);
|
|
const whiteArc = createArc(lower, upper, whiteMaterial);
|
|
const redRight = createArc(upper, motorUpper, redMaterial);
|
|
|
|
const up = new THREE.Vector3(0, 0, 1);
|
|
const quaternion = new THREE.Quaternion().setFromUnitVectors(up, axis.clone().normalize());
|
|
const basis = new THREE.Matrix4().makeRotationFromQuaternion(quaternion);
|
|
|
|
redLeft.applyMatrix4(basis);
|
|
whiteArc.applyMatrix4(basis);
|
|
redRight.applyMatrix4(basis);
|
|
|
|
const group = new THREE.Group();
|
|
group.add(redLeft, whiteArc, redRight);
|
|
return group;
|
|
}
|
|
|
|
export function createAngleIndicator(axis, angle, radius = 0.1) {
|
|
const dir = new THREE.Vector3(Math.cos(angle), Math.sin(angle), 0).multiplyScalar(radius);
|
|
const geometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), dir]);
|
|
const material = new THREE.LineBasicMaterial({ color: 0xffffff, depthTest: false, depthWrite: false });
|
|
const line = new THREE.Line(geometry, material);
|
|
|
|
const up = new THREE.Vector3(0, 0, 1);
|
|
const quaternion = new THREE.Quaternion().setFromUnitVectors(up, axis.clone().normalize());
|
|
line.applyQuaternion(quaternion);
|
|
|
|
return line;
|
|
}
|
|
|
|
export function createJointLabel(name, angle) {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = 256;
|
|
canvas.height = 64;
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
ctx.fillStyle = 'rgba(0,0,0,0.6)';
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
ctx.font = '20px monospace';
|
|
ctx.fillStyle = '#ffffff';
|
|
ctx.fillText(`${name}: ${(angle * 180 / Math.PI).toFixed(1)}°`, 10, 40);
|
|
|
|
const texture = new THREE.CanvasTexture(canvas);
|
|
const material = new THREE.SpriteMaterial({ map: texture, transparent: true });
|
|
const sprite = new THREE.Sprite(material);
|
|
sprite.scale.set(0.5, 0.125, 1); // adjust size
|
|
|
|
return sprite;
|
|
}
|
|
|