Refactor sequence handling and add new sequences panel

This commit is contained in:
2026-04-15 01:13:32 +02:00
parent 4cab97d785
commit 36f81d74b0
8 changed files with 585 additions and 450 deletions

View File

@@ -649,9 +649,6 @@ describe("RuntimeInteractionSystem", () => {
title: "Console Dialogue Sequence",
steps: [
{
startMinute: 0,
durationMinutes: 1,
lane: 0,
stepClass: "impulse",
type: "startDialogue",
dialogueId: "dialogue-sequence"

View File

@@ -22,8 +22,7 @@ import {
} from "../../src/sequencer/project-sequences";
import {
applyRuntimeProjectScheduleToControlState,
resolveRuntimeProjectScheduleState,
type RuntimeProjectSchedulePathDefinition
resolveRuntimeProjectScheduleState
} from "../../src/runtime-three/runtime-project-scheduler";
describe("runtime project scheduler", () => {
@@ -180,9 +179,6 @@ describe("runtime project scheduler", () => {
title: "Vendor Open Sequence",
steps: [
{
startMinute: 0,
durationMinutes: 480,
lane: 0,
stepClass: "held",
type: "controlEffect",
effect: createSetActorPresenceControlEffect({
@@ -191,9 +187,6 @@ describe("runtime project scheduler", () => {
})
},
{
startMinute: 0,
durationMinutes: 480,
lane: 1,
stepClass: "held",
type: "controlEffect",
effect: createPlayActorAnimationControlEffect({
@@ -240,130 +233,6 @@ describe("runtime project scheduler", () => {
);
});
it("resolves timed held sequence clips against local routine minutes", () => {
const actorTarget = createActorControlTargetRef("actor-timed-sequence");
const scheduler = createEmptyProjectScheduler();
const sequences = createEmptyProjectSequenceLibrary();
sequences.sequences["sequence-timed-open"] = createProjectSequence({
id: "sequence-timed-open",
title: "Timed Open Sequence",
durationMinutes: 180,
clips: [
{
startMinute: 30,
durationMinutes: 60,
lane: 0,
stepClass: "held",
type: "controlEffect",
effect: createSetActorPresenceControlEffect({
target: actorTarget,
active: true
})
},
{
startMinute: 60,
durationMinutes: 90,
lane: 1,
stepClass: "held",
type: "controlEffect",
effect: createFollowActorPathControlEffect({
target: actorTarget,
pathId: "path-market",
speed: 2,
loop: false,
progressMode: "deriveFromTime"
})
}
]
});
scheduler.routines["routine-timed-open"] = createProjectScheduleRoutine({
id: "routine-timed-open",
title: "Timed Open",
target: actorTarget,
startHour: 9,
endHour: 12,
sequenceId: "sequence-timed-open",
effects: [
createSetActorPresenceControlEffect({
target: actorTarget,
active: false
})
]
});
const pathsById = new Map<string, RuntimeProjectSchedulePathDefinition>([
[
"path-market",
{
id: "path-market",
loop: false,
points: [
{ position: { x: 0, y: 0, z: 0 } },
{ position: { x: 4, y: 0, z: 0 } }
],
segments: [
{
start: { x: 0, y: 0, z: 0 },
end: { x: 4, y: 0, z: 0 },
length: 4,
distanceStart: 0,
distanceEnd: 4,
tangent: { x: 1, y: 0, z: 0 }
}
],
totalLength: 4
}
]
]);
const beforePresence = resolveRuntimeProjectScheduleState({
scheduler,
sequences,
actorIds: ["actor-timed-sequence"],
dayNumber: 1,
timeOfDayHours: 9.25,
pathsById
});
const duringPresence = resolveRuntimeProjectScheduleState({
scheduler,
sequences,
actorIds: ["actor-timed-sequence"],
dayNumber: 1,
timeOfDayHours: 9.75,
pathsById
});
const duringPath = resolveRuntimeProjectScheduleState({
scheduler,
sequences,
actorIds: ["actor-timed-sequence"],
dayNumber: 1,
timeOfDayHours: 10.5,
pathsById
});
expect(beforePresence.actors[0]).toEqual(
expect.objectContaining({
active: false
})
);
expect(duringPresence.actors[0]).toEqual(
expect.objectContaining({
active: true
})
);
expect(duringPath.actors[0].pathEffect).toEqual(
expect.objectContaining({
type: "followActorPath",
pathId: "path-market"
})
);
expect(duringPath.actors[0].resolvedPath).toEqual(
expect.objectContaining({
elapsedHours: 0.5,
distance: 1
})
);
});
it("applies non-actor scheduler effects over baseline control state and restores defaults when inactive", () => {
const lightTarget = createLightControlTargetRef(
"pointLight",

View File

@@ -267,9 +267,6 @@ describe("validateSceneDocument", () => {
title: "Held Only",
steps: [
{
startMinute: 0,
durationMinutes: 120,
lane: 0,
stepClass: "held",
type: "controlEffect",
effect: createSetSoundVolumeControlEffect({