Add image background option to world settings

This commit is contained in:
2026-03-31 19:57:22 +02:00
parent 509ab454b6
commit 44f094e637

View File

@@ -1,6 +1,6 @@
import { DEFAULT_SUN_DIRECTION, type Vec3 } from "../core/vector"; import { DEFAULT_SUN_DIRECTION, type Vec3 } from "../core/vector";
export type WorldBackgroundMode = "solid" | "verticalGradient"; export type WorldBackgroundMode = "solid" | "verticalGradient" | "image";
export interface WorldSolidBackgroundSettings { export interface WorldSolidBackgroundSettings {
mode: "solid"; mode: "solid";
@@ -13,7 +13,15 @@ export interface WorldVerticalGradientBackgroundSettings {
bottomColorHex: string; bottomColorHex: string;
} }
export type WorldBackgroundSettings = WorldSolidBackgroundSettings | WorldVerticalGradientBackgroundSettings; export interface WorldImageBackgroundSettings {
mode: "image";
assetId: string;
}
export type WorldBackgroundSettings =
| WorldSolidBackgroundSettings
| WorldVerticalGradientBackgroundSettings
| WorldImageBackgroundSettings;
export interface WorldAmbientLightSettings { export interface WorldAmbientLightSettings {
colorHex: string; colorHex: string;
@@ -59,7 +67,7 @@ export function isHexColorString(value: string): boolean {
} }
export function isWorldBackgroundMode(value: unknown): value is WorldBackgroundMode { export function isWorldBackgroundMode(value: unknown): value is WorldBackgroundMode {
return value === "solid" || value === "verticalGradient"; return value === "solid" || value === "verticalGradient" || value === "image";
} }
export function cloneWorldBackgroundSettings(background: WorldBackgroundSettings): WorldBackgroundSettings { export function cloneWorldBackgroundSettings(background: WorldBackgroundSettings): WorldBackgroundSettings {
@@ -75,6 +83,11 @@ export function cloneWorldBackgroundSettings(background: WorldBackgroundSettings
topColorHex: background.topColorHex, topColorHex: background.topColorHex,
bottomColorHex: background.bottomColorHex bottomColorHex: background.bottomColorHex
}; };
return {
mode: "image",
assetId: background.assetId
};
} }
export function cloneWorldSettings(world: WorldSettings): WorldSettings { export function cloneWorldSettings(world: WorldSettings): WorldSettings {
@@ -101,12 +114,11 @@ export function areWorldBackgroundSettingsEqual(left: WorldBackgroundSettings, r
return left.colorHex === right.colorHex; return left.colorHex === right.colorHex;
} }
return ( if (left.mode === "verticalGradient" && right.mode === "verticalGradient") {
left.mode === "verticalGradient" && return left.topColorHex === right.topColorHex && left.bottomColorHex === right.bottomColorHex;
right.mode === "verticalGradient" && }
left.topColorHex === right.topColorHex &&
left.bottomColorHex === right.bottomColorHex return left.mode === "image" && right.mode === "image" && left.assetId === right.assetId;
);
} }
export function areWorldSettingsEqual(left: WorldSettings, right: WorldSettings): boolean { export function areWorldSettingsEqual(left: WorldSettings, right: WorldSettings): boolean {
@@ -122,7 +134,11 @@ export function areWorldSettingsEqual(left: WorldSettings, right: WorldSettings)
); );
} }
export function changeWorldBackgroundMode(background: WorldBackgroundSettings, mode: WorldBackgroundMode): WorldBackgroundSettings { export function changeWorldBackgroundMode(
background: WorldBackgroundSettings,
mode: WorldBackgroundMode,
imageAssetId?: string
): WorldBackgroundSettings {
if (background.mode === mode) { if (background.mode === mode) {
return cloneWorldBackgroundSettings(background); return cloneWorldBackgroundSettings(background);
} }
@@ -134,6 +150,21 @@ export function changeWorldBackgroundMode(background: WorldBackgroundSettings, m
}; };
} }
if (mode === "image") {
if (background.mode === "image") {
return cloneWorldBackgroundSettings(background);
}
if (imageAssetId === undefined || imageAssetId.trim().length === 0) {
throw new Error("An image asset must be selected to use an image background.");
}
return {
mode: "image",
assetId: imageAssetId
};
}
return { return {
mode: "verticalGradient", mode: "verticalGradient",
topColorHex: background.mode === "solid" ? background.colorHex : background.topColorHex, topColorHex: background.mode === "solid" ? background.colorHex : background.topColorHex,