Skip to content

Commit

Permalink
Globe covering tiles optimization (#4937)
Browse files Browse the repository at this point in the history
* Add aabb cache

* Add globe coveringTiles benchmark

* Add CoveringTilesGlobePitched benchmark

* Fast plane-AABB intersection

* Faster aabb-frustum test

* Faster frustum-aabb test with better frustum-outside-aabb check

* Fix merge, adapt for coveringTiles changes

* Add more globe coveringTiles tests

* Add changelog entry

* Split primitives.ts into multiple files

* Move aabb cache into a separte file

* Update build size
  • Loading branch information
kubapelc authored Nov 6, 2024
1 parent 093dead commit 138ed60
Show file tree
Hide file tree
Showing 18 changed files with 476 additions and 202 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### ✨ Features and improvements
- Support Terrain in Globe projection ([#4976](https://github.com/maplibre/maplibre-gl-js/pull/4976))
- Improved performance of the `coveringTiles` (tile culling) function for globe ([#4937](https://github.com/maplibre/maplibre-gl-js/pull/4937))
- _...Add new stuff here..._

### 🐞 Bug fixes
Expand Down
3 changes: 2 additions & 1 deletion src/geo/projection/covering_tiles.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {OverscaledTileID} from '../../source/tile_id';
import {Aabb, Frustum, IntersectionResult} from '../../util/primitives';
import {vec2, vec4} from 'gl-matrix';
import {IReadonlyTransform} from '../transform_interface';
import {MercatorCoordinate} from '../mercator_coordinate';
import {scaleZoom} from '../transform_helper';
import {clamp, degreesToRadians} from '../../util/util';
import {Terrain} from '../../render/terrain';
import {Frustum} from '../../util/primitives/frustum';
import {Aabb, IntersectionResult} from '../../util/primitives/aabb';

type CoveringTilesResult = {
tileID: OverscaledTileID;
Expand Down
2 changes: 1 addition & 1 deletion src/geo/projection/covering_tiles_details_provider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Aabb} from '../../util/primitives';
import {Aabb} from '../../util/primitives/aabb';
import {MercatorCoordinate} from '../mercator_coordinate';
import {IReadonlyTransform} from '../transform_interface';
import {CoveringTilesOptions} from './covering_tiles';
Expand Down
4 changes: 2 additions & 2 deletions src/geo/projection/globe_covering_tiles.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {Aabb} from '../../util/primitives';
import {Aabb} from '../../util/primitives/aabb';
import {expectToBeCloseToArray} from '../../util/test/util';
import {GlobeCoveringTilesDetailsProvider} from './globe_covering_tiles_details_provider';

describe('aabb', () => {
describe('aabb creation', () => {
test('z=0', () => {
const detailsProvider = new GlobeCoveringTilesDetailsProvider();
const aabb = detailsProvider.getTileAABB({
Expand Down
30 changes: 20 additions & 10 deletions src/geo/projection/globe_covering_tiles_details_provider.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {vec3} from 'gl-matrix';
import {Aabb} from '../../util/primitives';
import {IReadonlyTransform} from '../transform_interface';
import {MercatorCoordinate} from '../mercator_coordinate';
import {EXTENT} from '../../data/extent';
import {projectTileCoordinatesToSphere} from './globe_utils';
import {CoveringTilesOptions, coveringZoomLevel} from './covering_tiles';
import {CoveringTilesDetailsProvider} from './covering_tiles_details_provider';
import {Aabb} from '../../util/primitives/aabb';
import {AabbCache} from '../../util/primitives/aabb_cache';

/**
* Computes distance of a point to a tile in an arbitrary axis.
Expand Down Expand Up @@ -38,6 +39,15 @@ function distanceToTileWrapX(pointX: number, pointY: number, tileCornerX: number
}

export class GlobeCoveringTilesDetailsProvider implements CoveringTilesDetailsProvider {
private _aabbCache: AabbCache = new AabbCache(this._computeTileAABB);

/**
* Prepares the internal AABB cache for the next frame.
* @returns
*/
newFrame() {
this._aabbCache.newFrame();
}

/**
* Returns the distance of a point to a square tile. If the point is inside the tile, returns 0.
Expand Down Expand Up @@ -83,12 +93,16 @@ export class GlobeCoveringTilesDetailsProvider implements CoveringTilesDetailsPr
}
return 0;
}

allowVariableZoom(transform: IReadonlyTransform, options: CoveringTilesOptions): boolean {
return coveringZoomLevel(transform, options) > 4;
}

/**
* Returns the AABB of the specified tile. The AABB is in the coordinate space where the globe is a unit sphere.
* @param tileID - Tile x, y and z for zoom.
*/
getTileAABB(tileID: {x: number; y: number; z: number}, _wrap: number, _elevation: number, _options: CoveringTilesOptions): Aabb {
getTileAABB(tileID: { x: number; y: number; z: number }, wrap: number, elevation: number, options: CoveringTilesOptions) {
return this._aabbCache.getTileAABB(tileID, wrap, elevation, options);
}

private _computeTileAABB(tileID: {x: number; y: number; z: number}, _wrap: number, _elevation: number, _options: CoveringTilesOptions): Aabb {
// We can get away with only checking the 4 tile corners for AABB construction, because for any tile of zoom level 2 or higher
// it holds that the extremes (minimal or maximal value) of X, Y or Z coordinates must lie in one of the tile corners.
//
Expand Down Expand Up @@ -170,8 +184,4 @@ export class GlobeCoveringTilesDetailsProvider implements CoveringTilesDetailsPr
);
}
}

allowVariableZoom(transform: IReadonlyTransform, options: CoveringTilesOptions): boolean {
return coveringZoomLevel(transform, options) > 4;
}
}
9 changes: 5 additions & 4 deletions src/geo/projection/globe_transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {angularCoordinatesToSurfaceVector, getGlobeRadiusPixels, getZoomAdjustme
import {EXTENT} from '../../data/extent';
import type {ProjectionData, ProjectionDataParams} from './projection_data';
import {GlobeCoveringTilesDetailsProvider} from './globe_covering_tiles_details_provider';
import {Frustum} from '../../util/primitives';
import {Frustum} from '../../util/primitives/frustum';
import {CoveringTilesDetailsProvider} from './covering_tiles_details_provider';

/**
Expand Down Expand Up @@ -278,10 +278,10 @@ export class GlobeTransform implements ITransform {
private _globeness: number = 1.0;
private _mercatorTransform: MercatorTransform;

private _nearZ;
private _farZ;
private _nearZ: number;
private _farZ: number;

private _coveringTilesDetailsProvider;
private _coveringTilesDetailsProvider: GlobeCoveringTilesDetailsProvider;

public constructor(globeProjection: GlobeProjection, globeProjectionEnabled: boolean = true) {
this._helper = new TransformHelper({
Expand Down Expand Up @@ -376,6 +376,7 @@ export class GlobeTransform implements ITransform {
// Everything below this comment must happen AFTER globeness update
this._updateErrorCorrectionValue();
this._calcMatrices();
this._coveringTilesDetailsProvider.newFrame();

if (oldGlobeRendering === this.isGlobeRendering) {
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {OverscaledTileID} from '../../source/tile_id';
import {Aabb} from '../../util/primitives';
import {Aabb} from '../../util/primitives/aabb';
import {clamp} from '../../util/util';
import {MercatorCoordinate} from '../mercator_coordinate';
import {IReadonlyTransform} from '../transform_interface';
Expand Down
2 changes: 1 addition & 1 deletion src/geo/projection/mercator_transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {EXTENT} from '../../data/extent';
import type {ProjectionData, ProjectionDataParams} from './projection_data';
import {scaleZoom, TransformHelper, zoomScale} from '../transform_helper';
import {MercatorCoveringTilesDetailsProvider} from './mercator_covering_tiles_details_provider';
import {Frustum} from '../../util/primitives';
import {Frustum} from '../../util/primitives/frustum';
import {CoveringTilesDetailsProvider} from './covering_tiles_details_provider';

export class MercatorTransform implements ITransform {
Expand Down
2 changes: 1 addition & 1 deletion src/geo/transform_interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {PointProjection} from '../symbol/projection';
import {MapProjectionEvent} from '../ui/events';
import type {ProjectionData, ProjectionDataParams} from './projection/projection_data';
import {CoveringTilesDetailsProvider} from './projection/covering_tiles_details_provider';
import {Frustum} from '../util/primitives';
import {Frustum} from '../util/primitives/frustum';

export type TransformUpdateResult = {
forcePlacementUpdate?: boolean;
Expand Down
179 changes: 0 additions & 179 deletions src/util/primitives.ts

This file was deleted.

Loading

0 comments on commit 138ed60

Please sign in to comment.