From 8b722ca729fa64c4505b2b173a3fcdf5caedaec8 Mon Sep 17 00:00:00 2001 From: Adriano Dal Pastro Date: Thu, 21 May 2026 16:46:44 +0200 Subject: [PATCH] feat(pose_3d): silhouette robot completa (testa+gambe+spalle) + FRONT come marker terra --- web/pose_3d.js | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/web/pose_3d.js b/web/pose_3d.js index 5caa248..90799e0 100644 --- a/web/pose_3d.js +++ b/web/pose_3d.js @@ -109,18 +109,53 @@ function initScene() { const baseUCS = makeUCS(0.2); scene.add(baseUCS); - const frontArrow = makeLabelSprite('FRONT', '#ffd54f'); - frontArrow.position.set(0.30, 0, 0.05); + // "FRONT" label sul piano del pavimento (Z=0.01, sotto tutto) per indicare + // la direzione +X del base frame. Solo marker visivo, NON interagibile + // (la raycaster considera solo le sfere dei polsi). + const frontArrow = makeLabelSprite('▲ FRONT (base +X)', '#ffd54f'); + frontArrow.position.set(0.30, 0, 0.01); + frontArrow.scale.set(0.18, 0.045, 1); // più largo ma sottile, "etichetta a terra" scene.add(frontArrow); - // Torso - const torso = new THREE.Mesh( - new THREE.BoxGeometry(0.20, 0.40, 0.50), - new THREE.MeshStandardMaterial({ color: 0x4a5560, transparent: true, opacity: 0.7 }), - ); + // Body silhouette: torso + head + legs + shoulders + const bodyMat = new THREE.MeshStandardMaterial({ + color: 0x4a5560, transparent: true, opacity: 0.6, + }); + + // Torso: 20cm x 40cm x 50cm, centered at TORSO_POS + const torso = new THREE.Mesh(new THREE.BoxGeometry(0.20, 0.40, 0.50), bodyMat); torso.position.copy(TORSO_POS); scene.add(torso); + // Head: sfera 12cm sopra il torso + const head = new THREE.Mesh( + new THREE.SphereGeometry(0.09, 24, 16), bodyMat, + ); + head.position.set(TORSO_POS.x, TORSO_POS.y, TORSO_POS.z + 0.25 + 0.09); + scene.add(head); + + // Hips (rectangle) just below torso + const hips = new THREE.Mesh(new THREE.BoxGeometry(0.22, 0.36, 0.10), bodyMat); + hips.position.set(TORSO_POS.x, TORSO_POS.y, TORSO_POS.z - 0.25 - 0.05); + scene.add(hips); + + // Gambe: 2 cilindri verticali, da hip a Z=0 + const legGeom = new THREE.CylinderGeometry(0.06, 0.06, 0.55, 16); + for (const ly of [-0.10, 0.10]) { + const leg = new THREE.Mesh(legGeom, bodyMat); + leg.rotation.x = Math.PI / 2; // asse cilindro su Z + leg.position.set(TORSO_POS.x, TORSO_POS.y + ly, (TORSO_POS.z - 0.30 - 0.275)); + scene.add(leg); + } + + // Spalle: 2 sferette in corrispondenza degli SHOULDER + const shoulderGeom = new THREE.SphereGeometry(0.04, 16, 12); + for (const side of ['right', 'left']) { + const sh = new THREE.Mesh(shoulderGeom, bodyMat); + sh.position.copy(SHOULDER[side]); + scene.add(sh); + } + // Arms for (const side of ['right', 'left']) { const wrist = makeWristMarker(side === 'right' ? 0x4da3ff : 0xff5e7e);