fix(lab): stabilize recorded spatial playback

This commit is contained in:
DCCONSTRUCTIONS
2026-08-06 08:51:10 +03:00
parent 9df9f58ab8
commit e38f2fb1da
11 changed files with 316 additions and 99 deletions
@@ -96,6 +96,7 @@ export function LaboratoryMetricEvidenceScene({
obstacles,
rig,
corridor,
occupiedVoxelSizeM,
mode,
label,
}: {
@@ -103,6 +104,7 @@ export function LaboratoryMetricEvidenceScene({
obstacles: readonly LaboratoryMetricObstacleVisual[];
rig: LaboratoryMetricRigVisual;
corridor: LaboratoryMetricCorridorVisual;
occupiedVoxelSizeM: number;
mode: LaboratoryMetricSceneMode;
label: string;
}) {
@@ -205,10 +207,10 @@ export function LaboratoryMetricEvidenceScene({
contextGeometry,
new THREE.PointsMaterial({
color: tokenColor(host, "--nodedc-text-muted", [147, 151, 159]),
size: 1.7,
size: 1.55,
sizeAttenuation: false,
transparent: true,
opacity: 0.34,
opacity: 0.58,
depthWrite: false,
}),
));
@@ -224,36 +226,62 @@ export function LaboratoryMetricEvidenceScene({
continue;
}
const color = decisionColor(host, obstacle.decision);
const cellsGeometry = new THREE.BufferGeometry();
cellsGeometry.setAttribute(
"position",
new THREE.BufferAttribute(positions(obstacle.cellCentersBodyXyzM), 3),
);
content.add(new THREE.Points(
cellsGeometry,
new THREE.PointsMaterial({
if (obstacle.state === "retained") {
const geometry = new THREE.BoxGeometry(
occupiedVoxelSizeM * 0.82,
occupiedVoxelSizeM * 0.82,
occupiedVoxelSizeM * 0.82,
);
const material = new THREE.MeshBasicMaterial({
color,
size: obstacle.state === "current" ? 4.8 : 5.2,
sizeAttenuation: false,
wireframe: true,
transparent: true,
opacity: obstacle.state === "current" ? 0.94 : 0.78,
opacity: 0.34,
depthWrite: false,
}),
));
const centroid = new THREE.Mesh(
new THREE.SphereGeometry(0.1, 16, 12),
new THREE.MeshBasicMaterial({
color,
wireframe: obstacle.state === "retained",
}),
);
centroid.position.fromArray(scenePoint(obstacle.centroidBodyXyzM));
centroid.userData.evidenceId = obstacle.id;
content.add(centroid);
});
const voxels = new THREE.InstancedMesh(
geometry,
material,
obstacle.cellCentersBodyXyzM.length,
);
const matrix = new THREE.Matrix4();
obstacle.cellCentersBodyXyzM.forEach((point, index) => {
matrix.makeTranslation(...scenePoint(point));
voxels.setMatrixAt(index, matrix);
});
voxels.instanceMatrix.needsUpdate = true;
voxels.userData.evidenceId = obstacle.id;
content.add(voxels);
} else {
const cellsGeometry = new THREE.BufferGeometry();
cellsGeometry.setAttribute(
"position",
new THREE.BufferAttribute(positions(obstacle.cellCentersBodyXyzM), 3),
);
content.add(new THREE.Points(
cellsGeometry,
new THREE.PointsMaterial({
color,
size: 4.4,
sizeAttenuation: false,
transparent: true,
opacity: 0.96,
depthWrite: false,
}),
));
const centroid = new THREE.Mesh(
new THREE.SphereGeometry(0.065, 12, 8),
new THREE.MeshBasicMaterial({ color }),
);
centroid.position.fromArray(scenePoint(obstacle.centroidBodyXyzM));
centroid.userData.evidenceId = obstacle.id;
content.add(centroid);
}
}
}, [
obstacles,
occupiedVoxelSizeM,
pointCloudBodyXyzM,
showCurrentIncrement,
showRollingMap,