diff --git a/public/boardViewer.html b/public/boardViewer.html index df3864e..491bb09 100644 --- a/public/boardViewer.html +++ b/public/boardViewer.html @@ -366,6 +366,11 @@ function buildSkeletonFK(robot, angles) { const corner0W = posWorld.clone().add(ptrDir.multiplyScalar(markerSizeM * Math.SQRT1_2)); gArmMarkers.add(makeLine(posWorld, corner0W, col, 0.9)); gArmMarkers.add(makeSphere(corner0W, 0.0008, col)); + + // Modell-Normale (Pfeil, gleiche Link-Farbe, halbtransparent) + const modelNormalEnd = posWorld.clone().add(normalW.clone().multiplyScalar(markerSizeM * 1.5)); + gArmMarkers.add(makeLine(posWorld, modelNormalEnd, col, 0.5)); + gArmMarkers.add(makeSphere(modelNormalEnd, 0.0005, col)); } } } @@ -391,8 +396,28 @@ function buildSkeletonFK(robot, angles) { const [lx, ly, lz] = modelM.position; const modelPosW = new THREE.Vector3(lx * S, lz * S, -ly * S).applyMatrix4(frames[obsLink]); const obsPosW = r2vArr(obs.position_mm); + const obsCol = LINK_COLORS[obsLink] ?? 0x3b82f6; gArmMarkers.add(makeLine(modelPosW, obsPosW, 0xff8800, 0.85)); - gArmMarkers.add(makeSphere(obsPosW, 0.007, LINK_COLORS[obsLink] ?? 0x3b82f6)); + gArmMarkers.add(makeSphere(obsPosW, 0.007, obsCol)); + + // Beobachtungs-Ecke 0: Orientierungszeiger für Spin-Vergleich + // corners_m sind Weltkoordinaten in Metern → direkt in Three.js (Y↑=Z, Z↑=-Y) + const c0 = obs.corners_m?.[0]; + if (c0) { + const obsCorner0W = new THREE.Vector3(c0[0], c0[2], -c0[1]); + gArmMarkers.add(makeLine(obsPosW, obsCorner0W, obsCol, 0.85)); + gArmMarkers.add(makeSphere(obsCorner0W, 0.006, obsCol)); + } + + // Beobachtungs-Normale (weißer Pfeil) + if (obs.normal) { + const [on0, on1, on2] = obs.normal; + const obsNormalW = new THREE.Vector3(on0, on2, -on1).normalize(); + const arrowLen = (modelM.size ?? 25) * S * 1.5; + const obsNormalEnd = obsPosW.clone().add(obsNormalW.multiplyScalar(arrowLen)); + gArmMarkers.add(makeLine(obsPosW, obsNormalEnd, 0xffffff, 0.55)); + gArmMarkers.add(makeSphere(obsNormalEnd, 0.005, 0xffffff)); + } } } }