242 lines
7.3 KiB
TypeScript
242 lines
7.3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { BoxGeometry } from "three";
|
|
|
|
import { deleteProjectAssetFromProjectDocument } from "../../src/assets/delete-project-asset";
|
|
import { createModelInstance } from "../../src/assets/model-instances";
|
|
import {
|
|
createProjectAssetStorageKey,
|
|
type AudioAssetRecord,
|
|
type ImageAssetRecord
|
|
} from "../../src/assets/project-assets";
|
|
import {
|
|
createEmptyProjectDocument,
|
|
type ProjectDocument
|
|
} from "../../src/document/scene-document";
|
|
import { createDefaultWorldSettings } from "../../src/document/world-settings";
|
|
import {
|
|
createNpcEntity,
|
|
createSoundEmitterEntity,
|
|
createTeleportTargetEntity,
|
|
createTriggerVolumeEntity
|
|
} from "../../src/entities/entity-instances";
|
|
import {
|
|
createPlayAnimationInteractionLink,
|
|
createPlaySoundInteractionLink,
|
|
createStopAnimationInteractionLink,
|
|
createStopSoundInteractionLink,
|
|
createTeleportPlayerInteractionLink
|
|
} from "../../src/interactions/interaction-links";
|
|
import { createFixtureLoadedModelAssetFromGeometry } from "../helpers/model-collider-fixtures";
|
|
|
|
function createProjectDocumentFixture() {
|
|
const baseProjectDocument = createEmptyProjectDocument({
|
|
sceneName: "Asset Cleanup Scene"
|
|
});
|
|
const sceneId = baseProjectDocument.activeSceneId;
|
|
const baseScene = baseProjectDocument.scenes[sceneId];
|
|
const { asset: modelAsset } = createFixtureLoadedModelAssetFromGeometry(
|
|
"asset-model-cleanup",
|
|
new BoxGeometry(1, 2, 1)
|
|
);
|
|
const imageAsset: ImageAssetRecord = {
|
|
id: "asset-image-cleanup",
|
|
kind: "image",
|
|
sourceName: "panorama-cleanup.png",
|
|
mimeType: "image/png",
|
|
storageKey: createProjectAssetStorageKey("asset-image-cleanup"),
|
|
byteLength: 2048,
|
|
metadata: {
|
|
kind: "image",
|
|
width: 1024,
|
|
height: 512,
|
|
hasAlpha: false,
|
|
warnings: []
|
|
}
|
|
};
|
|
const audioAsset: AudioAssetRecord = {
|
|
id: "asset-audio-cleanup",
|
|
kind: "audio",
|
|
sourceName: "cleanup-loop.ogg",
|
|
mimeType: "audio/ogg",
|
|
storageKey: createProjectAssetStorageKey("asset-audio-cleanup"),
|
|
byteLength: 4096,
|
|
metadata: {
|
|
kind: "audio",
|
|
durationSeconds: 6.5,
|
|
channelCount: 2,
|
|
sampleRateHz: 44100,
|
|
warnings: []
|
|
}
|
|
};
|
|
const modelInstance = createModelInstance({
|
|
id: "model-instance-cleanup",
|
|
assetId: modelAsset.id
|
|
});
|
|
const triggerVolume = createTriggerVolumeEntity({
|
|
id: "entity-trigger-cleanup"
|
|
});
|
|
const teleportTarget = createTeleportTargetEntity({
|
|
id: "entity-teleport-cleanup"
|
|
});
|
|
const soundEmitter = createSoundEmitterEntity({
|
|
id: "entity-sound-cleanup",
|
|
audioAssetId: audioAsset.id,
|
|
autoplay: true,
|
|
loop: true
|
|
});
|
|
const npc = createNpcEntity({
|
|
id: "entity-npc-cleanup",
|
|
actorId: "actor-cleanup-guide",
|
|
modelAssetId: modelAsset.id
|
|
});
|
|
const projectDocument: ProjectDocument = {
|
|
...baseProjectDocument,
|
|
assets: {
|
|
...baseProjectDocument.assets,
|
|
[modelAsset.id]: modelAsset,
|
|
[imageAsset.id]: imageAsset,
|
|
[audioAsset.id]: audioAsset
|
|
},
|
|
scenes: {
|
|
...baseProjectDocument.scenes,
|
|
[sceneId]: {
|
|
...baseScene,
|
|
world: {
|
|
...baseScene.world,
|
|
background: {
|
|
mode: "image",
|
|
assetId: imageAsset.id,
|
|
environmentIntensity: 0.8
|
|
},
|
|
timeOfDay: {
|
|
...baseScene.world.timeOfDay,
|
|
dawn: {
|
|
...baseScene.world.timeOfDay.dawn,
|
|
background: {
|
|
mode: "image",
|
|
assetId: imageAsset.id,
|
|
environmentIntensity: 0.55
|
|
}
|
|
}
|
|
}
|
|
},
|
|
modelInstances: {
|
|
[modelInstance.id]: modelInstance
|
|
},
|
|
entities: {
|
|
[triggerVolume.id]: triggerVolume,
|
|
[teleportTarget.id]: teleportTarget,
|
|
[soundEmitter.id]: soundEmitter,
|
|
[npc.id]: npc
|
|
},
|
|
interactionLinks: {
|
|
"link-play-animation": createPlayAnimationInteractionLink({
|
|
id: "link-play-animation",
|
|
sourceEntityId: triggerVolume.id,
|
|
targetModelInstanceId: modelInstance.id,
|
|
clipName: "Idle"
|
|
}),
|
|
"link-stop-animation": createStopAnimationInteractionLink({
|
|
id: "link-stop-animation",
|
|
sourceEntityId: triggerVolume.id,
|
|
targetModelInstanceId: modelInstance.id
|
|
}),
|
|
"link-play-sound": createPlaySoundInteractionLink({
|
|
id: "link-play-sound",
|
|
sourceEntityId: triggerVolume.id,
|
|
targetSoundEmitterId: soundEmitter.id
|
|
}),
|
|
"link-stop-sound": createStopSoundInteractionLink({
|
|
id: "link-stop-sound",
|
|
sourceEntityId: triggerVolume.id,
|
|
targetSoundEmitterId: soundEmitter.id
|
|
}),
|
|
"link-teleport": createTeleportPlayerInteractionLink({
|
|
id: "link-teleport",
|
|
sourceEntityId: triggerVolume.id,
|
|
targetEntityId: teleportTarget.id
|
|
})
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
return {
|
|
sceneId,
|
|
projectDocument,
|
|
modelAsset,
|
|
imageAsset,
|
|
audioAsset,
|
|
modelInstance,
|
|
npc,
|
|
soundEmitter
|
|
};
|
|
}
|
|
|
|
describe("deleteProjectAssetFromProjectDocument", () => {
|
|
it("removes deleted model assets from model instances and animation links", () => {
|
|
const fixture = createProjectDocumentFixture();
|
|
|
|
const nextProjectDocument = deleteProjectAssetFromProjectDocument(
|
|
fixture.projectDocument,
|
|
fixture.modelAsset.id
|
|
);
|
|
const nextScene = nextProjectDocument.scenes[fixture.sceneId];
|
|
|
|
expect(nextProjectDocument.assets[fixture.modelAsset.id]).toBeUndefined();
|
|
expect(nextScene.modelInstances).toEqual({});
|
|
expect(nextScene.entities[fixture.npc.id]).toMatchObject({
|
|
kind: "npc",
|
|
modelAssetId: null
|
|
});
|
|
expect(Object.keys(nextScene.interactionLinks).sort()).toEqual([
|
|
"link-play-sound",
|
|
"link-stop-sound",
|
|
"link-teleport"
|
|
]);
|
|
});
|
|
|
|
it("resets image backgrounds when deleting a referenced image asset", () => {
|
|
const fixture = createProjectDocumentFixture();
|
|
|
|
const nextProjectDocument = deleteProjectAssetFromProjectDocument(
|
|
fixture.projectDocument,
|
|
fixture.imageAsset.id
|
|
);
|
|
const nextScene = nextProjectDocument.scenes[fixture.sceneId];
|
|
|
|
expect(nextProjectDocument.assets[fixture.imageAsset.id]).toBeUndefined();
|
|
expect(nextScene.world.background).toEqual(
|
|
createDefaultWorldSettings().background
|
|
);
|
|
expect(nextScene.world.timeOfDay.dawn.background).toEqual({
|
|
mode: "image",
|
|
assetId: "",
|
|
environmentIntensity: 0.55
|
|
});
|
|
});
|
|
|
|
it("silences sound emitters and removes sound links when deleting an audio asset", () => {
|
|
const fixture = createProjectDocumentFixture();
|
|
|
|
const nextProjectDocument = deleteProjectAssetFromProjectDocument(
|
|
fixture.projectDocument,
|
|
fixture.audioAsset.id
|
|
);
|
|
const nextScene = nextProjectDocument.scenes[fixture.sceneId];
|
|
|
|
expect(nextProjectDocument.assets[fixture.audioAsset.id]).toBeUndefined();
|
|
expect(nextScene.entities[fixture.soundEmitter.id]).toMatchObject({
|
|
kind: "soundEmitter",
|
|
audioAssetId: null,
|
|
autoplay: false,
|
|
loop: true
|
|
});
|
|
expect(Object.keys(nextScene.interactionLinks).sort()).toEqual([
|
|
"link-play-animation",
|
|
"link-stop-animation",
|
|
"link-teleport"
|
|
]);
|
|
});
|
|
});
|