diff --git a/script.js b/script.js index c8fff56..45bd7e5 100644 --- a/script.js +++ b/script.js @@ -8,7 +8,7 @@ const renderer = new THREE.WebGLRenderer({ canvas, antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); 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); camera.position.set(2, 2, 2); @@ -18,7 +18,9 @@ camera.lookAt(0, 0, 0); scene.add(new THREE.AmbientLight(0xffffff, 0.6)); const directional = new THREE.DirectionalLight(0xffffff, 0.8); 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 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) { - const shape = new THREE.Shape(); - shape.moveTo(0, 0); + const motorMargin = 0.4; // hardcoded extra range beyond joint limits + const motorLower = lower - motorMargin; + const motorUpper = upper + motorMargin; - for (let i = 0; i <= segments; i++) { - const angle = lower + (upper - lower) * (i / segments); - 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 + const redMaterial = new THREE.MeshBasicMaterial({ + color: 0xff0000, transparent: true, - opacity: 0.3, // translucent - side: THREE.DoubleSide, // show both sides of the fill - depthTest: false, // ✅ always on top + 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 + }); - 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 up = new THREE.Vector3(0, 0, 1); const quaternion = new THREE.Quaternion().setFromUnitVectors(up, axis.clone().normalize()); 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) { const dir = new THREE.Vector3(Math.cos(angle), Math.sin(angle), 0).multiplyScalar(radius); @@ -123,11 +149,11 @@ function createAngleIndicator(axis, angle, radius = 0.1) { ]); const material = new THREE.LineBasicMaterial({ - color: 0xffffff, // white - linewidth: 2, // note: linewidth only works in some renderers - depthTest: false, // ✅ always on top - depthWrite: false -}); + color: 0xffffff, // white + linewidth: 2, // note: linewidth only works in some renderers + depthTest: false, // ✅ always on top + depthWrite: false + }); const line = new THREE.Line(geometry, material);