UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

262 lines (261 loc) 8.87 kB
"use strict"; import { TypedViewer } from "./_Base"; import { CoreCameraPostProcessController } from "../../core/camera/CoreCameraPostProcessController"; import { CoreCameraCSSRendererController } from "../../core/camera/CoreCameraCSSRendererController"; import { CoreCameraRenderSceneController } from "../../core/camera/CoreCameraRenderSceneController"; import { CoreStylesheetLoader } from "../../core/loader/Stylesheet"; import { MapboxMapsController } from "../../core/thirdParty/Mapbox/MapboxMapsController"; import { MapboxRaycaster } from "../../core/thirdParty/Mapbox/MapboxRaycaster"; import { ThreeMeshBVHHelper } from "../../core/geometry/bvh/ThreeMeshBVHHelper"; const CSS_CLASS = "CoreMapboxViewer"; const CSS_URL = "https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css"; export class MapboxViewer extends TypedViewer { constructor(options) { super(options); this.options = options; // private _disposeEvents() { // window.removeEventListener('resize', this._onResizeBound, false); // } this._onResizeBound = this.onResize.bind(this); // private _startAnimate() { // // if (this.isXR()) { // // const renderer = this._renderer as WebGLRenderer; // // if (!renderer) { // // return; // // } // // const webXRController = this.scene().webXR; // // const xrCallback: XRFrameRequestCallback = (timestamp, frame) => { // // webXRController.activeXRController()?.process(frame); // // this._animateWebXR(); // // }; // // renderer.setAnimationLoop(xrCallback); // // } else { // this._animateWeb(); // // } // } // private _cancelAnimate() { // // if (this.isXR()) { // // (this._renderer as WebGLRenderer)?.setAnimationLoop(null); // // } else { // this._cancelAnimateCommon(); // // } // } // private _animateWebBound: () => void = this._animateWeb.bind(this); // private _animateWeb() { // if (!this._doRender) { // return; // } // this._requestAnimationFrameId = requestAnimationFrame(this._animateWebBound); // this.__animateCommon__(); // } // private _animateWebXR() { // this.__animateCommon__(); // } this._animateCommonBound = this.__animateCommon__.bind(this); this._canvasContainer = document.createElement("div"); this._canvasContainer.id = `mapbox_container_id_${Math.random()}`.replace(".", "_"); this._canvasContainer.style.height = "100%"; CoreStylesheetLoader.loadUrl(CSS_URL); const data = MapboxMapsController.createMap({ camera: options.camera, container: this._canvasContainer, scene: options.scene, renderFunc: this._animateCommonBound, viewer: this }); this._map = data.map; this._map.on("resize", this._onResizeBound); } // private _layersController: MapboxLayersController; static _canvasIdPrefix() { return "MapboxViewer"; } rendererConfig() { return void 0; } createRaycaster() { const raycaster = new MapboxRaycaster(); ThreeMeshBVHHelper.updateRaycaster(raycaster); return raycaster; } setRenderer(renderer) { this._renderer = renderer; this._setupFunctions(renderer, this.options); } renderer() { return this._renderer; } canvas() { return this._map.getCanvas(); } _setupFunctions(renderer, options) { var _a; const camera = this.camera(); const scene = this.scene(); const canvas = this.canvas(); const threejsScene = scene.threejsScene(); const rendererScene = CoreCameraRenderSceneController.renderScene({ camera, scene }); const renderScene = rendererScene || threejsScene; this._effectComposer = CoreCameraPostProcessController.createComposer({ camera, scene, renderScene, renderer, viewer: this }); const effectComposer = this._effectComposer; this._cssRendererConfig = CoreCameraCSSRendererController.cssRendererConfig({ scene, camera, canvas }); const cssRenderer = (_a = this._cssRendererConfig) == null ? void 0 : _a.cssRenderer; this._renderCSSFunc = cssRenderer ? () => cssRenderer.render(renderScene, camera) : void 0; if (effectComposer) { this._renderFunc = (delta) => effectComposer.render(delta); } else { this._renderFunc = () => renderer.render(renderScene, camera); } this._mountCSSRenderer(); } /** * mounts the viewer onto an element * * */ mount(element) { var _a, _b; super.mount(element); (_a = this._domElement) == null ? void 0 : _a.appendChild(this._canvasContainer); (_b = this._domElement) == null ? void 0 : _b.classList.add(CSS_CLASS); this._setEvents(); } _mountCSSRenderer() { var _a; const canvas = this._map.getCanvas(); const cssRendererNode = (_a = this._cssRendererConfig) == null ? void 0 : _a.cssRendererNode; if (cssRendererNode) { cssRendererNode.mountRenderer(canvas); } } _build() { this.activate(); } /** * disposes the viewer * * */ // override dispose() { // const canvas = this.canvas(); // // dispose cssRenderer // const cssRendererNode = this._cssRendererConfig?.cssRendererNode; // if (cssRendererNode) { // cssRendererNode.unmountRenderer(canvas); // } // this._cssRendererConfig = undefined; // // dispose webXR // this._webXRConfig?.unmountFunction(); // this._markerTrackingConfig?.unmountFunction(); // // dispose effectComposer // this._effectComposer = undefined; // this.setAutoRender(false); // this._cancelAnimate(); // // this.controlsController().dispose(); // this._disposeEvents(); // // if I dispose the renderer here, // // this prevents env maps from displaying // // when the viewer is switched // // TODO: consider disposing the renderer only if it is not a default one, // // as this may satisfy most cases // //this._renderer?.dispose(); // super.dispose(); // } _setEvents() { this.eventsController().init(); this.webglController().init(); } onResize() { var _a, _b; const canvas = this._map.getCanvas(); const rect = canvas.getBoundingClientRect(); this._size.set(rect.width, rect.height); if (!this._renderer) { return; } const devicePixelRatio = globalThis.devicePixelRatio; this._renderer.setSize(this._size.x * devicePixelRatio, this._size.y * devicePixelRatio, false); this.camerasController().computeSizeAndAspect(globalThis.devicePixelRatio); (_a = this._cssRendererConfig) == null ? void 0 : _a.cssRenderer.setSize(this._size.x, this._size.y); (_b = this._effectComposer) == null ? void 0 : _b.setSize(this._size.x, this._size.y); this.camerasController().updateCameraAspect(); this._runOnResizeCallbacks(); } // private _initDisplay() { // if (!this._canvas) { // console.warn('no canvas found for viewer'); // return; // } // if (!this._renderer) { // return; // } // const pixelRatio = this._renderer.getPixelRatio(); // this.camerasController().computeSizeAndAspect(pixelRatio); // this.audioController().update(); // this._startAnimate(); // } /** * setAutoRender to false will stop the rendering. This can be useful if you know that nothing has changed in the scene, or if the renderer is currently not visible. * * */ // override setAutoRender(state = true) { // super.setAutoRender(state); // // if this._requestAnimationFrameId is already defined, // // calling this a second time would start another requestAnimationFrame // // and we would therefore render at twice the rate // if (this._doRender && this._requestAnimationFrameId == null) { // this._startAnimate(); // } // if (!this._doRender) { // this._cancelAnimate(); // } // } isXR() { return false; } __animateCommon__() { const delta = this._scene.timeController.updateClockDelta(); this._tickAndRender(delta); } // private _cancelAnimateCommon() { // this._doRender = false; // if (this._requestAnimationFrameId != null) { // cancelAnimationFrame(this._requestAnimationFrameId); // this._requestAnimationFrameId = undefined; // } // if (this._canvas) { // // this._cameraNode.renderController().deleteRenderer(this._canvas); // } // } /** * returns the current renderer * * */ // renderer() { // return this._renderer; // // if (this._canvas) { // // // return this._cameraNode.renderController().renderer(this._canvas); // // } // } // effectComposer() { // return this._effectComposer; // } preCompile() { if (!this._renderer) { return; } this._renderer.compile(this._scene.threejsScene(), this._camera); } markAsReady() { this.preCompile(); this.setAutoRender(true); } }