@polygonjs/plugin-mapbox
Version:
Mapbox plugin for the 3D engine https://polygonjs.com
130 lines (129 loc) • 4.61 kB
JavaScript
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);
}
}