feat(3d): integrate ZJB scene with project context
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
import type { SceneResultsPayload } from "./sceneData";
|
||||
|
||||
export const SCENE_CHANNEL = "tjwater:zjb-scene";
|
||||
export const SCENE_PROTOCOL_VERSION = 2;
|
||||
|
||||
export type SceneMode =
|
||||
| "network"
|
||||
| "hydraulic"
|
||||
| "map"
|
||||
| "detail"
|
||||
| "pump"
|
||||
| "meters";
|
||||
|
||||
export type SceneDisplayMode = "global" | "coordinated";
|
||||
export type SceneMetricMode = "uniform" | "velocity" | "pressure" | "direction";
|
||||
export type SceneDirectionMode = "none" | "topology" | "results";
|
||||
export type SceneLightingPreset = "day" | "studio" | "evening";
|
||||
export type SceneQuality = "standard" | "high";
|
||||
|
||||
export type SceneNetworkStyle = {
|
||||
scale: number;
|
||||
mode: SceneMetricMode;
|
||||
color: string;
|
||||
missingColor: string;
|
||||
lowColor: string;
|
||||
highColor: string;
|
||||
opacity: number;
|
||||
roughness: number;
|
||||
metalness: number;
|
||||
nodes: boolean;
|
||||
direction: SceneDirectionMode;
|
||||
arrowColor: string;
|
||||
autoRange: boolean;
|
||||
min: number;
|
||||
max: number;
|
||||
};
|
||||
|
||||
export type SceneAppearance = {
|
||||
preset: SceneLightingPreset;
|
||||
exposure: number;
|
||||
shadows: boolean;
|
||||
effects: boolean;
|
||||
quality: SceneQuality;
|
||||
};
|
||||
|
||||
export type SceneCameraView = {
|
||||
id: string;
|
||||
label: string;
|
||||
mode: SceneMode;
|
||||
note?: string;
|
||||
saved: boolean;
|
||||
};
|
||||
|
||||
export type SceneCameraState = {
|
||||
active: string | null;
|
||||
note: string;
|
||||
views: SceneCameraView[];
|
||||
};
|
||||
|
||||
export type SceneStyleSummary = {
|
||||
mode?: SceneMetricMode;
|
||||
min?: number;
|
||||
max?: number;
|
||||
dataLinks?: number;
|
||||
totalLinks?: number;
|
||||
arrows?: number;
|
||||
hasResults?: boolean;
|
||||
resultTime?: string | null;
|
||||
scale?: number;
|
||||
};
|
||||
|
||||
export type SceneRuntimeState = {
|
||||
mode: SceneMode;
|
||||
status: string;
|
||||
contextVisible: boolean;
|
||||
roofVisible: boolean;
|
||||
displayMode: SceneDisplayMode;
|
||||
style: SceneNetworkStyle;
|
||||
styleSummary: SceneStyleSummary;
|
||||
appearance: SceneAppearance;
|
||||
camera: SceneCameraState;
|
||||
};
|
||||
|
||||
export type SceneAssetField = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type SceneAssetSection = {
|
||||
title: string;
|
||||
fields: SceneAssetField[];
|
||||
};
|
||||
|
||||
export type SceneAssetNeighbor = {
|
||||
id: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type SceneAssetSelection = {
|
||||
assetId: string;
|
||||
elementId: string;
|
||||
kind: string;
|
||||
title: string;
|
||||
sections: SceneAssetSection[];
|
||||
neighbors: SceneAssetNeighbor[];
|
||||
};
|
||||
|
||||
export type SceneCommand =
|
||||
| { name: "set-mode"; mode: SceneMode }
|
||||
| { name: "visit-camera"; viewId: string }
|
||||
| { name: "save-camera"; label: string }
|
||||
| { name: "remove-camera"; viewId: string }
|
||||
| { name: "set-style"; patch: Partial<SceneNetworkStyle> }
|
||||
| { name: "reset-style" }
|
||||
| { name: "set-display-mode"; mode: SceneDisplayMode }
|
||||
| { name: "set-appearance"; patch: Partial<SceneAppearance> }
|
||||
| { name: "toggle-context" }
|
||||
| { name: "toggle-roof" }
|
||||
| { name: "fit-view" }
|
||||
| { name: "select-asset"; assetId: string }
|
||||
| { name: "locate-selection" }
|
||||
| { name: "clear-selection" };
|
||||
|
||||
type HostMessageBase = {
|
||||
channel: typeof SCENE_CHANNEL;
|
||||
version: typeof SCENE_PROTOCOL_VERSION;
|
||||
projectCode: string;
|
||||
modelId: string;
|
||||
};
|
||||
|
||||
export type SceneHostMessage = HostMessageBase &
|
||||
(
|
||||
| { type: "results"; payload: SceneResultsPayload }
|
||||
| { type: "clear-results" }
|
||||
| { type: "command"; command: SceneCommand }
|
||||
);
|
||||
|
||||
export type SceneRuntimeMessage = HostMessageBase &
|
||||
(
|
||||
| {
|
||||
type: "ready";
|
||||
nodeIds: string[];
|
||||
linkIds: string[];
|
||||
state: SceneRuntimeState;
|
||||
}
|
||||
| { type: "scene-state"; state: SceneRuntimeState }
|
||||
| { type: "selection-changed"; selection: SceneAssetSelection | null }
|
||||
| { type: "results-applied"; summary: SceneStyleSummary }
|
||||
| { type: "results-cleared" }
|
||||
| { type: "error"; message: string }
|
||||
);
|
||||
|
||||
export const isSceneRuntimeMessage = (
|
||||
input: unknown,
|
||||
): input is SceneRuntimeMessage => {
|
||||
if (!input || typeof input !== "object") return false;
|
||||
const message = input as Partial<SceneRuntimeMessage>;
|
||||
return (
|
||||
message.channel === SCENE_CHANNEL &&
|
||||
message.version === SCENE_PROTOCOL_VERSION &&
|
||||
typeof message.projectCode === "string" &&
|
||||
typeof message.modelId === "string" &&
|
||||
typeof message.type === "string"
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user