@treasuryspatial/map-kit 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mapThreeLayer.d.ts +1 -0
- package/dist/mapThreeLayer.d.ts.map +1 -1
- package/dist/mapThreeLayer.js +124 -14
- package/package.json +1 -1
package/dist/mapThreeLayer.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type MapThreeLayerOptions = {
|
|
|
13
13
|
id: string;
|
|
14
14
|
zOffsetMeters?: number;
|
|
15
15
|
onInit?: (scene: THREE.Scene, renderer: THREE.WebGLRenderer, camera: THREE.Camera) => void;
|
|
16
|
+
debug?: boolean;
|
|
16
17
|
};
|
|
17
18
|
export declare function createMapThreeLayer(options: MapThreeLayerOptions): MapThreeLayer;
|
|
18
19
|
//# sourceMappingURL=mapThreeLayer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapThreeLayer.d.ts","sourceRoot":"","sources":["../src/mapThreeLayer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,QAAQ,CAAC,oBAAoB,CAAC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,SAAS,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"mapThreeLayer.d.ts","sourceRoot":"","sources":["../src/mapThreeLayer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,QAAQ,CAAC,oBAAoB,CAAC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,SAAS,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC;IAC3F,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAyMhF"}
|
package/dist/mapThreeLayer.js
CHANGED
|
@@ -1,20 +1,53 @@
|
|
|
1
1
|
import mapboxgl from 'mapbox-gl';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
export function createMapThreeLayer(options) {
|
|
4
|
-
const { id, zOffsetMeters = 0.02, onInit } = options;
|
|
4
|
+
const { id, zOffsetMeters = 0.02, onInit, debug = false } = options;
|
|
5
5
|
let mapRef = null;
|
|
6
6
|
let scene = null;
|
|
7
7
|
let camera = null;
|
|
8
8
|
let renderer = null;
|
|
9
|
+
let screenScene = null;
|
|
10
|
+
let screenCamera = null;
|
|
11
|
+
let screenMaterial = null;
|
|
12
|
+
let screenQuad = null;
|
|
13
|
+
let renderTarget = null;
|
|
9
14
|
let rootGroup = null;
|
|
10
15
|
let meshGroup = null;
|
|
11
16
|
let mercatorOrigin = null;
|
|
12
17
|
let meterScale = 1;
|
|
13
18
|
let zOffset = zOffsetMeters;
|
|
19
|
+
let targetWidth = 0;
|
|
20
|
+
let targetHeight = 0;
|
|
21
|
+
let renderDisabled = false;
|
|
22
|
+
let errorCount = 0;
|
|
23
|
+
const log = (...args) => {
|
|
24
|
+
if (!debug)
|
|
25
|
+
return;
|
|
26
|
+
console.info(`[map-kit:${id}]`, ...args);
|
|
27
|
+
};
|
|
28
|
+
const logError = (message, err) => {
|
|
29
|
+
console.error(`[map-kit:${id}] ${message}`, err);
|
|
30
|
+
};
|
|
31
|
+
const logGlError = (gl, label) => {
|
|
32
|
+
if (!debug)
|
|
33
|
+
return;
|
|
34
|
+
const error = gl.getError();
|
|
35
|
+
if (error !== gl.NO_ERROR) {
|
|
36
|
+
log(`GL error (${label})`, error);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const checkFramebuffer = (gl, label) => {
|
|
40
|
+
if (!debug)
|
|
41
|
+
return;
|
|
42
|
+
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
|
43
|
+
if (status !== gl.FRAMEBUFFER_COMPLETE) {
|
|
44
|
+
log(`Framebuffer incomplete (${label})`, status);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
14
47
|
const layer = {
|
|
15
48
|
id,
|
|
16
49
|
type: 'custom',
|
|
17
|
-
renderingMode: '
|
|
50
|
+
renderingMode: '2d',
|
|
18
51
|
onAdd: (map, gl) => {
|
|
19
52
|
mapRef = map;
|
|
20
53
|
scene = new THREE.Scene();
|
|
@@ -29,6 +62,28 @@ export function createMapThreeLayer(options) {
|
|
|
29
62
|
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
|
30
63
|
renderer.toneMapping = THREE.NeutralToneMapping;
|
|
31
64
|
renderer.toneMappingExposure = 1.05;
|
|
65
|
+
renderer.setClearColor(0x000000, 0);
|
|
66
|
+
const canvas = map.getCanvas();
|
|
67
|
+
targetWidth = canvas.width;
|
|
68
|
+
targetHeight = canvas.height;
|
|
69
|
+
renderTarget = new THREE.WebGLRenderTarget(targetWidth, targetHeight, {
|
|
70
|
+
depthBuffer: true,
|
|
71
|
+
stencilBuffer: false,
|
|
72
|
+
});
|
|
73
|
+
renderTarget.texture.colorSpace = THREE.SRGBColorSpace;
|
|
74
|
+
renderTarget.texture.premultiplyAlpha = true;
|
|
75
|
+
log('renderTarget', { width: targetWidth, height: targetHeight });
|
|
76
|
+
screenScene = new THREE.Scene();
|
|
77
|
+
screenCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
78
|
+
screenMaterial = new THREE.MeshBasicMaterial({
|
|
79
|
+
map: renderTarget.texture,
|
|
80
|
+
transparent: true,
|
|
81
|
+
depthTest: false,
|
|
82
|
+
depthWrite: false,
|
|
83
|
+
});
|
|
84
|
+
screenMaterial.premultipliedAlpha = true;
|
|
85
|
+
screenQuad = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), screenMaterial);
|
|
86
|
+
screenScene.add(screenQuad);
|
|
32
87
|
rootGroup = new THREE.Group();
|
|
33
88
|
rootGroup.matrixAutoUpdate = false;
|
|
34
89
|
scene.add(rootGroup);
|
|
@@ -37,20 +92,65 @@ export function createMapThreeLayer(options) {
|
|
|
37
92
|
if (onInit && renderer && camera)
|
|
38
93
|
onInit(scene, renderer, camera);
|
|
39
94
|
},
|
|
40
|
-
|
|
41
|
-
if (
|
|
95
|
+
prerender: (_gl, matrix) => {
|
|
96
|
+
if (renderDisabled)
|
|
97
|
+
return;
|
|
98
|
+
if (!renderer || !scene || !camera || !rootGroup || !renderTarget)
|
|
99
|
+
return;
|
|
100
|
+
try {
|
|
101
|
+
camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
|
|
102
|
+
if (mercatorOrigin) {
|
|
103
|
+
const translate = new THREE.Matrix4().makeTranslation(mercatorOrigin.x, mercatorOrigin.y, (mercatorOrigin.z ?? 0) + zOffset * meterScale);
|
|
104
|
+
const scale = new THREE.Matrix4().makeScale(meterScale, -meterScale, meterScale);
|
|
105
|
+
rootGroup.matrix = new THREE.Matrix4().multiplyMatrices(translate, scale);
|
|
106
|
+
rootGroup.matrixWorldNeedsUpdate = true;
|
|
107
|
+
}
|
|
108
|
+
const canvas = mapRef?.getCanvas();
|
|
109
|
+
if (canvas && (canvas.width !== targetWidth || canvas.height !== targetHeight)) {
|
|
110
|
+
targetWidth = canvas.width;
|
|
111
|
+
targetHeight = canvas.height;
|
|
112
|
+
renderTarget.setSize(targetWidth, targetHeight);
|
|
113
|
+
log('renderTarget resized', { width: targetWidth, height: targetHeight });
|
|
114
|
+
}
|
|
115
|
+
renderer.setRenderTarget(renderTarget);
|
|
116
|
+
renderer.clear(true, true, true);
|
|
117
|
+
const gl = renderer.getContext();
|
|
118
|
+
checkFramebuffer(gl, 'prerender');
|
|
119
|
+
renderer.render(scene, camera);
|
|
120
|
+
logGlError(gl, 'prerender');
|
|
121
|
+
renderer.setRenderTarget(null);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
errorCount += 1;
|
|
125
|
+
logError('prerender failed', err);
|
|
126
|
+
if (errorCount > 2) {
|
|
127
|
+
renderDisabled = true;
|
|
128
|
+
log('render disabled after repeated errors');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
render: (gl) => {
|
|
133
|
+
if (renderDisabled)
|
|
42
134
|
return;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
135
|
+
if (!renderer || !screenScene || !screenCamera)
|
|
136
|
+
return;
|
|
137
|
+
try {
|
|
138
|
+
renderer.resetState();
|
|
139
|
+
gl.disable(gl.DEPTH_TEST);
|
|
140
|
+
gl.enable(gl.BLEND);
|
|
141
|
+
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
142
|
+
renderer.render(screenScene, screenCamera);
|
|
143
|
+
logGlError(gl, 'render');
|
|
144
|
+
mapRef?.triggerRepaint();
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
errorCount += 1;
|
|
148
|
+
logError('render failed', err);
|
|
149
|
+
if (errorCount > 2) {
|
|
150
|
+
renderDisabled = true;
|
|
151
|
+
log('render disabled after repeated errors');
|
|
152
|
+
}
|
|
49
153
|
}
|
|
50
|
-
renderer.resetState();
|
|
51
|
-
renderer.clearDepth();
|
|
52
|
-
renderer.render(scene, camera);
|
|
53
|
-
mapRef?.triggerRepaint();
|
|
54
154
|
},
|
|
55
155
|
};
|
|
56
156
|
return {
|
|
@@ -78,9 +178,19 @@ export function createMapThreeLayer(options) {
|
|
|
78
178
|
if (rootGroup) {
|
|
79
179
|
rootGroup.clear();
|
|
80
180
|
}
|
|
181
|
+
if (screenQuad) {
|
|
182
|
+
screenQuad.geometry.dispose();
|
|
183
|
+
}
|
|
184
|
+
screenMaterial?.dispose();
|
|
185
|
+
renderTarget?.dispose();
|
|
81
186
|
meshGroup = null;
|
|
82
187
|
scene = null;
|
|
83
188
|
camera = null;
|
|
189
|
+
screenScene = null;
|
|
190
|
+
screenCamera = null;
|
|
191
|
+
screenMaterial = null;
|
|
192
|
+
screenQuad = null;
|
|
193
|
+
renderTarget = null;
|
|
84
194
|
renderer = null;
|
|
85
195
|
mapRef = null;
|
|
86
196
|
mercatorOrigin = null;
|