Remove unused background overlay and update tests
This commit is contained in:
@@ -1258,13 +1258,6 @@ button:disabled {
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.runner-canvas__background-overlay {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
z-index: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.runner-canvas__loading-overlay--hidden {
|
.runner-canvas__loading-overlay--hidden {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|||||||
@@ -15,14 +15,12 @@ import type { RuntimeInteractionPrompt } from "../runtime-three/runtime-interact
|
|||||||
import {
|
import {
|
||||||
areRuntimeClockStatesEqual,
|
areRuntimeClockStatesEqual,
|
||||||
createRuntimeClockState,
|
createRuntimeClockState,
|
||||||
resolveRuntimeDayNightWorldState,
|
|
||||||
type RuntimeClockState
|
type RuntimeClockState
|
||||||
} from "../runtime-three/runtime-project-time";
|
} from "../runtime-three/runtime-project-time";
|
||||||
import type {
|
import type {
|
||||||
RuntimeNavigationMode,
|
RuntimeNavigationMode,
|
||||||
RuntimeSceneDefinition
|
RuntimeSceneDefinition
|
||||||
} from "../runtime-three/runtime-scene-build";
|
} from "../runtime-three/runtime-scene-build";
|
||||||
import { createWorldBackgroundStyle } from "../shared-ui/world-background-style";
|
|
||||||
|
|
||||||
const FORWARD_RUNTIME_CLOCK_INTERVAL_MS = 240;
|
const FORWARD_RUNTIME_CLOCK_INTERVAL_MS = 240;
|
||||||
|
|
||||||
@@ -73,28 +71,13 @@ export function RunnerCanvas({
|
|||||||
useState<RuntimeInteractionPrompt | null>(null);
|
useState<RuntimeInteractionPrompt | null>(null);
|
||||||
const [firstPersonTelemetry, setFirstPersonTelemetry] =
|
const [firstPersonTelemetry, setFirstPersonTelemetry] =
|
||||||
useState<FirstPersonTelemetry | null>(null);
|
useState<FirstPersonTelemetry | null>(null);
|
||||||
const [visualRuntimeClock, setVisualRuntimeClock] = useState(runtimeClock);
|
|
||||||
const overlayMessage = runnerMessage ?? sceneLoadState.message;
|
const overlayMessage = runnerMessage ?? sceneLoadState.message;
|
||||||
const overlayStatus =
|
const overlayStatus =
|
||||||
overlayMessage !== null ? "error" : sceneLoadState.status;
|
overlayMessage !== null ? "error" : sceneLoadState.status;
|
||||||
const runnerReady = overlayStatus === "ready";
|
const runnerReady = overlayStatus === "ready";
|
||||||
const resolvedWorld = resolveRuntimeDayNightWorldState(
|
|
||||||
runtimeScene.world,
|
|
||||||
runtimeScene.time,
|
|
||||||
visualRuntimeClock
|
|
||||||
);
|
|
||||||
|
|
||||||
onRuntimeClockChangeRef.current = onRuntimeClockChange;
|
onRuntimeClockChangeRef.current = onRuntimeClockChange;
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
lastForwardedRuntimeClockRef.current = runtimeClock;
|
|
||||||
setVisualRuntimeClock((currentClock) =>
|
|
||||||
areRuntimeClockStatesEqual(currentClock, runtimeClock)
|
|
||||||
? currentClock
|
|
||||||
: runtimeClock
|
|
||||||
);
|
|
||||||
}, [runtimeClock.dayCount, runtimeClock.dayLengthMinutes, runtimeClock.timeOfDayHours]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const container = containerRef.current;
|
const container = containerRef.current;
|
||||||
|
|
||||||
@@ -111,12 +94,6 @@ export function RunnerCanvas({
|
|||||||
runtimeHost.setRuntimeMessageHandler(onRuntimeMessageChange);
|
runtimeHost.setRuntimeMessageHandler(onRuntimeMessageChange);
|
||||||
runtimeHost.setSceneLoadStateHandler(setSceneLoadState);
|
runtimeHost.setSceneLoadStateHandler(setSceneLoadState);
|
||||||
runtimeHost.setRuntimeClockStateHandler?.((clock) => {
|
runtimeHost.setRuntimeClockStateHandler?.((clock) => {
|
||||||
setVisualRuntimeClock((currentClock) =>
|
|
||||||
areRuntimeClockStatesEqual(currentClock, clock)
|
|
||||||
? currentClock
|
|
||||||
: clock
|
|
||||||
);
|
|
||||||
|
|
||||||
const now = performance.now();
|
const now = performance.now();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -226,35 +203,7 @@ export function RunnerCanvas({
|
|||||||
data-testid="runner-shell"
|
data-testid="runner-shell"
|
||||||
aria-label="Built-in scene runner"
|
aria-label="Built-in scene runner"
|
||||||
aria-busy={!runnerReady}
|
aria-busy={!runnerReady}
|
||||||
style={createWorldBackgroundStyle(
|
|
||||||
resolvedWorld.background,
|
|
||||||
resolvedWorld.background.mode === "image"
|
|
||||||
? (loadedImageAssets[resolvedWorld.background.assetId]
|
|
||||||
?.sourceUrl ?? null)
|
|
||||||
: null
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
{resolvedWorld.nightBackgroundOverlay === null ? null : (
|
|
||||||
<div
|
|
||||||
className="runner-canvas__background-overlay"
|
|
||||||
data-testid="runner-night-background-overlay"
|
|
||||||
aria-hidden="true"
|
|
||||||
style={{
|
|
||||||
...createWorldBackgroundStyle(
|
|
||||||
{
|
|
||||||
mode: "image",
|
|
||||||
assetId: resolvedWorld.nightBackgroundOverlay.assetId,
|
|
||||||
environmentIntensity:
|
|
||||||
resolvedWorld.nightBackgroundOverlay.environmentIntensity
|
|
||||||
},
|
|
||||||
loadedImageAssets[
|
|
||||||
resolvedWorld.nightBackgroundOverlay.assetId
|
|
||||||
]?.sourceUrl ?? null
|
|
||||||
),
|
|
||||||
opacity: resolvedWorld.nightBackgroundOverlay.opacity
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div
|
<div
|
||||||
className={`runner-canvas__loading-overlay ${runnerReady ? "runner-canvas__loading-overlay--hidden" : ""}`}
|
className={`runner-canvas__loading-overlay ${runnerReady ? "runner-canvas__loading-overlay--hidden" : ""}`}
|
||||||
data-testid="runner-loading-overlay"
|
data-testid="runner-loading-overlay"
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ describe("RunnerCanvas", () => {
|
|||||||
).toHaveBeenCalledTimes(2);
|
).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders the night background overlay behind the scene when the night profile is active", async () => {
|
it("does not render a DOM night background overlay because the runtime host owns background blending", async () => {
|
||||||
const document = createEmptySceneDocument();
|
const document = createEmptySceneDocument();
|
||||||
document.assets["asset-night-sky"] = {
|
document.assets["asset-night-sky"] = {
|
||||||
id: "asset-night-sky",
|
id: "asset-night-sky",
|
||||||
@@ -439,7 +439,9 @@ describe("RunnerCanvas", () => {
|
|||||||
expect(runtimeHostInstances).toHaveLength(1);
|
expect(runtimeHostInstances).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(screen.getByTestId("runner-night-background-overlay")).toBeVisible();
|
expect(
|
||||||
|
screen.queryByTestId("runner-night-background-overlay")
|
||||||
|
).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("keeps the crosshair hidden in third-person mode while still showing interaction prompts", async () => {
|
it("keeps the crosshair hidden in third-person mode while still showing interaction prompts", async () => {
|
||||||
|
|||||||
73
tests/unit/world-background-renderer.test.ts
Normal file
73
tests/unit/world-background-renderer.test.ts
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import { Texture } from "three";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
import { createDefaultWorldSettings } from "../../src/document/world-settings";
|
||||||
|
import { resolveWorldEnvironmentState } from "../../src/rendering/world-background-renderer";
|
||||||
|
|
||||||
|
describe("resolveWorldEnvironmentState", () => {
|
||||||
|
it("keeps the authored day environment when no night overlay is active", () => {
|
||||||
|
const world = createDefaultWorldSettings();
|
||||||
|
const dayTexture = new Texture();
|
||||||
|
world.background = {
|
||||||
|
mode: "image",
|
||||||
|
assetId: "asset-day-sky",
|
||||||
|
environmentIntensity: 0.65
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
resolveWorldEnvironmentState(world.background, dayTexture, null)
|
||||||
|
).toEqual({
|
||||||
|
texture: dayTexture,
|
||||||
|
intensity: 0.65
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("hands the environment off through zero intensity during a day-to-night crossfade", () => {
|
||||||
|
const world = createDefaultWorldSettings();
|
||||||
|
const dayTexture = new Texture();
|
||||||
|
const nightTexture = new Texture();
|
||||||
|
world.background = {
|
||||||
|
mode: "image",
|
||||||
|
assetId: "asset-day-sky",
|
||||||
|
environmentIntensity: 0.4
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
resolveWorldEnvironmentState(world.background, dayTexture, {
|
||||||
|
texture: nightTexture,
|
||||||
|
opacity: 0.25,
|
||||||
|
environmentIntensity: 0.8
|
||||||
|
})
|
||||||
|
).toEqual({
|
||||||
|
texture: dayTexture,
|
||||||
|
intensity: 0.2
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
resolveWorldEnvironmentState(world.background, dayTexture, {
|
||||||
|
texture: nightTexture,
|
||||||
|
opacity: 0.75,
|
||||||
|
environmentIntensity: 0.8
|
||||||
|
})
|
||||||
|
).toEqual({
|
||||||
|
texture: nightTexture,
|
||||||
|
intensity: 0.4
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("fades the night environment in when the authored day background has no image environment", () => {
|
||||||
|
const world = createDefaultWorldSettings();
|
||||||
|
const nightTexture = new Texture();
|
||||||
|
|
||||||
|
expect(
|
||||||
|
resolveWorldEnvironmentState(world.background, null, {
|
||||||
|
texture: nightTexture,
|
||||||
|
opacity: 0.5,
|
||||||
|
environmentIntensity: 0.7
|
||||||
|
})
|
||||||
|
).toEqual({
|
||||||
|
texture: nightTexture,
|
||||||
|
intensity: 0.35
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user