auto-git:
[change] src/runtime-three/runtime-scene-build.ts [change] src/viewport-three/transform-surface-snap.ts [change] src/viewport-three/viewport-host.ts [change] tests/domain/runtime-interaction-system.test.ts [change] tests/domain/transform-session.command.test.ts [change] tests/serialization/scene-document-json.test.ts [change] tests/unit/runtime-interaction-system.test.ts [change] tests/unit/transform-foundation.integration.test.tsx
This commit is contained in:
@@ -159,7 +159,7 @@ function createRuntimeSceneFixture(): RuntimeSceneDefinition {
|
||||
prompt: "Disabled Prompt",
|
||||
interactionEnabled: false
|
||||
}
|
||||
],
|
||||
]
|
||||
},
|
||||
interactionLinks: [],
|
||||
control: createEmptyRuntimeControlSurfaceDefinition(),
|
||||
@@ -288,7 +288,7 @@ describe("RuntimeInteractionSystem", () => {
|
||||
playAnimation: () => {},
|
||||
stopAnimation: () => {},
|
||||
playSound: () => {},
|
||||
stopSound: () => {},
|
||||
stopSound: () => {}
|
||||
}
|
||||
);
|
||||
interactionSystem.updatePlayerPosition(
|
||||
@@ -309,7 +309,7 @@ describe("RuntimeInteractionSystem", () => {
|
||||
playAnimation: () => {},
|
||||
stopAnimation: () => {},
|
||||
playSound: () => {},
|
||||
stopSound: () => {},
|
||||
stopSound: () => {}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -423,7 +423,7 @@ describe("RuntimeInteractionSystem", () => {
|
||||
dispatches.push(`${link.id}:${instanceId}`);
|
||||
},
|
||||
playSound: () => {},
|
||||
stopSound: () => {},
|
||||
stopSound: () => {}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -462,7 +462,9 @@ describe("RuntimeInteractionSystem", () => {
|
||||
throw new Error("Expected a camera rig entity control target.");
|
||||
}
|
||||
|
||||
dispatches.push(`${link.id}:${effect.type}:${effect.target.entityId}`);
|
||||
dispatches.push(
|
||||
`${link.id}:${effect.type}:${effect.target.entityId}`
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -480,7 +482,9 @@ describe("RuntimeInteractionSystem", () => {
|
||||
throw new Error("Expected a camera rig entity control target.");
|
||||
}
|
||||
|
||||
dispatches.push(`${link.id}:${effect.type}:${effect.target.entityId}`);
|
||||
dispatches.push(
|
||||
`${link.id}:${effect.type}:${effect.target.entityId}`
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -515,7 +519,9 @@ describe("RuntimeInteractionSystem", () => {
|
||||
throw new Error("Expected a camera rig entity control target.");
|
||||
}
|
||||
|
||||
dispatches.push(`${link.id}:${effect.type}:${effect.target.entityId}`);
|
||||
dispatches.push(
|
||||
`${link.id}:${effect.type}:${effect.target.entityId}`
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -564,7 +570,7 @@ describe("RuntimeInteractionSystem", () => {
|
||||
playAnimation: () => {},
|
||||
stopAnimation: () => {},
|
||||
playSound: () => {},
|
||||
stopSound: () => {},
|
||||
stopSound: () => {}
|
||||
}
|
||||
);
|
||||
interactionSystem.updatePlayerPosition(
|
||||
@@ -590,7 +596,7 @@ describe("RuntimeInteractionSystem", () => {
|
||||
playAnimation: () => {},
|
||||
stopAnimation: () => {},
|
||||
playSound: () => {},
|
||||
stopSound: () => {},
|
||||
stopSound: () => {}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -728,7 +734,7 @@ describe("RuntimeInteractionSystem", () => {
|
||||
playAnimation: () => {},
|
||||
stopAnimation: () => {},
|
||||
playSound: () => {},
|
||||
stopSound: () => {},
|
||||
stopSound: () => {}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -779,7 +785,7 @@ describe("RuntimeInteractionSystem", () => {
|
||||
},
|
||||
stopSound: (soundEmitterId, link) => {
|
||||
dispatches.push(`${link.id}:${soundEmitterId}`);
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1402,7 +1408,9 @@ describe("RuntimeInteractionSystem", () => {
|
||||
runtimeScene,
|
||||
{
|
||||
teleportPlayer: () => {
|
||||
throw new Error("Teleport should not dispatch for a scene transition.");
|
||||
throw new Error(
|
||||
"Teleport should not dispatch for a scene transition."
|
||||
);
|
||||
},
|
||||
startSceneTransition: (request) => {
|
||||
dispatches.push(
|
||||
@@ -1410,12 +1418,14 @@ describe("RuntimeInteractionSystem", () => {
|
||||
);
|
||||
},
|
||||
toggleBrushVisibility: () => {
|
||||
throw new Error("Visibility should not dispatch for a scene transition.");
|
||||
throw new Error(
|
||||
"Visibility should not dispatch for a scene transition."
|
||||
);
|
||||
},
|
||||
playAnimation: () => {},
|
||||
stopAnimation: () => {},
|
||||
playSound: () => {},
|
||||
stopSound: () => {},
|
||||
stopSound: () => {}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -248,19 +248,25 @@ describe("transform session commit commands", () => {
|
||||
|
||||
expect(
|
||||
supportsTransformOperation(
|
||||
pathPointResolved.target as NonNullable<typeof pathPointResolved.target>,
|
||||
pathPointResolved.target as NonNullable<
|
||||
typeof pathPointResolved.target
|
||||
>,
|
||||
"translate"
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
supportsTransformOperation(
|
||||
pathPointResolved.target as NonNullable<typeof pathPointResolved.target>,
|
||||
pathPointResolved.target as NonNullable<
|
||||
typeof pathPointResolved.target
|
||||
>,
|
||||
"rotate"
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
supportsTransformOperation(
|
||||
pathPointResolved.target as NonNullable<typeof pathPointResolved.target>,
|
||||
pathPointResolved.target as NonNullable<
|
||||
typeof pathPointResolved.target
|
||||
>,
|
||||
"scale"
|
||||
)
|
||||
).toBe(false);
|
||||
@@ -1343,12 +1349,13 @@ describe("transform session commit commands", () => {
|
||||
};
|
||||
|
||||
store.executeCommand(
|
||||
createCommitTransformSessionCommand(store.getState().document, scaleSession)
|
||||
createCommitTransformSessionCommand(
|
||||
store.getState().document,
|
||||
scaleSession
|
||||
)
|
||||
);
|
||||
|
||||
expect(
|
||||
store.getState().document.entities[triggerVolume.id]
|
||||
).toMatchObject({
|
||||
expect(store.getState().document.entities[triggerVolume.id]).toMatchObject({
|
||||
position: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
@@ -1367,9 +1374,7 @@ describe("transform session commit commands", () => {
|
||||
});
|
||||
|
||||
expect(store.undo()).toBe(true);
|
||||
expect(
|
||||
store.getState().document.entities[triggerVolume.id]
|
||||
).toMatchObject({
|
||||
expect(store.getState().document.entities[triggerVolume.id]).toMatchObject({
|
||||
rotationDegrees: {
|
||||
x: 0,
|
||||
y: 45,
|
||||
@@ -1379,9 +1384,7 @@ describe("transform session commit commands", () => {
|
||||
});
|
||||
|
||||
expect(store.redo()).toBe(true);
|
||||
expect(
|
||||
store.getState().document.entities[triggerVolume.id]
|
||||
).toMatchObject({
|
||||
expect(store.getState().document.entities[triggerVolume.id]).toMatchObject({
|
||||
size: {
|
||||
x: 4,
|
||||
y: 3,
|
||||
@@ -1726,7 +1729,9 @@ describe("transform session commit commands", () => {
|
||||
createCommitTransformSessionCommand(store.getState().document, session)
|
||||
);
|
||||
|
||||
expect(store.getState().document.modelInstances[modelInstanceA.id]).toMatchObject({
|
||||
expect(
|
||||
store.getState().document.modelInstances[modelInstanceA.id]
|
||||
).toMatchObject({
|
||||
position: {
|
||||
x: -2,
|
||||
y: 0,
|
||||
@@ -1738,7 +1743,9 @@ describe("transform session commit commands", () => {
|
||||
z: 2
|
||||
}
|
||||
});
|
||||
expect(store.getState().document.modelInstances[modelInstanceB.id]).toMatchObject({
|
||||
expect(
|
||||
store.getState().document.modelInstances[modelInstanceB.id]
|
||||
).toMatchObject({
|
||||
position: {
|
||||
x: 2,
|
||||
y: 0,
|
||||
@@ -1760,7 +1767,9 @@ describe("transform session commit commands", () => {
|
||||
);
|
||||
|
||||
expect(store.redo()).toBe(true);
|
||||
expect(store.getState().document.modelInstances[modelInstanceA.id]).toMatchObject({
|
||||
expect(
|
||||
store.getState().document.modelInstances[modelInstanceA.id]
|
||||
).toMatchObject({
|
||||
position: {
|
||||
x: -2,
|
||||
y: 0,
|
||||
|
||||
@@ -237,9 +237,11 @@ describe("scene document JSON", () => {
|
||||
) as Record<string, unknown>;
|
||||
|
||||
legacyDocument.version = FOLIAGE_FOUNDATION_SCENE_DOCUMENT_VERSION;
|
||||
delete ((legacyDocument.terrains as Record<string, Record<string, unknown>>)[
|
||||
terrain.id
|
||||
] as Record<string, unknown>).foliageMasks;
|
||||
delete (
|
||||
(legacyDocument.terrains as Record<string, Record<string, unknown>>)[
|
||||
terrain.id
|
||||
] as Record<string, unknown>
|
||||
).foliageMasks;
|
||||
|
||||
const migratedDocument = parseSceneDocumentJson(
|
||||
JSON.stringify(legacyDocument)
|
||||
@@ -264,18 +266,18 @@ describe("scene document JSON", () => {
|
||||
) as Record<string, unknown>;
|
||||
|
||||
legacyDocument.version = FOLIAGE_QUALITY_SCENE_DOCUMENT_VERSION;
|
||||
delete ((legacyDocument.terrains as Record<string, Record<string, unknown>>)[
|
||||
terrain.id
|
||||
] as Record<string, unknown>).foliageBlockerMask;
|
||||
delete (
|
||||
(legacyDocument.terrains as Record<string, Record<string, unknown>>)[
|
||||
terrain.id
|
||||
] as Record<string, unknown>
|
||||
).foliageBlockerMask;
|
||||
|
||||
const migratedDocument = parseSceneDocumentJson(
|
||||
JSON.stringify(legacyDocument)
|
||||
);
|
||||
|
||||
expect(migratedDocument.version).toBe(SCENE_DOCUMENT_VERSION);
|
||||
expect(
|
||||
migratedDocument.terrains[terrain.id]?.foliageBlockerMask
|
||||
).toEqual({
|
||||
expect(migratedDocument.terrains[terrain.id]?.foliageBlockerMask).toEqual({
|
||||
resolutionX: 2,
|
||||
resolutionZ: 2,
|
||||
values: [0, 0, 0, 0]
|
||||
@@ -805,9 +807,7 @@ describe("scene document JSON", () => {
|
||||
const migratedDocument = migrateSceneDocument(legacyDocument);
|
||||
|
||||
expect(migratedDocument.version).toBe(SCENE_DOCUMENT_VERSION);
|
||||
expect(
|
||||
migratedDocument.brushes[brush.id].faces.posZ.climbable
|
||||
).toBe(false);
|
||||
expect(migratedDocument.brushes[brush.id].faces.posZ.climbable).toBe(false);
|
||||
});
|
||||
|
||||
it("round-trips whitebox box volume settings", () => {
|
||||
|
||||
@@ -26,7 +26,9 @@ function createClickLink(sourceEntityId: string): InteractionLink {
|
||||
};
|
||||
}
|
||||
|
||||
function createNpc(overrides: Partial<RuntimeNpc> & { entityId: string }): RuntimeNpc {
|
||||
function createNpc(
|
||||
overrides: Partial<RuntimeNpc> & { entityId: string }
|
||||
): RuntimeNpc {
|
||||
return {
|
||||
entityId: overrides.entityId,
|
||||
actorId: overrides.actorId ?? "",
|
||||
@@ -38,13 +40,12 @@ function createNpc(overrides: Partial<RuntimeNpc> & { entityId: string }): Runti
|
||||
modelAssetId: overrides.modelAssetId ?? null,
|
||||
dialogues: overrides.dialogues ?? [],
|
||||
defaultDialogueId: overrides.defaultDialogueId ?? null,
|
||||
collider:
|
||||
overrides.collider ?? {
|
||||
mode: "capsule",
|
||||
radius: 0.35,
|
||||
height: 1.8,
|
||||
eyeHeight: 1.6
|
||||
},
|
||||
collider: overrides.collider ?? {
|
||||
mode: "capsule",
|
||||
radius: 0.35,
|
||||
height: 1.8,
|
||||
eyeHeight: 1.6
|
||||
},
|
||||
activeRoutineTitle: overrides.activeRoutineTitle ?? null,
|
||||
animationClipName: overrides.animationClipName ?? null,
|
||||
animationLoop: overrides.animationLoop,
|
||||
@@ -102,7 +103,10 @@ describe("runtime interaction targeting", () => {
|
||||
const scene = createRuntimeSceneFixture({
|
||||
npcs: [centerNpc],
|
||||
interactables: [sideInteractable],
|
||||
links: [createClickLink(centerNpc.entityId), createClickLink(sideInteractable.entityId)]
|
||||
links: [
|
||||
createClickLink(centerNpc.entityId),
|
||||
createClickLink(sideInteractable.entityId)
|
||||
]
|
||||
});
|
||||
|
||||
const candidates = resolveRuntimeTargetCandidates({
|
||||
|
||||
@@ -9,9 +9,7 @@ import {
|
||||
createProjectAssetStorageKey,
|
||||
type ModelAssetRecord
|
||||
} from "../../src/assets/project-assets";
|
||||
import type {
|
||||
ActiveTransformSession
|
||||
} from "../../src/core/transform-session";
|
||||
import type { ActiveTransformSession } from "../../src/core/transform-session";
|
||||
import { createBoxBrush } from "../../src/document/brushes";
|
||||
import { createEmptySceneDocument } from "../../src/document/scene-document";
|
||||
import { createPlayerStartEntity } from "../../src/entities/entity-instances";
|
||||
@@ -275,7 +273,9 @@ async function renderMultiSelectionFixtureApp() {
|
||||
|
||||
await waitFor(() => {
|
||||
expect(viewportHostInstances.length).toBeGreaterThan(0);
|
||||
expect(getTopLeftViewportHost().setBrushSelectionChangeHandler).toHaveBeenCalled();
|
||||
expect(
|
||||
getTopLeftViewportHost().setBrushSelectionChangeHandler
|
||||
).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -611,9 +611,10 @@ describe("transform foundation integration", () => {
|
||||
});
|
||||
|
||||
expect(store.getState().whiteboxSelectionMode).toBe("edge");
|
||||
expect(
|
||||
screen.getByTestId("whitebox-selection-mode-edge")
|
||||
).toHaveAttribute("aria-pressed", "true");
|
||||
expect(screen.getByTestId("whitebox-selection-mode-edge")).toHaveAttribute(
|
||||
"aria-pressed",
|
||||
"true"
|
||||
);
|
||||
|
||||
fireEvent.keyDown(window, {
|
||||
key: "3",
|
||||
@@ -635,7 +636,9 @@ describe("transform foundation integration", () => {
|
||||
expect(
|
||||
screen.getByTestId("whitebox-selection-mode-object")
|
||||
).toHaveAttribute("aria-pressed", "true");
|
||||
expect(screen.getByText(/selection mode set to object/i)).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/selection mode set to object/i)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("keeps outliner and viewport selection state synchronized for same-kind multi-selection", async () => {
|
||||
@@ -660,9 +663,10 @@ describe("transform foundation integration", () => {
|
||||
expect(screen.getByText("2 selected")).toBeInTheDocument();
|
||||
expect(screen.getByText("Brush Multi B")).toBeInTheDocument();
|
||||
|
||||
const selectionHandler = viewportHost.setBrushSelectionChangeHandler.mock.calls.at(
|
||||
-1
|
||||
)?.[0] as ((selection: { kind: "entities"; ids: string[] }) => void);
|
||||
const selectionHandler =
|
||||
viewportHost.setBrushSelectionChangeHandler.mock.calls.at(
|
||||
-1
|
||||
)?.[0] as (selection: { kind: "entities"; ids: string[] }) => void;
|
||||
|
||||
act(() => {
|
||||
selectionHandler({
|
||||
|
||||
Reference in New Issue
Block a user