feat(lab): separate current increment from rolling map
This commit is contained in:
@@ -10,7 +10,7 @@ export type LaboratoryMetricSceneMode = "3d" | "plan";
|
||||
export interface LaboratoryMetricObstacleVisual {
|
||||
id: string;
|
||||
decision: LaboratoryMetricDecision;
|
||||
state: "current" | "held" | "expired";
|
||||
state: "current" | "retained" | "held" | "expired";
|
||||
centroidBodyXyzM: LaboratoryMetricPoint3;
|
||||
cellCentersBodyXyzM: readonly LaboratoryMetricPoint3[];
|
||||
}
|
||||
@@ -103,6 +103,8 @@ export function LaboratoryMetricEvidenceScene({
|
||||
const controlsRef = useRef<OrbitControls | null>(null);
|
||||
const contentRef = useRef<THREE.Group | null>(null);
|
||||
const [renderError, setRenderError] = useState<string | null>(null);
|
||||
const [showCurrentIncrement, setShowCurrentIncrement] = useState(true);
|
||||
const [showRollingMap, setShowRollingMap] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const host = hostRef.current;
|
||||
@@ -185,24 +187,34 @@ export function LaboratoryMetricEvidenceScene({
|
||||
child.traverse(disposeRenderable);
|
||||
}
|
||||
|
||||
const contextGeometry = new THREE.BufferGeometry();
|
||||
contextGeometry.setAttribute(
|
||||
"position",
|
||||
new THREE.BufferAttribute(positions(pointCloudBodyXyzM), 3),
|
||||
);
|
||||
content.add(new THREE.Points(
|
||||
contextGeometry,
|
||||
new THREE.PointsMaterial({
|
||||
color: tokenColor(host, "--nodedc-text-muted", [147, 151, 159]),
|
||||
size: 1.7,
|
||||
sizeAttenuation: false,
|
||||
transparent: true,
|
||||
opacity: 0.34,
|
||||
depthWrite: false,
|
||||
}),
|
||||
));
|
||||
if (showCurrentIncrement) {
|
||||
const contextGeometry = new THREE.BufferGeometry();
|
||||
contextGeometry.setAttribute(
|
||||
"position",
|
||||
new THREE.BufferAttribute(positions(pointCloudBodyXyzM), 3),
|
||||
);
|
||||
content.add(new THREE.Points(
|
||||
contextGeometry,
|
||||
new THREE.PointsMaterial({
|
||||
color: tokenColor(host, "--nodedc-text-muted", [147, 151, 159]),
|
||||
size: 1.7,
|
||||
sizeAttenuation: false,
|
||||
transparent: true,
|
||||
opacity: 0.34,
|
||||
depthWrite: false,
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
for (const obstacle of obstacles) {
|
||||
if (
|
||||
(obstacle.state === "current" && !showCurrentIncrement)
|
||||
|| (obstacle.state === "retained" && !showRollingMap)
|
||||
|| obstacle.state === "held"
|
||||
|| obstacle.state === "expired"
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const color = decisionColor(host, obstacle.decision);
|
||||
const cellsGeometry = new THREE.BufferGeometry();
|
||||
cellsGeometry.setAttribute(
|
||||
@@ -213,16 +225,19 @@ export function LaboratoryMetricEvidenceScene({
|
||||
cellsGeometry,
|
||||
new THREE.PointsMaterial({
|
||||
color,
|
||||
size: obstacle.state === "current" ? 4.8 : 3.8,
|
||||
size: obstacle.state === "current" ? 4.8 : 5.2,
|
||||
sizeAttenuation: false,
|
||||
transparent: true,
|
||||
opacity: obstacle.state === "current" ? 0.94 : 0.45,
|
||||
opacity: obstacle.state === "current" ? 0.94 : 0.78,
|
||||
depthWrite: false,
|
||||
}),
|
||||
));
|
||||
const centroid = new THREE.Mesh(
|
||||
new THREE.SphereGeometry(0.1, 16, 12),
|
||||
new THREE.MeshBasicMaterial({ color, wireframe: obstacle.state !== "current" }),
|
||||
new THREE.MeshBasicMaterial({
|
||||
color,
|
||||
wireframe: obstacle.state === "retained",
|
||||
}),
|
||||
);
|
||||
centroid.position.fromArray(scenePoint(obstacle.centroidBodyXyzM));
|
||||
centroid.userData.evidenceId = obstacle.id;
|
||||
@@ -287,7 +302,14 @@ export function LaboratoryMetricEvidenceScene({
|
||||
material.depthWrite = false;
|
||||
});
|
||||
content.add(grid);
|
||||
}, [corridor, obstacles, pointCloudBodyXyzM, rig]);
|
||||
}, [
|
||||
corridor,
|
||||
obstacles,
|
||||
pointCloudBodyXyzM,
|
||||
rig,
|
||||
showCurrentIncrement,
|
||||
showRollingMap,
|
||||
]);
|
||||
|
||||
const resetView = () => {
|
||||
const camera = cameraRef.current;
|
||||
@@ -321,13 +343,30 @@ export function LaboratoryMetricEvidenceScene({
|
||||
>
|
||||
Сбросить ракурс
|
||||
</Button>
|
||||
<Button
|
||||
variant={showCurrentIncrement ? "primary" : "secondary"}
|
||||
size="compact"
|
||||
aria-pressed={showCurrentIncrement}
|
||||
onClick={() => setShowCurrentIncrement((visible) => !visible)}
|
||||
>
|
||||
CURRENT INCREMENT
|
||||
</Button>
|
||||
<Button
|
||||
variant={showRollingMap ? "primary" : "secondary"}
|
||||
size="compact"
|
||||
aria-pressed={showRollingMap}
|
||||
onClick={() => setShowRollingMap((visible) => !visible)}
|
||||
>
|
||||
ROLLING MAP
|
||||
</Button>
|
||||
<span>ЛКМ · вращение · колесо · масштаб · ПКМ · панорама</span>
|
||||
</div>
|
||||
<div className="laboratory-metric-evidence-scene__legend">
|
||||
<span data-decision="threat">Угроза</span>
|
||||
<span data-decision="not-threat">Вне коридора</span>
|
||||
<span data-decision="unknown">Неизвестно</span>
|
||||
<span data-decision="context">LiDAR context</span>
|
||||
<span data-decision="context">Current increment</span>
|
||||
<span data-decision="rolling">Rolling-map occupied</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user