UNPKG

@polygonjs/plugin-mapbox

Version:

Mapbox plugin for the 3D engine https://polygonjs.com

130 lines (129 loc) 4.61 kB
import { CoreMapboxTransform } from "../../../../core/mapbox/Transform"; import { Mesh, Matrix4, Vector3, WebGLRenderer, PlaneGeometry } from "three"; import mapboxgl from "mapbox-gl"; import { TIME_CONTROLLER_UPDATE_TIME_OPTIONS_DEFAULT } from "@polygonjs/polygonjs/dist/src/engine/scene/utils/TimeController"; import { CoreCameraCSSRendererController } from "@polygonjs/polygonjs/dist/src/core/camera/CoreCameraCSSRendererController"; const ID = "threejs_layer"; export class ThreejsLayer { constructor(_cameraNode, _displayScene, _viewer) { this._cameraNode = _cameraNode; this._displayScene = _displayScene; this._viewer = _viewer; this.id = ID; this.type = "custom"; this.renderingMode = "3d"; this._vX = new Vector3(1, 0, 0); this._vY = new Vector3(0, 1, 0); this._vZ = new Vector3(0, 0, 1); this.mRX = new Matrix4(); this.mRY = new Matrix4(); this.mRZ = new Matrix4(); this.s = new Vector3(); this.m = new Matrix4(); this.l = new Matrix4(); this._camera = this._cameraNode.object; this._scene = this._cameraNode.scene(); } onAdd(map, gl) { this._map = map; this._gl = gl; this.createRenderer(); } onRemove() { var _a; (_a = this._renderer) == null ? void 0 : _a.dispose(); } createRenderer() { var _a, _b; if (this._renderer != null) { this._renderer.dispose(); } if (!this._map) { console.error("no map given"); return; } if (!this._gl) { console.error("no gl context given"); return; } this._renderer = new WebGLRenderer({ canvas: this._map.getCanvas(), context: this._gl }); this._renderer.autoClear = false; this._renderer.shadowMap.enabled = true; this._cssRendererConfig = CoreCameraCSSRendererController.cssRendererConfig({ scene: this._scene, camera: this._camera, canvas: this._viewer.canvas() }); const cssRendererNode = (_a = this._cssRendererConfig) == null ? void 0 : _a.cssRendererNode; if (cssRendererNode) { cssRendererNode.mountRenderer(this._viewer.canvas()); } const cssRenderer = (_b = this._cssRendererConfig) == null ? void 0 : _b.cssRenderer; if (cssRenderer) { cssRenderer.domElement.style.zIndex = "99999"; } this._renderCSSFunc = cssRenderer ? () => cssRenderer.render(this._displayScene, this._camera) : void 0; this._hack(); } resize(size) { var _a; this.createRenderer(); (_a = this._cssRendererConfig) == null ? void 0 : _a.cssRenderer.setSize(size.x, size.y); } async render(gl, matrix) { if (!this._renderer || !this._map) { return; } if (this._displayScene.background) { console.warn("scene background is not null, this will cover the map and prevent it from being seen"); } this._scene.timeController.updateClockDelta(); this._scene.timeController.incrementTimeIfPlaying(TIME_CONTROLLER_UPDATE_TIME_OPTIONS_DEFAULT); this._updateCameraMatrix(matrix); this._renderer.state.reset(); this._renderer.render(this._displayScene, this._camera); this._map.triggerRepaint(); if (this._renderCSSFunc) { this._renderCSSFunc(); } } _updateCameraMatrix(matrix) { const lng_lat = this._viewer.cameraLngLat(); if (!lng_lat) { return; } const mercator = mapboxgl.MercatorCoordinate.fromLngLat([lng_lat.lng, lng_lat.lat], 0); const transform = { position: mercator, rotation: { x: Math.PI / 2, y: 0, z: 0 }, scale: CoreMapboxTransform.WORLD_SCALE }; this.mRX.identity(); this.mRY.identity(); this.mRZ.identity(); const rotationX = this.mRX.makeRotationAxis(this._vX, transform.rotation.x); const rotationY = this.mRY.makeRotationAxis(this._vY, transform.rotation.y); const rotationZ = this.mRZ.makeRotationAxis(this._vZ, transform.rotation.z); this.s.x = transform.scale; this.s.y = -transform.scale; this.s.z = transform.scale; this.m.fromArray(matrix); this.l.identity(); this.l.makeTranslation(1 * transform.position.x, 1 * transform.position.y, 1 * (transform.position.z || 0)).scale(this.s).multiply(rotationX).multiply(rotationY).multiply(rotationZ); this._camera.projectionMatrix.elements = matrix; this._camera.projectionMatrix = this.m.multiply(this.l); } _hack() { const hackObject = new Mesh(new PlaneGeometry()); hackObject.frustumCulled = false; hackObject.position.z = -1e3; hackObject.scale.set(0.01, 0.01, 0.01); const scene = this._scene.threejsScene(); scene.add(hackObject); } }