From be0cba6bcf8503db61603c350a4986988803c77f Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Tue, 31 Mar 2026 17:32:26 +0200 Subject: [PATCH] Refactor asset imports and add runtime model instance handling --- src/document/scene-document-validation.ts | 6 ++---- src/runtime-three/runtime-scene-build.ts | 24 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/document/scene-document-validation.ts b/src/document/scene-document-validation.ts index 263bb564..4ed89edd 100644 --- a/src/document/scene-document-validation.ts +++ b/src/document/scene-document-validation.ts @@ -2,12 +2,10 @@ import { type AudioAssetMetadata, type ImageAssetMetadata, type ModelAssetMetadata, - type ModelAssetRecord, type ProjectAssetBoundingBox, - type ProjectAssetRecord, - type ModelInstance, - getProjectAssetKindLabel + type ProjectAssetRecord } from "../assets/project-assets"; +import type { ModelInstance } from "../assets/model-instances"; import { type InteractableEntity, type PlayerStartEntity, diff --git a/src/runtime-three/runtime-scene-build.ts b/src/runtime-three/runtime-scene-build.ts index c23adc21..9623b267 100644 --- a/src/runtime-three/runtime-scene-build.ts +++ b/src/runtime-three/runtime-scene-build.ts @@ -1,4 +1,5 @@ import type { Vec3 } from "../core/vector"; +import { getModelInstances } from "../assets/model-instances"; import type { BoxBrush, BoxFaceId, FaceUvState } from "../document/brushes"; import type { SceneDocument, WorldSettings } from "../document/scene-document"; import { cloneWorldSettings } from "../document/world-settings"; @@ -76,6 +77,15 @@ export interface RuntimeInteractable { enabled: boolean; } +export interface RuntimeModelInstance { + instanceId: string; + assetId: string; + name?: string; + position: Vec3; + rotationDegrees: Vec3; + scale: Vec3; +} + export interface RuntimeEntityCollection { playerStarts: RuntimePlayerStart[]; soundEmitters: RuntimeSoundEmitter[]; @@ -96,6 +106,7 @@ export interface RuntimeSceneDefinition { brushes: RuntimeBoxBrushInstance[]; colliders: RuntimeBoxCollider[]; sceneBounds: RuntimeSceneBounds | null; + modelInstances: RuntimeModelInstance[]; entities: RuntimeEntityCollection; interactionLinks: InteractionLink[]; playerStart: RuntimePlayerStart | null; @@ -180,6 +191,17 @@ function buildRuntimeCollider(brush: BoxBrush): RuntimeBoxCollider { }; } +function buildRuntimeModelInstance(modelInstance: SceneDocument["modelInstances"][string]): RuntimeModelInstance { + return { + instanceId: modelInstance.id, + assetId: modelInstance.assetId, + name: modelInstance.name, + position: cloneVec3(modelInstance.position), + rotationDegrees: cloneVec3(modelInstance.rotationDegrees), + scale: cloneVec3(modelInstance.scale) + }; +} + function combineColliderBounds(colliders: RuntimeBoxCollider[]): RuntimeSceneBounds | null { if (colliders.length === 0) { return null; @@ -310,6 +332,7 @@ export function buildRuntimeSceneFromDocument(document: SceneDocument, options: const brushes = Object.values(document.brushes).map((brush) => buildRuntimeBrush(brush, document)); const colliders = Object.values(document.brushes).map((brush) => buildRuntimeCollider(brush)); const sceneBounds = combineColliderBounds(colliders); + const modelInstances = getModelInstances(document.modelInstances).map(buildRuntimeModelInstance); const entities = buildRuntimeEntityCollection(document); const interactionLinks = getInteractionLinks(document.interactionLinks).map((link) => cloneInteractionLink(link)); const playerStartEntity = getPrimaryPlayerStartEntity(document.entities); @@ -327,6 +350,7 @@ export function buildRuntimeSceneFromDocument(document: SceneDocument, options: brushes, colliders, sceneBounds, + modelInstances, entities, interactionLinks, playerStart,