Advance M8-M11 parity workflows
This commit is contained in:
@@ -7,6 +7,7 @@ import { normalizeProjectAssetPath } from "./asset-path";
|
||||
import { parseEditorWorkflow, type EditorWorkflowIR } from "./editor-workflow";
|
||||
import { parseScriptSourceInventory, type ScriptSourceInventoryIR } from "./scripting-platform";
|
||||
import { parsePhysicsSimulationManifest, type PhysicsSimulationManifestIR } from "./physics-simulation";
|
||||
import { GEOMETRY_NODE_GRAPH_BUDGET, parseGeometryNodeGraph, type GeometryNodeGraphIR } from "./geometry-nodes";
|
||||
|
||||
export type SceneNodeType =
|
||||
| "EMPTY"
|
||||
@@ -193,6 +194,8 @@ export interface MaterialIR {
|
||||
normalImageId?: string | null;
|
||||
imageIds?: string[];
|
||||
warnings?: string[];
|
||||
/** SHA-256 of the serialized bounded shader graph when a node tree was read. */
|
||||
shaderGraphHash?: string;
|
||||
nodes?: MaterialNodeIR[];
|
||||
links?: MaterialLinkIR[];
|
||||
}
|
||||
@@ -269,6 +272,7 @@ export interface ImageIR {
|
||||
width?: number;
|
||||
height?: number;
|
||||
sha256?: string;
|
||||
colorSpace?: "SRGB" | "NON_COLOR" | "LINEAR";
|
||||
sourcePath?: string;
|
||||
packed?: boolean;
|
||||
packedByteLength?: number;
|
||||
@@ -369,6 +373,8 @@ export interface VFontResourceIR {
|
||||
sourcePath: string;
|
||||
builtin: boolean;
|
||||
packed: boolean;
|
||||
packedByteLength?: number;
|
||||
sha256?: string;
|
||||
}
|
||||
|
||||
export interface NonMeshVolumePropertiesIR {
|
||||
@@ -493,6 +499,7 @@ export interface SceneSnapshotIR {
|
||||
scriptSources?: ScriptSourceInventoryIR;
|
||||
scriptSourceStatus?: "AVAILABLE" | "BLOCKED";
|
||||
physicsSimulation?: PhysicsSimulationManifestIR;
|
||||
geometryNodeGraphs?: GeometryNodeGraphIR[];
|
||||
libraries?: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -738,6 +745,7 @@ export function parseSceneSnapshotIR(value: unknown): SceneSnapshotIR {
|
||||
if (image.sourcePath !== undefined) requireString(image.sourcePath, `images[${index}].sourcePath`);
|
||||
if (image.packed !== undefined) requireBoolean(image.packed, `images[${index}].packed`);
|
||||
if (image.packedByteLength !== undefined) requireNumber(image.packedByteLength, `images[${index}].packedByteLength`);
|
||||
if (image.colorSpace !== undefined && !["SRGB", "NON_COLOR", "LINEAR"].includes(image.colorSpace as string)) throw new Error(`images[${index}].colorSpace is invalid`);
|
||||
if (image.sourceKind !== undefined) requireString(image.sourceKind, `images[${index}].sourceKind`);
|
||||
if (image.assetStatus !== undefined) requireString(image.assetStatus, `images[${index}].assetStatus`);
|
||||
if (image.libraryLinked !== undefined) requireBoolean(image.libraryLinked, `images[${index}].libraryLinked`);
|
||||
@@ -757,6 +765,15 @@ export function parseSceneSnapshotIR(value: unknown): SceneSnapshotIR {
|
||||
requireString(font.sourcePath, `vfonts[${index}].sourcePath`);
|
||||
requireBoolean(font.builtin, `vfonts[${index}].builtin`);
|
||||
requireBoolean(font.packed, `vfonts[${index}].packed`);
|
||||
if (font.packed) {
|
||||
if (!Number.isSafeInteger(font.packedByteLength) || (font.packedByteLength as number) <= 0 ||
|
||||
typeof font.sha256 !== "string" || !/^[0-9a-f]{64}$/.test(font.sha256)) {
|
||||
throw new Error(`SceneIR.vfonts[${index}] packed identity is invalid`);
|
||||
}
|
||||
}
|
||||
else if (font.packedByteLength !== undefined || font.sha256 !== undefined) {
|
||||
throw new Error(`SceneIR.vfonts[${index}] unpacked identity is invalid`);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const [index, data] of ((value.nonMeshData ?? []) as unknown[]).entries()) {
|
||||
@@ -1144,5 +1161,14 @@ export function parseSceneSnapshotIR(value: unknown): SceneSnapshotIR {
|
||||
if (value.scriptSourceStatus !== "AVAILABLE") throw new Error("SceneIR.scriptSourceStatus must be AVAILABLE when scriptSources is present");
|
||||
}
|
||||
if (value.physicsSimulation !== undefined) parsePhysicsSimulationManifest(value.physicsSimulation);
|
||||
if (value.geometryNodeGraphs !== undefined) {
|
||||
const graphs = requireArray(value.geometryNodeGraphs, "geometryNodeGraphs");
|
||||
if (graphs.length > GEOMETRY_NODE_GRAPH_BUDGET.maxGraphs) throw new Error("SceneIR.geometryNodeGraphs exceeds the graph budget");
|
||||
const graphIds = new Set<string>();
|
||||
for (const [index, graph] of graphs.entries()) {
|
||||
const parsed = parseGeometryNodeGraph(graph);
|
||||
if (!graphIds.add(parsed.id)) throw new Error(`SceneIR.geometryNodeGraphs[${index}] has a duplicate graph ID`);
|
||||
}
|
||||
}
|
||||
return value as unknown as SceneSnapshotIR;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user