Skip to content

Commit

Permalink
improved(editor): Added support for custom Navlink styles, which are …
Browse files Browse the repository at this point in the history
…now preserved and reapplied when re-rendering is required, such as during pointer events.

Signed-off-by: Tim Deubler <[email protected]>
  • Loading branch information
TerminalTim committed Aug 23, 2024
1 parent efb2821 commit 7b55741
Show file tree
Hide file tree
Showing 24 changed files with 609 additions and 126 deletions.
13 changes: 6 additions & 7 deletions packages/display/src/displays/BasicDisplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,18 +156,17 @@ abstract class Display {
return dpr < 1 ? 1 : dpr;
}

addLayer(layer: TileLayer | CustomLayer, index: number, styles?: XYZLayerStyle): boolean {
addLayer(layer: TileLayer | CustomLayer, index: number, styles?: XYZLayerStyle): Layer {
const display = this;
const layers = display.layers;
let added = layers.add(layer, index);
if (added) {
if (layers.add(layer, index)) {
const dLayer = layers.get(layer);
display.buckets.forEach((dTile) => {
dTile.addLayer(index);
});
toggleLayerEventListener('add', layer, display.listeners);

if (layer.custom) return added;
if (layer.custom) return dLayer;

styles?.clearCache();

Expand All @@ -183,8 +182,8 @@ abstract class Display {
if (index == 0) {
display.setLayerBgColor((layer as TileLayer).getStyleManager(), dLayer);
}
return dLayer;
}
return added;
}

removeLayer(layer: TileLayer | CustomLayer): number {
Expand Down Expand Up @@ -293,7 +292,7 @@ abstract class Display {
private processLayerBackgroundColor(zoomlevel?: number) {
const display = this;
const bgColor = display.layers[0]?.bgColor || display.globalBgc;
this.bgColor = typeof bgColor == 'function' ? display.render.convertColor(bgColor(zoomlevel^0)) : bgColor;
this.bgColor = typeof bgColor == 'function' ? display.render.convertColor(bgColor(zoomlevel ^ 0)) : bgColor;
}

private isVisible(tile: Tile, dLayer: Layer): boolean {
Expand Down Expand Up @@ -636,7 +635,7 @@ abstract class Display {
return 1;
}

protected setZoom(zoomLevel: number):boolean {
protected setZoom(zoomLevel: number): boolean {
if (this._zoom != zoomLevel) {
this._zoom = zoomLevel;
return true;
Expand Down
18 changes: 17 additions & 1 deletion packages/display/src/displays/Layers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
* License-Filename: LICENSE
*/

import {Tile, Layer as BasicLayer, TileLayer, Feature} from '@here/xyz-maps-core';
import {Tile, Layer as BasicLayer, TileLayer, Feature, DirectionalLight, AmbientLight} from '@here/xyz-maps-core';
import {Expression, ExpressionParser} from '@here/xyz-maps-common';
import BasicTile from './BasicTile';
import {parseStyleGroup} from './styleTools';
import {UniformMap} from './webgl/program/Program';
import {vec3, Color} from '@here/xyz-maps-common';
import {defaultLights} from './webgl/lights';

// import scale = vec3.scale;

class ScreenTile {
x: number;
Expand Down Expand Up @@ -148,6 +152,18 @@ class Layer {
}
return styleGroup;
}

getLights(lightSet?: string) {
const styleManager = this.layer.getStyleManager?.();
let lights = styleManager?.lights;
if (!lights || !Object.keys(lights).length) {
lights = {'default': defaultLights};
if (styleManager) {
styleManager.lights = lights;
}
}
return lights;
}
}

class Layers extends Array<Layer> {
Expand Down
35 changes: 32 additions & 3 deletions packages/display/src/displays/webgl/Display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ import GLTile from './GLTile';
import {FeatureFactory} from './buffer/FeatureFactory';
import {CollisionHandler} from './CollisionHandler';
import {GeometryBuffer} from './buffer/GeometryBuffer';
import {CustomLayer, TileLayer} from '@here/xyz-maps-core';
import {CustomLayer, TileLayer, XYZLayerStyle} from '@here/xyz-maps-core';
import {PASS} from './program/GLStates';
import {Raycaster} from './Raycaster';
import {defaultLightUniforms, initLightUniforms} from './lights';

const PREVIEW_LOOK_AHEAD_LEVELS: [number, number] = [3, 9];

Expand Down Expand Up @@ -100,6 +101,8 @@ type CustomBufferData = {

type BufferData = CustomBufferData | TileBufferData;

const PROCESSED_LIGHTS_SYMBOL = Symbol();

class WebGlDisplay extends BasicDisplay {
static zoomBehavior: 'fixed' | 'float' = 'float';

Expand Down Expand Up @@ -180,8 +183,33 @@ class WebGlDisplay extends BasicDisplay {
}
}

private initLights(displayLayer: Layer) {
const lightSets = displayLayer.getLights();
let processedLightSets = lightSets[PROCESSED_LIGHTS_SYMBOL];
if (!processedLightSets) {
// processedLightSets = {'default': defaultLightUniforms};
processedLightSets = {};
for (let name in lightSets) {
const lightSet = lightSets[name];
processedLightSets[name] = initLightUniforms(lightSet);
}
lightSets[PROCESSED_LIGHTS_SYMBOL] = processedLightSets;
}
this.render.processedLight[displayLayer.index] = processedLightSets;
}

addLayer(layer: TileLayer | CustomLayer, index: number, styles?: XYZLayerStyle): Layer {
const displayLayer = super.addLayer(layer, index, styles);
// if (displayLayer) {
// this.initLights(displayLayer);
// }
return displayLayer;
}

removeLayer(layer: TileLayer): number {
this.collision.removeTiles(this.layers.get(layer));
const displayLayer = this.layers.get(layer);
this.collision.removeTiles(displayLayer);
this.render.processedLight[displayLayer.index] = undefined;
return super.removeLayer(layer);
}

Expand Down Expand Up @@ -227,7 +255,6 @@ class WebGlDisplay extends BasicDisplay {

setSize(w: number, h: number) {
super.setSize(w, h);

this.initRenderer();
}

Expand Down Expand Up @@ -387,6 +414,8 @@ class WebGlDisplay extends BasicDisplay {
let absZOrder = {};

for (let layer of layers) {
this.initLights(layer);

let tiles = layer.tiles;
// reset tile ready count
layer.cnt = 0;
Expand Down
80 changes: 56 additions & 24 deletions packages/display/src/displays/webgl/GLRender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import BasicRender from '../BasicRender';
import {CustomLayer, Tile, TileLayer} from '@here/xyz-maps-core';
import {AmbientLight, CustomLayer, Tile, TileLayer} from '@here/xyz-maps-core';
import GLTile from './GLTile';
import RectProgram from './program/Rect';
import CircleProgram from './program/Circle';
Expand Down Expand Up @@ -62,11 +62,23 @@ import {GLExtensions} from './GLExtensions';
import {Texture} from './Texture';
import {ScreenTile} from '../Layers';

import {Color} from '@here/xyz-maps-common';
import {Color, vec3} from '@here/xyz-maps-common';
import toRGB = Color.toRGB;


const mat4 = {create, lookAt, multiply, perspective, rotateX, rotateZ, translate, scale, clone, copy, invert, identity};
const mat4 = {
create,
lookAt,
multiply,
perspective,
rotateX,
rotateZ,
translate,
scale,
clone,
copy,
invert,
identity
};

const PI2 = 2 * Math.PI;
const FIELD_OF_VIEW = Math.atan(1 / 3) * 2; // ~ 36.87 deg
Expand Down Expand Up @@ -141,12 +153,15 @@ export class GLRender implements BasicRender {
private readonly ctxAttr: WebGLContextAttributes;
private depthBufferSize: number;

processedLight: { [lightSetName: string]: UniformMap }[] = [];

pass: PASS;
buffers: BufferCache = new WeakMap();
gl: WebGLRenderingContext;
private glExt: GLExtensions;
zIndexLength: number;
fixedView: number;

private sharedUniforms: {
u_resolution: number[];
u_tileScale: number;
Expand All @@ -158,13 +173,14 @@ export class GLRender implements BasicRender {
u_groundResolution: number;
u_zMeterToPixel: number;
u_fixedView: number;
u_lightDir: number[];
u_camWorld: Float64Array;
// elapsedTime in seconds
u_time: number;
};

private _lightDir: number[] = [0.5, 0.0, -1.0];
private programConfig: { [name: string]: { program: typeof Program, default?: boolean, macros?: any } };
private resolution: number[] = [];
private startTime: number;

constructor(renderOptions: RenderOptions) {
this.ctxAttr = {
Expand Down Expand Up @@ -263,6 +279,9 @@ export class GLRender implements BasicRender {
// @ts-ignore
gl.dpr = devicePixelRation;


this.startTime = Date.now();

this.gl = gl;
this.glExt = new GLExtensions(gl, [
EXTENSION_OES_ELEMENT_INDEX_UINT,
Expand Down Expand Up @@ -340,7 +359,7 @@ export class GLRender implements BasicRender {
gl.clearStencil(0);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
// gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
// gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
// gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
}

grid(show: boolean | { grid3d: boolean }): void {
Expand Down Expand Up @@ -408,7 +427,6 @@ export class GLRender implements BasicRender {
this.tilePreviewTransform.ty = null;
this.tilePreviewTransform.s = null;


this.rz = (rotZ + PI2) % PI2;
this.rx = rotX;
this.scale = scale;
Expand All @@ -419,7 +437,6 @@ export class GLRender implements BasicRender {

mat4.perspective(projectionMatrix, FIELD_OF_VIEW, pixelWidth / pixelHeight, zNear, zFar);


const worldMatrix = mat4.copy(this.worldMatrix, projectionMatrix);
mat4.scale(worldMatrix, worldMatrix, [1, -1, 1]);
mat4.translate(worldMatrix, worldMatrix, [0, 0, -targetZ]);
Expand All @@ -430,8 +447,8 @@ export class GLRender implements BasicRender {
// mat4.translate(worldMatrix, worldMatrix, [-worldCenterX * worldSize, -worldCenterY * worldSize, 0]);
// mat4.scale(worldMatrix, worldMatrix, [worldSize, worldSize, worldSize]);


mat4.lookAt(viewMatrix, [centerPixelX, centerPixelY, -targetZ], [centerPixelX, centerPixelY, 0], [0, -1, 0]);
const cam = [centerPixelX, centerPixelY, -targetZ];
mat4.lookAt(viewMatrix, cam, [centerPixelX, centerPixelY, 0], [0, -1, 0]);
mat4.translate(viewMatrix, viewMatrix, [centerPixelX, centerPixelY, 0]);
mat4.rotateX(viewMatrix, viewMatrix, rotX);
mat4.rotateZ(viewMatrix, viewMatrix, rotZ);
Expand Down Expand Up @@ -461,6 +478,10 @@ export class GLRender implements BasicRender {
cameraWorld[1] = 0;
cameraWorld[2] = -1;
transformMat4(cameraWorld, cameraWorld, this.invVPMat);
// The Z-axis is scaled to meters per pixel, leading to a non-uniform coordinate system.
// To maintain consistent specular highlight sizes,
// we scale Z by zMeterToPixel to compensate for ground resolution scaling, ensuring a uniform coordinate system.
cameraWorld[2] *= this.zMeterToPixel;

// pixel perfect matrix used for crisper raster graphics, icons/text/raster-tiles
// rounding in shader leads to precision issues and tiles edges become visible when the map is scaled.
Expand All @@ -485,18 +506,18 @@ export class GLRender implements BasicRender {

private initSharedUniforms() {
this.sharedUniforms = {
u_fixedView: this.fixedView,
u_rotate: this.rz,
u_resolution: this.resolution,
u_scale: null, // this.scale * dZoom,
u_topLeft: [0, 0],
u_tileScale: 1,
u_matrix: this.vPMat,
u_inverseMatrix: this.invVPMat,
u_zMeterToPixel: null, // this.zMeterToPixel / dZoom,
u_groundResolution: 1 / this.zMeterToPixel,
u_lightDir: this._lightDir,
u_camWorld: this.cameraWorld
'u_fixedView': this.fixedView,
'u_rotate': this.rz,
'u_resolution': this.resolution,
'u_scale': null, // this.scale * dZoom,
'u_topLeft': [0, 0],
'u_tileScale': 1,
'u_matrix': this.vPMat,
'u_inverseMatrix': this.invVPMat,
'u_zMeterToPixel': null, // this.zMeterToPixel / dZoom,
'u_groundResolution': 1 / this.zMeterToPixel,
'u_camWorld': this.cameraWorld,
'u_time': (Date.now() - this.startTime) / 1000.0
};
}

Expand Down Expand Up @@ -658,10 +679,17 @@ export class GLRender implements BasicRender {
// initialize shared uniforms
const {sharedUniforms} = this;
sharedUniforms.u_fixedView = this.fixedView; // must be set at render time
sharedUniforms.u_scale = this.scale * dZoom;
const scale = this.scale * dZoom;
sharedUniforms.u_scale = scale;
sharedUniforms.u_matrix = pMat || (buffer.pixelPerfect ? this.vPRasterMat : this.vPMat);
sharedUniforms.u_zMeterToPixel = this.zMeterToPixel / dZoom;

// console.log(this.scale);
// console.log('dZoom', dZoom, this.tilePreviewTransform.s||1);
// sharedUniforms.u_camWorld = vec3.scale(this.cameraWorld, this.cameraWorldFixed, window._jalla||1);
// sharedUniforms.u_camWorld = vec3.multiply(this.cameraWorld, this.cameraWorldFixed, [1, 1, 1]);


const uses2PassAlpha = buffer.pass & PASS.POST_ALPHA;
let stencilRefVal = null;

Expand Down Expand Up @@ -880,6 +908,10 @@ export class GLRender implements BasicRender {
this.zIndex = bufferData.z;
this.min3dZIndex = min3dZIndex;


const lightUniforms = this.processedLight[bufferData.layer.index][buffer.light || 'default'];
Object.assign(this.sharedUniforms, lightUniforms);

// make sure to reset stencil
this.stencilVal = null;

Expand Down
Loading

0 comments on commit 7b55741

Please sign in to comment.