/** * Application */ import React, { useState, useEffect } from "react"; import * as THREE from "three"; import { MTLLoader, OBJLoader } from "@hbis/three-obj-mtl-loader"; import Graph from "./Graph.js"; import Intro from "./Intro.js"; import LandscapeWarning from "./LandscapeWarning.js"; export default function App() { const [db, setDb] = useState(null); const [intro, setIntro] = useState(true); useEffect(async () => { const newDb = await loadDB(); await loadObjects(newDb); setDb(newDb); }, []); const closeIntro = () => { setIntro(false); }; return ( <> {intro && } {!intro && db && } ); } async function loadDB() { const request = await fetch("./assets/db.json"); return await request.json(); } async function loadObjects(db) { await Promise.all( db.page.reduce((promises, item) => { if (item.threeObject) { promises.push(loadObject(item)); } return promises; }, []) ); } function loadObject(item) { return new Promise((resolve) => { let { path, file } = item.threeObject; path = "./assets/" + path; const manager = new THREE.LoadingManager(); manager.setURLModifier((url) => { if (!url.match("/")) { url = path + url; } return url; }); const mtlLoader = new MTLLoader(manager); const objLoader = new OBJLoader(manager); mtlLoader.setMaterialOptions({ side: THREE.FrontSide }); mtlLoader.load(file.replace(".obj", ".mtl"), (materials) => { materials.preload(); objLoader.setMaterials(materials); objLoader.load(file, (object) => { object.children.forEach((child) => (child.material.transparent = true)); item.object = object; resolve(); }); }); }); }