@openglobus/og 1.0.0-rc33 → 1.0.0-rc35
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/lib/Globe.d.ts +4 -0
- package/lib/assets/LabelWorker.worker-C24YLEkW.js.map +1 -1
- package/lib/assets/PlainSegmentWorker.worker-DJHXd0bF.js.map +1 -1
- package/lib/assets/RgbTerrainWorker.worker-BL6dQGZ3.js.map +1 -0
- package/lib/assets/TerrainWorker.worker-DIGKd23M.js.map +1 -0
- package/lib/control/DragAndDrop.d.ts +1 -0
- package/lib/control/entityGizmo/EntityGizmo.d.ts +4 -3
- package/lib/control/entityGizmo/EntityGizmoScene.d.ts +13 -1
- package/lib/index.d.ts +3 -2
- package/lib/layer/BaseTileMaterialLayer.d.ts +1 -0
- package/lib/layer/GeoTIFFLayer.d.ts +8 -0
- package/lib/layer/geotiff/GeoTIFFReader.d.ts +2 -0
- package/lib/layer/geotiff/MultiGeoTIFFReader.d.ts +2 -0
- package/lib/layer/geotiff/types.d.ts +3 -4
- package/lib/layer/geotiff/utm.d.ts +1 -1
- package/lib/og.es.js +1 -1
- package/lib/og.es.js.map +1 -1
- package/lib/proj/epsgIo.d.ts +5 -0
- package/lib/proj/proj4.d.ts +1 -0
- package/lib/quadTree/EntityCollectionNode.d.ts +2 -0
- package/lib/quadTree/QuadTreeStrategy.d.ts +8 -0
- package/lib/terrain/GlobusTerrain.d.ts +13 -5
- package/lib/terrain/ProceduralTerrain.d.ts +71 -0
- package/lib/terrain/RgbTerrain.d.ts +25 -3
- package/lib/terrain/index.d.ts +4 -2
- package/lib/terrain/terrainUtils.d.ts +145 -0
- package/lib/utils/RgbTerrainWorker.d.ts +21 -0
- package/lib/utils/RgbTerrainWorker.worker.d.ts +1 -0
- package/lib/utils/RgbTerrainWorkerParams.d.ts +15 -0
- package/package.json +7 -5
- package/lib/assets/TerrainWorker.worker-BwueoQpg.js.map +0 -1
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers the CRS in {@link proj4}, taking its definition from epsg.io. Returns whether the
|
|
3
|
+
* projection became available, i.e. whether the data in that CRS is worth reading again.
|
|
4
|
+
*/
|
|
5
|
+
export declare function defineProjection(crsCode: number): Promise<boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const proj4: any;
|
|
@@ -33,6 +33,8 @@ declare class EntityCollectionNode {
|
|
|
33
33
|
protected _setExtentBounds(): void;
|
|
34
34
|
__setLonLat__(entity: Entity): LonLat;
|
|
35
35
|
buildTree(entities: Entity[], rightNow?: boolean): void;
|
|
36
|
+
protected _addEntitiesToChildNodes(entities: Entity[], rightNow?: boolean): void;
|
|
37
|
+
protected _moveCollectionToChildNodes(): void;
|
|
36
38
|
isInside(entity: Entity): boolean;
|
|
37
39
|
createChildNodes(): void;
|
|
38
40
|
collectRenderCollectionsPASS1(visibleNodes: NodesDict, outArr: EntityCollection[]): void;
|
|
@@ -128,6 +128,14 @@ export declare class QuadTreeStrategy {
|
|
|
128
128
|
protected _collectRenderNodes(camera: PlanetCamera): void;
|
|
129
129
|
clear(): void;
|
|
130
130
|
get quadTreeList(): Node[];
|
|
131
|
+
/**
|
|
132
|
+
* Returns the most detailed node made under the point, not deeper than the zoom.
|
|
133
|
+
* @public
|
|
134
|
+
* @param {LonLat} lonLat - Point.
|
|
135
|
+
* @param {number} [zoom] - Maximal node zoom.
|
|
136
|
+
* @returns {Node | null} -
|
|
137
|
+
*/
|
|
138
|
+
getNodeByLonLat(lonLat: LonLat, zoom?: number): Node | null;
|
|
131
139
|
getTileXY(lonLat: LonLat, zoom: number): [number, number, number, number];
|
|
132
140
|
getLonLatTileOffset(lonLat: LonLat, x: number, y: number, z: number, gridSize: number): [number, number];
|
|
133
141
|
collectVisibleNode(node: Node): void;
|
|
@@ -45,7 +45,7 @@ type TileData = {
|
|
|
45
45
|
* @fires loadend
|
|
46
46
|
*/
|
|
47
47
|
declare class GlobusTerrain extends EmptyTerrain {
|
|
48
|
-
events:
|
|
48
|
+
events: TerrainEvents;
|
|
49
49
|
protected _s: string[];
|
|
50
50
|
protected _requestCount: number;
|
|
51
51
|
protected _requestsPeerSubdomain: number;
|
|
@@ -103,6 +103,13 @@ declare class GlobusTerrain extends EmptyTerrain {
|
|
|
103
103
|
* @param {boolean} [forceLoading=false] - Forces loading even if default filter would skip it.
|
|
104
104
|
*/
|
|
105
105
|
loadTerrain(segment: Segment, forceLoading?: boolean): void;
|
|
106
|
+
/**
|
|
107
|
+
* Converts loaded segment data to elevations and applies them.
|
|
108
|
+
* @protected
|
|
109
|
+
* @param {Segment} segment - Segment that requested terrain data.
|
|
110
|
+
* @param {any} data - Loaded data.
|
|
111
|
+
*/
|
|
112
|
+
protected _onTerrainLoaded(segment: Segment, data: any): void;
|
|
106
113
|
protected _getSubdomain(): string;
|
|
107
114
|
buildURL(x: number, y: number, z: number, tileGroup: number): string;
|
|
108
115
|
/**
|
|
@@ -122,11 +129,11 @@ declare class GlobusTerrain extends EmptyTerrain {
|
|
|
122
129
|
/**
|
|
123
130
|
* Sets url rewrite callback, used for custom url rewriting for every tile loading.
|
|
124
131
|
* @public
|
|
125
|
-
* @param {UrlRewriteFunc} ur - The callback that returns tile custom
|
|
132
|
+
* @param {UrlRewriteFunc} ur - The callback that returns tile custom-created url.
|
|
126
133
|
*/
|
|
127
134
|
setUrlRewriteCallback(ur: UrlRewriteFunc): void;
|
|
128
135
|
/**
|
|
129
|
-
* Converts loaded data to segment elevation data type(column major elevation data array in meters)
|
|
136
|
+
* Converts loaded data to segment elevation data type (column major elevation data array in meters)
|
|
130
137
|
* @public
|
|
131
138
|
* @returns {Array.<number> | TypedArray} Column-major elevation data array in meters.
|
|
132
139
|
*/
|
|
@@ -136,6 +143,7 @@ declare class GlobusTerrain extends EmptyTerrain {
|
|
|
136
143
|
*/
|
|
137
144
|
protected _applyElevationsData(segment: Segment, elevations: number[] | TypedArray | null): void;
|
|
138
145
|
}
|
|
139
|
-
type
|
|
140
|
-
type
|
|
146
|
+
export type TerrainEventsList = ["load", "loadend"];
|
|
147
|
+
export type TerrainEvents = EventsHandler<TerrainEventsList>;
|
|
148
|
+
export declare const TERRAIN_EVENTS: TerrainEventsList;
|
|
141
149
|
export { GlobusTerrain };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { EmptyTerrain } from "./EmptyTerrain";
|
|
2
|
+
import type { IEmptyTerrainParams } from "./EmptyTerrain";
|
|
3
|
+
import type { TerrainEvents } from "./GlobusTerrain";
|
|
4
|
+
import { Extent } from "../Extent";
|
|
5
|
+
import { LonLat } from "../LonLat";
|
|
6
|
+
import { Vec3 } from "../math/Vec3";
|
|
7
|
+
import type { Segment } from "../segment/Segment";
|
|
8
|
+
import type { TypedArray } from "../utils/shared";
|
|
9
|
+
export type ProceduralHeights = number[] | TypedArray | null;
|
|
10
|
+
export type GetHeightsFunc = (segment: Segment) => ProceduralHeights | Promise<ProceduralHeights>;
|
|
11
|
+
export interface IProceduralTerrainParams extends IEmptyTerrainParams {
|
|
12
|
+
getHeights: GetHeightsFunc;
|
|
13
|
+
plainGridSize?: number;
|
|
14
|
+
noDataValues?: number[];
|
|
15
|
+
}
|
|
16
|
+
type TileHeights = {
|
|
17
|
+
heights: ProceduralHeights;
|
|
18
|
+
extent: Extent;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Terrain with the heights made by a function, without a server.
|
|
22
|
+
* @class
|
|
23
|
+
* @extends {EmptyTerrain}
|
|
24
|
+
* @param {string} [name="ProceduralTerrain"] - Terrain provider name.
|
|
25
|
+
* @param {IProceduralTerrainParams} options - Provider options:
|
|
26
|
+
* @param {GetHeightsFunc} options.getHeights - Returns the segment heights, or a promise of them, rows from north
|
|
27
|
+
* to south, vertices evenly spaced in segment.getExtent(), or null when the segment has no terrain.
|
|
28
|
+
* (plainGridSize + 1)² heights are taken as they are. Larger (2^n + 1)² vertices, or 2^n x 2^n pixels, are reduced
|
|
29
|
+
* to them keeping peaks and pits. Segments of the height requests are not in the quad tree, their node is null.
|
|
30
|
+
* @param {number} [options.plainGridSize=32] - Elevation grid size.
|
|
31
|
+
* @param {Array.<number>} [options.gridSizeByZoom] - Segment grid sizes by zoom, the same as RgbTerrain ones by default.
|
|
32
|
+
* @param {Array.<number>} [options.noDataValues] - Heights of no data.
|
|
33
|
+
*
|
|
34
|
+
* @fires load
|
|
35
|
+
* @fires loadend
|
|
36
|
+
*/
|
|
37
|
+
declare class ProceduralTerrain extends EmptyTerrain {
|
|
38
|
+
events: TerrainEvents;
|
|
39
|
+
/**
|
|
40
|
+
* Height requests counters as GlobusTerrain loader ones: promises in progress, the queue is empty,
|
|
41
|
+
* every request starts right away.
|
|
42
|
+
*/
|
|
43
|
+
loader: {
|
|
44
|
+
loading: number;
|
|
45
|
+
queue: Segment[];
|
|
46
|
+
};
|
|
47
|
+
protected _getHeights: GetHeightsFunc;
|
|
48
|
+
protected _heightsCache: Record<string, TileHeights>;
|
|
49
|
+
protected _pendingHeights: Record<string, Promise<TileHeights>>;
|
|
50
|
+
protected _loadendFrame: number;
|
|
51
|
+
constructor(name: string | null, options: IProceduralTerrainParams);
|
|
52
|
+
clearCache(): void;
|
|
53
|
+
abortLoading(): void;
|
|
54
|
+
loadTerrain(segment: Segment): void;
|
|
55
|
+
protected _applyHeights(segment: Segment, tile: TileHeights): void;
|
|
56
|
+
protected _checkLoadend: () => void;
|
|
57
|
+
/**
|
|
58
|
+
* Returns the height under the point from the zoom tile heights, they are made for the request if there are none.
|
|
59
|
+
* Calls back right away and returns true when the heights are ready.
|
|
60
|
+
*/
|
|
61
|
+
getHeightAsync(lonLat: LonLat, callback: (h: number) => void, zoom?: number): boolean;
|
|
62
|
+
protected _getPointTileHeights(lonLat: LonLat, zoom: number, outPoint: Vec3): TileHeights | Promise<TileHeights> | null;
|
|
63
|
+
/**
|
|
64
|
+
* Returns the segment heights, or the promise of them while they are made. Every tile heights are requested once,
|
|
65
|
+
* failed requests are made again next time.
|
|
66
|
+
*/
|
|
67
|
+
protected _getSegmentHeights(segment: Segment): TileHeights | Promise<TileHeights>;
|
|
68
|
+
protected _setHeights(segment: Segment, extent: Extent, heights: ProceduralHeights): TileHeights;
|
|
69
|
+
protected _toGridHeights(segment: Segment, heights: ProceduralHeights): ProceduralHeights;
|
|
70
|
+
}
|
|
71
|
+
export { ProceduralTerrain };
|
|
@@ -4,6 +4,7 @@ import { GlobusTerrain } from "./GlobusTerrain";
|
|
|
4
4
|
import { LonLat } from "../LonLat";
|
|
5
5
|
import { Segment } from "../segment/Segment";
|
|
6
6
|
import type { TypedArray } from "../utils/shared";
|
|
7
|
+
import type { DecodeHeightsRowFunc, IRgbHeightsParams } from "./terrainUtils";
|
|
7
8
|
export type RgbTerrainEncoding = "rgb" | "terrarium";
|
|
8
9
|
export type RgbToHeightFunc = (r: number, g: number, b: number, minHeight: number, resolution: number) => number;
|
|
9
10
|
export declare function rgbToHeightRgb(r: number, g: number, b: number, minHeight: number, resolution: number): number;
|
|
@@ -39,16 +40,37 @@ declare class RgbTerrain extends GlobusTerrain {
|
|
|
39
40
|
protected _minHeight: number;
|
|
40
41
|
protected _resolution: number;
|
|
41
42
|
protected _rgbToHeight: RgbToHeightFunc;
|
|
43
|
+
protected _encoding: number;
|
|
42
44
|
constructor(name: string | null, options?: IRgbTerrainParams);
|
|
43
45
|
static checkNoDataValue(noDataValues: number[] | TypedArray, value: number): boolean;
|
|
44
46
|
rgb2Height(r: number, g: number, b: number): number;
|
|
45
47
|
isBlur(segment: Segment): boolean;
|
|
46
48
|
protected _createTemporalCanvas(size: number): CanvasRenderingContext2D;
|
|
49
|
+
/**
|
|
50
|
+
* Returns true when "rgb" or "terrarium" heights are decoded without rgb2Height calls.
|
|
51
|
+
* @protected
|
|
52
|
+
* @returns {boolean} -
|
|
53
|
+
*/
|
|
54
|
+
protected _isBuiltInDecoding(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Returns true when the loaded image heights are created in the worker.
|
|
57
|
+
* @protected
|
|
58
|
+
* @param {HTMLImageElement | ImageBitmap} data - Loaded image.
|
|
59
|
+
* @returns {boolean} -
|
|
60
|
+
*/
|
|
61
|
+
protected _isWorkerDecoding(data: HTMLImageElement | ImageBitmap): boolean;
|
|
62
|
+
protected _getHeightsParams(segment: Segment | null, tileZoom: number, preventChildren: boolean): IRgbHeightsParams;
|
|
63
|
+
protected _createDecodeRow(rgbaData: number[] | TypedArray, p: IRgbHeightsParams): DecodeHeightsRowFunc;
|
|
64
|
+
/**
|
|
65
|
+
* Saves the tile and its subdivision levels heights to cache.
|
|
66
|
+
* @protected
|
|
67
|
+
* @returns {Float32Array} - Tile heights.
|
|
68
|
+
*/
|
|
69
|
+
protected _cacheHeightsLevels(heights: Float32Array, p: IRgbHeightsParams, tileGroup: number, tileX: number, tileY: number, tileZoom: number, extent: Extent): Float32Array;
|
|
70
|
+
protected _onTerrainLoaded(segment: Segment, data: HTMLImageElement | ImageBitmap): void;
|
|
47
71
|
protected _createHeights(data: HTMLImageElement | ImageBitmap, segment: Segment | null, tileGroup: number, tileX: number, tileY: number, tileZoom: number, extent: Extent, preventChildren: boolean): TypedArray | number[];
|
|
48
72
|
getHeightAsync(lonLat: LonLat, callback: (h: number) => void, zoom?: number): boolean;
|
|
49
|
-
|
|
73
|
+
extractHeightsRgbRow(rgbaData: number[] | TypedArray, row: number, heightFactor: number, noDataValues: number[] | TypedArray, availableParentData: TypedArray | number[] | null, availableParentOffsetX: number, availableParentOffsetY: number, availableZoomDiff: number, skipPositiveHeights: boolean, size: number, parentScale: number, outHeights: Float32Array, noDataHeight: number): void;
|
|
50
74
|
extractElevationTilesRgbNonPowerOfTwo(rgbaData: number[] | TypedArray, outCurrenElevations: number[] | TypedArray, heightFactor?: number): void;
|
|
51
|
-
extractElevationTilesRgb(rgbaData: number[] | TypedArray, heightFactor: number, noDataValues: number[] | TypedArray, availableParentData: (TypedArray | number[] | null) | undefined, availableParentTileX: number, availableParentTileY: number, availableParentTileZoom: number, currentTileX: number, currentTileY: number, currentTileZoom: number, skipPositiveHeights: boolean, outCurrenElevations: number[] | TypedArray, outChildrenElevations: number[][][] | TypedArray[][]): void;
|
|
52
|
-
extractElevationTilesRgbNoChildren(rgbaData: number[] | TypedArray, heightFactor: number, noDataValues: number[] | TypedArray, availableParentData: (TypedArray | number[] | null) | undefined, availableParentTileX: number, availableParentTileY: number, availableParentTileZoom: number, currentTileX: number, currentTileY: number, currentTileZoom: number, skipPositiveHeights: boolean, outCurrenElevations: number[] | TypedArray): void;
|
|
53
75
|
}
|
|
54
76
|
export { RgbTerrain };
|
package/lib/terrain/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { RgbTerrain, rgbToHeightByEncoding, rgbToHeightRgb, rgbToHeightTerrarium
|
|
|
5
5
|
import type { IRgbTerrainParams, RgbTerrainEncoding, RgbToHeightFunc } from "./RgbTerrain";
|
|
6
6
|
import { GlobusRgbTerrain } from "./GlobusRgbTerrain";
|
|
7
7
|
import { MapterhornTerrain } from "./MapterhornTerrain";
|
|
8
|
-
|
|
8
|
+
import { ProceduralTerrain } from "./ProceduralTerrain";
|
|
9
|
+
import type { GetHeightsFunc, IProceduralTerrainParams } from "./ProceduralTerrain";
|
|
10
|
+
export { EmptyTerrain, GlobusTerrain, RgbTerrain, BilTerrain, GlobusRgbTerrain, MapterhornTerrain, ProceduralTerrain };
|
|
9
11
|
export { rgbToHeightByEncoding, rgbToHeightRgb, rgbToHeightTerrarium, resolveRgbToHeightFunc };
|
|
10
|
-
export type { IRgbTerrainParams, RgbTerrainEncoding, RgbToHeightFunc };
|
|
12
|
+
export type { IRgbTerrainParams, RgbTerrainEncoding, RgbToHeightFunc, GetHeightsFunc, IProceduralTerrainParams };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { TypedArray } from "../utils/shared";
|
|
2
|
+
import type { Extent } from "../Extent";
|
|
3
|
+
export declare const RGB_ENCODING_CUSTOM = -1;
|
|
4
|
+
export declare const RGB_ENCODING_RGB = 0;
|
|
5
|
+
export declare const RGB_ENCODING_TERRARIUM = 1;
|
|
6
|
+
/** Segment grid sizes by zoom of the elevation terrains. */
|
|
7
|
+
export declare const TERRAIN_GRID_SIZE_BY_ZOOM: number[];
|
|
8
|
+
/** Writes a row of pixel heights, NaN for no data pixels. */
|
|
9
|
+
export type DecodeHeightsRowFunc = (row: number, outHeights: Float32Array) => void;
|
|
10
|
+
export interface IRgbDecodeParams {
|
|
11
|
+
encoding: number;
|
|
12
|
+
minHeight: number;
|
|
13
|
+
resolution: number;
|
|
14
|
+
heightFactor: number;
|
|
15
|
+
noDataValues: number[] | TypedArray;
|
|
16
|
+
parentData: number[] | TypedArray | null;
|
|
17
|
+
parentOffsetX: number;
|
|
18
|
+
parentOffsetY: number;
|
|
19
|
+
parentZoomDiff: number;
|
|
20
|
+
skipPositiveHeights: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface IRgbHeightsParams {
|
|
23
|
+
decode: IRgbDecodeParams;
|
|
24
|
+
size: number;
|
|
25
|
+
gridSize: number;
|
|
26
|
+
levels: number;
|
|
27
|
+
noDataHeight: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Returns pixel grid cells for the image size, 2^n and (2^n + 1) sizes only.
|
|
31
|
+
* @param {number} size - Image size.
|
|
32
|
+
* @returns {number} -
|
|
33
|
+
*/
|
|
34
|
+
export declare function getGridCells(size: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Returns vertex grid cells for the image size. 2^n images have vertices at the pixel centers and corners,
|
|
37
|
+
* (2^n + 1) images are the grid itself.
|
|
38
|
+
* @param {number} size - Image size.
|
|
39
|
+
* @returns {number} -
|
|
40
|
+
*/
|
|
41
|
+
export declare function getVertexGridCells(size: number): number;
|
|
42
|
+
/**
|
|
43
|
+
* Returns subdivision levels of the image tile. Native zoom levels are not finer than the image pixels,
|
|
44
|
+
* finer data comes with their own tiles. Levels above the native zooms go down to the vertex grid.
|
|
45
|
+
* @param {number} size - Image size.
|
|
46
|
+
* @param {number} gridSize - Tile grid size.
|
|
47
|
+
* @param {number} tileZoom - Image tile zoom.
|
|
48
|
+
* @param {number} maxZoom - Maximal terrain zoom.
|
|
49
|
+
* @param {number} maxNativeZoom - Maximal zoom of the terrain tiles.
|
|
50
|
+
* @returns {number} -
|
|
51
|
+
*/
|
|
52
|
+
export declare function getSubdivisionLevels(size: number, gridSize: number, tileZoom: number, maxZoom: number, maxNativeZoom: number): number;
|
|
53
|
+
export declare function getParentHeight(oneByDz2: number, offsetX: number, offsetY: number, heights: TypedArray | number[], i: number, j: number, skipPositiveHeights?: boolean): number;
|
|
54
|
+
/**
|
|
55
|
+
* Decodes "rgb" or "terrarium" encoded pixel row heights.
|
|
56
|
+
* @param {number[] | TypedArray} rgbaData - Image RGBA data.
|
|
57
|
+
* @param {number} row - Pixel row.
|
|
58
|
+
* @param {number} size - Image size.
|
|
59
|
+
* @param {number} parentScale - Parent grid cells by image grid cells.
|
|
60
|
+
* @param {IRgbDecodeParams} p - Decode parameters.
|
|
61
|
+
* @param {Float32Array} outHeights - Row heights.
|
|
62
|
+
* @param {number} noDataHeight - Height for no data pixels.
|
|
63
|
+
*/
|
|
64
|
+
export declare function decodeRgbHeightsRow(rgbaData: number[] | TypedArray, row: number, size: number, parentScale: number, p: IRgbDecodeParams, outHeights: Float32Array, noDataHeight: number): void;
|
|
65
|
+
/**
|
|
66
|
+
* Returns the height at the tile edge, extrapolated from the edge pixel p0 inwards through p1 and p2.
|
|
67
|
+
* The slope is limited (minmod), so peaks, pits and slope breaks at the edge are not overshot.
|
|
68
|
+
* @param {number} p0 - Edge pixel height.
|
|
69
|
+
* @param {number} p1 - Next pixel height.
|
|
70
|
+
* @param {number} p2 - Pixel height after the next.
|
|
71
|
+
* @returns {number} -
|
|
72
|
+
*/
|
|
73
|
+
export declare function getEdgeHeight(p0: number, p1: number, p2: number): number;
|
|
74
|
+
/**
|
|
75
|
+
* Returns the ground height at the point of the tile heights grid, on the grid triangles as they are rendered.
|
|
76
|
+
* @param {number} x - Point x in the tile extent projection.
|
|
77
|
+
* @param {number} y - Point y in the tile extent projection.
|
|
78
|
+
* @param {Extent} extent - Tile extent.
|
|
79
|
+
* @param {number[] | TypedArray} heights - Tile heights grid, rows from north to south.
|
|
80
|
+
* @returns {number} -
|
|
81
|
+
*/
|
|
82
|
+
export declare function getGroundHeight(x: number, y: number, extent: Extent, heights: number[] | TypedArray): number;
|
|
83
|
+
/**
|
|
84
|
+
* Converts size x size pixel heights to the vertex grid in the pixel corners, (size + 1) x (size + 1),
|
|
85
|
+
* or in the pixel centers and corners, (2 * size + 1) x (2 * size + 1). Pixel center vertices keep the pixel heights.
|
|
86
|
+
* @param {Float32Array} pixels - Pixel heights, NaN for no data.
|
|
87
|
+
* @param {number} size - Image size.
|
|
88
|
+
* @param {number} noDataHeight - Height for vertices without data around.
|
|
89
|
+
* @param {boolean} [pixelCenters=true] - Vertices at the pixel centers too.
|
|
90
|
+
* @returns {Float32Array} -
|
|
91
|
+
*/
|
|
92
|
+
export declare function createVertexGrid(pixels: Float32Array, size: number, noDataHeight: number, pixelCenters?: boolean): Float32Array;
|
|
93
|
+
/** Peak and pit pixels, and their place in the vertex grid. */
|
|
94
|
+
export interface IGridPeaks {
|
|
95
|
+
pixels: Float32Array;
|
|
96
|
+
size: number;
|
|
97
|
+
/** Peaks by pixel rows, columns of row r are cols[rowStart[r]] ... cols[rowStart[r + 1] - 1]. */
|
|
98
|
+
rowStart: Int32Array;
|
|
99
|
+
cols: Int32Array;
|
|
100
|
+
/** 1 for peaks, 0 for pits. */
|
|
101
|
+
isPeak: Uint8Array;
|
|
102
|
+
/** Pixel p is at (p + offset) * scale vertex. */
|
|
103
|
+
offset: number;
|
|
104
|
+
scale: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Finds the pixels that are not lower (peaks) or not higher (pits) than the pixels around,
|
|
108
|
+
* and differ from at least one of them.
|
|
109
|
+
* @param {Float32Array} pixels - Pixel heights, NaN for no data.
|
|
110
|
+
* @param {number} size - Image size.
|
|
111
|
+
* @param {number} offset - Pixel p is at (p + offset) * scale vertex of the grid.
|
|
112
|
+
* @param {number} scale - Grid vertices by pixel.
|
|
113
|
+
* @returns {IGridPeaks} -
|
|
114
|
+
*/
|
|
115
|
+
export declare function findPeaks(pixels: Float32Array, size: number, offset: number, scale: number): IGridPeaks;
|
|
116
|
+
/**
|
|
117
|
+
* Takes (gridSize + 1) x (gridSize + 1) vertices of the cells x cells square starting at
|
|
118
|
+
* the row0, col0 vertex of the (size + 1) x (size + 1) grid. Cells must be gridSize multiplied by a power of two.
|
|
119
|
+
*
|
|
120
|
+
* With peaks, peaks and pits are moved to the nearest inner vertices, slopes and edge vertices stay sampled.
|
|
121
|
+
*/
|
|
122
|
+
export declare function sampleSubGrid(grid: Float32Array, size: number, row0: number, col0: number, cells: number, gridSize: number, out?: Float32Array, outOffset?: number, peaks?: IGridPeaks | null, noDataHeight?: number): Float32Array;
|
|
123
|
+
/**
|
|
124
|
+
* Returns (gridSize + 1) x (gridSize + 1) mesh heights of (fileGridSize + 1) x (fileGridSize + 1) elevations,
|
|
125
|
+
* their peaks and pits are moved to the nearest mesh vertices.
|
|
126
|
+
* @param {Float32Array} elevations - Elevations grid, rows from north to south.
|
|
127
|
+
* @param {number} fileGridSize - Elevations grid size.
|
|
128
|
+
* @param {number} gridSize - Mesh grid size, fileGridSize divided by a power of two.
|
|
129
|
+
* @param {number} noDataHeight - Height of no data elevations.
|
|
130
|
+
* @param {Float32Array} [out] - Mesh heights.
|
|
131
|
+
* @returns {Float32Array} -
|
|
132
|
+
*/
|
|
133
|
+
export declare function getMeshHeights(elevations: Float32Array, fileGridSize: number, gridSize: number, noDataHeight: number, out?: Float32Array): Float32Array;
|
|
134
|
+
/**
|
|
135
|
+
* Creates the tile heights grid and its subdivision levels, each tile is (gridSize + 1) x (gridSize + 1).
|
|
136
|
+
* Output order is the tile itself, then 2x2 tiles of the first level, 4x4 of the second and so on, row by row.
|
|
137
|
+
* Peaks and pits of the pixels stay in all the levels.
|
|
138
|
+
* @param {number} size - Image size, 2^n or (2^n + 1).
|
|
139
|
+
* @param {number} gridSize - Tile grid size.
|
|
140
|
+
* @param {number} levels - Subdivision levels.
|
|
141
|
+
* @param {DecodeHeightsRowFunc} decodeRow - Decodes pixel row heights, NaN for no data.
|
|
142
|
+
* @param {number} noDataHeight - Height for vertices without data.
|
|
143
|
+
* @returns {Float32Array} -
|
|
144
|
+
*/
|
|
145
|
+
export declare function createHeightsLevels(size: number, gridSize: number, levels: number, decodeRow: DecodeHeightsRowFunc, noDataHeight: number): Float32Array;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseWorker } from "./BaseWorker";
|
|
2
|
+
import { Segment } from "../segment/Segment";
|
|
3
|
+
import type { IRgbHeightsParams } from "../terrain/terrainUtils";
|
|
4
|
+
export interface IRgbTerrainWorkerTask {
|
|
5
|
+
segment: Segment;
|
|
6
|
+
bitmap: ImageBitmap;
|
|
7
|
+
params: IRgbHeightsParams;
|
|
8
|
+
callback: (heights: Float32Array | null) => void;
|
|
9
|
+
}
|
|
10
|
+
type MessageEventExt = MessageEvent & {
|
|
11
|
+
data: {
|
|
12
|
+
id: number;
|
|
13
|
+
heights: Float32Array | null;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
declare class RgbTerrainWorker extends BaseWorker<IRgbTerrainWorkerTask> {
|
|
17
|
+
constructor(numWorkers?: number);
|
|
18
|
+
protected _onMessage(e: MessageEventExt): void;
|
|
19
|
+
make(task: IRgbTerrainWorkerTask): void;
|
|
20
|
+
}
|
|
21
|
+
export { RgbTerrainWorker };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IRgbHeightsParams } from "../terrain/terrainUtils";
|
|
2
|
+
/**
|
|
3
|
+
* Packs height parameters to the buffer for the worker message.
|
|
4
|
+
* @param {number} id - Worker task id.
|
|
5
|
+
* @param {IRgbHeightsParams} p - Heights parameters, parent data is sent separately.
|
|
6
|
+
* @returns {Float64Array} -
|
|
7
|
+
*/
|
|
8
|
+
export declare function packRgbHeightsParams(id: number, p: IRgbHeightsParams): Float64Array;
|
|
9
|
+
/**
|
|
10
|
+
* Unpacks height parameters from the worker message buffer.
|
|
11
|
+
* @param {Float64Array} params - Packed parameters.
|
|
12
|
+
* @param {Float32Array | null} parentData - Parent segment elevations.
|
|
13
|
+
* @returns {Array} - Task id and parameters (exactly 2 entries).
|
|
14
|
+
*/
|
|
15
|
+
export declare function unpackRgbHeightsParams(params: Float64Array, parentData: Float32Array | null): [number, IRgbHeightsParams];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openglobus/og",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-rc35",
|
|
4
4
|
"description": "[openglobus](https://www.openglobus.org/) is a javascript/typescript library designed to display interactive 3d maps and planets with map tiles, imagery and vector data, markers, and 3D objects. It uses the WebGL technology, open source, and completely free.",
|
|
5
5
|
"main": "lib/og.es.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"@rollup/plugin-terser": "^1.0.0",
|
|
56
56
|
"@types/draco3d": "^1.4.10",
|
|
57
57
|
"@types/node": "^22.15.3",
|
|
58
|
+
"@types/proj4": "^2.5.6",
|
|
58
59
|
"@typescript-eslint/eslint-plugin": "^8.65.0",
|
|
59
60
|
"@typescript-eslint/parser": "^8.65.0",
|
|
60
61
|
"clean-jsdoc-theme": "^5.1.0",
|
|
@@ -67,10 +68,10 @@
|
|
|
67
68
|
"prettier": "^3.6.2",
|
|
68
69
|
"terser": "^5.39.0",
|
|
69
70
|
"typescript": "^5.8.3",
|
|
70
|
-
"vite": "^8.
|
|
71
|
+
"vite": "^8.3.5",
|
|
71
72
|
"vite-plugin-glsl": "^1.6.0",
|
|
72
73
|
"vite-plugin-static-copy": "^4.1.1",
|
|
73
|
-
"vitest": "^4.1.
|
|
74
|
+
"vitest": "^4.1.12"
|
|
74
75
|
},
|
|
75
76
|
"keywords": [
|
|
76
77
|
"map",
|
|
@@ -80,8 +81,9 @@
|
|
|
80
81
|
"og"
|
|
81
82
|
],
|
|
82
83
|
"dependencies": {
|
|
84
|
+
"@photostructure/tz-lookup": "^11.6.1",
|
|
83
85
|
"geotiff": "^3.0.5",
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
+
"proj4": "^2.22.0",
|
|
87
|
+
"tz-lookup": "^6.1.25"
|
|
86
88
|
}
|
|
87
89
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TerrainWorker.worker-BwueoQpg.js","names":[],"sources":["../../src/utils/TerrainWorker.worker.js"],"sourcesContent":["\"use strict\";\n//\n//Terrain worker\n//\n\nfunction binarySearchFast(arr, x) {\n let start = 0,\n end = arr.length - 1;\n while (start <= end) {\n let k = Math.floor((start + end) * 0.5);\n if (Math.abs(arr[k] - x) < 1e-3) return k;\n else if (arr[k] < x) start = k + 1;\n else end = k - 1;\n }\n return -1;\n}\n\nfunction checkNoDataValue(noDataValues, value) {\n return binarySearchFast(noDataValues, value) !== -1;\n}\n\nvar Vec3 = function (x, y, z) {\n this.x = x;\n this.y = y;\n this.z = z;\n};\n\nvar doubleToTwoFloats = function (v, high, low) {\n let x = v.x,\n y = v.y,\n z = v.z;\n\n var doubleHigh;\n\n if (x >= 0.0) {\n doubleHigh = Math.floor(x / 65536.0) * 65536.0;\n high.x = Math.fround(doubleHigh);\n low.x = Math.fround(x - doubleHigh);\n } else {\n doubleHigh = Math.floor(-x / 65536.0) * 65536.0;\n high.x = Math.fround(-doubleHigh);\n low.x = Math.fround(x + doubleHigh);\n }\n\n if (y >= 0.0) {\n doubleHigh = Math.floor(y / 65536.0) * 65536.0;\n high.y = Math.fround(doubleHigh);\n low.y = Math.fround(y - doubleHigh);\n } else {\n doubleHigh = Math.floor(-y / 65536.0) * 65536.0;\n high.y = Math.fround(-doubleHigh);\n low.y = Math.fround(y + doubleHigh);\n }\n\n if (z >= 0.0) {\n doubleHigh = Math.floor(z / 65536.0) * 65536.0;\n high.z = Math.fround(doubleHigh);\n low.z = Math.fround(z - doubleHigh);\n } else {\n doubleHigh = Math.floor(-z / 65536.0) * 65536.0;\n high.z = Math.fround(-doubleHigh);\n low.z = Math.fround(z + doubleHigh);\n }\n};\n\nVec3.prototype.sub = function (v) {\n return new Vec3(this.x - v.x, this.y - v.y, this.z - v.z);\n};\n\nVec3.prototype.add = function (v) {\n return new Vec3(this.x + v.x, this.y + v.y, this.z + v.z);\n};\n\nVec3.prototype.cross = function (v) {\n return new Vec3(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x);\n};\n\nVec3.prototype.normalize = function () {\n var x = this.x,\n y = this.y,\n z = this.z;\n var length = 1.0 / Math.sqrt(x * x + y * y + z * z);\n this.x = x * length;\n this.y = y * length;\n this.z = z * length;\n return this;\n};\n\nVec3.prototype.distance = function (v) {\n return this.sub(v).length();\n};\n\nVec3.prototype.length = function () {\n return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);\n};\n\nvar blerp = function (x, y, fQ11, fQ21, fQ12, fQ22) {\n return fQ11 * (1.0 - x) * (1.0 - y) + fQ21 * x * (1.0 - y) + fQ12 * (1.0 - x) * y + fQ22 * x * y;\n};\n\nvar _tempVec = new Vec3(0.0, 0.0, 0.0);\nvar _rtcTempVec = new Vec3(0.0, 0.0, 0.0);\n\nvar _tempHigh = new Vec3(0.0, 0.0, 0.0),\n _tempLow = new Vec3(0.0, 0.0, 0.0);\n\nself.onmessage = function (e) {\n var elevations = e.data.elevations,\n this_plainVertices = e.data.this_plainVertices,\n this_plainNormals = e.data.this_plainNormals,\n this_normalMapVertices = e.data.this_normalMapVertices,\n this_normalMapNormals = e.data.this_normalMapNormals,\n heightFactor = e.data.heightFactor,\n gridSize = e.data.gridSize,\n noDataValues = e.data.noDataValues,\n id = e.data.id;\n\n let rtc_x = e.data.relativeCenter[0],\n rtc_y = e.data.relativeCenter[1],\n rtc_z = e.data.relativeCenter[2];\n\n var xmin = 549755748352.0,\n xmax = -549755748352.0,\n ymin = 549755748352.0,\n ymax = -549755748352.0,\n zmin = 549755748352.0,\n zmax = -549755748352.0;\n\n // Squared geocentric distance of the same vertices. The axis aligned bounds above cannot tell\n // relief from segment size, because the box of a tilted patch is far larger than the patch, so\n // the radius range is accumulated here instead. Kept squared to avoid a root per vertex.\n var r2min = Infinity,\n r2max = -Infinity;\n\n const fileGridSize = Math.sqrt(elevations.length) - 1;\n\n const fileGridSize_one = fileGridSize + 1;\n const fileGridSize_one_x2 = fileGridSize_one * fileGridSize_one;\n const tgs = gridSize;\n const dg = fileGridSize / tgs;\n const gs = tgs + 1;\n const hf = heightFactor;\n\n var vInd = 0,\n noDataInd = 0;\n\n var gsgs3 = gs * gs * 3;\n\n var terrainVertices = new Float64Array(gsgs3),\n terrainVerticesHigh = new Float32Array(gsgs3),\n terrainVerticesLow = new Float32Array(gsgs3),\n noDataVertices = new Uint8Array(gs * gs);\n\n var normalMapNormals, normalMapVertices;\n\n var nv = this_normalMapVertices,\n nn = this_normalMapNormals;\n\n if (fileGridSize >= tgs) {\n normalMapNormals = new Float32Array(fileGridSize_one_x2 * 3);\n normalMapVertices = new Float64Array(fileGridSize_one_x2 * 3);\n\n for (let k = 0; k < fileGridSize_one_x2; k++) {\n var j = k % fileGridSize_one,\n i = ~~(k / fileGridSize_one);\n\n //\n // V0\n //\n var hInd0 = k;\n var vInd0 = hInd0 * 3;\n var currElv = elevations[hInd0];\n if (checkNoDataValue(noDataValues, currElv)) {\n currElv = 0.0;\n }\n var h0 = hf * currElv;\n var v0 = new Vec3(\n rtc_x + nv[vInd0] + h0 * nn[vInd0],\n rtc_y + nv[vInd0 + 1] + h0 * nn[vInd0 + 1],\n rtc_z + nv[vInd0 + 2] + h0 * nn[vInd0 + 2]\n );\n\n normalMapVertices[vInd0] = v0.x - rtc_x;\n normalMapVertices[vInd0 + 1] = v0.y - rtc_y;\n normalMapVertices[vInd0 + 2] = v0.z - rtc_z;\n\n //\n // The vertex goes into screen buffer\n if (i % dg === 0 && j % dg === 0) {\n let currVert = new Vec3(rtc_x + nv[vInd0], rtc_y + nv[vInd0 + 1], rtc_z + nv[vInd0 + 2]);\n let nextVert = new Vec3(rtc_x + nv[vInd0 + 3], rtc_y + nv[vInd0 + 4], rtc_z + nv[vInd0 + 5]);\n\n let nextElv = elevations[hInd0 + 1];\n if (checkNoDataValue(noDataValues, nextElv)) {\n nextElv = 0.0;\n }\n\n let eps = false;\n if (noDataValues.length === 0) {\n let step = currVert.distance(nextVert);\n let deltaElv = Math.abs(currElv - nextElv);\n eps = deltaElv / step > 10.0 || currElv < -5000;\n }\n\n if (eps) {\n noDataVertices[noDataInd] = 1;\n } else {\n noDataVertices[noDataInd] = 0;\n if (v0.x < xmin) xmin = v0.x;\n if (v0.x > xmax) xmax = v0.x;\n if (v0.y < ymin) ymin = v0.y;\n if (v0.y > ymax) ymax = v0.y;\n if (v0.z < zmin) zmin = v0.z;\n if (v0.z > zmax) zmax = v0.z;\n\n let r2_v0 = v0.x * v0.x + v0.y * v0.y + v0.z * v0.z;\n if (r2_v0 < r2min) r2min = r2_v0;\n if (r2_v0 > r2max) r2max = r2_v0;\n }\n\n let rtc_v0 = new Vec3(v0.x - rtc_x, v0.y - rtc_y, v0.z - rtc_z);\n doubleToTwoFloats(rtc_v0, _tempHigh, _tempLow);\n\n terrainVerticesHigh[vInd] = _tempHigh.x;\n terrainVerticesLow[vInd] = _tempLow.x;\n terrainVertices[vInd++] = rtc_v0.x;\n\n terrainVerticesHigh[vInd] = _tempHigh.y;\n terrainVerticesLow[vInd] = _tempLow.y;\n terrainVertices[vInd++] = rtc_v0.y;\n\n terrainVerticesHigh[vInd] = _tempHigh.z;\n terrainVerticesLow[vInd] = _tempLow.z;\n terrainVertices[vInd++] = rtc_v0.z;\n\n noDataInd++;\n }\n\n if (i !== fileGridSize && j !== fileGridSize) {\n //\n // V1\n //\n var hInd1 = k + 1;\n var vInd1 = hInd1 * 3;\n var elv = elevations[hInd1];\n if (checkNoDataValue(noDataValues, elv)) {\n elv = 0.0;\n }\n var h1 = hf * elv;\n var v1 = new Vec3(\n rtc_x + nv[vInd1] + h1 * nn[vInd1],\n rtc_y + nv[vInd1 + 1] + h1 * nn[vInd1 + 1],\n rtc_z + nv[vInd1 + 2] + h1 * nn[vInd1 + 2]\n );\n\n normalMapVertices[vInd1] = v1.x - rtc_x;\n normalMapVertices[vInd1 + 1] = v1.y - rtc_y;\n normalMapVertices[vInd1 + 2] = v1.z - rtc_z;\n\n //\n // V2\n //\n var hInd2 = k + fileGridSize_one;\n var vInd2 = hInd2 * 3;\n elv = elevations[hInd2];\n if (checkNoDataValue(noDataValues, elv)) {\n elv = 0.0;\n }\n var h2 = hf * elv;\n var v2 = new Vec3(\n rtc_x + nv[vInd2] + h2 * nn[vInd2],\n rtc_y + nv[vInd2 + 1] + h2 * nn[vInd2 + 1],\n rtc_z + nv[vInd2 + 2] + h2 * nn[vInd2 + 2]\n );\n\n normalMapVertices[vInd2] = v2.x - rtc_x;\n normalMapVertices[vInd2 + 1] = v2.y - rtc_y;\n normalMapVertices[vInd2 + 2] = v2.z - rtc_z;\n\n //\n // V3\n //\n var hInd3 = k + fileGridSize_one + 1;\n var vInd3 = hInd3 * 3;\n elv = elevations[hInd3];\n if (checkNoDataValue(noDataValues, elv)) {\n elv = 0.0;\n }\n var h3 = hf * elv;\n var v3 = new Vec3(\n rtc_x + nv[vInd3] + h3 * nn[vInd3],\n rtc_y + nv[vInd3 + 1] + h3 * nn[vInd3 + 1],\n rtc_z + nv[vInd3 + 2] + h3 * nn[vInd3 + 2]\n );\n\n normalMapVertices[vInd3] = v3.x - rtc_x;\n normalMapVertices[vInd3 + 1] = v3.y - rtc_y;\n normalMapVertices[vInd3 + 2] = v3.z - rtc_z;\n\n //\n // Normal\n //\n var e10 = v1.sub(v0),\n e20 = v2.sub(v0),\n e30 = v3.sub(v0);\n\n var sw = e20.cross(e30).normalize();\n var ne = e30.cross(e10).normalize();\n var n0 = ne.add(sw).normalize();\n\n normalMapNormals[vInd0] += n0.x;\n normalMapNormals[vInd0 + 1] += n0.y;\n normalMapNormals[vInd0 + 2] += n0.z;\n\n normalMapNormals[vInd1] += ne.x;\n normalMapNormals[vInd1 + 1] += ne.y;\n normalMapNormals[vInd1 + 2] += ne.z;\n\n normalMapNormals[vInd2] += sw.x;\n normalMapNormals[vInd2 + 1] += sw.y;\n normalMapNormals[vInd2 + 2] += sw.z;\n\n normalMapNormals[vInd3] += n0.x;\n normalMapNormals[vInd3 + 1] += n0.y;\n normalMapNormals[vInd3 + 2] += n0.z;\n }\n }\n } else {\n normalMapNormals = new Float32Array(gsgs3);\n normalMapVertices = new Float64Array(gsgs3);\n\n var oneSize = tgs / fileGridSize;\n var gsgs = gsgs3 / 3;\n var fgsOne = fileGridSize + 1;\n\n for (let i = 0; i < gsgs; i++) {\n let ii = Math.floor(i / gs),\n ij = i % gs;\n\n let qii = ii % oneSize,\n qij = ij % oneSize;\n\n let hlt_ind = Math.floor(ii / oneSize) * fgsOne + Math.floor(ij / oneSize);\n\n if (ij === tgs) {\n hlt_ind -= 1;\n qij = oneSize;\n }\n\n if (ii === tgs) {\n hlt_ind -= fgsOne;\n qii = oneSize;\n }\n\n let hrt_ind = hlt_ind + 1,\n hlb_ind = hlt_ind + fgsOne,\n hrb_ind = hlb_ind + 1;\n\n let h_lt = elevations[hlt_ind],\n h_rt = elevations[hrt_ind],\n h_lb = elevations[hlb_ind],\n h_rb = elevations[hrb_ind];\n\n if (checkNoDataValue(noDataValues, h_lt)) {\n h_lt = 0.0;\n }\n\n if (checkNoDataValue(noDataValues, h_rt)) {\n h_rt = 0.0;\n }\n\n if (checkNoDataValue(noDataValues, h_lb)) {\n h_lb = 0.0;\n }\n\n if (checkNoDataValue(noDataValues, h_rb)) {\n h_rb = 0.0;\n }\n\n let hi = blerp(qij / oneSize, qii / oneSize, h_lt, h_rt, h_lb, h_rb);\n\n let i3 = i * 3;\n\n _rtcTempVec.x = this_plainVertices[i3] + hi * this_plainNormals[i3];\n _rtcTempVec.y = this_plainVertices[i3 + 1] + hi * this_plainNormals[i3 + 1];\n _rtcTempVec.z = this_plainVertices[i3 + 2] + hi * this_plainNormals[i3 + 2];\n\n doubleToTwoFloats(_rtcTempVec, _tempHigh, _tempLow);\n\n terrainVertices[i3] = _rtcTempVec.x;\n terrainVertices[i3 + 1] = _rtcTempVec.y;\n terrainVertices[i3 + 2] = _rtcTempVec.z;\n\n terrainVerticesHigh[i3] = _tempHigh.x;\n terrainVerticesHigh[i3 + 1] = _tempHigh.y;\n terrainVerticesHigh[i3 + 2] = _tempHigh.z;\n\n terrainVerticesLow[i3] = _tempLow.x;\n terrainVerticesLow[i3 + 1] = _tempLow.y;\n terrainVerticesLow[i3 + 2] = _tempLow.z;\n\n _tempVec.x = _rtcTempVec.x + rtc_x;\n _tempVec.y = _rtcTempVec.y + rtc_y;\n _tempVec.z = _rtcTempVec.z + rtc_z;\n\n if (_tempVec.x < xmin) xmin = _tempVec.x;\n if (_tempVec.x > xmax) xmax = _tempVec.x;\n if (_tempVec.y < ymin) ymin = _tempVec.y;\n if (_tempVec.y > ymax) ymax = _tempVec.y;\n if (_tempVec.z < zmin) zmin = _tempVec.z;\n if (_tempVec.z > zmax) zmax = _tempVec.z;\n\n let r2_tmp = _tempVec.x * _tempVec.x + _tempVec.y * _tempVec.y + _tempVec.z * _tempVec.z;\n if (r2_tmp < r2min) r2min = r2_tmp;\n if (r2_tmp > r2max) r2max = r2_tmp;\n }\n\n normalMapVertices.set(terrainVertices);\n\n for (let k = 0; k < gsgs; k++) {\n let j = k % gs,\n i = ~~(k / gs);\n\n if (i !== tgs && j !== tgs) {\n let v0ind = k * 3,\n v1ind = v0ind + 3,\n v2ind = v0ind + gs * 3,\n v3ind = v2ind + 3;\n\n let v0 = new Vec3(\n terrainVertices[v0ind] + rtc_x,\n terrainVertices[v0ind + 1] + rtc_y,\n terrainVertices[v0ind + 2] + rtc_z\n ),\n v1 = new Vec3(\n terrainVertices[v1ind] + rtc_x,\n terrainVertices[v1ind + 1] + rtc_y,\n terrainVertices[v1ind + 2] + rtc_z\n ),\n v2 = new Vec3(\n terrainVertices[v2ind] + rtc_x,\n terrainVertices[v2ind + 1] + rtc_y,\n terrainVertices[v2ind + 2] + rtc_z\n ),\n v3 = new Vec3(\n terrainVertices[v3ind] + rtc_x,\n terrainVertices[v3ind + 1] + rtc_y,\n terrainVertices[v3ind + 2] + rtc_z\n );\n\n let e10 = v1.sub(v0).normalize(),\n e20 = v2.sub(v0).normalize(),\n e30 = v3.sub(v0).normalize();\n\n let sw = e20.cross(e30).normalize();\n let ne = e30.cross(e10).normalize();\n let n0 = ne.add(sw).normalize();\n\n normalMapNormals[v0ind] += n0.x;\n normalMapNormals[v0ind + 1] += n0.y;\n normalMapNormals[v0ind + 2] += n0.z;\n\n normalMapNormals[v1ind] += ne.x;\n normalMapNormals[v1ind + 1] += ne.y;\n normalMapNormals[v1ind + 2] += ne.z;\n\n normalMapNormals[v2ind] += sw.x;\n normalMapNormals[v2ind + 1] += sw.y;\n normalMapNormals[v2ind + 2] += sw.z;\n\n normalMapNormals[v3ind] += n0.x;\n normalMapNormals[v3ind + 1] += n0.y;\n normalMapNormals[v3ind + 2] += n0.z;\n }\n }\n }\n\n self.postMessage(\n {\n id: id,\n normalMapNormals: normalMapNormals,\n normalMapVertices: normalMapVertices,\n terrainVertices: terrainVertices,\n terrainVerticesHigh: terrainVerticesHigh,\n terrainVerticesLow: terrainVerticesLow,\n noDataVertices: noDataVertices,\n bounds: [xmin, ymin, zmin, xmax, ymax, zmax],\n radiusRange: r2max >= r2min ? [Math.sqrt(r2min), Math.sqrt(r2max)] : null,\n relativeCenter: e.data.relativeCenter\n },\n [\n normalMapNormals.buffer,\n normalMapVertices.buffer,\n terrainVertices.buffer,\n terrainVerticesHigh.buffer,\n terrainVerticesLow.buffer,\n noDataVertices.buffer\n ]\n );\n};\n"],"mappings":"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"}
|