Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type matrix and vector calculations #11400

Merged
merged 12 commits into from
Jan 19, 2022
2 changes: 1 addition & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
.*/_site/.*

[version]
0.103.0
0.108.0

[options]
server.max_workers=4
Expand Down
102 changes: 102 additions & 0 deletions flow-typed/gl-matrix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@

type VecType = Array<number> | Float32Array | Float64Array;

declare module "gl-matrix" {
declare type Vec2 = VecType;
declare type Vec3 = VecType;
declare type Vec4 = VecType;
declare type Quat = VecType;
declare type Mat2 = VecType;
declare type Mat3 = VecType;
declare type Mat4 = VecType;

declare var vec2: {
exactEquals(Vec2, Vec2): boolean
};

declare var vec3: {
create(): Float32Array,
fromValues(number, number, number): Float32Array,
length(Vec3): number,
len(Vec3): number,
squaredLength(Vec3): number,
dot(Vec3, Vec3): number,
equals(Vec3, Vec3): boolean,
exactEquals(Vec3, Vec3): boolean,

clone<T: Vec3>(T): T,
normalize<T: Vec3>(T, Vec3): T,
add<T: Vec3>(T, Vec3, Vec3): T,
sub<T: Vec3>(T, Vec3, Vec3): T,
subtract<T: Vec3>(T, Vec3, Vec3): T,
cross<T: Vec3>(T, Vec3, Vec3): T,
negate<T: Vec3>(T, Vec3): T,
scale<T: Vec3>(T, Vec3, number): T,
scaleAndAdd<T: Vec3>(T, Vec3, Vec3, number): T,
multiply<T: Vec3>(T, Vec3, Vec3): T,
mul<T: Vec3>(T, Vec3, Vec3): T,
div<T: Vec3>(T, Vec3, Vec3): T,
min<T: Vec3>(T, Vec3, Vec3): T,
max<T: Vec3>(T, Vec3, Vec3): T,
transformQuat<T: Vec3>(T, Vec3, Quat): T,
transformMat3<T: Vec3>(T, Vec3, Mat3): T,
transformMat4<T: Vec3>(T, Vec3, Mat4): T
};

declare var vec4: {
scale<T: Vec4>(T, Vec4, number): T,
mul<T: Vec4>(T, Vec4, Vec4): T,
transformMat4<T: Vec4>(T, Vec4, Mat4): T
};

declare var mat2: {
create(): Float32Array,
rotate<T: Mat2>(T, Mat2, number): T,
invert<T: Mat2>(T, Mat2): T,
scale<T: Mat2>(T, Mat2, Vec2): T
};

declare var mat3: {
create(): Float32Array,

fromMat4<T: Mat3>(T, Mat4): T,
fromRotation<T: Mat3>(T, number): T,
mul<T: Mat3>(T, Mat3, Mat3): T,
multiply<T: Mat3>(T, Mat3, Mat3): T,
adjoint<T: Mat3>(T, Mat3): T,
transpose<T: Mat3>(T, Mat3): T
};

declare var mat4: {
create(): Float32Array,

fromScaling<T: Mat4>(T, Vec3): T,
fromQuat<T: Mat4>(T, Quat): T,
ortho<T: Mat4>(T, number, number, number, number, number, number): T,
perspective<T: Mat4>(T, number, number, number, number): T,
identity<T: Mat4>(T): T,
scale<T: Mat4>(T, Mat4, Vec3): T,
mul<T: Mat4>(T, Mat4, Mat4): T,
multiply<T: Mat4>(T, Mat4, Mat4): T,
rotateX<T: Mat4>(T, Mat4, number): T,
rotateY<T: Mat4>(T, Mat4, number): T,
rotateZ<T: Mat4>(T, Mat4, number): T,
translate<T: Mat4>(T, Mat4, Vec3): T,
invert<T: Mat4>(T, Mat4): T,
copy<T: Mat4>(T, Mat4): T,
clone<T: Mat4>(T): T
};

declare var quat: {
create(): Float32Array,
length(Quat): number,
exactEquals(Quat, Quat): boolean,

normalize<T: Quat>(T, Quat): T,
conjugate<T: Quat>(T, Quat): T,
identity<T: Quat>(T): T,
rotateX<T: Quat>(T, Quat, number): T,
rotateY<T: Quat>(T, Quat, number): T,
rotateZ<T: Quat>(T, Quat, number): T
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"eslint-plugin-html": "^6.1.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsdoc": "^32.3.4",
"flow-bin": "0.103.0",
"flow-bin": "0.108.0",
"gl": "^4.9.0",
"glob": "^7.1.6",
"is-builtin-module": "^3.0.0",
Expand Down
5 changes: 3 additions & 2 deletions src/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export type SingleCollisionBox = {
elevation?: number;
tileID?: OverscaledTileID;
};
import type {Mat4} from 'gl-matrix';

export type CollisionArrays = {
textBox?: SingleCollisionBox;
Expand Down Expand Up @@ -349,8 +350,8 @@ class SymbolBucket implements Bucket {
featureSortOrder: Array<number>;

collisionCircleArray: Array<number>;
placementInvProjMatrix: mat4;
placementViewportMatrix: mat4;
placementInvProjMatrix: Mat4;
placementViewportMatrix: Mat4;

text: SymbolBuffers;
icon: SymbolBuffers;
Expand Down
10 changes: 5 additions & 5 deletions src/data/dem_tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {vec3} from 'gl-matrix';
import {number as interpolate} from '../style-spec/util/interpolate.js';
import {clamp} from '../util/util.js';

type vec3Like = vec3 | [number, number, number];
import type {Vec3} from 'gl-matrix';

class MipLevel {
size: number;
Expand Down Expand Up @@ -37,7 +37,7 @@ class MipLevel {
}
}

function aabbRayIntersect(min: vec3Like, max: vec3Like, pos: vec3Like, dir: vec3Like): ?number {
function aabbRayIntersect(min: Vec3, max: Vec3, pos: Vec3, dir: Vec3): ?number {
let tMin = 0;
let tMax = Number.MAX_VALUE;

Expand Down Expand Up @@ -69,7 +69,7 @@ function aabbRayIntersect(min: vec3Like, max: vec3Like, pos: vec3Like, dir: vec3
return tMin;
}

function triangleRayIntersect(ax, ay, az, bx, by, bz, cx, cy, cz, pos: vec3Like, dir: vec3Like): ?number {
function triangleRayIntersect(ax, ay, az, bx, by, bz, cx, cy, cz, pos: Vec3, dir: Vec3): ?number {
// Compute barycentric coordinates u and v to find the intersection
const abX = bx - ax;
const abY = by - ay;
Expand Down Expand Up @@ -178,13 +178,13 @@ export default class DemMinMaxQuadTree {
}

// Performs raycast against the tree root only. Min and max coordinates defines the size of the root node
raycastRoot(minx: number, miny: number, maxx: number, maxy: number, p: vec3Like, d: vec3Like, exaggeration: number = 1): ?number {
raycastRoot(minx: number, miny: number, maxx: number, maxy: number, p: Vec3, d: Vec3, exaggeration: number = 1): ?number {
const min = [minx, miny, -aabbSkirtPadding];
const max = [maxx, maxy, this.maximums[0] * exaggeration];
return aabbRayIntersect(min, max, p, d);
}

raycast(rootMinx: number, rootMiny: number, rootMaxx: number, rootMaxy: number, p: vec3Like, d: vec3Like, exaggeration: number = 1): ?number {
raycast(rootMinx: number, rootMiny: number, rootMaxx: number, rootMaxy: number, p: Vec3, d: Vec3, exaggeration: number = 1): ?number {
if (!this.nodeCount)
return null;

Expand Down
10 changes: 6 additions & 4 deletions src/geo/projection/flat_tile_transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
import type Transform from '../transform.js';
import type {ElevationScale} from './index.js';
import {UnwrappedTileID} from '../../source/tile_id.js';
import {mat4, vec3} from 'gl-matrix';
import {mat4} from 'gl-matrix';
import MercatorCoordinate from '../mercator_coordinate.js';
import Point from '@mapbox/point-geometry';
import EXTENT from '../../data/extent.js';
import tileTransform from './tile_transform.js';

import type {Mat4, Vec3} from 'gl-matrix';

const identity = mat4.identity(new Float64Array(16));

export default class FlatTileTransform {
Expand All @@ -20,11 +22,11 @@ export default class FlatTileTransform {
this._worldSize = worldSize;
}

createInversionMatrix(): mat4 {
createInversionMatrix(): Mat4 {
return identity;
}

createTileMatrix(id: UnwrappedTileID): mat4 {
createTileMatrix(id: UnwrappedTileID): Mat4 {
let scale, scaledX, scaledY;
const canonical = id.canonical;
const posMatrix = mat4.identity(new Float64Array(16));
Expand Down Expand Up @@ -55,7 +57,7 @@ export default class FlatTileTransform {
return this._tr.rayIntersectionCoordinate(this._tr.pointRayIntersection(clamped, z));
}

upVector(): vec3 {
upVector(): Vec3 {
return [0, 0, 1];
}

Expand Down
16 changes: 7 additions & 9 deletions src/geo/projection/globe.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export function globeECEFUnitsToPixelScale(worldSize: number) {
return wsRadius / localRadius;
}

export function calculateGlobeMatrix(tr: Transform, worldSize: number, offset?: [number, number]): mat4 {
export function calculateGlobeMatrix(tr: Transform, worldSize: number, offset?: [number, number]): Float64Array {
const wsRadius = worldSize / (2.0 * Math.PI);
const scale = globeECEFUnitsToPixelScale(worldSize);

Expand All @@ -242,7 +242,7 @@ export function calculateGlobeMatrix(tr: Transform, worldSize: number, offset?:
return posMatrix;
}

export function calculateGlobeMercatorMatrix(tr: Transform): mat4 {
export function calculateGlobeMercatorMatrix(tr: Transform): Float32Array {
const worldSize = tr.worldSize;
const lat = clamp(tr.center.lat, -MAX_MERCATOR_LATITUDE, MAX_MERCATOR_LATITUDE);
const point = new Point(
Expand All @@ -258,7 +258,7 @@ export function calculateGlobeMercatorMatrix(tr: Transform): mat4 {
mat4.translate(posMatrix, posMatrix, [point.x, point.y, 0.0]);
mat4.scale(posMatrix, posMatrix, [ws, ws, zScale]);

return posMatrix;
return Float32Array.from(posMatrix);
karimnaaji marked this conversation as resolved.
Show resolved Hide resolved
}

export const GLOBE_ZOOM_THRESHOLD_MIN = 5;
Expand Down Expand Up @@ -288,14 +288,12 @@ export function globeBuffersForTileMesh(painter: Painter, tile: Tile, coord: Ove
return [gridBuffer, poleBuffer];
}

export function globeMatrixForTile(id: CanonicalTileID, globeMatrix: mat4) {
export function globeMatrixForTile(id: CanonicalTileID, globeMatrix: Float64Array): Float32Array {
const decode = globeDenormalizeECEF(globeTileBounds(id));
const posMatrix = mat4.copy(new Float64Array(16), globeMatrix);
mat4.mul(posMatrix, posMatrix, decode);
return posMatrix;
return mat4.mul(mat4.create(), globeMatrix, decode);
karimnaaji marked this conversation as resolved.
Show resolved Hide resolved
}

export function globePoleMatrixForTile(id: CanonicalTileID, south: boolean, tr: Transform) {
export function globePoleMatrixForTile(id: CanonicalTileID, south: boolean, tr: Transform): Float32Array {
const poleMatrix = mat4.identity(new Float64Array(16));

const tileDim = Math.pow(2, id.z);
Expand All @@ -315,7 +313,7 @@ export function globePoleMatrixForTile(id: CanonicalTileID, south: boolean, tr:
mat4.scale(poleMatrix, poleMatrix, [1, -1, 1]);
}

return poleMatrix;
return Float32Array.from(poleMatrix);
karimnaaji marked this conversation as resolved.
Show resolved Hide resolved
}

export class GlobeSharedBuffers {
Expand Down
13 changes: 8 additions & 5 deletions src/geo/projection/globe_tile_transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
globeDenormalizeECEF
} from './globe.js';

import type {Vec3} from 'gl-matrix';

const GLOBE_RADIUS = EXTENT / Math.PI / 2.0;
const GLOBE_METERS_TO_ECEF = mercatorZfromAltitude(1, 0.0) * 2.0 * GLOBE_RADIUS * Math.PI;

Expand All @@ -31,12 +33,12 @@ export default class GlobeTileTransform {
this._globeMatrix = calculateGlobeMatrix(tr, worldSize);
}

createTileMatrix(id: UnwrappedTileID): mat4 {
createTileMatrix(id: UnwrappedTileID): Float64Array {
const decode = globeDenormalizeECEF(globeTileBounds(id.canonical));
return mat4.multiply([], this._globeMatrix, decode);
return mat4.multiply(new Float64Array(16), this._globeMatrix, decode);
}

createInversionMatrix(id: UnwrappedTileID): mat4 {
createInversionMatrix(id: UnwrappedTileID): Float32Array {
const identity = mat4.identity(new Float64Array(16));

const center = this._tr.center;
Expand All @@ -57,11 +59,12 @@ export default class GlobeTileTransform {
const ecefUnitsToMercatorPixels = wsRadius / localRadius;

mat4.scale(identity, identity, [ecefUnitsToMercatorPixels, ecefUnitsToMercatorPixels, 1.0]);
mat4.multiply(matrix, matrix, identity);

return mat4.multiply(matrix, matrix, identity);
return Float32Array.from(matrix);
}

upVector(id: CanonicalTileID, x: number, y: number): vec3 {
upVector(id: CanonicalTileID, x: number, y: number): Vec3 {
const tiles = 1 << id.z;
const mercX = (x / EXTENT + id.x) / tiles;
const mercY = (y / EXTENT + id.y) / tiles;
Expand Down
7 changes: 3 additions & 4 deletions src/geo/projection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import cylindricalEqualArea from './cylindrical_equal_area.js';
import {extend} from '../../util/util.js';
import type {ProjectionSpecification} from '../../style-spec/types.js';
import globe from './globe.js';
import {mat4, vec3} from 'gl-matrix';
import {CanonicalTileID, UnwrappedTileID} from '../../source/tile_id.js';
import Transform from '../transform.js';
import LngLat from '../lng_lat.js';
Expand Down Expand Up @@ -92,9 +91,9 @@ export type ElevationScale = {
}

export type TileTransform = {
createTileMatrix: (id: UnwrappedTileID) => mat4,
createInversionMatrix: (id: UnwrappedTileID) => mat4,
upVector: (id: CanonicalTileID, x: number, y: number) => vec3,
createTileMatrix: (id: UnwrappedTileID) => Float64Array,
createInversionMatrix: (id: UnwrappedTileID) => Float32Array,
upVector: (id: CanonicalTileID, x: number, y: number) => [number, number, number],
upVectorScale: (id: CanonicalTileID, latitude: number, worldSize: number) => ElevationScale,
pointCoordinate: (x: number, y: number, z?: number) => MercatorCoordinate
};
4 changes: 3 additions & 1 deletion src/geo/projection/tile_transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import type Transform from '../transform.js';
import {UnwrappedTileID, CanonicalTileID} from '../../source/tile_id.js';
import assert from 'assert';

import type {Vec3} from 'gl-matrix';

export type TileTransform = {
scale: number,
x: number,
Expand Down Expand Up @@ -134,7 +136,7 @@ export function getTilePoint(tileTransform: TileTransform, {x, y}: {x: number, y
(y * tileTransform.scale - tileTransform.y) * EXTENT);
}

export function getTileVec3(tileTransform: TileTransform, coord: MercatorCoordinate, wrap: number = 0): vec3 {
export function getTileVec3(tileTransform: TileTransform, coord: MercatorCoordinate, wrap: number = 0): Vec3 {
const x = ((coord.x - wrap) * tileTransform.scale - tileTransform.x) * EXTENT;
const y = (coord.y * tileTransform.scale - tileTransform.y) * EXTENT;
return vec3.fromValues(x, y, altitudeFromMercatorZ(coord.z, coord.y));
Expand Down
Loading