Feature: Add editor simulation controls and state to viewport

This commit is contained in:
2026-04-27 19:23:01 +02:00
parent bc3aa24c83
commit 1b3709a81b
3 changed files with 87 additions and 1 deletions

View File

@@ -14244,6 +14244,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
world={editorState.document.world}
sceneDocument={editorState.document}
editorSimulationController={editorSimulationController}
editorSimulationPlaying={editorSimulationPlaying}
projectAssets={editorState.document.assets}
loadedModelAssets={loadedModelAssets}
loadedImageAssets={loadedImageAssets}
@@ -14308,6 +14309,9 @@ export function App({ store, initialStatusMessage }: AppProps) {
onSelectionChange={(selection) =>
applySelection(selection, "viewport")
}
onPlayEditorSimulation={handlePlayEditorSimulation}
onPauseEditorSimulation={handlePauseEditorSimulation}
onStepEditorSimulation={handleStepEditorSimulation}
/>
))}
{layoutMode !== "quad" ? null : (

View File

@@ -1411,6 +1411,10 @@ button:disabled {
pointer-events: none;
}
.viewport-canvas[data-active="true"] .viewport-canvas__overlay {
max-width: calc(100% - 132px);
}
.viewport-canvas__overlay-badges {
display: flex;
flex-wrap: wrap;
@@ -1447,6 +1451,72 @@ button:disabled {
backdrop-filter: blur(10px);
}
.viewport-canvas__time-transport {
position: absolute;
right: 10px;
bottom: 10px;
z-index: 1;
display: flex;
align-items: center;
gap: 3px;
padding: 4px;
color: #f8efe3;
background: rgba(8, 10, 14, 0.72);
border: 1px solid rgba(255, 255, 255, 0.16);
border-radius: 8px;
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.22);
backdrop-filter: blur(10px);
pointer-events: auto;
}
.viewport-canvas__time-button {
width: 30px;
height: 28px;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
color: #f8efe3;
background: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(255, 255, 255, 0.14);
border-radius: 6px;
font-size: 0.72rem;
font-weight: 800;
line-height: 1;
cursor: pointer;
touch-action: none;
user-select: none;
}
.viewport-canvas__time-button:hover,
.viewport-canvas__time-button:focus-visible {
color: #ffffff;
background: rgba(255, 255, 255, 0.16);
border-color: rgba(255, 255, 255, 0.28);
}
.viewport-canvas__time-button:focus-visible {
outline: 2px solid rgba(240, 197, 116, 0.78);
outline-offset: 2px;
}
.viewport-canvas__time-button:active {
transform: translateY(1px);
}
.viewport-canvas__time-button--primary {
width: 34px;
color: #20180e;
background: #f0c574;
border-color: rgba(255, 255, 255, 0.24);
}
.viewport-canvas__time-button--primary:hover,
.viewport-canvas__time-button--primary:focus-visible {
color: #140f08;
background: #ffd68a;
}
.viewport-region__splitter {
position: absolute;
z-index: 3;

View File

@@ -54,6 +54,7 @@ interface ViewportPanelProps {
world: WorldSettings;
sceneDocument: SceneDocument;
editorSimulationController: EditorSimulationController;
editorSimulationPlaying: boolean;
projectAssets: Record<string, ProjectAssetRecord>;
loadedModelAssets: Record<string, LoadedModelAsset>;
loadedImageAssets: Record<string, LoadedImageAsset>;
@@ -103,6 +104,9 @@ interface ViewportPanelProps {
onTransformCommit(transformSession: ActiveTransformSession): void;
onTransformCancel(): void;
onSelectionChange(selection: EditorSelection): void;
onPlayEditorSimulation(): void;
onPauseEditorSimulation(): void;
onStepEditorSimulation(deltaHours: number): void;
}
const VIEWPORT_DISPLAY_MODES = ["normal", "authoring", "wireframe"] as const;
@@ -130,6 +134,7 @@ export function ViewportPanel({
world,
sceneDocument,
editorSimulationController,
editorSimulationPlaying,
projectAssets,
loadedModelAssets,
loadedImageAssets,
@@ -172,7 +177,10 @@ export function ViewportPanel({
onTransformPreviewChange,
onTransformCommit,
onTransformCancel,
onSelectionChange
onSelectionChange,
onPlayEditorSimulation,
onPauseEditorSimulation,
onStepEditorSimulation
}: ViewportPanelProps) {
const shouldShow = layoutMode === "quad" || isActive;
const panelStyle = shouldShow ? style : { ...(style ?? {}), display: "none" };
@@ -195,6 +203,7 @@ export function ViewportPanel({
world={world}
sceneDocument={sceneDocument}
editorSimulationController={editorSimulationController}
editorSimulationPlaying={editorSimulationPlaying}
projectAssets={projectAssets}
loadedModelAssets={loadedModelAssets}
loadedImageAssets={loadedImageAssets}
@@ -224,6 +233,9 @@ export function ViewportPanel({
onTransformPreviewChange={onTransformPreviewChange}
onTransformCommit={onTransformCommit}
onTransformCancel={onTransformCancel}
onPlayEditorSimulation={onPlayEditorSimulation}
onPauseEditorSimulation={onPauseEditorSimulation}
onStepEditorSimulation={onStepEditorSimulation}
/>
<div className="viewport-panel__overlay viewport-panel__overlay--top">