154 lines
5.3 KiB
JavaScript
154 lines
5.3 KiB
JavaScript
import {} from "@iiif/3d-manifesto-dev";
|
|
import { IIIFManifest } from "./iiif";
|
|
|
|
export async function loadIIIFManifest(manifestUrlOrJson) {
|
|
let iiifManifest = new IIIFManifest(manifestUrlOrJson);
|
|
await iiifManifest.loadManifest();
|
|
let modelTarget;
|
|
let filteredAnnos;
|
|
let i = 0;
|
|
iiifManifest.modelUrls = new Array();
|
|
|
|
if (iiifManifest.scenes.length > 0) {
|
|
for (const [i, scene] of iiifManifest.scenes.entries()) { //TODO: support multiple scenes const manifestScene = scene;
|
|
//if (!scene) return;
|
|
// Root scene
|
|
const manifestScene = iiifManifest.scenes[i];
|
|
|
|
// Add scene BG color
|
|
iiifManifest.scenes[i].background = await manifestScene.getBackgroundColor();
|
|
|
|
// Load individual model annotations
|
|
const annos = iiifManifest.annotationsFromScene(manifestScene);
|
|
|
|
filteredAnnos = annos.filter((anno) => {
|
|
const body = anno.getBody()[0];
|
|
return (
|
|
anno.getMotivation()?.[0] === "painting" &&
|
|
(body.isSpecificResource || body?.getType() === "model")
|
|
);
|
|
});
|
|
|
|
filteredAnnos.forEach((modelAnnotation) => {
|
|
let modelUrl;
|
|
if (modelAnnotation.getBody()[0].isSpecificResource) {
|
|
modelUrl = modelAnnotation.getBody()[0].getSource()?.id;
|
|
} else {
|
|
modelUrl = modelAnnotation.getBody()[0].id;
|
|
}
|
|
modelTarget = modelAnnotation.getTarget();
|
|
if (modelUrl && modelTarget) {
|
|
iiifManifest.modelUrls.push(modelUrl);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
return {
|
|
manifest: iiifManifest.manifest,
|
|
scenes: iiifManifest.scenes,
|
|
annotations: filteredAnnos,
|
|
modelUrls: iiifManifest.modelUrls,
|
|
modelTarget: modelTarget
|
|
};
|
|
}
|
|
|
|
export async function getAnnotations(iiifManifest, objectsConfig) {
|
|
let ind = objectsConfig.index || 0;
|
|
const modelAnnotations = iiifManifest.annotations[ind];
|
|
if (!modelAnnotations) return;
|
|
|
|
const target = iiifManifest.annotations?.[ind];
|
|
|
|
if (target == null) {
|
|
// handle missing (out-of-range or undefined)
|
|
throw new Error(`No annotation at index ${ind}`);
|
|
}
|
|
|
|
// make sure we have an array to map over
|
|
const items = Array.isArray(target) ? target : [target];
|
|
|
|
await Promise.all(
|
|
items.map(async (modelAnnotation) => {
|
|
if (modelAnnotation.getBody()[0].isSpecificResource) {
|
|
let transforms = new Array();
|
|
|
|
try {
|
|
const body = modelAnnotation.getBody?.();
|
|
const first = Array.isArray(body) ? body[0] : null;
|
|
transforms = first?.getTransform?.() || [];
|
|
} catch (e) {
|
|
// No transforms present so keep defaults
|
|
//objectsConfig.models[ind].scale = {x: 1, y: 1, z: 1};
|
|
//objectsConfig.models[ind].rotation = {x: 0, y: 0, z: 0};
|
|
//objectsConfig.models[ind].position = {x: 0, y: 0, z: 0};
|
|
//console.log("No transform present in specific resource body");
|
|
}
|
|
// Correct use of async-safe loop
|
|
for (const transform of transforms) {
|
|
if (!transform.isTransform) continue;
|
|
|
|
const transformHandlers = [
|
|
{
|
|
key: "isScaleTransform",
|
|
action: () => {
|
|
const scale = transform.getScale();
|
|
if (scale) {
|
|
objectsConfig.models[ind].scale = scale;
|
|
}
|
|
else {
|
|
objectsConfig.models[ind].scale = {x: 1, y: 1, z: 1};
|
|
console.log("No scale defined in scale transform");
|
|
}
|
|
},
|
|
},
|
|
{
|
|
key: "isRotateTransform",
|
|
action: () => {
|
|
const rotation = transform.getRotation();
|
|
if (rotation) {
|
|
objectsConfig.models[ind].rotation = rotation;
|
|
}
|
|
else {
|
|
objectsConfig.models[ind].rotation = {x: 0, y: 0, z: 0};
|
|
console.log("No rotation defined in rotate transform");
|
|
}
|
|
},
|
|
},
|
|
{
|
|
key: "isTranslateTransform",
|
|
action: () => {
|
|
const translation = transform.getTranslation();
|
|
if (translation) {
|
|
objectsConfig.models[ind].position = translation;
|
|
}
|
|
else {
|
|
objectsConfig.models[ind].position = {x: 0, y: 0, z: 0};
|
|
}
|
|
},
|
|
},
|
|
];
|
|
|
|
for (const { key, action } of transformHandlers) {
|
|
if (transform[key]) {
|
|
action();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Position model within target scene if position selector present
|
|
if (iiifManifest.modelTarget.isSpecificResource == true) {
|
|
const selector = iiifManifest.modelTarget.getSelector();
|
|
if (selector && selector.isPointSelector) {
|
|
const position = selector.getLocation();
|
|
if (position) {
|
|
objectsConfig.models[ind].position.x += position.x;
|
|
objectsConfig.models[ind].position.y += position.y;
|
|
objectsConfig.models[ind].position.z += position.z;
|
|
}
|
|
}
|
|
}
|
|
}));
|
|
|
|
return iiifManifest.annotations;
|
|
}
|