UNPKG

xeokit-viewer

Version:

BIM viewer built on xeokit and Bootstrap

239 lines (185 loc) 7.42 kB
import {StoreyViewsPlugin} from "../../lib/xeokit/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js"; import {Controller} from "../Controller.js"; import {ObjectsMemento} from "../../lib/xeokit/viewer/scene/mementos/ObjectsMemento.js"; import {CameraMemento} from "../../lib/xeokit/viewer/scene/mementos/CameraMemento.js"; import {math} from "../../lib/xeokit/viewer/scene/math/math.js"; /** * @desc Manages storeys. * * Located at {@link Toolbar#storeys}. */ class Storeys extends Controller { constructor(parent, cfg) { super(parent, cfg); this._element = document.getElementById(cfg.storeysPanelId); this._storeyViewsPlugin = new StoreyViewsPlugin(this.viewer); this._storeyViewsPlugin.on("storeys", () => { this._repaint(); }); this._objectsMemento = new ObjectsMemento(); this._cameraMemento = new CameraMemento(); this._storeyOpen = false; this._openStoreyId = null; const canStandOnTypes = { IfcSlab: true, IfcStair: true, IfcFloor: true, IfcFooting: true }; const viewer = this.viewer; const worldPos = math.vec3(); viewer.cameraControl.on("pickedSurface", (pickResult) => { if (!this._storeyOpen) { return; } const entity = pickResult.entity; const metaObject = viewer.metaScene.metaObjects[entity.id]; if (canStandOnTypes[metaObject.type]) { worldPos.set(pickResult.worldPos); worldPos[1] += 1.5; viewer.cameraFlight.flyTo({ eye: worldPos, up: viewer.camera.worldUp, look: math.addVec3(worldPos, viewer.camera.worldForward, []), projection: "perspective", duration: 1.5 }, () => { viewer.cameraControl.planView = false; viewer.cameraControl.firstPerson = true; viewer.cameraControl.pivoting = false; this._storeyOpen = false; this._openStoreyId = null; }); } }); viewer.cameraControl.on("pickedNothing", (pickResult) => { if (!this._storeyOpen) { return; } const openStoreyId = this._openStoreyId; this._storeyOpen = false; this._openStoreyId = null; this._objectsMemento.restoreObjects(this.viewer.scene); this._cameraMemento.restoreCamera(this.viewer.scene, () => { }); this.fire("storeyClosed", openStoreyId); // TODO: return to previous camera, saved in showStorey on first open storey // this._storeyViewsPlugin.gotoStoreyCamera("2SWZMQPyD9pfT9q87pgXa1", { // projection: "ortho", // duration: 1.5, // done: () => { // viewer.cameraControl.planView = true; // } // }); }); } _repaint() { const html = []; var storeyId; const models = this.viewer.scene.models; const storeyIds = []; for (var modelId in models) { const model = this.viewer.scene.models[modelId]; const metaModel = this.viewer.metaScene.metaModels[modelId]; if (!metaModel) { continue; } const storeys = this._storeyViewsPlugin.modelStoreys[modelId]; if (!storeys) { continue; } html.push("<div>" + metaModel.id + "</div>"); for (storeyId in storeys) { const storey = storeys[storeyId]; if (storey) { html.push("<div class='form-check'>"); html.push("<li>"); html.push("<a id='" + storey.storeyId + "' href=''>" + storey.name + "</a>"); html.push("</li>"); html.push("</div>"); storeyIds.push(storeyId); } } html.push("<br>"); } this._element.innerHTML = html.join(""); for (var i = 0, len = storeyIds.length; i < len; i++) { const _storeyId = storeyIds[i]; const link = $("#" + _storeyId); link.on('click', (e) => { this.showStorey(_storeyId, () => { }); e.preventDefault(); }); } } showStorey(storeyId, done) { const storey = this._storeyViewsPlugin.storeys[storeyId]; if (!storey) { return; } const viewer = this.viewer; const scene = viewer.scene; const metaScene = viewer.metaScene; const metaObject = metaScene.metaObjects[storeyId]; if (this._storeyOpen) { scene.setObjectsVisible(scene.objectIds, true); scene.setObjectsXRayed(scene.objectIds, true); const objectIds = metaObject.getObjectIDsInSubtree(); scene.setObjectsVisible(objectIds, true); scene.setObjectsXRayed(objectIds, false); this._storeyViewsPlugin.gotoStoreyCamera(storeyId, { projection: "ortho", // Orthographic projection duration: 0.3, // 2.5 second transition done: () => { this._storeyViewsPlugin.showStoreyObjects(storeyId, { hideOthers: true, useObjectStates: true }); this.viewer.cameraControl.planView = true; // Disable camera rotation if (done) { done(); } } }); } else { this._cameraMemento.saveCamera(scene); this._objectsMemento.saveObjects(scene); scene.setObjectsVisible(scene.objectIds, true); scene.setObjectsXRayed(scene.objectIds, true); const objectIds = metaObject.getObjectIDsInSubtree(); scene.setObjectsVisible(objectIds, true); scene.setObjectsXRayed(objectIds, false); this._storeyViewsPlugin.gotoStoreyCamera(storeyId, { projection: "ortho", // Orthographic projection duration: 1.0, // 2.5 second transition done: () => { this._storeyViewsPlugin.showStoreyObjects(storeyId, { hideOthers: true, useObjectStates: true }); this.viewer.cameraControl.planView = true; // Disable camera rotation if (done) { done(); } } }); } this._storeyOpen = true; this._openStoreyId = storeyId; this.fire("storeyOpened", this._openStoreyId); } setToolbarEnabled(enabled) { if (!enabled) { $("#storeys-tab").addClass("disabled"); } else { $("#storeys-tab").removeClass("disabled"); } } /** @private */ destroy() { super.destroy(); this._storeyViewsPlugin.destroy(); } } export {Storeys};