fix(gui): work_plane 3D view = camera POV + red = excluded points
- Camera at origin (CV frame) looking at +Z with screen-up = CV −Y, so the rendered scene matches the camera's vantage point. OrbitControls retargets to the plane centroid on fit so rotation feels natural. - Simplify scatter coloring to two tones: red for filter-excluded points (signed_distance < −offset_mm/1000), cyan-white for everything kept. Matches the backend filter contract exactly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
652fa4b912
commit
56f8888217
2 files changed
+25
-11
No files matched your search
+1
-1
@@ -192,7 +192,7 @@
|
|||||||
<div class="canvas-wrap" style="width:min(100%,720px)">
|
<div class="canvas-wrap" style="width:min(100%,720px)">
|
||||||
<canvas id="wp3dCanvas" width="720" height="360" style="display:block;background:#0a0d11;border:1px solid var(--border);border-radius:4px"></canvas>
|
<canvas id="wp3dCanvas" width="720" height="360" style="display:block;background:#0a0d11;border:1px solid var(--border);border-radius:4px"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="marker-info">piano viola · verde = inlier · giallo = sopra piano+offset · rosso = sotto piano-offset · grigio = buffer · drag = ruota · wheel = zoom</div>
|
<div class="marker-info">vista camera · piano viola · ciano = punti tenuti · rosso = esclusi (sotto piano−offset) · drag = ruota · wheel = zoom</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Calibrazione</h2>
|
<h2>Calibrazione</h2>
|
||||||
|
|||||||
+24
-10
@@ -135,16 +135,26 @@ function startRgbLoop() {
|
|||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// ---------------- Three.js 3D viewer ----------------
|
// ---------------- Three.js 3D viewer — camera-POV ----------------
|
||||||
|
//
|
||||||
|
// CV camera frame: X right, Y down, Z forward.
|
||||||
|
// We render the scene so the user sees it from the camera's vantage point:
|
||||||
|
// camera at the origin, looking at +Z, with screen-up = CV -Y. OrbitControls
|
||||||
|
// can rotate around the scene centroid once it's defined; before any fit the
|
||||||
|
// view stays at camera-POV.
|
||||||
const three = (function setupThree() {
|
const three = (function setupThree() {
|
||||||
const canvas = $('wp3dCanvas');
|
const canvas = $('wp3dCanvas');
|
||||||
const scene = new THREE.Scene();
|
const scene = new THREE.Scene();
|
||||||
const camera = new THREE.PerspectiveCamera(45, canvas.width / canvas.height, 0.01, 20);
|
const camera = new THREE.PerspectiveCamera(45, canvas.width / canvas.height, 0.01, 20);
|
||||||
camera.position.set(0.5, -0.5, -1.2);
|
// Camera-POV: stand just behind the camera origin so OrbitControls has a
|
||||||
camera.lookAt(0, 0, 1);
|
// non-zero distance to its target. Screen-up = CV -Y.
|
||||||
|
camera.up.set(0, -1, 0);
|
||||||
|
camera.position.set(0, 0, -0.001);
|
||||||
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
|
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
|
||||||
renderer.setSize(canvas.width, canvas.height);
|
renderer.setSize(canvas.width, canvas.height);
|
||||||
const controls = new OrbitControls(camera, canvas);
|
const controls = new OrbitControls(camera, canvas);
|
||||||
|
controls.target.set(0, 0, 1);
|
||||||
|
controls.update();
|
||||||
scene.add(new THREE.AxesHelper(0.1));
|
scene.add(new THREE.AxesHelper(0.1));
|
||||||
const planeMesh = new THREE.Mesh(
|
const planeMesh = new THREE.Mesh(
|
||||||
new THREE.PlaneGeometry(0.4, 0.4),
|
new THREE.PlaneGeometry(0.4, 0.4),
|
||||||
@@ -165,6 +175,9 @@ const three = (function setupThree() {
|
|||||||
// Align plane to its normal.
|
// Align plane to its normal.
|
||||||
planeMesh.lookAt(c[0] + n[0], c[1] + n[1], c[2] + n[2]);
|
planeMesh.lookAt(c[0] + n[0], c[1] + n[1], c[2] + n[2]);
|
||||||
planeMesh.visible = true;
|
planeMesh.visible = true;
|
||||||
|
// Move the orbit target onto the plane centroid so rotation feels natural.
|
||||||
|
controls.target.set(c[0], c[1], c[2]);
|
||||||
|
controls.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setScatter(pointsCv, plane, offsetMm) {
|
function setScatter(pointsCv, plane, offsetMm) {
|
||||||
@@ -178,17 +191,18 @@ const three = (function setupThree() {
|
|||||||
const nz = plane ? plane.normal[2] : 0;
|
const nz = plane ? plane.normal[2] : 0;
|
||||||
const d = plane ? plane.offset : 0;
|
const d = plane ? plane.offset : 0;
|
||||||
const offsetM = (offsetMm || 0) / 1000.0;
|
const offsetM = (offsetMm || 0) / 1000.0;
|
||||||
const rmsM = plane ? (plane.fit_rms_mm / 1000.0) * 2.0 : 0.01;
|
// Two-tone colouring: filter-excluded points (signed < -offset_m) red,
|
||||||
|
// everything else cyan-white. This matches the backend filter contract
|
||||||
|
// (keep == signed >= -offset_m).
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i = 0; i < n; i++) {
|
||||||
const x = pointsCv[i][0], y = pointsCv[i][1], z = pointsCv[i][2];
|
const x = pointsCv[i][0], y = pointsCv[i][1], z = pointsCv[i][2];
|
||||||
positions[3 * i] = x; positions[3 * i + 1] = y; positions[3 * i + 2] = z;
|
positions[3 * i] = x; positions[3 * i + 1] = y; positions[3 * i + 2] = z;
|
||||||
const signed = plane ? (nx * x + ny * y + nz * z + d) : 0;
|
const signed = plane ? (nx * x + ny * y + nz * z + d) : 0;
|
||||||
let r = 0.5, g = 0.5, b = 0.5;
|
let r, g, b;
|
||||||
if (plane) {
|
if (plane && signed < -offsetM) {
|
||||||
if (signed > offsetM) { r = 1.0; g = 0.83; b = 0.31; } // yellow: above plane+offset
|
r = 0.93; g = 0.27; b = 0.27; // red: excluded by below-plane filter
|
||||||
else if (signed < -offsetM) { r = 0.93; g = 0.27; b = 0.27; } // red: below plane-offset
|
} else {
|
||||||
else if (Math.abs(signed) <= rmsM) { r = 0.30; g = 0.78; b = 0.40; } // green: inlier
|
r = 0.75; g = 0.92; b = 1.00; // cyan-white: kept
|
||||||
else { r = 0.55; g = 0.55; b = 0.55; } // grey: buffer
|
|
||||||
}
|
}
|
||||||
colors[3 * i] = r; colors[3 * i + 1] = g; colors[3 * i + 2] = b;
|
colors[3 * i] = r; colors[3 * i + 1] = g; colors[3 * i + 2] = b;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user