Update runtime scene build to include volume data
This commit is contained in:
@@ -1,7 +1,16 @@
|
|||||||
import type { LoadedModelAsset } from "../assets/gltf-model-import";
|
import type { LoadedModelAsset } from "../assets/gltf-model-import";
|
||||||
import type { Vec3 } from "../core/vector";
|
import type { Vec3 } from "../core/vector";
|
||||||
import { getModelInstances } from "../assets/model-instances";
|
import { getModelInstances } from "../assets/model-instances";
|
||||||
import { cloneBoxBrushGeometry, cloneFaceUvState, type BoxBrush, type BoxBrushGeometry, type BoxFaceId, type FaceUvState } from "../document/brushes";
|
import {
|
||||||
|
cloneBoxBrushGeometry,
|
||||||
|
cloneBoxBrushVolumeSettings,
|
||||||
|
cloneFaceUvState,
|
||||||
|
type BoxBrush,
|
||||||
|
type BoxBrushGeometry,
|
||||||
|
type BoxBrushVolumeSettings,
|
||||||
|
type BoxFaceId,
|
||||||
|
type FaceUvState
|
||||||
|
} from "../document/brushes";
|
||||||
import type { SceneDocument } from "../document/scene-document";
|
import type { SceneDocument } from "../document/scene-document";
|
||||||
import { cloneWorldSettings, type WorldSettings } from "../document/world-settings";
|
import { cloneWorldSettings, type WorldSettings } from "../document/world-settings";
|
||||||
import { getEntityInstances, getPrimaryPlayerStartEntity, type EntityInstance } from "../entities/entity-instances";
|
import { getEntityInstances, getPrimaryPlayerStartEntity, type EntityInstance } from "../entities/entity-instances";
|
||||||
@@ -29,6 +38,32 @@ export interface RuntimeBoxBrushInstance {
|
|||||||
size: Vec3;
|
size: Vec3;
|
||||||
geometry: BoxBrushGeometry;
|
geometry: BoxBrushGeometry;
|
||||||
faces: Record<BoxFaceId, RuntimeBrushFace>;
|
faces: Record<BoxFaceId, RuntimeBrushFace>;
|
||||||
|
volume: BoxBrushVolumeSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RuntimeFogVolume {
|
||||||
|
brushId: string;
|
||||||
|
center: Vec3;
|
||||||
|
rotationDegrees: Vec3;
|
||||||
|
size: Vec3;
|
||||||
|
colorHex: string;
|
||||||
|
density: number;
|
||||||
|
padding: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RuntimeWaterVolume {
|
||||||
|
brushId: string;
|
||||||
|
center: Vec3;
|
||||||
|
rotationDegrees: Vec3;
|
||||||
|
size: Vec3;
|
||||||
|
colorHex: string;
|
||||||
|
surfaceOpacity: number;
|
||||||
|
waveStrength: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RuntimeBoxVolumeCollection {
|
||||||
|
fog: RuntimeFogVolume[];
|
||||||
|
water: RuntimeWaterVolume[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuntimeBrushTriMeshCollider {
|
export interface RuntimeBrushTriMeshCollider {
|
||||||
@@ -147,6 +182,7 @@ export interface RuntimeSceneDefinition {
|
|||||||
world: WorldSettings;
|
world: WorldSettings;
|
||||||
localLights: RuntimeLocalLightCollection;
|
localLights: RuntimeLocalLightCollection;
|
||||||
brushes: RuntimeBoxBrushInstance[];
|
brushes: RuntimeBoxBrushInstance[];
|
||||||
|
volumes: RuntimeBoxVolumeCollection;
|
||||||
colliders: RuntimeSceneCollider[];
|
colliders: RuntimeSceneCollider[];
|
||||||
sceneBounds: RuntimeSceneBounds | null;
|
sceneBounds: RuntimeSceneBounds | null;
|
||||||
modelInstances: RuntimeModelInstance[];
|
modelInstances: RuntimeModelInstance[];
|
||||||
@@ -192,6 +228,7 @@ function buildRuntimeBrush(brush: BoxBrush, document: SceneDocument): RuntimeBox
|
|||||||
rotationDegrees: cloneVec3(brush.rotationDegrees),
|
rotationDegrees: cloneVec3(brush.rotationDegrees),
|
||||||
size: cloneVec3(brush.size),
|
size: cloneVec3(brush.size),
|
||||||
geometry: cloneBoxBrushGeometry(brush.geometry),
|
geometry: cloneBoxBrushGeometry(brush.geometry),
|
||||||
|
volume: cloneBoxBrushVolumeSettings(brush.volume),
|
||||||
faces: {
|
faces: {
|
||||||
posX: {
|
posX: {
|
||||||
materialId: brush.faces.posX.materialId,
|
materialId: brush.faces.posX.materialId,
|
||||||
@@ -227,6 +264,38 @@ function buildRuntimeBrush(brush: BoxBrush, document: SceneDocument): RuntimeBox
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildRuntimeFogVolume(brush: BoxBrush): RuntimeFogVolume {
|
||||||
|
if (brush.volume.mode !== "fog") {
|
||||||
|
throw new Error(`Cannot build fog volume from non-fog brush ${brush.id}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
brushId: brush.id,
|
||||||
|
center: cloneVec3(brush.center),
|
||||||
|
rotationDegrees: cloneVec3(brush.rotationDegrees),
|
||||||
|
size: cloneVec3(brush.size),
|
||||||
|
colorHex: brush.volume.fog.colorHex,
|
||||||
|
density: brush.volume.fog.density,
|
||||||
|
padding: brush.volume.fog.padding
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildRuntimeWaterVolume(brush: BoxBrush): RuntimeWaterVolume {
|
||||||
|
if (brush.volume.mode !== "water") {
|
||||||
|
throw new Error(`Cannot build water volume from non-water brush ${brush.id}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
brushId: brush.id,
|
||||||
|
center: cloneVec3(brush.center),
|
||||||
|
rotationDegrees: cloneVec3(brush.rotationDegrees),
|
||||||
|
size: cloneVec3(brush.size),
|
||||||
|
colorHex: brush.volume.water.colorHex,
|
||||||
|
surfaceOpacity: brush.volume.water.surfaceOpacity,
|
||||||
|
waveStrength: brush.volume.water.waveStrength
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildRuntimeCollider(brush: BoxBrush): RuntimeBrushTriMeshCollider {
|
function buildRuntimeCollider(brush: BoxBrush): RuntimeBrushTriMeshCollider {
|
||||||
const bounds = getBoxBrushBounds(brush);
|
const bounds = getBoxBrushBounds(brush);
|
||||||
const derivedMesh = buildBoxBrushDerivedMeshData(brush);
|
const derivedMesh = buildBoxBrushDerivedMeshData(brush);
|
||||||
@@ -475,7 +544,25 @@ export function buildRuntimeSceneFromDocument(document: SceneDocument, options:
|
|||||||
});
|
});
|
||||||
|
|
||||||
const brushes = Object.values(document.brushes).map((brush) => buildRuntimeBrush(brush, document));
|
const brushes = Object.values(document.brushes).map((brush) => buildRuntimeBrush(brush, document));
|
||||||
const colliders: RuntimeSceneCollider[] = Object.values(document.brushes).map((brush) => buildRuntimeCollider(brush));
|
const colliders: RuntimeSceneCollider[] = [];
|
||||||
|
const volumes: RuntimeBoxVolumeCollection = {
|
||||||
|
fog: [],
|
||||||
|
water: []
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const brush of Object.values(document.brushes)) {
|
||||||
|
if (brush.volume.mode === "none") {
|
||||||
|
colliders.push(buildRuntimeCollider(brush));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (brush.volume.mode === "fog") {
|
||||||
|
volumes.fog.push(buildRuntimeFogVolume(brush));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
volumes.water.push(buildRuntimeWaterVolume(brush));
|
||||||
|
}
|
||||||
const modelInstances = getModelInstances(document.modelInstances).map(buildRuntimeModelInstance);
|
const modelInstances = getModelInstances(document.modelInstances).map(buildRuntimeModelInstance);
|
||||||
const collections = buildRuntimeSceneCollections(document);
|
const collections = buildRuntimeSceneCollections(document);
|
||||||
const interactionLinks = getInteractionLinks(document.interactionLinks).map((link) => cloneInteractionLink(link));
|
const interactionLinks = getInteractionLinks(document.interactionLinks).map((link) => cloneInteractionLink(link));
|
||||||
@@ -511,6 +598,7 @@ export function buildRuntimeSceneFromDocument(document: SceneDocument, options:
|
|||||||
world: cloneWorldSettings(document.world),
|
world: cloneWorldSettings(document.world),
|
||||||
localLights: collections.localLights,
|
localLights: collections.localLights,
|
||||||
brushes,
|
brushes,
|
||||||
|
volumes,
|
||||||
colliders,
|
colliders,
|
||||||
sceneBounds: combinedSceneBounds,
|
sceneBounds: combinedSceneBounds,
|
||||||
modelInstances,
|
modelInstances,
|
||||||
|
|||||||
Reference in New Issue
Block a user