@mappedin/mappedin-js 5.3.0 → 5.5.0

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.
@@ -4,6 +4,7 @@
4
4
  // ../minisearch
5
5
  // ../@tweenjs/tween.js
6
6
  // ../geojson
7
+ // ../stats.js
7
8
 
8
9
  declare module '@mappedin/mappedin-js' {
9
10
  import { MapView } from '@mappedin/mappedin-js/renderer/MapView';
@@ -12,6 +13,7 @@ declare module '@mappedin/mappedin-js' {
12
13
  import type { TMapViewOptions, TJourneyOptions } from '@mappedin/mappedin-js/renderer/MapView.types';
13
14
  import { labelThemes } from '@mappedin/mappedin-js/renderer/MapView.types';
14
15
  import { MARKER_ANCHOR } from '@mappedin/mappedin-js/renderer/internal/Mappedin.Marker';
16
+ export type { Marker } from '@mappedin/mappedin-js/renderer/layers/Markers';
15
17
  export { BEARING_TYPE, ACTION_TYPE } from '@mappedin/mappedin-js/navigator';
16
18
  export type { IDirectionsResult, E_MESSAGES as E_GET_DIRECTIONS_MESSAGES } from '@mappedin/mappedin-js/navigator';
17
19
  export type { IFlatLabels, FlatLabels } from '@mappedin/mappedin-js/renderer/MapView.FlatLabels';
@@ -42,6 +44,7 @@ declare module '@mappedin/mappedin-js' {
42
44
  export { COLLISION_RANKING_TIERS, STATE, E_SDK_EVENT, E_BLUEDOT_STATE_REASON, E_BLUEDOT_MARKER_STATE, E_BLUEDOT_EVENT, E_BLUEDOT_STATE, E_CAMERA_EVENT, E_CAMERA_DIRECTION, SAFE_AREA_INSET_TYPE, ANIMATION_TWEENS, CAMERA_EASING_MODE } from '@mappedin/mappedin-js/renderer/MapView.enums';
43
45
  export { getVenue, getVenueBundle, showVenue, downloadBundle, getVenueBundleURL, downloadVenueBundleMVF, PositionUpdater, MappedinDestinationSet, MARKER_ANCHOR, labelThemes };
44
46
  import DefaultAssetManager from '@mappedin/mappedin-js/renderer/internal/Mappedin.AssetManager';
47
+ import { TTileManagerOptions } from '@mappedin/mappedin-js/renderer/layers/Outdoor-Context/Mappedin.TileManager';
45
48
  /**
46
49
  * @internal
47
50
  */
@@ -75,17 +78,32 @@ declare module '@mappedin/mappedin-js' {
75
78
  * @internal
76
79
  */
77
80
  export function __useSceneManager(value: boolean): void;
81
+ export function __enableTileManager(options?: TTileManagerOptions): void;
82
+ export {
83
+ /**
84
+ * @internal
85
+ */
86
+ AzureOutdoorContextProvider,
87
+ /**
88
+ * @internal
89
+ */
90
+ OpenStreetMapOutdoorContext } from './layers/Outdoor-Context/Outdoor-Context.provider';
91
+ export type {
92
+ /**
93
+ * @internal
94
+ */
95
+ IOutdoorContextProvider } from './layers/Outdoor-Context/Outdoor-Context.provider';
78
96
  }
79
97
 
80
98
  declare module '@mappedin/mappedin-js/renderer/MapView' {
81
99
  import { Texture } from 'three';
82
100
  import './internal/Mappedin.css';
83
101
  import { Mappedin, MappedinCoordinate, MappedinLocation, MappedinMap, MappedinNode, MappedinPolygon } from '@mappedin/mappedin-js/get-venue';
84
- import { E_SDK_EVENT_PAYLOAD, TCreateMarkerOptions, TLabelAllLocationFlatLabelOptions, TLabelAllLocationFloatingLabelOptions, TMapViewOptions, TPathOptions, TCreateTooltipCommonOptions, TCreateTooltipOptions } from '@mappedin/mappedin-js/renderer/MapView.types';
102
+ import { E_SDK_EVENT_PAYLOAD, TCreateMarkerOptions, TLabelAllLocationFlatLabelOptions, TLabelAllLocationFloatingLabelOptions, TMapViewOptions, TPathOptions, TCreateTooltipCommonOptions, TCreateTooltipOptions, TMapClickEvent } from '@mappedin/mappedin-js/renderer/MapView.types';
85
103
  import { E_SDK_EVENT, STATE } from '@mappedin/mappedin-js/renderer/MapView.enums';
86
- import Marker from '@mappedin/mappedin-js/renderer/internal/Mappedin.Marker';
87
104
  import SmartTooltip from '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartTooltip';
88
105
  import Camera from '@mappedin/mappedin-js/renderer/Camera';
106
+ import { Marker } from '@mappedin/mappedin-js/renderer/layers/Markers';
89
107
  import { PubSub } from '@mappedin/mappedin-js/renderer/internal/pub-sub.typed';
90
108
  import BlueDotLayer from '@mappedin/mappedin-js/renderer/layers/BlueDot';
91
109
  import JourneyLayer from '@mappedin/mappedin-js/renderer/layers/Journey';
@@ -106,7 +124,20 @@ declare module '@mappedin/mappedin-js/renderer/MapView' {
106
124
  SET_STATE_SILENT = 10,
107
125
  BLUE_DOT_UPDATE_POSITION = 11,
108
126
  BLUE_DOT_SET_FOLLOWING = 12,
109
- CLEAR_MOUSE = 13
127
+ CLEAR_MOUSE = 13,
128
+ MAP_CLICK = 14,
129
+ USER_ZOOM = 15,
130
+ USER_ZOOM_BEGIN = 16,
131
+ USER_ROTATE = 17,
132
+ USER_ROTATE_BEGIN = 18,
133
+ USER_PAN = 19,
134
+ USER_PAN_BEGIN = 20,
135
+ USER_TILT = 21,
136
+ USER_MULTI_BEGIN = 22,
137
+ USER_MULTI_END = 23,
138
+ FOCUSON_BEGIN = 24,
139
+ USER_HANDS_ON = 25,
140
+ USER_HANDS_OFF = 26
110
141
  }
111
142
  export type INTERNAL_EVENT_PAYLOAD = {
112
143
  [INTERNAL_EVENT.SET_MAP_START]: undefined;
@@ -128,6 +159,19 @@ declare module '@mappedin/mappedin-js/renderer/MapView' {
128
159
  y: number;
129
160
  };
130
161
  [INTERNAL_EVENT.BLUE_DOT_SET_FOLLOWING]: boolean;
162
+ [INTERNAL_EVENT.MAP_CLICK]: TMapClickEvent;
163
+ [INTERNAL_EVENT.USER_ZOOM]: undefined;
164
+ [INTERNAL_EVENT.USER_ZOOM_BEGIN]: undefined;
165
+ [INTERNAL_EVENT.USER_ROTATE_BEGIN]: undefined;
166
+ [INTERNAL_EVENT.USER_MULTI_BEGIN]: undefined;
167
+ [INTERNAL_EVENT.USER_PAN_BEGIN]: undefined;
168
+ [INTERNAL_EVENT.USER_ROTATE]: undefined;
169
+ [INTERNAL_EVENT.USER_MULTI_END]: undefined;
170
+ [INTERNAL_EVENT.FOCUSON_BEGIN]: undefined;
171
+ [INTERNAL_EVENT.USER_HANDS_ON]: undefined;
172
+ [INTERNAL_EVENT.USER_HANDS_OFF]: undefined;
173
+ [INTERNAL_EVENT.USER_PAN]: undefined;
174
+ [INTERNAL_EVENT.USER_TILT]: undefined;
131
175
  };
132
176
  export class MapView extends PubSub<E_SDK_EVENT_PAYLOAD, E_SDK_EVENT> {
133
177
  #private;
@@ -365,8 +409,9 @@ declare module '@mappedin/mappedin-js/renderer/MapView' {
365
409
  * but if you are doing something weird, or have your own special tween for something, you will want to call this function.
366
410
  * You can call it as often as you want, it just sets a flag that we need to render again, and renders a few frames if we weren't already doing that.
367
411
  * Ignored in 2D.
412
+ * @deprecated
368
413
  */
369
- tryRendering(renderMode?: any): void;
414
+ tryRendering(_renderMode?: any): void;
370
415
  /**
371
416
  * Finds the main Location associated with a Polygon. This means a Location
372
417
  * attached to the Polygon that has no parents, or, if there are none of those,
@@ -390,6 +435,19 @@ declare module '@mappedin/mappedin-js/renderer/MapView' {
390
435
  * @returns MappedinPolygon[]
391
436
  */
392
437
  getPolygonsAtCoordinate(coordinate: MappedinCoordinate, options?: TGetPolygonsAtCoordinateOptions): MappedinPolygon[];
438
+ /**
439
+ * Finds all the polygons on a screen coordinate x and y. If multiple
440
+ * polygons are stacked on top of each other, the array of polygons returned will be
441
+ * in the order of farthest to closest.
442
+ *
443
+ * By default, this only considers interactive polygons.
444
+ *
445
+ * @param x
446
+ * @param y
447
+ * @param options {@link TGetPolygonsAtCoordinateOptions}
448
+ * @returns MappedinPolygon[]
449
+ */
450
+ getPolygonsAtScreenCoordinate(x: number, y: number, options?: TGetPolygonsAtCoordinateOptions): MappedinPolygon[];
393
451
  /**
394
452
  * Destroy instance and reclaim memory. Note: this does not destroy the instance of {@link Mappedin}
395
453
  * that was passed in. For applications that require destroying and re-creating the mapView, it is
@@ -1360,7 +1418,7 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.Marker' {
1360
1418
  LEFT = 3,
1361
1419
  RIGHT = 4
1362
1420
  }
1363
- class Marker extends HTMLCollider implements IHTMLCollider {
1421
+ class InternalMarker extends HTMLCollider implements IHTMLCollider {
1364
1422
  _el: Element | null;
1365
1423
  style: TTooltipStyle;
1366
1424
  polygon: any;
@@ -1372,7 +1430,41 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.Marker' {
1372
1430
  colliderDidGoOffscreen(): void;
1373
1431
  colliderDidUpdateVisiblity(): void;
1374
1432
  }
1375
- export default Marker;
1433
+ export default InternalMarker;
1434
+ }
1435
+
1436
+ declare module '@mappedin/mappedin-js/renderer/layers/Markers' {
1437
+ import { MappedinCoordinate, MappedinNode } from '@mappedin/mappedin-js/get-venue';
1438
+ import { TCreateMarkerOptions } from '@mappedin/mappedin-js/renderer';
1439
+ import InternalMarker from '@mappedin/mappedin-js/renderer/internal/Mappedin.Marker';
1440
+ import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
1441
+ /**
1442
+ * A marker containing some HTML content.
1443
+ */
1444
+ export class Marker {
1445
+ #private;
1446
+ constructor(internalMarker: InternalMarker);
1447
+ /**
1448
+ * A generated ID for this marker.
1449
+ */
1450
+ get id(): string;
1451
+ /**
1452
+ * The container element for this marker. This element's position is automatically updated.
1453
+ */
1454
+ get containerEl(): any;
1455
+ /**
1456
+ * The content that was provided when creating this marker.
1457
+ */
1458
+ get contentEl(): any;
1459
+ }
1460
+ class MarkersLayer {
1461
+ #private;
1462
+ constructor(core: ICore);
1463
+ createMarker(nodeOrCoordinate: MappedinNode | MappedinCoordinate, contentHtml: string, options?: TCreateMarkerOptions): Marker;
1464
+ removeMarker(markerOrMarkerId: Marker | Marker['id']): void;
1465
+ removeAllMarkers(): void;
1466
+ }
1467
+ export default MarkersLayer;
1376
1468
  }
1377
1469
 
1378
1470
  declare module '@mappedin/mappedin-js/navigator' {
@@ -1681,6 +1773,64 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.AssetManager' {
1681
1773
  }
1682
1774
  }
1683
1775
 
1776
+ declare module '@mappedin/mappedin-js/renderer/layers/Outdoor-Context/Mappedin.TileManager' {
1777
+ import { Box3 } from 'three';
1778
+ import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
1779
+ import { MappedinCoordinate, MappedinMap } from '@mappedin/mappedin-js/renderer/index.rn';
1780
+ import Object3D from '@mappedin/mappedin-js/renderer/internal/object3D.destroy';
1781
+ import { MapView } from '@mappedin/mappedin-js/renderer/MapView';
1782
+ import { Tile } from '@mappedin/mappedin-js/renderer/layers/Outdoor-Context/Mappedin.Tile';
1783
+ import { IOutdoorContextProvider } from '@mappedin/mappedin-js/renderer/layers/Outdoor-Context/Outdoor-Context.provider';
1784
+ export enum TILE_RENDER_MODES {
1785
+ NORMAL = 0,
1786
+ AGGRESSIVE = 1
1787
+ }
1788
+ export const TILE_COLOR = "#f0f0f1";
1789
+ /**
1790
+ * @internal
1791
+ */
1792
+ export type TTileManagerOptions = {
1793
+ tileRenderMode?: TILE_RENDER_MODES;
1794
+ provider: IOutdoorContextProvider;
1795
+ };
1796
+ export class TileManager {
1797
+ #private;
1798
+ static ENABLED: boolean;
1799
+ static OPTIONS: TTileManagerOptions;
1800
+ tileSize: number;
1801
+ token: string;
1802
+ apiKey?: string;
1803
+ tileRenderMode: TILE_RENDER_MODES;
1804
+ currentAbortController: AbortController;
1805
+ attributionEl: HTMLDivElement;
1806
+ outdoorContextProvider: IOutdoorContextProvider;
1807
+ constructor(mapView: MapView, core: ICore);
1808
+ createAttributionEl(): void;
1809
+ renderVisibleTiles: () => void;
1810
+ _renderVisibleTiles(): void;
1811
+ cachedZoomLevel: number;
1812
+ fetchTiles(): void;
1813
+ zoomLevelToAltitudeMap: number[][];
1814
+ plane: Object3D;
1815
+ tiles: Tile[];
1816
+ maskMeshBoundingBox: Box3;
1817
+ fetchTilesForZoomLevel(zoomLevel: number): Promise<void>;
1818
+ /**
1819
+ * This function populates a layer of tiles starting from the center clockwise
1820
+ *
1821
+ * Here's an example of layer = 1
1822
+ *
1823
+ * [ ][ ][ ][ ][ ]
1824
+ * [ ][1][2][3][ ]
1825
+ * [ ][8][X][4][ ]
1826
+ * [ ][7][6][5][ ]
1827
+ * [ ][ ][ ][ ][ ]
1828
+ */
1829
+ populateLayer(layerId: number | undefined, center: MappedinCoordinate, zoomLevel: number, metersPerTile: number, referenceMap: MappedinMap): void;
1830
+ checkIfTileIsInBoundingBox(tile: Tile): any;
1831
+ }
1832
+ }
1833
+
1684
1834
  declare module '@mappedin/mappedin-js/get-venue/MappedinDirections' {
1685
1835
  import { IDirectionsResult } from '@mappedin/mappedin-js/navigator';
1686
1836
  import { ACTION_TYPE, BEARING_TYPE } from '@mappedin/mappedin-js/navigator/Directive';
@@ -1871,7 +2021,7 @@ declare module '@mappedin/mappedin-js/renderer/Camera' {
1871
2021
  bottom: number;
1872
2022
  right: number;
1873
2023
  }): void;
1874
- getSafeAreaInsets(): any;
2024
+ getSafeAreaInsets(): import("./MapView.types").TPadding;
1875
2025
  /**
1876
2026
  * Focus the Camera view on a collection of targets and animate to that state.
1877
2027
  * @returns a Promise that resolves when the animation finishes, or rejects when it is cancelled.
@@ -2028,8 +2178,10 @@ declare module '@mappedin/mappedin-js/renderer/layers/BlueDot' {
2028
2178
  * @private
2029
2179
  */
2030
2180
  constructor(mapView: MapView, core: ICore, eventsLayer: EventSystemLayer);
2031
- on(eventName: any, fn: any): void;
2032
- off(eventName: any, fn: any): void;
2181
+ on<EVENT_NAME extends E_BLUEDOT_EVENT>(eventName: EVENT_NAME, fn: (payload: E_BLUEDOT_EVENT_PAYLOAD[EVENT_NAME] extends {
2182
+ data: null;
2183
+ } ? E_BLUEDOT_EVENT_PAYLOAD[EVENT_NAME]['data'] : E_BLUEDOT_EVENT_PAYLOAD[EVENT_NAME]) => void): void;
2184
+ off<EVENT_NAME extends E_BLUEDOT_EVENT>(eventName: EVENT_NAME, fn: (payload: E_BLUEDOT_EVENT_PAYLOAD[EVENT_NAME]) => void): void;
2033
2185
  /**
2034
2186
  * Enables Blue Dot. BlueDot then emits {@link TBlueDotStateChange} and {@link TBlueDotPositionUpdate} events via {@link E_BLUEDOT_EVENT}
2035
2187
  */
@@ -2086,6 +2238,7 @@ declare module '@mappedin/mappedin-js/renderer' {
2086
2238
  import type { TMapViewOptions, TJourneyOptions } from '@mappedin/mappedin-js/renderer/MapView.types';
2087
2239
  import { labelThemes } from '@mappedin/mappedin-js/renderer/MapView.types';
2088
2240
  import { MARKER_ANCHOR } from '@mappedin/mappedin-js/renderer/internal/Mappedin.Marker';
2241
+ export type { Marker } from '@mappedin/mappedin-js/renderer/layers/Markers';
2089
2242
  export { BEARING_TYPE, ACTION_TYPE } from '@mappedin/mappedin-js/navigator';
2090
2243
  export type { IDirectionsResult, E_MESSAGES as E_GET_DIRECTIONS_MESSAGES } from '@mappedin/mappedin-js/navigator';
2091
2244
  export type { IFlatLabels, FlatLabels } from '@mappedin/mappedin-js/renderer/MapView.FlatLabels';
@@ -2116,6 +2269,7 @@ declare module '@mappedin/mappedin-js/renderer' {
2116
2269
  export { COLLISION_RANKING_TIERS, STATE, E_SDK_EVENT, E_BLUEDOT_STATE_REASON, E_BLUEDOT_MARKER_STATE, E_BLUEDOT_EVENT, E_BLUEDOT_STATE, E_CAMERA_EVENT, E_CAMERA_DIRECTION, SAFE_AREA_INSET_TYPE, ANIMATION_TWEENS, CAMERA_EASING_MODE } from '@mappedin/mappedin-js/renderer/MapView.enums';
2117
2270
  export { getVenue, getVenueBundle, showVenue, downloadBundle, getVenueBundleURL, downloadVenueBundleMVF, PositionUpdater, MappedinDestinationSet, MARKER_ANCHOR, labelThemes };
2118
2271
  import DefaultAssetManager from '@mappedin/mappedin-js/renderer/internal/Mappedin.AssetManager';
2272
+ import { TTileManagerOptions } from '@mappedin/mappedin-js/renderer/layers/Outdoor-Context/Mappedin.TileManager';
2119
2273
  /**
2120
2274
  * @internal
2121
2275
  */
@@ -2149,6 +2303,21 @@ declare module '@mappedin/mappedin-js/renderer' {
2149
2303
  * @internal
2150
2304
  */
2151
2305
  export function __useSceneManager(value: boolean): void;
2306
+ export function __enableTileManager(options?: TTileManagerOptions): void;
2307
+ export {
2308
+ /**
2309
+ * @internal
2310
+ */
2311
+ AzureOutdoorContextProvider,
2312
+ /**
2313
+ * @internal
2314
+ */
2315
+ OpenStreetMapOutdoorContext } from './layers/Outdoor-Context/Outdoor-Context.provider';
2316
+ export type {
2317
+ /**
2318
+ * @internal
2319
+ */
2320
+ IOutdoorContextProvider } from './layers/Outdoor-Context/Outdoor-Context.provider';
2152
2321
  }
2153
2322
 
2154
2323
  declare module '@mappedin/mappedin-js/get-venue/Mappedin.types' {
@@ -3230,7 +3399,7 @@ declare module '@mappedin/mappedin-js/get-venue/MappedinNavigatable' {
3230
3399
  import type { MappedinPolygon } from '@mappedin/mappedin-js/get-venue/MappedinPolygon';
3231
3400
  import type { MappedinNode } from '@mappedin/mappedin-js/get-venue/MappedinNode';
3232
3401
  import { MappedinDestinationSet } from '@mappedin/mappedin-js/get-venue/MappedinDestinationSet';
3233
- import type { Mappedin } from '@mappedin/mappedin-js/get-venue/Mappedin';
3402
+ import { Mappedin } from '@mappedin/mappedin-js/get-venue/Mappedin';
3234
3403
  import { MappedinDirections } from '@mappedin/mappedin-js/get-venue/MappedinDirections';
3235
3404
  export type TDirectionToOptions = {
3236
3405
  accessible?: boolean;
@@ -3253,7 +3422,7 @@ declare module '@mappedin/mappedin-js/get-venue/MappedinNavigatable' {
3253
3422
  }
3254
3423
 
3255
3424
  declare module '@mappedin/mappedin-js/get-venue/Mappedin.CustomerAnalytics' {
3256
- import { MappedinCategory, MappedinLocation } from '@mappedin/mappedin-js/get-venue';
3425
+ import { MappedinCategory, MappedinLocation, MappedinNavigatable } from '@mappedin/mappedin-js/get-venue';
3257
3426
  type AnalyticsOptions = {
3258
3427
  clientId?: string;
3259
3428
  clientSecret?: string;
@@ -3267,7 +3436,12 @@ declare module '@mappedin/mappedin-js/get-venue/Mappedin.CustomerAnalytics' {
3267
3436
  interface IAnalytics {
3268
3437
  locationSelected(location: MappedinLocation): void;
3269
3438
  categorySelected(category: MappedinCategory): void;
3270
- getDirections(start: MappedinLocation, end: MappedinLocation): void;
3439
+ /**
3440
+ * @hidden
3441
+ * @internal
3442
+ * @deprecated
3443
+ */
3444
+ getDirections(start: MappedinNavigatable, end: MappedinNavigatable): void;
3271
3445
  }
3272
3446
  interface IInternalAnalytics extends IAnalytics {
3273
3447
  track(target: string, query: any): void;
@@ -3884,15 +4058,10 @@ declare module '@mappedin/mappedin-js/renderer/internal/pub-sub' {
3884
4058
  }
3885
4059
 
3886
4060
  declare module '@mappedin/mappedin-js/renderer/Core.interface' {
3887
- import { MappedinMap, Mappedin, MappedinCoordinate, MappedinPolygon, MappedinNode } from '@mappedin/mappedin-js/get-venue';
3888
- import { Vector2, Vector3 } from 'three';
3889
- import { changeListenerFn, TMapViewOptions } from '@mappedin/mappedin-js/renderer/MapView.types';
3890
- import RENDER from '@mappedin/mappedin-js/renderer/internal/Mappedin.RenderTasks';
3891
- import { INTERNAL_EVENT_PAYLOAD } from '@mappedin/mappedin-js/renderer/MapView';
4061
+ import { MappedinPolygon, MappedinNode } from '@mappedin/mappedin-js/get-venue';
3892
4062
  import { TPadding } from '@mappedin/mappedin-js/renderer';
3893
- import Tween, { Easing } from '@tweenjs/tween.js';
3894
- import { TaskScheduler } from '@mappedin/mappedin-js/get-venue/Mappedin.TaskScheduler';
3895
- import SceneManager from '@mappedin/mappedin-js/renderer/MapView.SceneManager';
4063
+ import { Easing } from '@tweenjs/tween.js';
4064
+ import Core from '@mappedin/mappedin-js/renderer/Core';
3896
4065
  export type TFocusOptionsLegacy = {
3897
4066
  /**
3898
4067
  * An array of Nodes to focus in on
@@ -3937,186 +4106,7 @@ declare module '@mappedin/mappedin-js/renderer/Core.interface' {
3937
4106
  points?: any[];
3938
4107
  callback: () => void;
3939
4108
  };
3940
- export interface ICore {
3941
- new (container: HTMLElement, venue: Mappedin, options?: TMapViewOptions): ICore;
3942
- /**
3943
- * @internal
3944
- */
3945
- currentScale: number;
3946
- /**
3947
- * @internal
3948
- */
3949
- USE_SCENE_MANAGER: boolean;
3950
- referenceMap: MappedinMap;
3951
- taskScheduler: TaskScheduler;
3952
- sceneManager: SceneManager;
3953
- loadOptions?: TMapViewOptions['loadOptions'];
3954
- imageFlippingEnabled: boolean;
3955
- imageFlippingCache: any;
3956
- cachedPadding: any;
3957
- getCameraFrameForPoints: any;
3958
- polygonMeshesById: any;
3959
- textLabelsByPolygonId: any;
3960
- renderer: any;
3961
- scene: any;
3962
- cameraParameters: Vector2;
3963
- resolution: Vector2;
3964
- determineNewLabelSize: any;
3965
- on<EVENT_NAME extends keyof INTERNAL_EVENT_PAYLOAD>(eventName: EVENT_NAME, fn: changeListenerFn<INTERNAL_EVENT_PAYLOAD[EVENT_NAME]>): void;
3966
- off<EVENT_NAME extends keyof INTERNAL_EVENT_PAYLOAD>(eventName: EVENT_NAME, fn: changeListenerFn<INTERNAL_EVENT_PAYLOAD[EVENT_NAME]>): void;
3967
- publish<EVENT_NAME extends keyof INTERNAL_EVENT_PAYLOAD>(eventName: EVENT_NAME, payload?: INTERNAL_EVENT_PAYLOAD[EVENT_NAME]): void;
3968
- /**
3969
- * Manual camera controls for MapView. Generally you should be using the functions on MapView like {{#crossLink "MapView/focusOn:method"}}{{/crossLink}},
3970
- * but if you have some cool animations in mind, you can do it with the {{#crossLink "CameraControls"}}{{/crossLink}}.
3971
- * Some of the functions don't do anything in 2D.
3972
- *
3973
- */
3974
- controls: any;
3975
- /**
3976
- * The Venue data this MapView is using.
3977
- *
3978
- * @property venue {MappedinVenue}
3979
- * @final
3980
- */
3981
- readonly venue: Mappedin;
3982
- /**
3983
- * The div MapView is using.
3984
- *
3985
- * @property container {Div}
3986
- * @final
3987
- */
3988
- readonly container: HTMLElement;
3989
- /**
3990
- * The ID of the Map currently being displayed.
3991
- *
3992
- */
3993
- readonly currentMap: string;
3994
- /**
3995
- * Change this factor to influence how much the camera zooms in on a {@link IMapView3D.focusOn} call.
3996
- *
3997
- * @property focusZoomFactor {Integer}
3998
- * @default 3
3999
- */
4000
- focusZoomFactor: number;
4001
- /**
4002
- * Returns the value you should call {@link CameraControls.setZoom} on to fit the Polygon exactly.
4003
- *
4004
- * @return The zoom level that will fit the Polygon
4005
- */
4006
- getZoomLevelForPolygon(props: {
4007
- /**
4008
- * The Polygon or Polygon ID to get the zoom level for
4009
- */
4010
- polygonOrPolygonId: MappedinPolygon | string;
4011
- }): number;
4012
- /**
4013
- * Returns the value you should call {@link CameraControls.setZoom} on to fit the {@link IMapView3D.currentMap} exactly.
4014
- *
4015
- * @return The zoom level that will fit the {@link IMapView3D.currentMap}.
4016
- */
4017
- getZoomLevelForCurrentMap(): number;
4018
- /**
4019
- * Returns the angle that points to north, in radians, from the default orientation.
4020
- *
4021
- * @return The angle to north from the default orientation, in radians.
4022
- */
4023
- getNorth(): number;
4024
- /**
4025
- * Takes an element on the DOM and rotates it such that the top is pointing north. It will rotate with the camera, staying locked
4026
- * on north. If you would like to align it do a different direction, or a different side of the element, pass in an offset. This
4027
- * is how you would do a compass rose.
4028
- *
4029
- * This will modify your element's transform.
4030
- *
4031
- * @param element The element on the page to rotate.
4032
- * @param offset The amount to offset the rotation by, in radians.
4033
- *
4034
- */
4035
- lockNorth(element: HTMLElement, offset?: number): void;
4036
- /**
4037
- * Stops the MapView from trying to rotate your element with the camera. Do this if you remove the element, or want to stop it from rotating.
4038
- * @param element The node to stop rotating. It won't reset the transform, just leave it as is.
4039
- */
4040
- unlockNorth(element: HTMLElement): void;
4041
- currentInteractionEvent: string;
4042
- interactivePolygons: any;
4043
- highlightedPolygons: any;
4044
- cameraPlane: any;
4045
- /**
4046
- * Called any time a user touches or clicks the map. Only fires on "single" touches/clicks.
4047
- *
4048
- * @param position Object containing the latitude & longitude of the location touched on the map
4049
- * @param polygons Array of polygon IDs that were touched, in order of front to back.
4050
- * @param nearBlueDot Whether the touch was close enough to the Blue Dot to be considered a touch on the Blue Dot.
4051
- */
4052
- onMapClicked(position: {
4053
- latitude: number;
4054
- longitude: number;
4055
- }, polygons: string[], maps: MappedinMap[], nearBlueDot: boolean): void;
4056
- /**
4057
- * This is called when an interactive Polygon is clicked on.
4058
- * You will almost certainly want to replace this with your own function in your client app.
4059
- * Return "false" if you have consumed the event and it shouldn't bubble down to other Polygons beneath this one.
4060
- *
4061
- * @param polygonId polygonId passed in when tapping an interactive polygon
4062
- */
4063
- onPolygonClicked(polygonId: string): boolean | void;
4064
- onMapChanged(map: string): void;
4065
- getPositionLatLon(lat: number, lon: number, map?: MappedinMap | string): Vector3;
4066
- getPositionPolygon(polygon: MappedinPolygon | string): Vector3;
4067
- /**
4068
- * Takes an x/y pair in Mappedin coordinate space and gives you a Vector3 in scene space
4069
- * @param nodeOrCoordinate a node or coordinate
4070
- */
4071
- convertTo3DMapPosition(nodeOrCoordinate: MappedinCoordinate | MappedinNode): Vector3;
4072
- /**
4073
- * Converts a Vector-like object into a MappedinCoordinate for a map.
4074
- * @param position an object with x and y, like a Vector3
4075
- * @param mapClass An optional map; otherwise, the current map will be used.
4076
- */
4077
- convert3DMapPositionToCoordinate(position: {
4078
- x: number;
4079
- y: number;
4080
- }, mapClass?: MappedinMap): MappedinCoordinate;
4081
- /**
4082
- * Converts a 2D x,y screen position into a 3D MappedinCoordinate using projection
4083
- */
4084
- convertScreenCoordinateToMapCoordinate(x: number, y: number, map: MappedinMap): MappedinCoordinate;
4085
- setPadding(padding: {
4086
- top: number;
4087
- left: number;
4088
- bottom: number;
4089
- right: number;
4090
- }): void;
4091
- /**
4092
- * This is fired when the user taps/clicks on the MapView without hitting an interactive Polygon.
4093
- * You will almost certainly want to replace this with your own function in your client app.
4094
- * You would probably use this to clear any Polygon highlighting, in certain situations.
4095
- */
4096
- onNothingClicked(): void;
4097
- smartCollisionEngine: any;
4098
- mapObjects: any;
4099
- /**
4100
- * The scene only renders when something has changed. This should be something a 3rd party developer doesn't need to worry about,
4101
- * but if you are doing something weird, or have your own special tween for something, you will want to call this function.
4102
- * You can call it as often as you want, it just sets a flag that we need to render again, and renders a few frames if we weren't already doing that.
4103
- * Ignored in 2D.
4104
- */
4105
- tryRendering(renderMode?: typeof RENDER): void;
4106
- setMap(mapOrMapId: MappedinMap | string): Promise<null>;
4107
- getPositionNode(node: MappedinNode): Vector3;
4108
- cameraObject: any;
4109
- setBackgroundColor(color: string, alpha?: number): void;
4110
- mapManager: any;
4111
- focusOn(focusOptions: TFocusOptionsLegacy): Tween;
4112
- canvasWidth: number;
4113
- canvasHeight: number;
4114
- /**
4115
- * Resets the MapView to the default state.
4116
- */
4117
- resetState(): void;
4118
- destroy(): void;
4119
- }
4109
+ export type ICore = Core;
4120
4110
  }
4121
4111
 
4122
4112
  declare module '@mappedin/mappedin-js/renderer/internal/blue-dot-manager' {
@@ -4261,7 +4251,7 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.FloatingLabel'
4261
4251
  }
4262
4252
  export type TFloatingLabelAppearance = {
4263
4253
  /**
4264
- * Margin around the label and marker. This will affect label density
4254
+ * Margin around the label and marker. This will affect label density, with a mininum of 7px around
4265
4255
  * @default 6
4266
4256
  */
4267
4257
  margin?: number;
@@ -4319,6 +4309,10 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.FloatingLabel'
4319
4309
  */
4320
4310
  inactive?: string;
4321
4311
  };
4312
+ /**
4313
+ * Size of bounding box of SVG icon
4314
+ */
4315
+ iconSize?: number;
4322
4316
  /**
4323
4317
  * SVG of icon to place inside Floating Label
4324
4318
  */
@@ -4352,6 +4346,7 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.FloatingLabel'
4352
4346
  active: string;
4353
4347
  inactive: string;
4354
4348
  };
4349
+ iconSize?: number;
4355
4350
  icon?: string;
4356
4351
  iconVisibilityThreshold?: number;
4357
4352
  };
@@ -4416,6 +4411,7 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.FloatingLabel'
4416
4411
  static imagePromiseCache: {
4417
4412
  [key in number]?: Promise<HTMLImageElement>;
4418
4413
  };
4414
+ get pinCanvasSize(): number;
4419
4415
  draw(context: CanvasRenderingContext2D): void;
4420
4416
  }
4421
4417
  export default FloatingLabel;
@@ -4455,8 +4451,8 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.HTMLCollider' {
4455
4451
 
4456
4452
  declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollider' {
4457
4453
  import SmartCollisionEngine from '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollisionEngine';
4458
- import { Vector3 } from 'three';
4459
4454
  import { Rectangle } from '@mappedin/mappedin-js/renderer/internal/quad-tree';
4455
+ import { MappedinCoordinate, MappedinNode } from '@mappedin/mappedin-js/renderer/index.rn';
4460
4456
  export type TRange = [number, number, number, number];
4461
4457
  type TCustomCollider<T> = ICollider & T;
4462
4458
  export type TColliderStrategyProps = {
@@ -4483,6 +4479,10 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollider'
4483
4479
  'show' = 1,
4484
4480
  'hide' = 2
4485
4481
  }
4482
+ export type TColliderPosition = {
4483
+ nodeOrCoordinate: MappedinNode | MappedinCoordinate;
4484
+ height?: number;
4485
+ };
4486
4486
  export interface ICollider {
4487
4487
  dimensions: TDimensions;
4488
4488
  screenPosition: [number, number];
@@ -4501,7 +4501,7 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollider'
4501
4501
  offscreen?: boolean;
4502
4502
  setAction: (action: EColliderAction) => void;
4503
4503
  action?: EColliderAction;
4504
- position: Vector3;
4504
+ position: TColliderPosition;
4505
4505
  __engine?: SmartCollisionEngine;
4506
4506
  enable: () => void;
4507
4507
  disable: () => void;
@@ -4770,6 +4770,98 @@ declare module '@mappedin/mappedin-js/renderer/layers/Labels/FloatingLabelContro
4770
4770
  export default FloatingLabelController;
4771
4771
  }
4772
4772
 
4773
+ declare module '@mappedin/mappedin-js/renderer/index.rn' {
4774
+ import { getVenue, getVenueBundle, Mappedin, MappedinDestinationSet } from '@mappedin/mappedin-js/get-venue';
4775
+ import { randomId } from '@mappedin/mappedin-js/--/common/random-id';
4776
+ export * from '@mappedin/mappedin-js/renderer/MapView.enums';
4777
+ export { getVenue,
4778
+ /**
4779
+ * @deprecated
4780
+ */
4781
+ getVenueBundle, MappedinDestinationSet, Mappedin, randomId };
4782
+ export { GEOLOCATION_STATUS, COLLISION_RANKING_TIERS, E_BLUEDOT_STATE_REASON, E_BLUEDOT_STATE, E_BLUEDOT_MARKER_STATE, STATE, MARKER_ANCHOR, E_SDK_EVENT, E_BLUEDOT_EVENT, E_CAMERA_EVENT, E_CAMERA_DIRECTION, SAFE_AREA_INSET_TYPE, ANIMATION_TWEENS, CAMERA_EASING_MODE } from '@mappedin/mappedin-js/renderer/MapView.enums';
4783
+ export { labelThemes } from '@mappedin/mappedin-js/renderer/MapView.types';
4784
+ export type { IFlatLabels } from '@mappedin/mappedin-js/renderer/MapView.FlatLabels';
4785
+ export type { IFloatingLabels } from '@mappedin/mappedin-js/renderer/MapView.FloatingLabels';
4786
+ export type { TBlueDotPositionUpdate, TBlueDotStateChange, TJourneyOptions, TMapViewOptions, TCreateMarkerOptions, TGeolocationObject, TPathOptions, TFlatLabelOptions, TAddFloatingLabelOptions, TAddFlatLabelOptions, TLabelAllLocationCommonOptions, TFloatingLabelAllLocationsOptions, TFlatLabelAllLocationsOptions, TLabelAllLocationFlatLabelOptions, TLabelAllLocationFloatingLabelOptions, TEnableBlueDotOptions, TFloatingLabelAppearance, TFlatLabelAppearance, CAMERA_EVENT_PAYLOAD, TMapClickEvent, TGetPolygonsAtCoordinateOptions } from '@mappedin/mappedin-js/renderer/MapView.types';
4787
+ export { BEARING_TYPE, ACTION_TYPE } from '@mappedin/mappedin-js/navigator';
4788
+ export type { IDirectionsResult, E_MESSAGES as E_GET_DIRECTIONS_MESSAGES } from '@mappedin/mappedin-js/navigator';
4789
+ export type { TGetVenueBundleOptions, TGetVenueOptions, TMappedinDirective, TShowVenueOptions, TMappedinOfflineSearchOptions, TMappedinOfflineSearchResult, TMappedinOfflineSearchSuggestions, TMappedinOfflineSearchAllOptions, TMappedinOfflineAllSearchMatch } from '@mappedin/mappedin-js/get-venue';
4790
+ export { MappedinLocation, MappedinPolygon, MappedinNode, MappedinCategory, MappedinMap, MappedinEvent, MappedinMapGroup, MappedinVenue, MappedinVortex, MappedinDirections, MappedinNavigatable, MappedinCoordinate, MappedinRankings, MAP_RENDER_MODE, OfflineSearch, MappedinCollectionType } from '@mappedin/mappedin-js/get-venue';
4791
+ export type { TSafeAreaInsets, TCameraTargets, TFocusOnCameraOptions, TCameraTransform, TCameraAnimationOptions } from '@mappedin/mappedin-js/renderer/Camera';
4792
+ }
4793
+
4794
+ declare module '@mappedin/mappedin-js/renderer/internal/object3D.destroy' {
4795
+ export default Object3D;
4796
+ }
4797
+
4798
+ declare module '@mappedin/mappedin-js/renderer/layers/Outdoor-Context/Mappedin.Tile' {
4799
+ import { Texture, Mesh, MeshBasicMaterial } from 'three';
4800
+ import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
4801
+ import { MappedinCoordinate, MappedinMap } from '@mappedin/mappedin-js/renderer/index.rn';
4802
+ import { TileManager } from '@mappedin/mappedin-js/renderer/layers/Outdoor-Context/Mappedin.TileManager';
4803
+ export class Tile {
4804
+ #private;
4805
+ center: MappedinCoordinate;
4806
+ zoomLevel: number;
4807
+ mesh: Mesh;
4808
+ material: MeshBasicMaterial;
4809
+ texture: Texture;
4810
+ cache: {
4811
+ tileXY?: {
4812
+ tileX: number;
4813
+ tileY: number;
4814
+ };
4815
+ tileBoundingBoxInLatLon?: number[];
4816
+ };
4817
+ get tileXY(): {
4818
+ tileX: number;
4819
+ tileY: number;
4820
+ };
4821
+ get tileBoundingBoxInLatLon(): number[];
4822
+ constructor(center: MappedinCoordinate, zoomLevel: number, tileManager: TileManager, core: ICore, currentAbortController: AbortController);
4823
+ rendered: boolean;
4824
+ discardTexture(): void;
4825
+ applyTexture(): void;
4826
+ render(metersPerTile: number, referenceMap: MappedinMap): any;
4827
+ }
4828
+ }
4829
+
4830
+ declare module '@mappedin/mappedin-js/renderer/layers/Outdoor-Context/Outdoor-Context.provider' {
4831
+ export interface IOutdoorContextProvider {
4832
+ fetchTile(tileX: number, tileY: number, zoom: number, signal: AbortSignal): Promise<Response>;
4833
+ fetchAttribution?(zoomLevel: number, bounds: [number, number, number, number]): Promise<Response>;
4834
+ }
4835
+ export class AzureOutdoorContextProvider implements IOutdoorContextProvider {
4836
+ lang: string;
4837
+ apiKey?: string;
4838
+ token?: string;
4839
+ tileSize: number;
4840
+ tilesetId: string;
4841
+ constructor(lang?: string, tileSize?: 256 | 512, apiKey?: string, token?: string);
4842
+ makeURL(x: number, y: number, zoom: number): string;
4843
+ /**
4844
+ * Fetch attribution for the current tiles
4845
+ * format: [SouthwestCorner_Longitude, SouthwestCorner_Latitude, NortheastCorner_Longitude, NortheastCorner_Latitude]
4846
+ */
4847
+ fetchAttribution(zoomLevel: number, bounds: [number, number, number, number]): Promise<Response>;
4848
+ fetchTile(tileX: number, tileY: number, zoom: number, signal: AbortSignal): Promise<Response>;
4849
+ }
4850
+ export class GoogleOutdoorContextProvider implements IOutdoorContextProvider {
4851
+ apiKey: string;
4852
+ sessionToken: string;
4853
+ lang: string;
4854
+ constructor(lang: string | undefined, apiKey: string);
4855
+ makeURL(x: number, y: number, zoom: number): string;
4856
+ fetchSessionToken(): Promise<void>;
4857
+ fetchTile(tileX: number, tileY: number, zoom: number, signal: any): Promise<Response>;
4858
+ }
4859
+ export class OpenStreetMapOutdoorContext implements IOutdoorContextProvider {
4860
+ makeURL(x: number, y: number, z: number): string;
4861
+ fetchTile(tileX: number, tileY: number, zoom: number, signal: any): Promise<Response>;
4862
+ }
4863
+ }
4864
+
4773
4865
  declare module '@mappedin/mappedin-js/renderer/layers/EventSystem' {
4774
4866
  import { Object3D, Color } from 'three';
4775
4867
  import { MapView } from '@mappedin/mappedin-js/renderer';
@@ -4780,7 +4872,7 @@ declare module '@mappedin/mappedin-js/renderer/layers/EventSystem' {
4780
4872
  core: ICore;
4781
4873
  blueDotManager?: BlueDotManager;
4782
4874
  rendererDomElement: any;
4783
- currentHover: null;
4875
+ currentHover: string | null;
4784
4876
  hoverLabel: any;
4785
4877
  hoverColor: Color;
4786
4878
  options: {
@@ -4822,7 +4914,7 @@ declare module '@mappedin/mappedin-js/renderer/layers/EventSystem' {
4822
4914
  hasTouched: boolean;
4823
4915
  calculateMouseCoordinates: (event: any) => void;
4824
4916
  getMouseRayIntersects: (objects: Object3D | Object3D[]) => any;
4825
- detectPolygonsUnderMouse: () => any[];
4917
+ detectPolygonsUnderMouse: () => string[];
4826
4918
  detectMapsUnderMouse: () => any;
4827
4919
  getMouseMapPosition: () => {
4828
4920
  x: number;
@@ -4867,7 +4959,7 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.Journey' {
4867
4959
  constructor(directions: MappedinDirections | MappedinDirections[], options: TJourneyOptions | undefined, mapView: MapView, core: ICore);
4868
4960
  setStep: (step: any) => void;
4869
4961
  static instance: Journey | null;
4870
- static create(directions: MappedinDirections | MappedinDirections[], options: any, mapView: MapView, mapManager: any): Journey;
4962
+ static create(directions: MappedinDirections | MappedinDirections[], options: any, mapView: MapView, core: ICore): Journey;
4871
4963
  destroy(): void;
4872
4964
  }
4873
4965
  }
@@ -5146,423 +5238,1415 @@ declare module '@mappedin/mappedin-js/get-venue/MappedinTheme' {
5146
5238
  }
5147
5239
  }
5148
5240
 
5149
- declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.RenderTasks' {
5150
- export default RENDER;
5151
- namespace RENDER {
5152
- const ANIMATED: string;
5153
- const ALWAYS_ON_TOP: string;
5154
- const ALL: string;
5155
- const TWEEN: string;
5156
- }
5157
- }
5158
-
5159
- declare module '@mappedin/mappedin-js/get-venue/Mappedin.TaskScheduler' {
5241
+ declare module '@mappedin/mappedin-js/renderer/Core' {
5242
+ import './internal/externals/globalThisPolyfill';
5243
+ import { Mesh, PerspectiveCamera, Scene, Vector2 } from 'three';
5244
+ import './internal/object3D.destroy';
5245
+ import Renderer from '@mappedin/mappedin-js/renderer/internal/Mappedin.Renderer.js';
5246
+ import { TaskScheduler } from '@mappedin/mappedin-js/get-venue/Mappedin.TaskScheduler';
5247
+ import MapManager from '@mappedin/mappedin-js/renderer/internal/Mappedin.MapManager';
5248
+ import { FlatLabel } from '@mappedin/mappedin-js/renderer/internal/Mappedin.LabelAtlas.js';
5249
+ import SmartCollisionEngine from '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollisionEngine';
5250
+ import { TGetPolygonsAtCoordinateOptions, TMapViewOptions } from '@mappedin/mappedin-js/renderer/MapView.types';
5251
+ import { Mappedin as IMappedin, MappedinCoordinate, MappedinMap, MappedinNode } from '@mappedin/mappedin-js/get-venue';
5252
+ import { PubSub } from '@mappedin/mappedin-js/renderer/internal/pub-sub.typed';
5253
+ import { INTERNAL_EVENT, INTERNAL_EVENT_PAYLOAD, MapView } from '@mappedin/mappedin-js/renderer/MapView';
5254
+ import { TPadding } from '@mappedin/mappedin-js/renderer';
5255
+ import MapObject from '@mappedin/mappedin-js/renderer/internal/Mappedin.MapObject';
5256
+ import SceneManager from '@mappedin/mappedin-js/renderer/MapView.SceneManager';
5257
+ export const raycaster: any;
5258
+ let Mappedin: any;
5160
5259
  /**
5161
- * A function that can be submitted to the Task Scheduler to run each frame for
5162
- * some provided number of frames. A single update can be repeatedly submitted;
5163
- * if the number of frames left on the update is less than `frameCount`, it will
5164
- * be reset to `frameCount`.
5165
- *
5166
- * @class FrameUpdate
5167
- * @private
5260
+ * Some preset orderings for updates.
5168
5261
  */
5169
- export class FrameUpdate {
5262
+ export const UPDATE_ORDERING: {
5263
+ BEFORE_CAMERA: number;
5264
+ CAMERA: number;
5265
+ AFTER_CAMERA: number;
5266
+ RENDER: number;
5267
+ AFTER_RENDER: number;
5268
+ AFTER_ALL_UPDATES: number;
5269
+ };
5270
+ type TCoreColors = {
5271
+ defaultHover2D: string;
5272
+ select: string;
5273
+ text: string;
5274
+ path: string;
5275
+ pathPulse: string;
5276
+ textSelect: string;
5277
+ };
5278
+ class Core extends PubSub<INTERNAL_EVENT_PAYLOAD, INTERNAL_EVENT> {
5279
+ #private;
5280
+ static USE_SCENE_MANAGER: boolean;
5281
+ imageFlippingCache: {};
5282
+ imageFlippingEnabled: boolean;
5283
+ MapView: MapView;
5284
+ type: string;
5285
+ container: HTMLDivElement;
5286
+ venue: IMappedin;
5287
+ colors: TCoreColors;
5288
+ loadOptions: TMapViewOptions['loadOptions'];
5289
+ smartCollisionEngine: SmartCollisionEngine;
5290
+ taskScheduler: TaskScheduler;
5291
+ renderer: Renderer;
5292
+ highlightedPolygons: Record<string, string>;
5293
+ scene: Scene;
5294
+ focusZoomFactor: number;
5295
+ cameraObject: PerspectiveCamera;
5296
+ polygonMeshesById: Record<string, Mesh>;
5297
+ textLabelsByPolygonId: Record<string, FlatLabel>;
5298
+ labelOrientationDelay: number;
5299
+ interactivePolygons: Record<string, boolean>;
5300
+ mapManager: MapManager | undefined;
5301
+ sceneManager: SceneManager | undefined;
5302
+ mapObjects: Map<MappedinMap['id'], MapObject>;
5303
+ referenceMap: MappedinMap;
5304
+ currentInteractionEvent: INTERNAL_EVENT | undefined;
5305
+ resolution: Vector2;
5306
+ cameraParameters: Vector2;
5307
+ controls: typeof Mappedin.CameraControls;
5308
+ cameraPlane: Mesh;
5309
+ canvasWidth: number;
5310
+ canvasHeight: number;
5311
+ cachedPadding: TPadding;
5312
+ currentScale: number;
5313
+ rendererDomElement: HTMLCanvasElement;
5314
+ resolutionScale: number;
5315
+ constructor(container: HTMLDivElement, venue: IMappedin, options: (TMapViewOptions & {
5316
+ onDataLoaded?: ((data: IMappedin) => void) | undefined;
5317
+ onFirstMapLoaded?: ((data: IMappedin) => void) | undefined;
5318
+ }) | undefined, MapView: MapView);
5319
+ get currentMap(): string | null;
5320
+ getPolygon: (polygon: any) => any;
5321
+ showEntireMap: (options: any) => any;
5322
+ resetPanBounds: () => void;
5323
+ focusOn: (options: any) => any;
5324
+ focusOnPolygon: (polygon: any, changeZoom: any, duration: any, curve: any) => any;
5325
+ focusOnPath: (path: any, polygons: any, changeZoom: any, duration: any, curve: any) => any;
5326
+ getCameraFrameForPoints: (pointCloud: any, horizontalFovFactor: any, verticalFovFactor: any, padding: any, ignoreZoom: any) => {
5327
+ position: any;
5328
+ zoom: any;
5329
+ };
5330
+ setPadding: (padding?: TPadding | undefined) => void;
5331
+ getZoomLevelForPolygon: (polygon: any) => any;
5332
+ getZoomLevelForCurrentMap: () => any;
5333
+ getZoomLevelForObject: (object: any) => any;
5334
+ resetCamera: (forceOrigin?: boolean) => void;
5170
5335
  /**
5171
- * Create a new frame update that can be submitted to a scheduler.
5172
- * @constructor
5173
- * @param [options] {Object} Options for the update
5174
- * @param [options.callback] {function}
5175
- * The actual function to run every time this update is scheduled for
5176
- * a frame.
5177
- * @param [options.frameCount=1] {number}
5178
- * How many frames this update should run for when it's submitted to
5179
- * a scheduler
5180
- * @param [options.ordering=0] {number}
5181
- * An ordering value that's used to determine the order in which
5182
- * frame updates will be run within a frame; larger numbers will
5183
- * be run first
5184
- * @param [options.supersededBy=[]] {[FrameUpdate]}
5185
- * If this update is scheduled to run in a frame, but another update in
5186
- * the provided list is also scheduled to run on that frame, then
5187
- * this update will not be run.
5188
- * @param [options.name=undefined] {string}
5189
- * If provided, an arbitrary name for logging purposes.
5190
- * @param [options.userdata] {Any}
5191
- * Arbitrary data that you can store along with this update.
5192
- */
5193
- constructor(options: {
5194
- callback: Function;
5195
- frameCount?: number;
5196
- ordering?: number;
5197
- supersededBy?: Set<never>;
5198
- name: string;
5199
- userdata?: Record<string, any>;
5200
- });
5201
- _callback: Function;
5202
- _frameCount: number;
5203
- _ordering: number;
5204
- _supersededBy: Set<never>;
5205
- name: string;
5206
- _remainingFrameCount: number;
5207
- _lastFrameTime: number;
5208
- userdata?: Record<string, any>;
5209
- /**
5210
- * Return the amount of time that this frame update took to execute during
5211
- * its most recent execution, in milliseconds. If called during this frame
5212
- * update, the value returned will be for the previous invocation. If called
5213
- * before this frame update has been executed at least once, the returned
5214
- * value is unspecified.
5215
- *
5216
- * @method lastFrameTime
5217
- * @return {number} the previous frame time, in milliseconds
5218
- */
5219
- getLastFrameTime(): number;
5220
- }
5221
- /**
5222
- * A task that can be submitted to the Task Scheduler to be run every time
5223
- * there is a frame update with spare time in the frame.
5224
- *
5225
- * @class FrameTask
5226
- * @private
5227
- */
5228
- export class FrameTask {
5229
- /**
5230
- * Create a new frame task that can be submitted to a scheduler.
5231
- * @constructor
5232
- * @param [options] {Object} Options for the task
5233
- * @param [options.callback] {function}
5234
- * The actual function to run when this task is scheduled.
5235
- * @param [options.group=null] {FrameTaskGroup}
5236
- * If provided, a group to which this task will be added when scheduled
5237
- * @param [options.priority=0] {number}
5238
- * Tasks with higher priority will be taken from the queue before tasks
5239
- * with a lower priority.
5240
- * @param [options.postponeOnAdd=false] {number}
5241
- * If true, this task will not be run until `resumeTask` is called on the
5242
- * scheduler.
5243
- * @param [options.name=undefined] {string}
5244
- * If provided, an arbitrary name for logging purposes.
5245
- * @param [options.userdata] {Any}
5246
- * Arbitrary data that you can store along with this task.
5247
- */
5248
- constructor(options: {
5249
- userdata: Record<string, any>;
5250
- priority: number;
5251
- group?: FrameTaskGroup;
5252
- postponeOnAdd: number | boolean;
5253
- name: string;
5254
- lastFrameTime: number;
5255
- callback: Function;
5256
- });
5257
- _postponed: number | boolean;
5258
- userdata: Record<string, any>;
5259
- _priority: number;
5260
- _group: FrameTaskGroup | null;
5261
- name: string;
5262
- _lastFrameTime: number;
5263
- _callback: Function;
5264
- _complete: boolean;
5265
- _scheduled: boolean;
5266
- _cancelled: boolean;
5267
- /**
5268
- * Return true if this task has been run at least once.
5269
- *
5270
- * @method isComplete
5271
- * @return {boolean}
5272
- */
5273
- isComplete(): boolean;
5274
- /**
5275
- * Return the amount of time that this frame task took to execute,
5276
- * in milliseconds. If this task has not yet completed, the returned value
5277
- * is unspecified.
5336
+ * Gets a position (to anchor a {{#crossLink "Marker"}}{{/crossLink}} usually) from a latitude and longitude.
5278
5337
  *
5279
- * @method lastFrameTime
5280
- * @return {number} the frame time, in milliseconds
5338
+ * @method getPositionLatLon
5339
+ * @param latitude {Number} Latitude of position
5340
+ * @param longitude {Number} Longitude of position
5341
+ * @returns A position you can use with a Marker either initially or to update later when the user (for example) moves
5281
5342
  */
5282
- getLastFrameTime(): number;
5283
- }
5284
- /**
5285
- * A group of tasks that must all be completed before the group is considered
5286
- * complete. The tasks will be automatically garbage collected so that references
5287
- * to the task don't linger.
5288
- *
5289
- * @class FrameTaskGroup
5290
- * @private
5291
- */
5292
- export class FrameTaskGroup {
5343
+ getPositionLatLon: (lat: number, lon: number, mapId?: string | null | undefined) => any;
5344
+ lockNorth: (element: any, offset?: number) => void;
5345
+ unlockNorth: (element: any) => void;
5346
+ convertTo3DMapPosition: (nodeOrCoordinate: MappedinNode | MappedinCoordinate) => any;
5293
5347
  /**
5294
- * Create a new frame task group.
5295
- *
5296
- * @constructor
5297
- * @param [options] {Object} Options for the task group
5298
- * @param [options.onComplete] {function}
5299
- * A callback that will be triggered once every task in this group
5300
- * has been completed. This callback may schedule a task, and the
5301
- * scheduler will run that task in the same frame, if there is still
5302
- * frame time for it.
5303
- * @param [options.priority=0] {number}
5304
- * The priority of all the tasks in this group.
5305
- * @param [options.postponeOnAdd=false] {number}
5306
- * If true, tasks from this task group will not be run until `resumeTask`
5307
- * is called on the scheduler with this group.
5308
- * @param [options.name=undefined] {string}
5309
- * If provided, an arbitrary name for logging purposes.
5310
- * @param [options.userdata] {Any}
5311
- * Arbitrary data that you can store along with this task group.
5348
+ * Converts a 2D x,y screen position into a 3D MappedinCoordinate using projection
5312
5349
  */
5313
- constructor(options: {
5314
- onComplete?: Function;
5315
- priority?: number;
5316
- userdata: Record<string, any>;
5317
- postponeOnAdd: number | boolean;
5318
- name: string;
5319
- });
5320
- _postponed: number | boolean;
5321
- _onComplete: Function;
5322
- _priority: number;
5323
- userdata: Record<string, any>;
5324
- name: string;
5325
- _tasks: Set<any>;
5326
- _scheduledTasks: Set<any>;
5327
- _scheduled: boolean;
5328
- _cancelled: boolean;
5350
+ convertScreenCoordinateToMapCoordinate: (x: number, y: number, map: MappedinMap) => any;
5351
+ convert3DMapPositionToCoordinate: (coord: any, mapClass?: MappedinMap | null | undefined) => any;
5352
+ getPositionPolygon: (polygon: any) => any;
5353
+ getPositionNode: (node: any) => any;
5354
+ hideAllLabels: () => void;
5355
+ setBackgroundColor: (color: any, alpha: any) => void;
5356
+ setSize: (width: any, height: any) => void;
5357
+ getMapScale: () => number;
5358
+ getNorth: () => number;
5329
5359
  /**
5330
- * Return true if every task in this group has been run at least once.
5331
- * @method isComplete
5332
- * @return {boolean}
5360
+ * The scene only renders when something has changed. This should be something a 3rd party developer doesn't need to worry about,
5361
+ * but if you are doing something weird, or have your own special tween for something, you will want to call this function.
5362
+ * You can call it as often as you want, it just sets a flag that we need to render again, and renders a few frames if we weren't already doing that.
5363
+ * @method tryRendering
5364
+ * @param [renderMode=RENDER.ALL] {RENDER} Which parts of the scene to re-render
5333
5365
  */
5334
- isComplete(): boolean;
5366
+ tryRendering: (renderMode?: any) => void;
5335
5367
  /**
5336
- * Return a list of tasks in this group. This will be a copy of the
5337
- * underlying task group, so it's safe to mutate the group while
5338
- * iterating over this array.
5368
+ * Display the performance characteristics and debug controls for this
5369
+ * MapView.
5339
5370
  *
5340
- * @method tasks
5341
- * @return {[FrameTask]} list of tasks in this group
5371
+ * @method showDebugUI
5342
5372
  */
5343
- getTasks(): any[];
5373
+ showDebugUI: () => void;
5344
5374
  /**
5345
- * Empty this task group. This will trivially satisfy `isComplete`.
5375
+ * Hide the performance characteristics and debug controls for this
5376
+ * MapView.
5346
5377
  *
5347
- * @method clear
5378
+ * @method hideDebugUI
5348
5379
  */
5349
- clear(): void;
5380
+ hideDebugUI: () => void;
5381
+ determineNewLabelSize: () => void;
5382
+ setMap: (map: string | MappedinMap) => Promise<any>;
5383
+ getPolygonsAtScreenCoordinate: (coordinate: any, hoverableMeshChildren: any[], options?: TGetPolygonsAtCoordinateOptions | undefined) => any;
5384
+ getPolygonsAtCoordinate: (coordinate: MappedinCoordinate, hoverableMeshChildren: any[], options?: TGetPolygonsAtCoordinateOptions | undefined) => any;
5350
5385
  /**
5351
- * Return one arbitrary incomplete task from this group, or undefined if
5352
- * there are none.
5386
+ * Destroys instance and frees resources
5353
5387
  *
5354
- * @method _popTask
5355
- * @return {FrameTask} arbitrary scheduled task
5356
- * @private
5388
+ * @method destroy
5357
5389
  */
5358
- _popTask(): any;
5390
+ destroy: () => void;
5359
5391
  }
5360
- /**
5361
- * A timer for the task scheduler that uses real wall-time to determine if there's
5362
- * enough remaining time in a frame to execute another task.
5363
- *
5364
- * @class RealTimeTimer
5365
- * @private
5366
- */
5367
- export class RealTimeTimer {
5368
- _maxMillisecondsPerFrame: number;
5369
- _time: number;
5370
- /**
5371
- * @constructor
5372
- * @param [options] {Object} Options for the timer
5373
- * @param [options.maxMillisecondsPerFrame]
5374
- * If the time since the beginning of the frame has been less than
5375
- * or equal to this value, then another task may be executed
5376
- */
5377
- constructor(options?: {
5378
- maxMillisecondsPerFrame?: number;
5379
- });
5380
- /**
5381
- * Begin timing a frame.
5382
- *
5383
- * @method beginFrame
5384
- */
5385
- beginFrame(): void;
5386
- /**
5387
- * If true, there is enough time remaining to execute another task.
5388
- *
5389
- * @method hasTimeRemaining
5390
- * @return {boolean}
5391
- */
5392
- hasTimeRemaining(): boolean;
5392
+ export default Core;
5393
+ }
5394
+
5395
+ declare module '@mappedin/mappedin-js/renderer/internal/shave-text' {
5396
+ export type TDrawFn = (ctx: CanvasRenderingContext2D, x: number, y: number) => void;
5397
+ type TShave = (str: string, size: number, maxWidth: number, maxLines?: number, lineHeight?: number, options?: {
5398
+ strokeText: boolean;
5399
+ }) => {
5400
+ maxWidth: number;
5401
+ maxHeight: number;
5402
+ lines: number;
5403
+ draw: TDrawFn;
5404
+ };
5405
+ export const shaveText: TShave;
5406
+ export {};
5407
+ }
5408
+
5409
+ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollisionEngine' {
5410
+ import './Mappedin.SmartCollisionEngine.scss';
5411
+ import { ICollider, TRange, TColliderPosition } from '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollider';
5412
+ import { MappedinMap, MapView } from '@mappedin/mappedin-js/renderer';
5413
+ import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
5414
+ import { Rectangle, QuadTree } from '@mappedin/mappedin-js/renderer/internal/quad-tree';
5415
+ export const COLLIDER_STRATEGY_LOW_PRIORITY = "LOW_PRIORITY";
5416
+ class SmartCollisionEngine {
5417
+ #private;
5418
+ colliderCanvas: HTMLCanvasElement;
5419
+ debugCanvas: HTMLCanvasElement;
5420
+ colliderCanvasContext: CanvasRenderingContext2D;
5421
+ debugCanvasContext: CanvasRenderingContext2D;
5422
+ collisionEngineContainerEl: HTMLDivElement;
5423
+ stepsX: any;
5424
+ stepsY: any;
5425
+ totalWidth: any;
5426
+ totalHeight: any;
5427
+ project: any;
5428
+ colliders: Map<string, ICollider>;
5429
+ offscreenRanges: TRange[];
5430
+ get sortedColliders(): ICollider[];
5431
+ initialized: boolean;
5432
+ mapView: MapView;
5433
+ core: ICore;
5434
+ screen: Rectangle;
5435
+ constructor(mapView: any, core: ICore);
5436
+ beginUpdate(): void;
5437
+ init: (container: HTMLDivElement, projectFn: (position: TColliderPosition, mapId: MappedinMap['id']) => {
5438
+ x: number;
5439
+ y: number;
5440
+ }) => void;
5441
+ qtree: QuadTree;
5442
+ recompute: () => void;
5443
+ draw: () => void;
5444
+ reposition: () => void;
5445
+ add: (colliderId: string, collider: ICollider) => void;
5446
+ remove: (colliderId: string) => void;
5447
+ update: () => void;
5448
+ resize: (container: any) => void;
5449
+ destroy: () => void;
5393
5450
  }
5394
- /**
5395
- * A timer that ticks every time `hasTimeRemaining` is called.
5396
- *
5397
- * @class FixedTimer
5398
- * @private
5399
- */
5400
- export class FixedTimer {
5401
- _ticks: number;
5402
- maxTasksPerFrame: number;
5403
- /**
5404
- * @constructor
5405
- * @param [options] {Object} Options for the timer
5406
- * @param [options.maxTasksPerFrame=5]
5407
- * The number of tasks that will be exceuted in a single update call.
5408
- * Can be modified as the `maxTasksPerFrame` property on this boject.
5409
- */
5410
- constructor(options?: {
5411
- maxTasksPerFrame?: number;
5412
- });
5413
- /**
5414
- * Begin timing a frame.
5415
- *
5416
- * @method beginFrame
5417
- */
5418
- beginFrame(): void;
5419
- /**
5420
- * If true, there is enough time remaining to execute another task.
5421
- *
5422
- * @method hasTimeRemaining
5423
- * @return {boolean}
5424
- */
5425
- hasTimeRemaining(): boolean;
5451
+ export default SmartCollisionEngine;
5452
+ }
5453
+
5454
+ declare module '@mappedin/mappedin-js/renderer/internal/quad-tree' {
5455
+ export function contains(rect1: Rectangle, rect2: Rectangle): boolean;
5456
+ export function intersects(rect1: Rectangle, rect2: Rectangle): boolean;
5457
+ class Rectangle {
5458
+ x: number;
5459
+ y: number;
5460
+ w: number;
5461
+ h: number;
5462
+ userData?: any;
5463
+ constructor(x: number, y: number, w: number, h: number, userData?: any);
5464
+ contains(rectangle: Rectangle): boolean;
5465
+ intersects(rectangle: Rectangle): boolean;
5466
+ draw(context: CanvasRenderingContext2D): void;
5467
+ }
5468
+ class QuadTree {
5469
+ boundary: Rectangle;
5470
+ capacity: number;
5471
+ objects: Rectangle[];
5472
+ topLeft: QuadTree;
5473
+ topRight: QuadTree;
5474
+ bottomLeft: QuadTree;
5475
+ bottomRight: QuadTree;
5476
+ divided: boolean;
5477
+ parent?: QuadTree;
5478
+ getSize(): any;
5479
+ constructor(boundary: Rectangle, parent?: QuadTree);
5480
+ subdivide(): void;
5481
+ query(rectangle: Rectangle): Rectangle[];
5482
+ insert(rectangle: Rectangle): boolean;
5483
+ drawObjects(context: CanvasRenderingContext2D): void;
5484
+ draw(context: CanvasRenderingContext2D): void;
5485
+ }
5486
+ export { QuadTree, Rectangle };
5487
+ }
5488
+
5489
+ declare module '@mappedin/mappedin-js/navigator/Edge' {
5490
+ import INode from '@mappedin/mappedin-js/navigator/interfaces/INode';
5491
+ import IVortex from '@mappedin/mappedin-js/navigator/interfaces/IVortex';
5492
+ class Edge {
5493
+ origin: INode;
5494
+ destination: INode;
5495
+ vortex?: IVortex;
5496
+ distance: number;
5497
+ angle: number;
5498
+ weight: number;
5499
+ constructor({ origin, destination, vortex, elevationDelta, distance, angle }: {
5500
+ origin: INode;
5501
+ destination: INode;
5502
+ vortex?: IVortex;
5503
+ elevationDelta?: number;
5504
+ distance?: number;
5505
+ angle?: number;
5506
+ });
5507
+ }
5508
+ export default Edge;
5509
+ }
5510
+
5511
+ declare module '@mappedin/mappedin-js/navigator/interfaces/IMap' {
5512
+ interface IGeoReference {
5513
+ target: {
5514
+ x: number;
5515
+ y: number;
5516
+ };
5517
+ control: {
5518
+ x: number;
5519
+ y: number;
5520
+ };
5521
+ }
5522
+ interface IMap {
5523
+ id: string;
5524
+ name: string;
5525
+ shortName: string;
5526
+ elevation?: number;
5527
+ scale?: number;
5528
+ x_scale?: number;
5529
+ georeference?: IGeoReference[];
5530
+ [propName: string]: any;
5531
+ }
5532
+ export default IMap;
5533
+ }
5534
+
5535
+ declare module '@mappedin/mappedin-js/navigator/interfaces/INode' {
5536
+ interface INode {
5537
+ id: string;
5538
+ x: number;
5539
+ y: number;
5540
+ map: string;
5541
+ externalId?: string;
5542
+ [propName: string]: any;
5543
+ }
5544
+ export default INode;
5545
+ }
5546
+
5547
+ declare module '@mappedin/mappedin-js/navigator/interfaces/IVortex' {
5548
+ interface IVortex {
5549
+ id: string;
5550
+ name: string;
5551
+ type: string;
5552
+ weight: number;
5553
+ multiplier: number;
5554
+ [propName: string]: any;
5555
+ }
5556
+ export default IVortex;
5557
+ }
5558
+
5559
+ declare module '@mappedin/mappedin-js/navigator/interfaces/ILocation' {
5560
+ interface ILocation {
5561
+ id: string;
5562
+ name: string;
5563
+ [propName: string]: any;
5564
+ }
5565
+ export default ILocation;
5566
+ }
5567
+
5568
+ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.LabelAtlas' {
5569
+ export namespace DEFAULT_LABEL_SIZING {
5570
+ const MARGIN: number;
5571
+ const HEIGHT_MARGIN: number;
5572
+ const SIZE: number;
5573
+ }
5574
+ export class Atlas {
5575
+ layers: any[];
5576
+ canvas: HTMLCanvasElement;
5577
+ context: CanvasRenderingContext2D | null;
5578
+ addLabel(map: any, lines: any, font: any, size: any, scope: any, pixelsPerScale: any): Label | undefined;
5579
+ removeLayer(layer: any): void;
5580
+ measure(text: any, font: any, size: any): TextMetrics;
5581
+ onWebGLContextRestored(): void;
5582
+ dispose(): void;
5583
+ }
5584
+ export class FlatLabel {
5585
+ constructor(options: any, venue: any, mapObject: any, DEFAULT_FONT: any, polygonMeshesById: any, textLabelsByPolygonId: any, mapView: any, scope: any, atlas: any);
5586
+ id: any;
5587
+ text: any;
5588
+ stateText: string;
5589
+ fullText: any;
5590
+ font: any;
5591
+ atlas: any;
5592
+ canvasBounds: any;
5593
+ mapScale: any;
5594
+ margin: number;
5595
+ heightMargin: number;
5596
+ scaleMin: any;
5597
+ scaleStep: any;
5598
+ multiline: any;
5599
+ height: number | null;
5600
+ polygonMeshesById: any;
5601
+ polyId: any;
5602
+ map: any;
5603
+ color: any;
5604
+ hoverColor: any;
5605
+ baseColor: any;
5606
+ hideOnCreate: boolean;
5607
+ hoverLabelText: any;
5608
+ fontSize: number;
5609
+ hoverLabelMode: any;
5610
+ hoverLabelClass: any;
5611
+ showHoverLabel: boolean;
5612
+ hoverIfLabelFails: boolean;
5613
+ textLabelsByPolygonId: any;
5614
+ create(): void;
5615
+ invalid: boolean | undefined;
5616
+ label: any;
5617
+ created: boolean | undefined;
5618
+ flipIfNeeded(cameraAngle: any): void;
5619
+ removeSelf(bulk: any): void;
5620
+ doNotCreate: boolean | undefined;
5621
+ setColor(textColor: any): void;
5622
+ setHoverColor: (color: any) => void;
5623
+ clearColor(): void;
5624
+ hide(): void;
5625
+ show(): void;
5626
+ toString(): any;
5627
+ }
5628
+ class Label {
5629
+ x: number;
5630
+ y: number;
5631
+ width: number;
5632
+ height: number;
5633
+ layer: any;
5634
+ index: any;
5635
+ layout(map: any, origin: any, size: any, rotation: any, uv: any, color: any): void;
5426
5636
  }
5637
+ export {};
5638
+ }
5639
+
5640
+ import { Color, DepthTexture, Mesh, Vector2, NearestFilter, OrthographicCamera, PlaneBufferGeometry, RGBAFormat, Scene, ShaderMaterial, UnsignedIntType, WebGLRenderTarget, WebGL1Renderer, DepthStencilFormat } from 'three';
5641
+ import CAMERA_LAYER from '@mappedin/mappedin-js/renderer/internal/Mappedin.CameraLayers.js';
5642
+ import RENDER from '@mappedin/mappedin-js/renderer/internal/Mappedin.RenderTasks';
5643
+ import CompositeVertexShader from '@mappedin/mappedin-js/renderer/internal/shaders/Mappedin.Composite.Vertex.glsl';
5644
+ import CompositeFragmentShader from '@mappedin/mappedin-js/renderer/internal/shaders/Mappedin.Composite.Fragment.glsl';
5645
+ import Stats from 'stats.js';
5646
+ import Logger from '@mappedin/mappedin-js/--/common/Mappedin.Logger';
5647
+ let SHOW_FPS = false;
5648
+ let stats;
5649
+ if (SHOW_FPS) {
5650
+ stats = new Stats();
5651
+ stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
5652
+ document.body.appendChild(stats.dom);
5653
+ }
5654
+ /**
5655
+ * A class that controls the rendering resources for a canvas output.
5656
+ *
5657
+ * @class Renderer
5658
+ * @private
5659
+ */
5660
+ export default class Renderer {
5661
+ /**
5662
+ * @constructor
5663
+ * @param renderOptions {Object} Options for rendering
5664
+ * @param [options.multiBufferRendering=false] {boolean}
5665
+ * Whether to use a multi-buffer renderer
5666
+ * @param [options.alpha=true] {boolean}
5667
+ * If true, will allow for a semi-transparent background
5668
+ * @param [options.antialias=false] {boolean}
5669
+ * If true, will attempt to antialias rendering if supported
5670
+ * @param [options.backgroundColor='#ffffff'] {Color | string}
5671
+ * The color that will be displayed behind the scene
5672
+ * @param [options.backgroundAlpha=1.0] {number}
5673
+ * The opacity of the background color
5674
+ * @param [options.onWebGLContextCreationError=null] {function}
5675
+ * A callback that will be triggered if WebGL context creation fails
5676
+ * @param [options.onWebGLContextLost=null] {function}
5677
+ * A callback that will be triggered if the WebGL context is killed
5678
+ * @param [options.onWebGLContextRestored=null] {function}
5679
+ * A callback that will be triggered when three.js reacquires a WebGL context
5680
+ * @param [options.onWebGLRendererError=null] {function}
5681
+ * A callback that will be triggered if the renderer throws an error
5682
+ */
5683
+ constructor(renderOptions) {
5684
+ renderOptions.multiBufferRendering =
5685
+ renderOptions.multiBufferRendering || false;
5686
+ this.contextLost = false;
5687
+ this.implementation = renderOptions.multiBufferRendering
5688
+ ? new MultiBufferRenderer(renderOptions)
5689
+ : new SingleBufferRenderer(renderOptions);
5690
+ this.onWebGLContextCreationError =
5691
+ renderOptions.onWebGLContextCreationError;
5692
+ this.onWebGLContextLost = renderOptions.onWebGLContextLost;
5693
+ this.onWebGLContextRestored = renderOptions.onWebGLContextRestored;
5694
+ this.webGLContextCreationErrorListener = this.domElement().addEventListener('webglcontextcreationerror', e => this.reportWebGlContextCreationError(e));
5695
+ this.webGLContextLostListener = this.domElement().addEventListener('webglcontextlost', e => this.reportWebGlContextLost(e));
5696
+ this.webGLContextRestoredListener = this.domElement().addEventListener('webglcontextrestored', e => this.reportWebGLContextRestored(e));
5697
+ let backgroundColor = renderOptions.backgroundColor;
5698
+ if (typeof backgroundColor === 'string') {
5699
+ backgroundColor = new Color(renderOptions.backgroundColor);
5700
+ }
5701
+ if (backgroundColor == null) {
5702
+ backgroundColor = new Color('#ffffff');
5703
+ }
5704
+ let backgroundAlpha = renderOptions.backgroundAlpha;
5705
+ if (backgroundAlpha == null) {
5706
+ backgroundAlpha = 1.0;
5707
+ }
5708
+ this.shouldConsiderAlpha = renderOptions.alpha || false;
5709
+ this.antialias = renderOptions.antialias || false;
5710
+ this.setBackgroundColor(backgroundColor, backgroundAlpha);
5711
+ }
5712
+ /**
5713
+ * Dispose of any resources and connections allocated by the renderer.
5714
+ *
5715
+ * @method destroy
5716
+ */
5717
+ destroy() {
5718
+ this.domElement().removeEventListener('webglcontextcreationerror', this.webGLContextCreationErrorListener);
5719
+ this.domElement().removeEventListener('webglcontextlost', this.webGLContextLostListener);
5720
+ this.domElement().removeEventListener('webglcontextrestored', this.webGLContextRestoredListener);
5721
+ this.implementation.destroy();
5722
+ }
5723
+ /**
5724
+ * Render the scene to the provided framebuffer. A null framebuffer will
5725
+ * render to the default canvas.
5726
+ *
5727
+ * @method render
5728
+ * @param renderTask {RENDER}
5729
+ * @param renderTarget {null or WebGLRenderTarget}
5730
+ * @param scene {Scene}
5731
+ * @param sceneCamera {Camera}
5732
+ */
5733
+ render(renderTask, renderTarget, scene, sceneCamera) {
5734
+ this.implementation.render(renderTask, renderTarget, scene, sceneCamera);
5735
+ }
5736
+ /**
5737
+ * Return the maximum supported anisotropy of this renderer.
5738
+ *
5739
+ * @method getMaxAnisotropy
5740
+ * @return {number}
5741
+ */
5742
+ getMaxAnisotropy() {
5743
+ return this.implementation.renderer.capabilities.getMaxAnisotropy();
5744
+ }
5745
+ /**
5746
+ * Return the size of the renderer's target.
5747
+ *
5748
+ * @method getBufferSize
5749
+ * @return {Vector2}
5750
+ */
5751
+ getBufferSize() {
5752
+ return this.implementation.renderer.getSize(new Vector2());
5753
+ }
5754
+ /**
5755
+ * Return the WebGL context associated with this renderer, to ensure
5756
+ * other objects that use WebGL will put their textures in the same
5757
+ * context.
5758
+ *
5759
+ * @method context
5760
+ * @return {WebGLRenderingContext} context used by this renderer
5761
+ */
5762
+ getContext() {
5763
+ return this.implementation.renderer.getContext();
5764
+ }
5765
+ /**
5766
+ * Preload a texture, I think. Not actually sure what this does. TODO.
5767
+ *
5768
+ * @method preloadTexture
5769
+ * @param texture {Texture}
5770
+ */
5771
+ preloadTexture(texture) {
5772
+ this.implementation.renderer.initTexture(texture);
5773
+ }
5774
+ /**
5775
+ * Set the renderer and all its internal buffers to the provided width and
5776
+ * height in pixels.
5777
+ *
5778
+ * @method setBufferSize
5779
+ * @param width {number}
5780
+ * @param height {number}
5781
+ */
5782
+ setBufferSize(width, height) {
5783
+ this.implementation.setBufferSize(width, height);
5784
+ }
5785
+ get backgroundColor() {
5786
+ return this.implementation.backgroundColor;
5787
+ }
5788
+ get backgroundAlpha() {
5789
+ return this.implementation.backgroundAlpha;
5790
+ }
5791
+ /**
5792
+ * Set the color and opacity that will be drawn behind the scene.
5793
+ *
5794
+ * @method setBackgroundColor
5795
+ * @param color {Color}
5796
+ * @param alpha {number}
5797
+ */
5798
+ setBackgroundColor(color, alpha) {
5799
+ if (!this.shouldConsiderAlpha) {
5800
+ alpha = 1.0;
5801
+ }
5802
+ alpha = alpha !== undefined ? +alpha : 1.0;
5803
+ alpha = alpha >= 0.0 && alpha <= 1.0 ? alpha : 1.0;
5804
+ this.implementation.setBackgroundColor(color, alpha);
5805
+ }
5806
+ /**
5807
+ * Assign an outdoor context to this renderer, which will be included as
5808
+ * part of the `STATIC` rendering pass.
5809
+ *
5810
+ * @method setMapboxOutdoorContext
5811
+ * @param {MapboxOutdoorContext} mapboxOutdoorContext context to draw
5812
+ */
5813
+ setMapboxOutdoorContext(mapboxOutdoorContext) {
5814
+ this.implementation.setMapboxOutdoorContext(mapboxOutdoorContext);
5815
+ }
5816
+ // Return the DOM element to which this renderer will render when provided
5817
+ // a `null` `renderTarget` in the `render` method. You can position this
5818
+ // DOM element and add it to the DOM as you see fit.
5819
+ domElement() {
5820
+ return this.implementation.renderer.domElement;
5821
+ }
5822
+ // Return true if this renderer is available to use for rendering. If false,
5823
+ // this means that the context is currently lost, or the renderer failed to
5824
+ // initialize.
5825
+ isAvailable() {
5826
+ return this.implementation.renderer != null && !this.contextLost;
5827
+ }
5828
+ // Temporary solution until https://github.com/mrdoob/three.js/issues/12447 is addressed
5829
+ disposeOfRenderLists() {
5830
+ this.implementation.renderer.renderLists.dispose();
5831
+ }
5832
+ reportWebGlContextCreationError(e) {
5833
+ if (this.onWebGLContextCreationError) {
5834
+ this.onWebGLContextCreationError(e);
5835
+ }
5836
+ }
5837
+ reportWebGlContextLost(e) {
5838
+ e.preventDefault();
5839
+ if (this.onWebGLContextLost) {
5840
+ this.onWebGLContextLost(e);
5841
+ }
5842
+ this.contextLost = true;
5843
+ }
5844
+ reportWebGLContextRestored() {
5845
+ if (this.onWebGLContextRestored) {
5846
+ this.onWebGLContextRestored();
5847
+ }
5848
+ this.contextLost = false;
5849
+ }
5850
+ }
5851
+ /**
5852
+ * A legacy renderer that renders all the elements in the scene to a single
5853
+ * buffer. Does not support things like transparent paths behind polygons
5854
+ * natively, but can potentially fake it.
5855
+ *
5856
+ * 2019/07/10 Terence Dickson
5857
+ * Generally has worse performance under average loads compared to the
5858
+ * multi-buffer renderer, as the multi-buffer renderer can avoid re-rendering
5859
+ * the entire map if only animated elements on the map have changed.
5860
+ *
5861
+ * @class SingleBufferRenderer
5862
+ * @private
5863
+ */
5864
+ class SingleBufferRenderer {
5865
+ constructor(renderOptions) {
5866
+ try {
5867
+ this.renderer = new WebGL1Renderer({
5868
+ alpha: renderOptions.alpha || false,
5869
+ stencil: true,
5870
+ antialias: renderOptions.antialias,
5871
+ powerPreference: 'high-performance',
5872
+ preserveDrawingBuffer: true
5873
+ });
5874
+ }
5875
+ catch (e) {
5876
+ if (renderOptions.onWebGLRendererError) {
5877
+ renderOptions.onWebGLRendererError(e);
5878
+ }
5879
+ }
5880
+ this.backgroundColor = new Color();
5881
+ this.backgroundAlpha = 1.0;
5882
+ this.mapboxOutdoorContext = null;
5883
+ }
5884
+ /**
5885
+ * Dispose of the renderer.
5886
+ */
5887
+ destroy() {
5888
+ this.renderer.dispose();
5889
+ }
5890
+ /**
5891
+ * Re-render the scene. This ignores the `renderTask` argument, as all
5892
+ * re-renders in the single-buffer renderer are full re-renders.
5893
+ *
5894
+ * @method render
5895
+ * @param renderTask {RENDER}
5896
+ * @param renderTarget {null or WebGLRenderTarget}
5897
+ * @param scene {Scene}
5898
+ * @param sceneCamera {Camera}
5899
+ */
5900
+ render(renderTask, renderTarget, scene, sceneCamera) {
5901
+ sceneCamera.layers.enable(CAMERA_LAYER.STATIC);
5902
+ sceneCamera.layers.enable(CAMERA_LAYER.ANIMATED);
5903
+ sceneCamera.layers.enable(CAMERA_LAYER.ALWAYS_ON_TOP);
5904
+ this.renderer.autoClear = false;
5905
+ this.renderer.setClearColor(this.backgroundColor, this.backgroundAlpha);
5906
+ this.renderer.setRenderTarget(renderTarget);
5907
+ this.renderer.clear();
5908
+ if (SHOW_FPS) {
5909
+ stats.begin();
5910
+ }
5911
+ this.renderer.render(scene, sceneCamera);
5912
+ if (SHOW_FPS) {
5913
+ stats.end();
5914
+ }
5915
+ if (this.mapboxOutdoorContext != null) {
5916
+ this.renderer.state.reset();
5917
+ this.mapboxOutdoorContext.render({
5918
+ resolution: this.renderer.getSize(new Vector2()),
5919
+ camera: sceneCamera
5920
+ });
5921
+ this.renderer.state.reset();
5922
+ }
5923
+ }
5924
+ /**
5925
+ * Set the size of the renderer.
5926
+ *
5927
+ * @method setBufferSize
5928
+ * @param width {number}
5929
+ * @param height {number}
5930
+ */
5931
+ setBufferSize(width, height) {
5932
+ this.renderer.setSize(width, height, false);
5933
+ }
5934
+ /**
5935
+ * Set the color and opacity that will be drawn behind the scene.
5936
+ *
5937
+ * @method setBackgroundColor
5938
+ * @param color {Color}
5939
+ * @param alpha {number}
5940
+ */
5941
+ setBackgroundColor(color, alpha) {
5942
+ this.backgroundColor = color;
5943
+ this.backgroundAlpha = alpha;
5944
+ }
5945
+ /**
5946
+ * Assign an outdoor context to this renderer.
5947
+ *
5948
+ * @method setMapboxOutdoorContext
5949
+ * @param {MapboxOutdoorContext} mapboxOutdoorContext context to draw
5950
+ */
5951
+ setMapboxOutdoorContext(mapboxOutdoorContext) {
5952
+ this.mapboxOutdoorContext = mapboxOutdoorContext;
5953
+ }
5954
+ }
5955
+ /**
5956
+ * Our new renderer that renders static elements to one buffer and animated
5957
+ * elements to another buffer, allowing only the latter buffer to be
5958
+ * re-rendered if the camera isn't moving. There is also a third buffer that
5959
+ * can be used to render elements that must appear always on top.
5960
+ *
5961
+ * Does not yet support antialiasing.
5962
+ *
5963
+ * 2019/07/10 Terence Dickson
5964
+ * Generally has better performance under average loads compared to the
5965
+ * single-buffer renderer, but does not work on IE 11.
5966
+ *
5967
+ * @class MultiBufferRenderer
5968
+ * @private
5969
+ */
5970
+ class MultiBufferRenderer {
5971
+ constructor(renderOptions) {
5972
+ try {
5973
+ this.renderer = new WebGL1Renderer({
5974
+ alpha: renderOptions.alpha || false,
5975
+ antialias: false,
5976
+ stencil: true,
5977
+ powerPreference: 'high-performance',
5978
+ preserveDrawingBuffer: true
5979
+ });
5980
+ }
5981
+ catch (e) {
5982
+ if (renderOptions.onWebGLRendererError) {
5983
+ renderOptions.onWebGLRendererError(e);
5984
+ }
5985
+ }
5986
+ this.backgroundColor = new Color();
5987
+ this.backgroundAlpha = 1.0;
5988
+ this.mapboxOutdoorContext = null;
5989
+ // The render target (color and depth textures) that will be used to
5990
+ // store the static scene, to composite it with the animated scene.
5991
+ this.staticSceneRenderTarget = new WebGLRenderTarget(this.renderer.width, this.renderer.height);
5992
+ this.staticSceneRenderTarget.texture.format = RGBAFormat;
5993
+ this.staticSceneRenderTarget.texture.minFilter = NearestFilter;
5994
+ this.staticSceneRenderTarget.texture.magFilter = NearestFilter;
5995
+ this.staticSceneRenderTarget.texture.generateMipmaps = false;
5996
+ this.staticSceneRenderTarget.stencilBuffer = true;
5997
+ this.staticSceneRenderTarget.depthBuffer = true;
5998
+ this.staticSceneRenderTarget.depthTexture = new DepthTexture();
5999
+ this.staticSceneRenderTarget.depthTexture.type = UnsignedIntType;
6000
+ this.staticSceneRenderTarget.depthTexture.format = DepthStencilFormat;
6001
+ // The render target that will be used to store the dynamic scene,
6002
+ // re-rendered once per frame while animated elements exist in the
6003
+ // 3D scene (e.g., paths.)
6004
+ this.animatedSceneRenderTarget = new WebGLRenderTarget(this.renderer.width, this.renderer.height);
6005
+ this.animatedSceneRenderTarget.texture.format = RGBAFormat;
6006
+ this.animatedSceneRenderTarget.stencilBuffer = true;
6007
+ this.animatedSceneRenderTarget.texture.minFilter = NearestFilter;
6008
+ this.animatedSceneRenderTarget.texture.magFilter = NearestFilter;
6009
+ this.animatedSceneRenderTarget.texture.generateMipmaps = false;
6010
+ this.animatedSceneRenderTarget.stencilBuffer = true;
6011
+ this.animatedSceneRenderTarget.depthBuffer = true;
6012
+ this.animatedSceneRenderTarget.depthTexture = new DepthTexture();
6013
+ this.animatedSceneRenderTarget.depthTexture.type = UnsignedIntType;
6014
+ this.animatedSceneRenderTarget.depthTexture.format = DepthStencilFormat;
6015
+ // The render target that will be used to store the scene whose elements
6016
+ // are always drawn on top of everything else. Rendering is done once per
6017
+ // frame while such elements exist in the 3D scene, just like the animated scene target.
6018
+ // 2020/08/18 - Daniel Vijayakumar
6019
+ // This buffer should be used for animated objects that must appear on top of everything
6020
+ // else. I can't think of any use-cases where you'd ever want *static* elements to be
6021
+ // always on top. If this is not adequate, we can solve this problem with yet a 4th buffer.
6022
+ // although this would create a combinatoric explosion of render passes and might start
6023
+ // eating into the gains of the multi-buffer approach.
6024
+ this.alwaysOnTopSceneRenderTarget = new WebGLRenderTarget(this.renderer.width, this.renderer.height);
6025
+ this.alwaysOnTopSceneRenderTarget.texture.format = RGBAFormat;
6026
+ this.alwaysOnTopSceneRenderTarget.texture.minFilter = NearestFilter;
6027
+ this.alwaysOnTopSceneRenderTarget.texture.magFilter = NearestFilter;
6028
+ this.alwaysOnTopSceneRenderTarget.texture.generateMipmaps = false;
6029
+ this.alwaysOnTopSceneRenderTarget.stencilBuffer = true;
6030
+ this.alwaysOnTopSceneRenderTarget.depthBuffer = true;
6031
+ this.alwaysOnTopSceneRenderTarget.depthTexture = new DepthTexture();
6032
+ this.alwaysOnTopSceneRenderTarget.depthTexture.type = UnsignedIntType;
6033
+ this.alwaysOnTopSceneRenderTarget.depthTexture.format = DepthStencilFormat;
6034
+ this.compositeUniforms = {
6035
+ staticSceneColorTexture: {
6036
+ type: 't',
6037
+ value: this.staticSceneRenderTarget.texture
6038
+ },
6039
+ staticSceneDepthTexture: {
6040
+ type: 't',
6041
+ value: this.staticSceneRenderTarget.depthTexture
6042
+ },
6043
+ animatedSceneColorTexture: {
6044
+ type: 't',
6045
+ value: this.animatedSceneRenderTarget.texture
6046
+ },
6047
+ animatedSceneDepthTexture: {
6048
+ type: 't',
6049
+ value: this.animatedSceneRenderTarget.depthTexture
6050
+ },
6051
+ alwaysOnTopSceneColorTexture: {
6052
+ type: 't',
6053
+ value: this.alwaysOnTopSceneRenderTarget.texture
6054
+ }
6055
+ };
6056
+ // The scene that renders a full-screen quad that will sample from
6057
+ // all render targets to produce the composited result.
6058
+ this.compositeCamera = new OrthographicCamera(-1, 1, 1, -1, 0, 1);
6059
+ this.compositeMaterial = new ShaderMaterial({
6060
+ uniforms: this.compositeUniforms,
6061
+ vertexShader: CompositeVertexShader,
6062
+ fragmentShader: CompositeFragmentShader
6063
+ });
6064
+ this.compositeFullscreenQuad = new Mesh(new PlaneBufferGeometry(2, 2), this.compositeMaterial);
6065
+ this.compositeScene = new Scene();
6066
+ this.compositeScene.add(this.compositeFullscreenQuad);
6067
+ }
6068
+ /**
6069
+ * Dispose of the renderer and its buffers.
6070
+ */
6071
+ destroy() {
6072
+ this.staticSceneRenderTarget.dispose();
6073
+ this.animatedSceneRenderTarget.dispose();
6074
+ this.alwaysOnTopSceneRenderTarget.dispose();
6075
+ this.renderer.dispose();
6076
+ }
6077
+ /**
6078
+ * Compose all buffers into the final image that is sent to the viewport.
6079
+ *
6080
+ * @private
6081
+ * @method renderComposite
6082
+ * @param renderTarget {null or WebGLRenderTarget}
6083
+ */
6084
+ renderComposite(renderTarget) {
6085
+ this.renderer.setRenderTarget(renderTarget);
6086
+ this.renderer.clear();
6087
+ // 23/05/2019 Terence Dickson
6088
+ // We need to disable depth writes on the fullscreen-quad, since
6089
+ // otherwise it is considered "very close to the camera" and will
6090
+ // obscure the path rendering. Keep an eye on this if you update
6091
+ // three.js, since we're modifying properties on the WebGL context
6092
+ // itself, and three.js might decide to override this in the future.
6093
+ this.renderer.getContext().depthMask(false);
6094
+ this.renderer.render(this.compositeScene, this.compositeCamera);
6095
+ this.renderer.getContext().depthMask(true);
6096
+ }
6097
+ /**
6098
+ * Renders the scene's animated layer to its dedicated buffer.
6099
+ *
6100
+ * @private
6101
+ * @method renderToAnimatedBuffer
6102
+ * @param {*} scene
6103
+ * @param {*} sceneCamera
6104
+ */
6105
+ renderToAnimatedBuffer(scene, sceneCamera) {
6106
+ sceneCamera.layers.set(CAMERA_LAYER.ANIMATED);
6107
+ this.renderer.setClearColor(new Color(), 0.0);
6108
+ this.renderer.setRenderTarget(this.animatedSceneRenderTarget);
6109
+ this.renderer.clear();
6110
+ this.renderer.render(scene, sceneCamera);
6111
+ }
6112
+ /**
6113
+ * Render the provided scene using the given camera, re-rendering only
6114
+ * the animated parts.
6115
+ *
6116
+ * @method renderAnimated
6117
+ * @param renderTarget {null or WebGLRenderTarget}
6118
+ * @param scene {Scene}
6119
+ * @param sceneCamera {Camera}
6120
+ */
6121
+ renderAnimated(renderTarget, scene, sceneCamera) {
6122
+ this.renderToAnimatedBuffer(scene, sceneCamera);
6123
+ this.renderComposite(renderTarget);
6124
+ }
6125
+ /**
6126
+ * Renders the scene's always-on-top layer to its dedicated buffer.
6127
+ *
6128
+ * @private
6129
+ * @method renderToAlwaysOnTopBuffer
6130
+ * @param {*} scene
6131
+ * @param {*} sceneCamera
6132
+ */
6133
+ renderToAlwaysOnTopBuffer(scene, sceneCamera) {
6134
+ sceneCamera.layers.set(CAMERA_LAYER.ALWAYS_ON_TOP);
6135
+ this.renderer.setClearColor(new Color(), 0.0);
6136
+ this.renderer.setRenderTarget(this.alwaysOnTopSceneRenderTarget);
6137
+ this.renderer.clear();
6138
+ this.renderer.render(scene, sceneCamera);
6139
+ }
6140
+ /**
6141
+ * Render the provided scene using the given camera, re-rendering only
6142
+ * the parts that should appear on top of all other elements.
6143
+ *
6144
+ * @method renderAlwaysOnTop
6145
+ * @param renderTarget {null or WebGLRenderTarget}
6146
+ * @param scene {Scene}
6147
+ * @param sceneCamera {Camera}
6148
+ */
6149
+ renderAlwaysOnTop(renderTarget, scene, sceneCamera) {
6150
+ this.renderToAlwaysOnTopBuffer(scene, sceneCamera);
6151
+ this.renderComposite(renderTarget);
6152
+ }
6153
+ /**
6154
+ * Render all of the scene layers, then combine them.
6155
+ *
6156
+ * @method renderAll
6157
+ * @param renderTarget {null or WebGLRenderTarget}
6158
+ * @param scene {Scene}
6159
+ * @param sceneCamera {Camera}
6160
+ */
6161
+ renderAll(renderTarget, scene, sceneCamera) {
6162
+ // First, render to static buffer
6163
+ sceneCamera.layers.set(CAMERA_LAYER.STATIC);
6164
+ this.renderer.autoClear = false;
6165
+ this.renderer.setClearColor(this.backgroundColor, this.backgroundAlpha);
6166
+ this.renderer.setRenderTarget(this.staticSceneRenderTarget);
6167
+ this.renderer.clear();
6168
+ this.renderer.render(scene, sceneCamera);
6169
+ // Then render mapbox outdoor context
6170
+ if (this.mapboxOutdoorContext != null) {
6171
+ this.renderer.state.reset();
6172
+ this.mapboxOutdoorContext.render({
6173
+ resolution: this.renderer.getSize(new Vector2()),
6174
+ camera: sceneCamera,
6175
+ renderTarget: this.staticSceneRenderTarget
6176
+ });
6177
+ this.renderer.state.reset();
6178
+ }
6179
+ // Next, render the remaining buffers
6180
+ this.renderToAnimatedBuffer(scene, sceneCamera);
6181
+ this.renderToAlwaysOnTopBuffer(scene, sceneCamera);
6182
+ // Finally, composite the scene
6183
+ this.renderComposite(renderTarget);
6184
+ }
6185
+ /**
6186
+ * Re-render the scene, depending on which parts of the scene have been
6187
+ * invalidated.
6188
+ *
6189
+ * @method render
6190
+ * @param renderTarget {null or WebGLRenderTarget}
6191
+ * @param scene {Scene}
6192
+ * @param sceneCamera {Camera}
6193
+ */
6194
+ render(renderTask, renderTarget, scene, sceneCamera) {
6195
+ if (renderTask === RENDER.ANIMATED) {
6196
+ this.renderAnimated(renderTarget, scene, sceneCamera);
6197
+ }
6198
+ else if (renderTask === RENDER.ALWAYS_ON_TOP) {
6199
+ this.renderAlwaysOnTop(renderTarget, scene, sceneCamera);
6200
+ }
6201
+ else if (renderTask === RENDER.ALL) {
6202
+ this.renderAll(renderTarget, scene, sceneCamera);
6203
+ }
6204
+ else {
6205
+ Logger.error('Renderer.render called with invalid renderTask');
6206
+ }
6207
+ }
6208
+ /**
6209
+ * Set the size of the renderer, and all its internal buffers.
6210
+ *
6211
+ * @method setBufferSize
6212
+ * @param width {number}
6213
+ * @param height {number}
6214
+ */
6215
+ setBufferSize(width, height) {
6216
+ this.renderer.setSize(width, height, false);
6217
+ this.staticSceneRenderTarget.setSize(width, height);
6218
+ this.animatedSceneRenderTarget.setSize(width, height);
6219
+ this.alwaysOnTopSceneRenderTarget.setSize(width, height);
6220
+ }
6221
+ /**
6222
+ * Set the color and opacity that will be drawn behind the scene.
6223
+ *
6224
+ * @method setBackgroundColor
6225
+ * @param color {Color}
6226
+ * @param alpha {number}
6227
+ */
6228
+ setBackgroundColor(color, alpha) {
6229
+ this.backgroundColor = color;
6230
+ this.backgroundAlpha = alpha;
6231
+ }
6232
+ /**
6233
+ * Assign an outdoor context to this renderer.
6234
+ *
6235
+ * @method setMapboxOutdoorContext
6236
+ * @param {MapboxOutdoorContext} mapboxOutdoorContext context to draw
6237
+ */
6238
+ setMapboxOutdoorContext(mapboxOutdoorContext) {
6239
+ this.mapboxOutdoorContext = mapboxOutdoorContext;
6240
+ }
6241
+ }
6242
+
6243
+ declare module '@mappedin/mappedin-js/get-venue/Mappedin.TaskScheduler' {
5427
6244
  /**
5428
- * A class that handles scheduling tasks to be performed within the time
5429
- * constraints of frame updates, triggered using `requestAnimationFrame`.
6245
+ * A function that can be submitted to the Task Scheduler to run each frame for
6246
+ * some provided number of frames. A single update can be repeatedly submitted;
6247
+ * if the number of frames left on the update is less than `frameCount`, it will
6248
+ * be reset to `frameCount`.
5430
6249
  *
5431
- * Tasks can either be scheduled once per frame (called "frame updates"), or
5432
- * to execute as many times per frame as there is room for after processing
5433
- * all frame updates (called "frame tasks").
5434
- *
5435
- * Posted tasks will always run during the same frame, assuming there's time to
5436
- * process them. However, an update or task that posts an update will not run
5437
- * that update until the next frame.
5438
- *
5439
- * @class TaskScheduler
6250
+ * @class FrameUpdate
5440
6251
  * @private
5441
6252
  */
5442
- export class TaskScheduler {
6253
+ export class FrameUpdate {
5443
6254
  /**
5444
- * Construct a new `TaskScheduler` with no tasks scheduled.
5445
- *
5446
- * @constructor
5447
- * @param [options] {Object} Options for the scheduler
5448
- * @param [options.timer=new RealTimeTimer()]
5449
- * Timer that determines whether there is sufficient time left in a frame
5450
- * to continue executing tasks
5451
- * @param [options.performance=false]
5452
- * If true, this task scheduler will annotate tasks and frame updates with
5453
- * performance information.
6255
+ * Create a new frame update that can be submitted to a scheduler.
6256
+ * @constructor
6257
+ * @param [options] {Object} Options for the update
6258
+ * @param [options.callback] {function}
6259
+ * The actual function to run every time this update is scheduled for
6260
+ * a frame.
6261
+ * @param [options.frameCount=1] {number}
6262
+ * How many frames this update should run for when it's submitted to
6263
+ * a scheduler
6264
+ * @param [options.ordering=0] {number}
6265
+ * An ordering value that's used to determine the order in which
6266
+ * frame updates will be run within a frame; larger numbers will
6267
+ * be run first
6268
+ * @param [options.supersededBy=[]] {[FrameUpdate]}
6269
+ * If this update is scheduled to run in a frame, but another update in
6270
+ * the provided list is also scheduled to run on that frame, then
6271
+ * this update will not be run.
6272
+ * @param [options.name=undefined] {string}
6273
+ * If provided, an arbitrary name for logging purposes.
6274
+ * @param [options.userdata] {Any}
6275
+ * Arbitrary data that you can store along with this update.
5454
6276
  */
5455
- constructor(options?: {
5456
- timer?: RealTimeTimer;
5457
- performance?: boolean;
6277
+ constructor(options: {
6278
+ callback: Function;
6279
+ frameCount?: number;
6280
+ ordering?: number;
6281
+ supersededBy?: Set<any>;
6282
+ name: string;
6283
+ userdata?: Record<string, any>;
5458
6284
  });
5459
- _raf?: (callback: FrameRequestCallback) => number;
5460
- _timer: RealTimeTimer;
5461
- _performance: boolean;
5462
- _scheduledUpdatesByOrdering: Multimap;
5463
- _scheduledTasksByPriority: Multimap;
5464
- _postponedTasks: Set<any>;
5465
- _requestAnimationFrameHandle: number | null;
5466
- _updatesToRunThisFrame: any[];
6285
+ _callback: Function;
6286
+ _frameCount: number;
6287
+ _ordering: number;
6288
+ _supersededBy: Set<any>;
6289
+ name: string;
6290
+ _remainingFrameCount: number;
5467
6291
  _lastFrameTime: number;
5468
- _updatesRunLastFrame: Set<any>;
5469
- /**
5470
- * Empty the task scheduler's queue. All tasks in it will be cancelled.
5471
- *
5472
- * @method clear
5473
- */
5474
- clear(): void;
5475
- /**
5476
- * Destroy this task scheduler and remove all tasks from it.
5477
- *
5478
- * @method destroy
5479
- */
5480
- destroy(): void;
6292
+ userdata?: Record<string, any>;
5481
6293
  /**
5482
- * Schedule this task scheduler to execute updates and tasks on the next
5483
- * available animation frame.
6294
+ * Return the amount of time that this frame update took to execute during
6295
+ * its most recent execution, in milliseconds. If called during this frame
6296
+ * update, the value returned will be for the previous invocation. If called
6297
+ * before this frame update has been executed at least once, the returned
6298
+ * value is unspecified.
5484
6299
  *
5485
- * @method requestAnimationFrame
6300
+ * @method lastFrameTime
6301
+ * @return {number} the previous frame time, in milliseconds
5486
6302
  */
5487
- requestAnimationFrame(): void;
6303
+ getLastFrameTime(): number;
6304
+ }
6305
+ /**
6306
+ * A task that can be submitted to the Task Scheduler to be run every time
6307
+ * there is a frame update with spare time in the frame.
6308
+ *
6309
+ * @class FrameTask
6310
+ * @private
6311
+ */
6312
+ export class FrameTask {
5488
6313
  /**
5489
- * Run all scheduled updates, and re-schedule another animation frame if any
5490
- * scheduled updates still exist. If any scheduled update specifies
5491
- * `shouldRunTasksAfterCompletion`, this will also run queued tasks until the
5492
- * frame time runs out.
5493
- *
5494
- * @method update
5495
- * @param timestamp {number} the current animation time, as returned from
5496
- * `performance.now()`; will be automatically filled in by
5497
- * `requestAnimationFrame` when it triggers this as a callback
6314
+ * Create a new frame task that can be submitted to a scheduler.
6315
+ * @constructor
6316
+ * @param [options] {Object} Options for the task
6317
+ * @param [options.callback] {function}
6318
+ * The actual function to run when this task is scheduled.
6319
+ * @param [options.group=null] {FrameTaskGroup}
6320
+ * If provided, a group to which this task will be added when scheduled
6321
+ * @param [options.priority=0] {number}
6322
+ * Tasks with higher priority will be taken from the queue before tasks
6323
+ * with a lower priority.
6324
+ * @param [options.postponeOnAdd=false] {number}
6325
+ * If true, this task will not be run until `resumeTask` is called on the
6326
+ * scheduler.
6327
+ * @param [options.name=undefined] {string}
6328
+ * If provided, an arbitrary name for logging purposes.
6329
+ * @param [options.userdata] {Any}
6330
+ * Arbitrary data that you can store along with this task.
5498
6331
  */
5499
- update(timestamp: number): void;
6332
+ constructor(options: {
6333
+ userdata: Record<string, any>;
6334
+ priority: number;
6335
+ group?: FrameTaskGroup;
6336
+ postponeOnAdd: number | boolean;
6337
+ name: string;
6338
+ lastFrameTime: number;
6339
+ callback: Function;
6340
+ });
6341
+ _postponed: number | boolean;
6342
+ userdata: Record<string, any>;
6343
+ _priority: number;
6344
+ _group: FrameTaskGroup | null;
6345
+ name: string;
6346
+ _lastFrameTime: number;
6347
+ _callback: Function;
6348
+ _complete: boolean;
6349
+ _scheduled: boolean;
6350
+ _cancelled: boolean;
5500
6351
  /**
5501
- * Execute all tasks that are currently pending, without regard for the
5502
- * available frame time.
6352
+ * Return true if this task has been run at least once.
5503
6353
  *
5504
- * @method flushTasks
6354
+ * @method isComplete
6355
+ * @return {boolean}
5505
6356
  */
5506
- flushTasks(): void;
6357
+ isComplete(): boolean;
5507
6358
  /**
5508
- * Return the amount of time elapsed during the last completed frame update,
5509
- * in milliseconds. This value is unspecified if the task scheduler's
5510
- * `update` method has not yet run or if the scheduler has been cleared.
5511
- * If called during a frame update, this will
5512
- * return the time elapsed during the previous frame update.
6359
+ * Return the amount of time that this frame task took to execute,
6360
+ * in milliseconds. If this task has not yet completed, the returned value
6361
+ * is unspecified.
5513
6362
  *
5514
6363
  * @method lastFrameTime
5515
- * @return {number} time elapsed during last frame update, in milliseconds
6364
+ * @return {number} the frame time, in milliseconds
5516
6365
  */
5517
6366
  getLastFrameTime(): number;
6367
+ }
6368
+ /**
6369
+ * A group of tasks that must all be completed before the group is considered
6370
+ * complete. The tasks will be automatically garbage collected so that references
6371
+ * to the task don't linger.
6372
+ *
6373
+ * @class FrameTaskGroup
6374
+ * @private
6375
+ */
6376
+ export class FrameTaskGroup {
5518
6377
  /**
5519
- * Return a set containing every update that was run during the previous
5520
- * frame update. This will be empty if the task scheduler's `update` method
5521
- * has not yet been run or if the scheduler has been cleared.
5522
- */
5523
- getUpdatesRunLastFrame(): Set<any>;
5524
- _executeOneTask(timestamp: number): void;
5525
- /**
5526
- * Schedule an update to be run for the next `update.frameCount` frames. If
5527
- * the update already exists in the scheduler, the update's frame count will
5528
- * be refreshed to `update.frameCount`. This will also schedule an animation
5529
- * frame to begin processing the update.
6378
+ * Create a new frame task group.
5530
6379
  *
5531
- * @method scheduleUpdate
5532
- * @param task {FrameUpdate} the update to schedule
6380
+ * @constructor
6381
+ * @param [options] {Object} Options for the task group
6382
+ * @param [options.onComplete] {function}
6383
+ * A callback that will be triggered once every task in this group
6384
+ * has been completed. This callback may schedule a task, and the
6385
+ * scheduler will run that task in the same frame, if there is still
6386
+ * frame time for it.
6387
+ * @param [options.priority=0] {number}
6388
+ * The priority of all the tasks in this group.
6389
+ * @param [options.postponeOnAdd=false] {number}
6390
+ * If true, tasks from this task group will not be run until `resumeTask`
6391
+ * is called on the scheduler with this group.
6392
+ * @param [options.name=undefined] {string}
6393
+ * If provided, an arbitrary name for logging purposes.
6394
+ * @param [options.userdata] {Any}
6395
+ * Arbitrary data that you can store along with this task group.
5533
6396
  */
5534
- scheduleUpdate(update: FrameUpdate): void;
6397
+ constructor(options: {
6398
+ onComplete?: Function;
6399
+ priority?: number;
6400
+ userdata: Record<string, any>;
6401
+ postponeOnAdd: number | boolean;
6402
+ name: string;
6403
+ });
6404
+ _postponed: number | boolean;
6405
+ _onComplete: Function;
6406
+ _priority: number;
6407
+ userdata: Record<string, any>;
6408
+ name: string;
6409
+ _tasks: Set<any>;
6410
+ _scheduledTasks: Set<any>;
6411
+ _scheduled: boolean;
6412
+ _cancelled: boolean;
5535
6413
  /**
5536
- * Schedule a task to be run during a frame update. This will also schedule
5537
- * an animation frame to begin processing the task queue.
5538
- *
5539
- * @method scheduleTask
5540
- * @param task {FrameTask} the task to schedule
6414
+ * Return true if every task in this group has been run at least once.
6415
+ * @method isComplete
6416
+ * @return {boolean}
5541
6417
  */
5542
- scheduleTask(task: FrameTask): void;
6418
+ isComplete(): boolean;
5543
6419
  /**
5544
- * If the given update is in the queue, remove it.
6420
+ * Return a list of tasks in this group. This will be a copy of the
6421
+ * underlying task group, so it's safe to mutate the group while
6422
+ * iterating over this array.
5545
6423
  *
5546
- * @method cancelUpdate
5547
- * @param task {FrameUpdate} the update to cancel
6424
+ * @method tasks
6425
+ * @return {[FrameTask]} list of tasks in this group
5548
6426
  */
5549
- cancelUpdate(update: FrameUpdate): void;
6427
+ getTasks(): any[];
5550
6428
  /**
5551
- * If the given task or group is in the queue, remove it. Cancelling a
5552
- * completed task is a no-op.
5553
- *
5554
- * Canceling an individual task will also remove it from its task group, if
5555
- * it isn't already complete.
6429
+ * Empty this task group. This will trivially satisfy `isComplete`.
5556
6430
  *
5557
- * @method cancelTask
5558
- * @param task {FrameTask or FrameTaskGroup} the task to cancel
6431
+ * @method clear
5559
6432
  */
5560
- cancelTask(task: FrameTask | FrameTaskGroup): void;
6433
+ clear(): void;
5561
6434
  /**
5562
- * Set the provided task or group not to run, until it's resumed using `resumeTask`.
6435
+ * Return one arbitrary incomplete task from this group, or undefined if
6436
+ * there are none.
5563
6437
  *
5564
- * Tasks that are in a group can't be postponed individually; instead, call
5565
- * `postponeTask` with the entire group.
6438
+ * @method _popTask
6439
+ * @return {FrameTask} arbitrary scheduled task
6440
+ * @private
6441
+ */
6442
+ _popTask(): any;
6443
+ }
6444
+ /**
6445
+ * A timer for the task scheduler that uses real wall-time to determine if there's
6446
+ * enough remaining time in a frame to execute another task.
6447
+ *
6448
+ * @class RealTimeTimer
6449
+ * @private
6450
+ */
6451
+ export class RealTimeTimer {
6452
+ _maxMillisecondsPerFrame: number;
6453
+ _time: number;
6454
+ /**
6455
+ * @constructor
6456
+ * @param [options] {Object} Options for the timer
6457
+ * @param [options.maxMillisecondsPerFrame]
6458
+ * If the time since the beginning of the frame has been less than
6459
+ * or equal to this value, then another task may be executed
6460
+ */
6461
+ constructor(options?: {
6462
+ maxMillisecondsPerFrame?: number;
6463
+ });
6464
+ /**
6465
+ * Begin timing a frame.
6466
+ *
6467
+ * @method beginFrame
6468
+ */
6469
+ beginFrame(): void;
6470
+ /**
6471
+ * If true, there is enough time remaining to execute another task.
6472
+ *
6473
+ * @method hasTimeRemaining
6474
+ * @return {boolean}
6475
+ */
6476
+ hasTimeRemaining(): boolean;
6477
+ }
6478
+ /**
6479
+ * A timer that ticks every time `hasTimeRemaining` is called.
6480
+ *
6481
+ * @class FixedTimer
6482
+ * @private
6483
+ */
6484
+ export class FixedTimer {
6485
+ _ticks: number;
6486
+ maxTasksPerFrame: number;
6487
+ /**
6488
+ * @constructor
6489
+ * @param [options] {Object} Options for the timer
6490
+ * @param [options.maxTasksPerFrame=5]
6491
+ * The number of tasks that will be exceuted in a single update call.
6492
+ * Can be modified as the `maxTasksPerFrame` property on this boject.
6493
+ */
6494
+ constructor(options?: {
6495
+ maxTasksPerFrame?: number;
6496
+ });
6497
+ /**
6498
+ * Begin timing a frame.
6499
+ *
6500
+ * @method beginFrame
6501
+ */
6502
+ beginFrame(): void;
6503
+ /**
6504
+ * If true, there is enough time remaining to execute another task.
6505
+ *
6506
+ * @method hasTimeRemaining
6507
+ * @return {boolean}
6508
+ */
6509
+ hasTimeRemaining(): boolean;
6510
+ }
6511
+ /**
6512
+ * A class that handles scheduling tasks to be performed within the time
6513
+ * constraints of frame updates, triggered using `requestAnimationFrame`.
6514
+ *
6515
+ * Tasks can either be scheduled once per frame (called "frame updates"), or
6516
+ * to execute as many times per frame as there is room for after processing
6517
+ * all frame updates (called "frame tasks").
6518
+ *
6519
+ * Posted tasks will always run during the same frame, assuming there's time to
6520
+ * process them. However, an update or task that posts an update will not run
6521
+ * that update until the next frame.
6522
+ *
6523
+ * @class TaskScheduler
6524
+ * @private
6525
+ */
6526
+ export class TaskScheduler {
6527
+ /**
6528
+ * Construct a new `TaskScheduler` with no tasks scheduled.
6529
+ *
6530
+ * @constructor
6531
+ * @param [options] {Object} Options for the scheduler
6532
+ * @param [options.timer=new RealTimeTimer()]
6533
+ * Timer that determines whether there is sufficient time left in a frame
6534
+ * to continue executing tasks
6535
+ * @param [options.performance=false]
6536
+ * If true, this task scheduler will annotate tasks and frame updates with
6537
+ * performance information.
6538
+ */
6539
+ constructor(options?: {
6540
+ timer?: RealTimeTimer;
6541
+ performance?: boolean;
6542
+ });
6543
+ _raf?: (callback: FrameRequestCallback) => number;
6544
+ _timer: RealTimeTimer;
6545
+ _performance: boolean;
6546
+ _scheduledUpdatesByOrdering: Multimap;
6547
+ _scheduledTasksByPriority: Multimap;
6548
+ _postponedTasks: Set<any>;
6549
+ _requestAnimationFrameHandle: number | null;
6550
+ _updatesToRunThisFrame: any[];
6551
+ _lastFrameTime: number;
6552
+ _updatesRunLastFrame: Set<any>;
6553
+ /**
6554
+ * Empty the task scheduler's queue. All tasks in it will be cancelled.
6555
+ *
6556
+ * @method clear
6557
+ */
6558
+ clear(): void;
6559
+ /**
6560
+ * Destroy this task scheduler and remove all tasks from it.
6561
+ *
6562
+ * @method destroy
6563
+ */
6564
+ destroy(): void;
6565
+ /**
6566
+ * Schedule this task scheduler to execute updates and tasks on the next
6567
+ * available animation frame.
6568
+ *
6569
+ * @method requestAnimationFrame
6570
+ */
6571
+ requestAnimationFrame(): void;
6572
+ /**
6573
+ * Run all scheduled updates, and re-schedule another animation frame if any
6574
+ * scheduled updates still exist. If any scheduled update specifies
6575
+ * `shouldRunTasksAfterCompletion`, this will also run queued tasks until the
6576
+ * frame time runs out.
6577
+ *
6578
+ * @method update
6579
+ * @param timestamp {number} the current animation time, as returned from
6580
+ * `performance.now()`; will be automatically filled in by
6581
+ * `requestAnimationFrame` when it triggers this as a callback
6582
+ */
6583
+ update(timestamp: number): void;
6584
+ /**
6585
+ * Execute all tasks that are currently pending, without regard for the
6586
+ * available frame time.
6587
+ *
6588
+ * @method flushTasks
6589
+ */
6590
+ flushTasks(): void;
6591
+ /**
6592
+ * Return the amount of time elapsed during the last completed frame update,
6593
+ * in milliseconds. This value is unspecified if the task scheduler's
6594
+ * `update` method has not yet run or if the scheduler has been cleared.
6595
+ * If called during a frame update, this will
6596
+ * return the time elapsed during the previous frame update.
6597
+ *
6598
+ * @method lastFrameTime
6599
+ * @return {number} time elapsed during last frame update, in milliseconds
6600
+ */
6601
+ getLastFrameTime(): number;
6602
+ /**
6603
+ * Return a set containing every update that was run during the previous
6604
+ * frame update. This will be empty if the task scheduler's `update` method
6605
+ * has not yet been run or if the scheduler has been cleared.
6606
+ */
6607
+ getUpdatesRunLastFrame(): Set<any>;
6608
+ _executeOneTask(timestamp: number): void;
6609
+ /**
6610
+ * Schedule an update to be run for the next `update.frameCount` frames. If
6611
+ * the update already exists in the scheduler, the update's frame count will
6612
+ * be refreshed to `update.frameCount`. This will also schedule an animation
6613
+ * frame to begin processing the update.
6614
+ *
6615
+ * @method scheduleUpdate
6616
+ * @param task {FrameUpdate} the update to schedule
6617
+ */
6618
+ scheduleUpdate(update: FrameUpdate): void;
6619
+ /**
6620
+ * Schedule a task to be run during a frame update. This will also schedule
6621
+ * an animation frame to begin processing the task queue.
6622
+ *
6623
+ * @method scheduleTask
6624
+ * @param task {FrameTask} the task to schedule
6625
+ */
6626
+ scheduleTask(task: FrameTask): void;
6627
+ /**
6628
+ * If the given update is in the queue, remove it.
6629
+ *
6630
+ * @method cancelUpdate
6631
+ * @param task {FrameUpdate} the update to cancel
6632
+ */
6633
+ cancelUpdate(update: FrameUpdate): void;
6634
+ /**
6635
+ * If the given task or group is in the queue, remove it. Cancelling a
6636
+ * completed task is a no-op.
6637
+ *
6638
+ * Canceling an individual task will also remove it from its task group, if
6639
+ * it isn't already complete.
6640
+ *
6641
+ * @method cancelTask
6642
+ * @param task {FrameTask or FrameTaskGroup} the task to cancel
6643
+ */
6644
+ cancelTask(task: FrameTask | FrameTaskGroup): void;
6645
+ /**
6646
+ * Set the provided task or group not to run, until it's resumed using `resumeTask`.
6647
+ *
6648
+ * Tasks that are in a group can't be postponed individually; instead, call
6649
+ * `postponeTask` with the entire group.
5566
6650
  *
5567
6651
  * @method postponeTask
5568
6652
  * @param task {FrameTask or FrameTaskGroup} the task to postpone
@@ -5650,371 +6734,810 @@ declare module '@mappedin/mappedin-js/get-venue/Mappedin.TaskScheduler' {
5650
6734
  * @method popFromMaxKey
5651
6735
  * @return {Any} arbitrary value from the highest key's set, or undefined
5652
6736
  * if the map is empty
5653
- */
5654
- popFromMaxKey(): any;
5655
- /**
5656
- * Return an iterator over every value in this multimap, at every key.
5657
- * Mutating the multimap during iteration will result in undefined
5658
- * behaviour.
5659
- *
5660
- * @method values
5661
- * @return {Iterator} iterator over the values in the map
5662
- */
5663
- values(): {
5664
- [Symbol.iterator]: () => any;
5665
- next: () => any;
5666
- };
5667
- /**
5668
- * A list of keys in this set, sorted by numeric value. Not cloned,
5669
- * for efficiency's sake, so please don't mutate it.
5670
- *
5671
- * @method keys
5672
- * @return {[number]} sorted list of numeric keys in the map
5673
- */
5674
- keys(): any[];
5675
- /**
5676
- * The number of elements in this multimap, equal to the sum of the sizes
5677
- * of each key's set of values.
5678
- *
5679
- * @property size {number} number of elements in this multimap
5680
- */
5681
- get size(): number;
5682
- }
5683
- export {};
5684
- }
5685
-
5686
- declare module '@mappedin/mappedin-js/renderer/MapView.SceneManager' {
5687
- import { MappedinMap } from '@mappedin/mappedin-js/get-venue';
5688
- import { TCameraTransform, TCameraAnimationOptions } from '@mappedin/mappedin-js/renderer/Camera';
5689
- import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
5690
- import MapViewScene from '@mappedin/mappedin-js/renderer/MapView.Scene';
5691
- export type TSceneTransitionOptions = {
5692
- /**
5693
- * Map to set as active during the transition. This will decide where the camera will be positioned, as well as which
5694
- * colliders are enabled.
5695
- */
5696
- activeMap?: MappedinMap;
5697
- verticalDistanceBetweenMaps?: number;
5698
- /**
5699
- * Camera options to use when transitioning to the new scene
5700
- */
5701
- cameraTransform?: TCameraTransform;
5702
- cameraAnimationOptions?: TCameraAnimationOptions;
5703
- /**
5704
- * Whether to auto focus on the active map or leave the camera where it is.
5705
- * For single building venues, this should look the same way it did with MapManager
5706
- * For multi-building venues, this means the camera will not pan over to where the active map
5707
- * is relative to the world, which may look like broken behavior.
5708
- * @default true
5709
- */
5710
- autoFocusOnActiveMap?: boolean;
5711
- };
5712
- class SceneManager {
5713
- #private;
5714
- currentScene: MapViewScene;
5715
- constructor(core: ICore, startingScene: MapViewScene);
5716
- get currentMap(): MappedinMap;
5717
- renderGrid(): void;
5718
- transitionTo(scene: MapViewScene, transitionOptions?: TSceneTransitionOptions): Promise<void>;
5719
- }
5720
- export default SceneManager;
5721
- }
5722
-
5723
- declare module '@mappedin/mappedin-js/renderer/internal/shave-text' {
5724
- export type TDrawFn = (ctx: CanvasRenderingContext2D, x: number, y: number) => void;
5725
- type TShave = (str: string, size: number, maxWidth: number, maxLines?: number, lineHeight?: number, options?: {
5726
- strokeText: boolean;
5727
- }) => {
5728
- maxWidth: number;
5729
- maxHeight: number;
5730
- lines: number;
5731
- draw: TDrawFn;
5732
- };
5733
- export const shaveText: TShave;
5734
- export {};
5735
- }
5736
-
5737
- declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollisionEngine' {
5738
- import { Vector3 } from 'three';
5739
- import './Mappedin.SmartCollisionEngine.scss';
5740
- import { ICollider, TRange } from '@mappedin/mappedin-js/renderer/internal/Mappedin.SmartCollider';
5741
- import { MappedinMap, MapView } from '@mappedin/mappedin-js/renderer';
5742
- import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
5743
- import { Rectangle, QuadTree } from '@mappedin/mappedin-js/renderer/internal/quad-tree';
5744
- export const COLLIDER_STRATEGY_LOW_PRIORITY = "LOW_PRIORITY";
5745
- class SmartCollisionEngine {
5746
- #private;
5747
- colliderCanvas: HTMLCanvasElement;
5748
- debugCanvas: HTMLCanvasElement;
5749
- colliderCanvasContext: CanvasRenderingContext2D;
5750
- debugCanvasContext: CanvasRenderingContext2D;
5751
- collisionEngineContainerEl: HTMLDivElement;
5752
- stepsX: any;
5753
- stepsY: any;
5754
- totalWidth: any;
5755
- totalHeight: any;
5756
- project: any;
5757
- colliders: Map<string, ICollider>;
5758
- offscreenRanges: TRange[];
5759
- get sortedColliders(): ICollider[];
5760
- initialized: boolean;
5761
- mapView: MapView;
5762
- core: ICore;
5763
- screen: Rectangle;
5764
- constructor(mapView: any, core: ICore);
5765
- beginUpdate(): void;
5766
- init: (container: HTMLDivElement, projectFn: ({ position, mapId }: {
5767
- position: any;
5768
- mapId: MappedinMap['id'];
5769
- }) => {
5770
- x: number;
5771
- y: number;
5772
- }) => void;
5773
- qtree: QuadTree;
5774
- recompute: () => void;
5775
- draw: () => void;
5776
- reposition: () => void;
5777
- add: (colliderId: string, collider: ICollider) => void;
5778
- remove: (colliderId: string) => void;
5779
- update: () => void;
5780
- resize: (container: any) => void;
5781
- destroy: () => void;
5782
- }
5783
- export default SmartCollisionEngine;
5784
- }
5785
-
5786
- declare module '@mappedin/mappedin-js/renderer/internal/quad-tree' {
5787
- export function contains(rect1: Rectangle, rect2: Rectangle): boolean;
5788
- export function intersects(rect1: Rectangle, rect2: Rectangle): boolean;
5789
- class Rectangle {
5790
- x: number;
5791
- y: number;
5792
- w: number;
5793
- h: number;
5794
- userData?: any;
5795
- constructor(x: number, y: number, w: number, h: number, userData?: any);
5796
- contains(rectangle: Rectangle): boolean;
5797
- intersects(rectangle: Rectangle): boolean;
5798
- draw(context: CanvasRenderingContext2D): void;
5799
- }
5800
- class QuadTree {
5801
- boundary: Rectangle;
5802
- capacity: number;
5803
- objects: Rectangle[];
5804
- topLeft: QuadTree;
5805
- topRight: QuadTree;
5806
- bottomLeft: QuadTree;
5807
- bottomRight: QuadTree;
5808
- divided: boolean;
5809
- parent?: QuadTree;
5810
- getSize(): any;
5811
- constructor(boundary: Rectangle, parent?: QuadTree);
5812
- subdivide(): void;
5813
- query(rectangle: Rectangle): Rectangle[];
5814
- insert(rectangle: Rectangle): boolean;
5815
- drawObjects(context: CanvasRenderingContext2D): void;
5816
- draw(context: CanvasRenderingContext2D): void;
5817
- }
5818
- export { QuadTree, Rectangle };
5819
- }
5820
-
5821
- declare module '@mappedin/mappedin-js/navigator/Edge' {
5822
- import INode from '@mappedin/mappedin-js/navigator/interfaces/INode';
5823
- import IVortex from '@mappedin/mappedin-js/navigator/interfaces/IVortex';
5824
- class Edge {
5825
- origin: INode;
5826
- destination: INode;
5827
- vortex?: IVortex;
5828
- distance: number;
5829
- angle: number;
5830
- weight: number;
5831
- constructor({ origin, destination, vortex, elevationDelta, distance, angle }: {
5832
- origin: INode;
5833
- destination: INode;
5834
- vortex?: IVortex;
5835
- elevationDelta?: number;
5836
- distance?: number;
5837
- angle?: number;
5838
- });
5839
- }
5840
- export default Edge;
5841
- }
5842
-
5843
- declare module '@mappedin/mappedin-js/navigator/interfaces/IMap' {
5844
- interface IGeoReference {
5845
- target: {
5846
- x: number;
5847
- y: number;
5848
- };
5849
- control: {
5850
- x: number;
5851
- y: number;
5852
- };
5853
- }
5854
- interface IMap {
5855
- id: string;
5856
- name: string;
5857
- shortName: string;
5858
- elevation?: number;
5859
- scale?: number;
5860
- x_scale?: number;
5861
- georeference?: IGeoReference[];
5862
- [propName: string]: any;
5863
- }
5864
- export default IMap;
5865
- }
5866
-
5867
- declare module '@mappedin/mappedin-js/navigator/interfaces/INode' {
5868
- interface INode {
5869
- id: string;
5870
- x: number;
5871
- y: number;
5872
- map: string;
5873
- externalId?: string;
5874
- [propName: string]: any;
5875
- }
5876
- export default INode;
5877
- }
5878
-
5879
- declare module '@mappedin/mappedin-js/navigator/interfaces/IVortex' {
5880
- interface IVortex {
5881
- id: string;
5882
- name: string;
5883
- type: string;
5884
- weight: number;
5885
- multiplier: number;
5886
- [propName: string]: any;
5887
- }
5888
- export default IVortex;
5889
- }
5890
-
5891
- declare module '@mappedin/mappedin-js/navigator/interfaces/ILocation' {
5892
- interface ILocation {
5893
- id: string;
5894
- name: string;
5895
- [propName: string]: any;
5896
- }
5897
- export default ILocation;
5898
- }
5899
-
5900
- declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.LabelAtlas' {
5901
- export namespace DEFAULT_LABEL_SIZING {
5902
- const MARGIN: number;
5903
- const HEIGHT_MARGIN: number;
5904
- const SIZE: number;
5905
- }
5906
- export class Atlas {
5907
- layers: any[];
5908
- canvas: HTMLCanvasElement;
5909
- context: CanvasRenderingContext2D | null;
5910
- addLabel(map: any, lines: any, font: any, size: any, scope: any, pixelsPerScale: any): Label | undefined;
5911
- removeLayer(layer: any): void;
5912
- measure(text: any, font: any, size: any): TextMetrics;
5913
- onWebGLContextRestored(): void;
5914
- dispose(): void;
5915
- }
5916
- export class FlatLabel {
5917
- constructor(options: any, venue: any, mapObject: any, DEFAULT_FONT: any, polygonMeshesById: any, textLabelsByPolygonId: any, mapView: any, scope: any, atlas: any);
5918
- id: any;
5919
- text: any;
5920
- stateText: string;
5921
- fullText: any;
5922
- font: any;
5923
- atlas: any;
5924
- canvasBounds: any;
5925
- mapScale: any;
5926
- margin: number;
5927
- heightMargin: number;
5928
- scaleMin: any;
5929
- scaleStep: any;
5930
- multiline: any;
5931
- height: number | null;
5932
- polygonMeshesById: any;
5933
- polyId: any;
5934
- map: any;
5935
- color: any;
5936
- hoverColor: any;
5937
- baseColor: any;
5938
- hideOnCreate: boolean;
5939
- hoverLabelText: any;
5940
- fontSize: number;
5941
- hoverLabelMode: any;
5942
- hoverLabelClass: any;
5943
- showHoverLabel: boolean;
5944
- hoverIfLabelFails: boolean;
5945
- textLabelsByPolygonId: any;
5946
- create(): void;
5947
- invalid: boolean | undefined;
5948
- label: any;
5949
- created: boolean | undefined;
5950
- flipIfNeeded(cameraAngle: any): void;
5951
- removeSelf(bulk: any): void;
5952
- doNotCreate: boolean | undefined;
5953
- setColor(textColor: any): void;
5954
- setHoverColor: (color: any) => void;
5955
- clearColor(): void;
5956
- hide(): void;
5957
- show(): void;
5958
- toString(): any;
5959
- }
5960
- class Label {
5961
- x: number;
5962
- y: number;
5963
- width: number;
5964
- height: number;
5965
- layer: any;
5966
- index: any;
5967
- layout(map: any, origin: any, size: any, rotation: any, uv: any, color: any): void;
6737
+ */
6738
+ popFromMaxKey(): any;
6739
+ /**
6740
+ * Return an iterator over every value in this multimap, at every key.
6741
+ * Mutating the multimap during iteration will result in undefined
6742
+ * behaviour.
6743
+ *
6744
+ * @method values
6745
+ * @return {Iterator} iterator over the values in the map
6746
+ */
6747
+ values(): {
6748
+ [Symbol.iterator]: () => any;
6749
+ next: () => any;
6750
+ };
6751
+ /**
6752
+ * A list of keys in this set, sorted by numeric value. Not cloned,
6753
+ * for efficiency's sake, so please don't mutate it.
6754
+ *
6755
+ * @method keys
6756
+ * @return {[number]} sorted list of numeric keys in the map
6757
+ */
6758
+ keys(): any[];
6759
+ /**
6760
+ * The number of elements in this multimap, equal to the sum of the sizes
6761
+ * of each key's set of values.
6762
+ *
6763
+ * @property size {number} number of elements in this multimap
6764
+ */
6765
+ get size(): number;
5968
6766
  }
5969
6767
  export {};
5970
6768
  }
5971
6769
 
5972
- declare module '@mappedin/mappedin-js/renderer/index.rn' {
5973
- import { getVenue, getVenueBundle, Mappedin, MappedinDestinationSet } from '@mappedin/mappedin-js/get-venue';
5974
- import { randomId } from '@mappedin/mappedin-js/--/common/random-id';
5975
- export * from '@mappedin/mappedin-js/renderer/MapView.enums';
5976
- export { getVenue,
5977
- /**
5978
- * @deprecated
5979
- */
5980
- getVenueBundle, MappedinDestinationSet, Mappedin, randomId };
5981
- export { GEOLOCATION_STATUS, COLLISION_RANKING_TIERS, E_BLUEDOT_STATE_REASON, E_BLUEDOT_STATE, E_BLUEDOT_MARKER_STATE, STATE, MARKER_ANCHOR, E_SDK_EVENT, E_BLUEDOT_EVENT, E_CAMERA_EVENT, E_CAMERA_DIRECTION, SAFE_AREA_INSET_TYPE, ANIMATION_TWEENS, CAMERA_EASING_MODE } from '@mappedin/mappedin-js/renderer/MapView.enums';
5982
- export { labelThemes } from '@mappedin/mappedin-js/renderer/MapView.types';
5983
- export type { IFlatLabels } from '@mappedin/mappedin-js/renderer/MapView.FlatLabels';
5984
- export type { IFloatingLabels } from '@mappedin/mappedin-js/renderer/MapView.FloatingLabels';
5985
- export type { TBlueDotPositionUpdate, TBlueDotStateChange, TJourneyOptions, TMapViewOptions, TCreateMarkerOptions, TGeolocationObject, TPathOptions, TFlatLabelOptions, TAddFloatingLabelOptions, TAddFlatLabelOptions, TLabelAllLocationCommonOptions, TFloatingLabelAllLocationsOptions, TFlatLabelAllLocationsOptions, TLabelAllLocationFlatLabelOptions, TLabelAllLocationFloatingLabelOptions, TEnableBlueDotOptions, TFloatingLabelAppearance, TFlatLabelAppearance, CAMERA_EVENT_PAYLOAD, TMapClickEvent, TGetPolygonsAtCoordinateOptions } from '@mappedin/mappedin-js/renderer/MapView.types';
5986
- export { BEARING_TYPE, ACTION_TYPE } from '@mappedin/mappedin-js/navigator';
5987
- export type { IDirectionsResult, E_MESSAGES as E_GET_DIRECTIONS_MESSAGES } from '@mappedin/mappedin-js/navigator';
5988
- export type { TGetVenueBundleOptions, TGetVenueOptions, TMappedinDirective, TShowVenueOptions, TMappedinOfflineSearchOptions, TMappedinOfflineSearchResult, TMappedinOfflineSearchSuggestions, TMappedinOfflineSearchAllOptions, TMappedinOfflineAllSearchMatch } from '@mappedin/mappedin-js/get-venue';
5989
- export { MappedinLocation, MappedinPolygon, MappedinNode, MappedinCategory, MappedinMap, MappedinEvent, MappedinMapGroup, MappedinVenue, MappedinVortex, MappedinDirections, MappedinNavigatable, MappedinCoordinate, MappedinRankings, MAP_RENDER_MODE, OfflineSearch, MappedinCollectionType } from '@mappedin/mappedin-js/get-venue';
5990
- export type { TSafeAreaInsets, TCameraTargets, TFocusOnCameraOptions, TCameraTransform, TCameraAnimationOptions } from '@mappedin/mappedin-js/renderer/Camera';
6770
+ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.MapManager' {
6771
+ export default MapManager;
6772
+ class MapManager extends PubSub {
6773
+ constructor(polygonMeshesById: any, renderer: any, mapView: any, taskScheduler: any, loadOptions?: {});
6774
+ mapObjects: Map<any, any>;
6775
+ currentMap: undefined;
6776
+ object: any;
6777
+ _showCount: number;
6778
+ _mapObjectsSortedByElevationDirty: boolean;
6779
+ expanded: boolean;
6780
+ polygonMeshesById: any;
6781
+ mapView: any;
6782
+ renderer: any;
6783
+ loadOptions: {};
6784
+ addMap(mapClass: any, callback?: () => void): any;
6785
+ setMap(mapClassOrId: any, callback: any): Promise<any>;
6786
+ removeMap(mapClassOrId: any): void;
6787
+ removeAllMaps(): void;
6788
+ loadMaps(maps: any, startingMap: any, onFirstMapLoaded?: () => void, onDataLoaded?: () => void, onError?: () => void): void;
6789
+ /**
6790
+ * Expand maps to display within view, typically used for multi-floor navigation. When passed a connection, maps included will not be displayed, instead, their 2d projection
6791
+ will be available in the resulting promise, which can be used to display a 2D component in the client-side app.
6792
+ *
6793
+ * @method expandMaps
6794
+ * @param mapIds {Array} Array of mapIds or mapObjects to display while expanded. For connections, pass &#123; connection: true, maps: [], connectionNodes: [], &#125;
6795
+ * @param options {Object} Options object @optional
6796
+ @param [options.focus=false] {Boolean} Focus the camera onto expanded maps
6797
+ @param [options.debug=false] {Boolean} Display cubes around focus bounding box for debug info
6798
+ @param [options.rotation=0] {Number} Rotation of scene relative to zero (degrees)
6799
+ @param [options.duration=300] {Number} Duration of focus animation in ms
6800
+ @returns {Promise} Promise that resolves to 2d screen projections of each layer/map (see example)
6801
+ @example
6802
+ // expand maps with 3 connection maps in between
6803
+ expandMaps(
6804
+ '55e89771d982bc06ca000000',
6805
+ {
6806
+ connection: true,
6807
+ // connection nodes are an exit node from the '55e89771' man and entry node for the '55e9c73f' map
6808
+ connectionNodes: [{
6809
+ map: "55e89771",
6810
+ x: 6232,
6811
+ y: 4575
6812
+ }, {
6813
+ map: "55e9c73",
6814
+ x: 5945.000000000001,
6815
+ y: 4059.000000000001
6816
+ }],
6817
+ maps: [
6818
+ '55e9acbf',
6819
+ '55e8a9ed',
6820
+ '55e85e23'
6821
+ ]
6822
+ },
6823
+ '55e9c73f'
6824
+ );
6825
+
6826
+ // resulting promise (sorted by elevation (top to bottom))
6827
+
6828
+ [
6829
+ {
6830
+ min: { x: -100, y: -50 },
6831
+ max: { x: -100, y: -50 }
6832
+ },
6833
+ {
6834
+ min: { x: -100, y: -50 },
6835
+ max: { x: -100, y: -50 }
6836
+ },
6837
+ {
6838
+ min: { x: -100, y: -50 },
6839
+ max: { x: -100, y: -50 }
6840
+ }
6841
+ ]
6842
+ */
6843
+ expandMaps(mapsToExpand: any, options: any): Promise<any>;
6844
+ /**
6845
+ * Contract maps and display the current map
6846
+ *
6847
+ * @method contractMaps
6848
+ * @param options {Object} Options object @optional
6849
+ @param [options.focus] {Boolean} Focus the camera onto current map
6850
+ @param [options.debug] {Boolean} Display cubes around focus bounding box for debug info
6851
+ @param [options.duration=300] {Number} Duration of focus animation in ms
6852
+ */
6853
+ contractMaps(options?: any): Promise<any>;
6854
+ expandPanBounds(bounds: any): void;
6855
+ /**
6856
+ * This can be used to invoke a callback function for _every_ set map invocation.
6857
+ * @param {Function} cb callback function
6858
+ */
6859
+ addPersistentSetMapCallback(cb: Function): void;
6860
+ persistentSetMapCallbacks: any;
6861
+ setMapCallbacks: any[] | undefined;
6862
+ get mapObjectsSortedByElevation(): any[];
6863
+ _mapObjectsSortedByElevation: any[] | undefined;
6864
+ get visibleMaps(): any[];
6865
+ getCompoundBoundingBoxPoints(objects: any): any[];
6866
+ multiFloorView: MultiFloorView | undefined;
6867
+ renderedMaps: any[] | undefined;
6868
+ projections: any[] | undefined;
6869
+ mapsFullyLoaded(callback?: () => void): Promise<void>;
6870
+ /**
6871
+ * Scroll maps up
6872
+ * This will shift maps down to show next one (above)
6873
+ */
6874
+ scrollMapsUp(): Promise<any>;
6875
+ /**
6876
+ * Scroll maps down
6877
+ * This will shift maps up to show next one (below)
6878
+ */
6879
+ scrollMapsDown(): Promise<any>;
6880
+ tiltMaps(tilt: any): void;
6881
+ resize(): void;
6882
+ }
6883
+ import { PubSub } from "@mappedin/mappedin-js/renderer/internal/pub-sub";
6884
+ import MultiFloorView from "@mappedin/mappedin-js/renderer/internal/Mappedin.MultiFloorView";
5991
6885
  }
5992
6886
 
5993
- declare module '@mappedin/mappedin-js/renderer/MapView.Scene' {
5994
- import { MappedinMap } from '@mappedin/mappedin-js/get-venue';
5995
- import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
5996
- import MapObject from '@mappedin/mappedin-js/renderer/internal/Mappedin.MapObject';
5997
- import { TSceneTransitionOptions } from '@mappedin/mappedin-js/renderer/MapView.SceneManager';
5998
- class MapViewScene {
5999
- #private;
6000
- maps: MappedinMap[];
6001
- object: any;
6002
- currentMap: MappedinMap;
6003
- mapObjects: Map<MappedinMap['id'], MapObject>;
6004
- constructor(maps: MappedinMap[], core: ICore);
6005
- /**
6006
- * Determine each maps position and rotation relative to the refernce map
6007
- */
6008
- determineMapPositionAndRotation(map: MappedinMap): {
6009
- position: any[];
6010
- scale: number[];
6011
- rotation: number[];
6887
+ import { Mesh, BufferAttribute, InstancedBufferAttribute, InstancedBufferGeometry, Object3D, Color, CanvasTexture, RawShaderMaterial } from 'three';
6888
+ import { getObjectId, getObject } from '@mappedin/mappedin-js/renderer/internal/utils';
6889
+ import HoverLabel from '@mappedin/mappedin-js/renderer/internal/Mappedin.HoverLabel.js';
6890
+ import LabelAtlasFragment from '@mappedin/mappedin-js/renderer/internal/shaders/Mappedin.LabelAtlas.Fragment.glsl';
6891
+ import LabelAtlasVertex from '@mappedin/mappedin-js/renderer/internal/shaders/Mappedin.LabelAtlas.Vertex.glsl';
6892
+ export const DEFAULT_LABEL_SIZING = {
6893
+ MARGIN: 2,
6894
+ HEIGHT_MARGIN: 0.5,
6895
+ SIZE: 1.2
6896
+ };
6897
+ const FONT_SIZE = 56;
6898
+ const SIZE_IN_METERS = FONT_SIZE / DEFAULT_LABEL_SIZING.SIZE; // About this, make it the same as legacy labels anyway
6899
+ const PIXELS_PER_METER = FONT_SIZE / 2;
6900
+ const METERS_PER_PIXEL = 1 / PIXELS_PER_METER;
6901
+ const CANVAS_MAX_LABELS = 64;
6902
+ const MIN_SLOT_SIZE = 16;
6903
+ const LABEL_PADDING = 4;
6904
+ class Label {
6905
+ constructor() {
6906
+ this.x = 0;
6907
+ this.y = 0;
6908
+ this.width = 0;
6909
+ this.height = 0;
6910
+ this.layer = null;
6911
+ this.index = null;
6912
+ }
6913
+ /// This _just_ lays out the vertex into the attribute buffers.
6914
+ layout(map, origin, size, rotation, uv, color) {
6915
+ let angle = (this.canvasBounds.rotation * Math.PI) / 180;
6916
+ let width = this.width * this.pixelsPerMu;
6917
+ let height = this.height * this.pixelsPerMu;
6918
+ // fix the alignment of the labels. This just shifts them around
6919
+ // in canvasBound area to the left/right/center
6920
+ let offset;
6921
+ if (this.canvasBounds.align == 'left') {
6922
+ offset = this.margin;
6923
+ }
6924
+ else if (this.canvasBounds.align == 'right') {
6925
+ offset = this.canvasBounds.maxWidth - width - this.margin;
6926
+ }
6927
+ else if (this.canvasBounds.align == 'center') {
6928
+ offset = (this.canvasBounds.maxWidth - width - this.margin) / 2;
6929
+ }
6930
+ let offsetX = offset * Math.cos(angle);
6931
+ let offsetY = -offset * Math.sin(angle);
6932
+ let index = this.index;
6933
+ origin.setXYZ(index, this.canvasBounds.x - map.width / 2 + offsetX, -this.canvasBounds.y + map.height / 2 + offsetY, this.z + 0.1);
6934
+ size.setXY(index, width, height);
6935
+ rotation.setX(index, angle);
6936
+ let canvas = this.layer.canvas;
6937
+ uv.setXYZW(index, this.x / canvas.width, 1 - this.y / canvas.height, this.width / canvas.width, this.height / canvas.height);
6938
+ color.setXYZ(index, this.color.r, this.color.g, this.color.b);
6939
+ // mark all the arrays as needing to be updated (reuploaded) since
6940
+ // they have now been changed.
6941
+ origin.needsUpdate = true;
6942
+ size.needsUpdate = true;
6943
+ rotation.needsUpdate = true;
6944
+ uv.needsUpdate = true;
6945
+ color.needsUpdate = true;
6946
+ }
6947
+ }
6948
+ class Slot {
6949
+ constructor(x, y, width, height) {
6950
+ this.x = x;
6951
+ this.y = y;
6952
+ this.width = width;
6953
+ this.height = height;
6954
+ }
6955
+ leftOverSpace(glyph) {
6956
+ // check to see if it would not fit.
6957
+ if (this.width < glyph.width || this.height < glyph.height) {
6958
+ return null;
6959
+ }
6960
+ return (this.height * (this.width - glyph.width) +
6961
+ this.width * (this.height - glyph.height));
6962
+ }
6963
+ /// split this slot into 0-2 spaces.
6964
+ split(label, spaces, index) {
6965
+ label.x = this.x;
6966
+ label.y = this.y;
6967
+ if (this.width - label.height < MIN_SLOT_SIZE &&
6968
+ this.height - label.height < MIN_SLOT_SIZE) {
6969
+ // delete itself from the array
6970
+ spaces.splice(index, 1);
6971
+ }
6972
+ else if (this.width === label.width) {
6973
+ spaces.splice(index, 1, new Slot(this.x, this.y + label.height, this.width, this.height - label.height));
6974
+ }
6975
+ else if (this.height === label.height) {
6976
+ spaces.splice(index, 1, new Slot(this.x + label.width, this.y, this.width - label.width, this.height));
6977
+ }
6978
+ else {
6979
+ spaces.splice(index, 1, new Slot(this.x + label.width, this.y, this.width - label.width, label.height), new Slot(this.x, this.y + label.height, this.width, this.height - label.height));
6980
+ }
6981
+ }
6982
+ }
6983
+ class AtlasLayer {
6984
+ /// Creates a new Atlas Layer,
6985
+ constructor(atlas, map, width, height) {
6986
+ // height can be anything so we have to match it to a close power of two
6987
+ let power = 5; // start with 5 because 2^5 is 32 which is a good lower bounds
6988
+ while (Math.pow(2, power) < height) {
6989
+ power += 1;
6990
+ }
6991
+ height = Math.pow(2, power);
6992
+ power = 10; // start with 5 because 2^10 is 1024 which is a good lower bounds
6993
+ while (Math.pow(2, power) < width) {
6994
+ power += 1;
6995
+ }
6996
+ width = Math.pow(2, power);
6997
+ this.atlas = atlas;
6998
+ // the map that this layer is used for, since this get rendered
6999
+ // as a single object we cannot for any reason reuse a layer for a
7000
+ // different map.
7001
+ this.map = map;
7002
+ this.canvasWidth = width;
7003
+ this.canvasHeight = height;
7004
+ // create a canvas and context to draw the text labels into
7005
+ this.canvas = document.createElement('canvas');
7006
+ this.canvas.width = this.canvasWidth;
7007
+ this.canvas.height = this.canvasHeight;
7008
+ this.context = this.canvas.getContext('2d');
7009
+ this.context.textBaseline = 'bottom';
7010
+ // the list of free space in the canvas that we can put blocks int
7011
+ this.spaces = [new Slot(0, 0, this.canvas.width, this.canvas.height)];
7012
+ // an array of free slots for when labels get destroyed
7013
+ this.free = [];
7014
+ // an array of labels that are contained
7015
+ this.labels = [];
7016
+ this.count = CANVAS_MAX_LABELS;
7017
+ // Create buffers to hold the binary data for rendering data
7018
+ let origin = new Float32Array(this.count * 3);
7019
+ let size = new Float32Array(this.count * 2);
7020
+ let rotation = new Float32Array(this.count);
7021
+ let uv = new Float32Array(this.count * 4);
7022
+ let color = new Float32Array(this.count * 3);
7023
+ this.uv = new InstancedBufferAttribute(uv, 4, false, 1);
7024
+ this.uv.set(uv);
7025
+ this.uv.needsUpdate = true;
7026
+ this.origin = new InstancedBufferAttribute(origin, 3, false, 1);
7027
+ this.origin.set(origin);
7028
+ this.origin.needsUpdate = true;
7029
+ this.size = new InstancedBufferAttribute(size, 2, false, 1);
7030
+ this.size.set(size);
7031
+ this.size.needsUpdate = true;
7032
+ this.rotation = new InstancedBufferAttribute(rotation, 1, false, 1);
7033
+ this.rotation.set(rotation);
7034
+ this.rotation.needsUpdate = true;
7035
+ this.color = new InstancedBufferAttribute(color, 3, true, 1);
7036
+ this.color.set(color);
7037
+ this.color.needsUpdate = true;
7038
+ // these will probably always be zero, but we want to make sure anyhow
7039
+ // a none zero sized element might render with an invalid texture
7040
+ // coordinate which would be pretty bad.
7041
+ for (let i = 0; i < this.count; i++) {
7042
+ this.zero(i);
7043
+ }
7044
+ // create the polygon, this is just a square 1x1
7045
+ let positions = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]);
7046
+ let indicies = [0, 3, 1, 3, 2, 1];
7047
+ // Setup the geometry buffer
7048
+ this.geometry = new InstancedBufferGeometry();
7049
+ this.geometry.setIndex(indicies);
7050
+ this.geometry.setAttribute('position', new BufferAttribute(positions, 3));
7051
+ this.geometry.setAttribute('size', this.size);
7052
+ this.geometry.setAttribute('origin', this.origin);
7053
+ this.geometry.setAttribute('rotation', this.rotation);
7054
+ this.geometry.setAttribute('uv', this.uv);
7055
+ this.geometry.setAttribute('color', this.color);
7056
+ // Three allows for wrapping of a canvas into a texture, neat
7057
+ this.texture = new CanvasTexture(this.canvas);
7058
+ this.texture.anisotropy = 16;
7059
+ // create the shader
7060
+ this.material = new RawShaderMaterial();
7061
+ this.material.vertexShader = LabelAtlasVertex;
7062
+ this.material.fragmentShader = LabelAtlasFragment;
7063
+ this.material.uniforms = {
7064
+ textureLabel: { value: this.texture }
6012
7065
  };
6013
- /** Render scene */
6014
- render(map: MappedinMap, transitionOptions?: TSceneTransitionOptions, isStartingScene?: boolean): Promise<void>;
7066
+ // marked as transparent because the we alpha blend the textures
7067
+ this.material.transparent = true;
7068
+ // create the mesh
7069
+ this.mesh = new Mesh(this.geometry, this.material);
7070
+ // create a 3D object for the scene graph containing the mesh
7071
+ this.obj = new Object3D();
7072
+ this.obj.add(this.mesh);
7073
+ // This logic uses a custom vertex shader to position and size the
7074
+ // actual vertices. This has a side effect of the renderer not actually
7075
+ // knowing the size of the object. Disabling the frustum culling
7076
+ // prevents this.
7077
+ this.obj.frustumCulled = false;
7078
+ this.mesh.frustumCulled = false;
7079
+ // add to the map
7080
+ this.map.add(this.obj);
7081
+ }
7082
+ // return the number of bytes left in this layer
7083
+ space() {
7084
+ return this.spaces.map(x => x.width * x.height).reduce((x, y) => x + y);
7085
+ }
7086
+ // set a index of the arrays to zero.
7087
+ zero(index) {
7088
+ this.origin.array[index * 3 + 0] = 0;
7089
+ this.origin.array[index * 3 + 1] = 0;
7090
+ this.origin.array[index * 3 + 2] = 0;
7091
+ this.size.array[index * 2 + 0] = 0;
7092
+ this.size.array[index * 2 + 1] = 0;
7093
+ this.rotation.array[index] = 0;
7094
+ this.uv.array[index * 4 + 0] = 0;
7095
+ this.uv.array[index * 4 + 1] = 0;
7096
+ this.uv.array[index * 4 + 2] = 0;
7097
+ this.uv.array[index * 4 + 3] = 0;
7098
+ this.color.array[index * 3 + 0] = 0;
7099
+ this.color.array[index * 3 + 1] = 0;
7100
+ this.color.array[index * 3 + 2] = 0;
7101
+ this.origin.needsUpdate = true;
7102
+ this.size.needsUpdate = true;
7103
+ this.rotation.needsUpdate = true;
7104
+ this.uv.needsUpdate = true;
7105
+ this.color.needsUpdate = true;
7106
+ }
7107
+ // find space for a label, if there is no space this will return false.
7108
+ // if space was found, the label is added to this Atlas and the label index
7109
+ // is set.
7110
+ //
7111
+ // Note: The label is added for house keeping, the values of the buffers
7112
+ // have not been configured yet. And the text has not been rendered
7113
+ findSpace(label) {
7114
+ // even if there is space, there is no space left in the draw buffers
7115
+ if (this.free.length != 0 && this.labels.length == this.count) {
7116
+ return false;
7117
+ }
7118
+ // search 'spaces' for the entry that fits the glyph best. 'best' means
7119
+ // least amount of wasted space, ideally 0.
7120
+ let best = -1;
7121
+ for (let i = 0; i < this.spaces.length; i++) {
7122
+ let space = this.spaces[i].leftOverSpace(label);
7123
+ if (space === null) {
7124
+ continue;
7125
+ }
7126
+ if (best === -1 || this.spaces[i].leftOverSpace(label) < space) {
7127
+ best = i;
7128
+ }
7129
+ }
7130
+ if (best !== -1) {
7131
+ this.spaces[best].split(label, this.spaces, best);
7132
+ label.layer = this;
7133
+ // Append an element to an array if there no free slots,
7134
+ // if there are free slots we reuse the space instead.
7135
+ if (this.free.length === 0) {
7136
+ label.index = this.labels.length;
7137
+ this.labels.push(label);
7138
+ }
7139
+ else {
7140
+ label.index = this.free.pop();
7141
+ this.labels[label.index] = label;
7142
+ }
7143
+ }
7144
+ // returns true if there was space found.
7145
+ return best != -1;
7146
+ }
7147
+ // remove this label from the internal contents of this atlas.
7148
+ remove(label) {
7149
+ if (label.index === undefined) {
7150
+ return;
7151
+ }
7152
+ // remove this object from the vertex array.
7153
+ this.zero(label.index);
7154
+ // clear the pixel memory to avoid reuse of this area getting messed up
7155
+ this.context.clearRect(label.x, label.y, label.width, label.height);
7156
+ // add the free spaces to the free list
7157
+ this.spaces.push(new Slot(label.x, label.y, label.width, label.height));
7158
+ this.free.push(label.index);
7159
+ this.labels[label.index] = null;
7160
+ // check to see if there is actually any labels left
7161
+ let empty = true;
7162
+ for (let iLabel of this.labels) {
7163
+ empty = empty && iLabel != null;
7164
+ if (!empty) {
7165
+ break;
7166
+ }
7167
+ }
7168
+ // if there are no labels left, remove this layer
7169
+ if (empty) {
7170
+ this.atlas.removeLayer(this);
7171
+ }
7172
+ }
7173
+ // render a label to the canvas
7174
+ render(label) {
7175
+ this.context.save();
7176
+ this.context.rect(label.x + 1, label.y + 1, label.width - 1 * 2, label.height - 1 * 2);
7177
+ this.context.clip();
7178
+ this.context.font = label.size + 'px ' + label.font;
7179
+ for (let line of label.lines) {
7180
+ this.context.fillText(line.text, line.x + label.x + LABEL_PADDING, line.y + label.y + line.height + LABEL_PADDING);
7181
+ }
7182
+ this.texture.needsUpdate = true;
7183
+ this.context.restore();
7184
+ }
7185
+ // Reset canvas and re-render all labels
7186
+ onWebGLContextRestored() {
7187
+ this.canvas = document.createElement('canvas');
7188
+ this.canvas.width = this.canvasWidth;
7189
+ this.canvas.height = this.canvasHeight;
7190
+ this.context = this.canvas.getContext('2d');
7191
+ this.context.textBaseline = 'bottom';
7192
+ this.texture = new CanvasTexture(this.canvas);
7193
+ this.texture.anisotropy = 16;
7194
+ this.material.uniforms.textureLabel.value = this.texture;
7195
+ for (let label of this.labels) {
7196
+ if (label != null) {
7197
+ this.render(label);
7198
+ }
7199
+ }
7200
+ }
7201
+ // free all resources associated with this layer
7202
+ dispose() {
7203
+ this.geometry.dispose();
7204
+ this.material.dispose();
7205
+ this.texture.dispose();
7206
+ }
7207
+ }
7208
+ class Atlas {
7209
+ constructor() {
7210
+ this.layers = [];
7211
+ this.canvas = document.createElement('canvas');
7212
+ this.context = this.canvas.getContext('2d');
7213
+ }
7214
+ /// adds label to the atlas
7215
+ addLabel(map, lines, font, size, scope, pixelsPerScale) {
7216
+ // get the max width / height
7217
+ let height = 0;
7218
+ let width = 0;
7219
+ for (let line of lines) {
7220
+ width = Math.max(Math.ceil(line.width + line.x), width);
7221
+ height = Math.max(Math.ceil(line.height + line.y), height);
7222
+ }
7223
+ let label = new Label();
7224
+ label.map = map;
7225
+ label.width = width + LABEL_PADDING * 2;
7226
+ label.height = height + LABEL_PADDING * 2;
7227
+ label.lines = lines;
7228
+ label.font = font;
7229
+ label.size = size;
7230
+ label.canvasBounds = scope.canvasBounds;
7231
+ label.margin = scope.margin;
7232
+ label.heightMargin = scope.heightMargin;
7233
+ label.pixelsPerMu = pixelsPerScale;
7234
+ label.z = scope.height;
7235
+ label.view = scope;
7236
+ label.color = scope.color;
7237
+ let layer;
7238
+ // find a slot to place this label in
7239
+ for (let iLayer of this.layers) {
7240
+ layer = iLayer;
7241
+ if (layer.map !== map) {
7242
+ layer = null;
7243
+ continue;
7244
+ }
7245
+ if (layer.findSpace(label)) {
7246
+ break;
7247
+ }
7248
+ layer = null;
7249
+ }
7250
+ // no space was found, create a new layer
7251
+ if (layer == null) {
7252
+ layer = new AtlasLayer(this, map, label.width, label.height);
7253
+ this.layers.push(layer);
7254
+ if (!layer.findSpace(label)) {
7255
+ return;
7256
+ }
7257
+ // order the layers such that the least populated ones are first.
7258
+ this.layers.sort((a, b) => b.space() - a.space());
7259
+ }
7260
+ layer.render(label);
7261
+ label.layout(map.mapClass, layer.origin, layer.size, layer.rotation, layer.uv, layer.color);
7262
+ label.layer = layer;
7263
+ return label;
7264
+ }
7265
+ // delete a layer from the list of layers
7266
+ removeLayer(layer) {
7267
+ let index = this.layers.indexOf(layer);
7268
+ if (index != -1) {
7269
+ this.layers.splice(index, 1);
7270
+ }
7271
+ }
7272
+ // measure the size of a element with a given font and size
7273
+ measure(text, font, size) {
7274
+ this.context.font = size + 'px ' + font;
7275
+ return this.context.measureText(text);
7276
+ }
7277
+ // Retore all layers
7278
+ onWebGLContextRestored() {
7279
+ for (let layer of this.layers) {
7280
+ layer.onWebGLContextRestored();
7281
+ }
7282
+ }
7283
+ // cleans up all the layers of the Atlas
7284
+ dispose() {
7285
+ for (let layer of this.layers) {
7286
+ layer.dispose();
7287
+ }
7288
+ }
7289
+ }
7290
+ class FlatLabel {
7291
+ constructor(options, venue, mapObject, DEFAULT_FONT, polygonMeshesById, textLabelsByPolygonId, mapView, scope, atlas) {
7292
+ let polygon = getObject(options.polygon, venue.polygons);
7293
+ this.id = polygon.id;
7294
+ this.text = (options.shortText || options.text).trim();
7295
+ this.stateText = options.stateText ? ' (' + options.stateText + ')' : '';
7296
+ this.fullText = this.stateText ? this.text + this.stateText : this.text;
7297
+ this.font = options.font || DEFAULT_FONT;
7298
+ this.atlas = atlas;
7299
+ this.canvasBounds = options.canvasBounds || polygon.canvasBounds;
7300
+ this.mapScale = mapObject.getMapScale() || 1;
7301
+ this.margin =
7302
+ (options.margin || DEFAULT_LABEL_SIZING.MARGIN) * this.mapScale;
7303
+ this.heightMargin =
7304
+ (options.heightMargin || DEFAULT_LABEL_SIZING.HEIGHT_MARGIN) *
7305
+ this.mapScale;
7306
+ this.scaleMin = options.scaleMin || 0.25;
7307
+ this.scaleStep = options.scaleStep > 0 ? options.scaleStep : 0.25;
7308
+ this.multiline = options.multiline == undefined ? true : options.multiline;
7309
+ this.height = Number(options.height) || null;
7310
+ this.polygonMeshesById = polygonMeshesById;
7311
+ this.polyId =
7312
+ options.polygonId || getObjectId(options.polygon, venue.polygons);
7313
+ this.map = mapObject;
7314
+ this.color = new Color(options.color || scope.colors.text || '#000000');
7315
+ this.hoverColor = new Color(options.hoverColor || this.color);
7316
+ this.baseColor = this.color;
7317
+ this.hideOnCreate = false;
7318
+ this.hoverLabelText = options.text.trim();
7319
+ this.fontSize =
7320
+ options.fontSize * this.mapScale ||
7321
+ options.size * SIZE_IN_METERS ||
7322
+ FONT_SIZE;
7323
+ this.hoverLabelMode = options.hoverLabelMode3D || HoverLabel.MODES.ALL;
7324
+ this.hoverLabelClass = options.hoverLabelClass || 'mMapviewHoverLabel';
7325
+ this.showHoverLabel =
7326
+ this.hoverLabelMode == HoverLabel.MODES.ALL ||
7327
+ this.hoverLabelMode == HoverLabel.MODES.NO_TEXT_LABEL_ONLY;
7328
+ this.hoverIfLabelFails =
7329
+ this.hoverLabelMode == HoverLabel.MODES.ALL ||
7330
+ this.hoverLabelMode == HoverLabel.MODES.NO_TEXT_LABEL_ONLY;
7331
+ this.textLabelsByPolygonId = textLabelsByPolygonId;
7332
+ this.map.textObjects.push(this);
7333
+ }
7334
+ create() {
7335
+ let scope = this;
7336
+ // This could get killed before we even get to creation
7337
+ if (this.doNotCreate) {
7338
+ return;
7339
+ }
7340
+ if (scope.canvasBounds == null) {
7341
+ scope.invalid = true;
7342
+ scope.message = "No Canvas Bounds. Can't draw text '" + scope.text + "'";
7343
+ scope.showHoverLabel = scope.hoverIfLabelFails;
7344
+ return;
7345
+ }
7346
+ scope.showHoverLabel = this.hoverLabelMode == HoverLabel.MODES.ALL;
7347
+ let muPerPixel = METERS_PER_PIXEL * this.mapScale;
7348
+ let pixelsPerMu = PIXELS_PER_METER / this.mapScale;
7349
+ let labelsToAttempt = [this.text];
7350
+ if (this.stateText.length)
7351
+ labelsToAttempt.unshift(this.fullText);
7352
+ for (let attempt of labelsToAttempt) {
7353
+ // attempt to layout the words
7354
+ let words = attempt.split(' ').map(function (word) {
7355
+ return {
7356
+ width: scope.atlas.measure(word, scope.font, scope.fontSize).width,
7357
+ word: word
7358
+ };
7359
+ });
7360
+ // convert the canvas bounds to an area minus in pixels
7361
+ let availableWidth = (this.canvasBounds.maxWidth - this.margin * 2) * pixelsPerMu;
7362
+ let availableHeight = (this.canvasBounds.maxHeight - this.heightMargin * 2) * pixelsPerMu;
7363
+ let maxShrinkSteps = (1 - this.scaleMin) / this.scaleStep;
7364
+ let minimumShrinkSteps = 0;
7365
+ let spaceWidth = this.atlas.measure(' ', this.font, this.fontSize).width;
7366
+ let lineHeight = getTextHeight(this.fontSize + 'px ' + this.font);
7367
+ for (let i = 0, iLen = words.length; i < iLen; i++) {
7368
+ let width = words[i].width;
7369
+ let wShrinkSteps = Math.ceil((width - availableWidth) / (width * this.scaleStep));
7370
+ minimumShrinkSteps = Math.max(wShrinkSteps, minimumShrinkSteps);
7371
+ }
7372
+ if (this.height == null) {
7373
+ if (this.polygonMeshesById[this.polyId]) {
7374
+ let target = this.polygonMeshesById[this.polyId];
7375
+ if (!target.geometry.boundingBox) {
7376
+ target.geometry.computeBoundingBox();
7377
+ }
7378
+ this.height = target.geometry.boundingBox.max.z + target.position.z;
7379
+ }
7380
+ else {
7381
+ this.height = 0;
7382
+ }
7383
+ }
7384
+ var lines;
7385
+ var shrinkStep;
7386
+ var currentScale;
7387
+ let scaleStep = this.scaleStep;
7388
+ shrink: for (shrinkStep = minimumShrinkSteps; shrinkStep <= maxShrinkSteps; shrinkStep++) {
7389
+ currentScale = 1 - shrinkStep * scaleStep;
7390
+ let thisLineWidth = words[0].width * currentScale;
7391
+ lines = [
7392
+ {
7393
+ text: words[0].word,
7394
+ width: thisLineWidth,
7395
+ height: lineHeight * currentScale,
7396
+ x: 0,
7397
+ y: 0
7398
+ }
7399
+ ];
7400
+ for (let iWordSize = 1; iWordSize < words.length; iWordSize++) {
7401
+ let wordSize = words[iWordSize];
7402
+ let spaceForNextWord = (wordSize.width + spaceWidth) * currentScale;
7403
+ if (thisLineWidth + spaceForNextWord < availableWidth) {
7404
+ // Add to line
7405
+ lines[lines.length - 1].text += ' ' + wordSize.word;
7406
+ lines[lines.length - 1].width += spaceForNextWord;
7407
+ thisLineWidth += spaceForNextWord;
7408
+ }
7409
+ else {
7410
+ // New line
7411
+ if (!this.multiline)
7412
+ continue shrink;
7413
+ lines[lines.length - 1].width = thisLineWidth;
7414
+ thisLineWidth = wordSize.width * currentScale;
7415
+ lines.push({
7416
+ text: wordSize.word,
7417
+ width: thisLineWidth,
7418
+ height: lineHeight * currentScale,
7419
+ x: 0,
7420
+ y: lines[lines.length - 1].height + lines[lines.length - 1].y
7421
+ });
7422
+ }
7423
+ }
7424
+ let requiredHeight = lines.length * lineHeight * currentScale;
7425
+ if (requiredHeight <= availableHeight) {
7426
+ this.invalid = false;
7427
+ break;
7428
+ }
7429
+ }
7430
+ if (this.invalid == false)
7431
+ break;
7432
+ }
7433
+ if (this.invalid == false) {
7434
+ // center each line
7435
+ let lineTotalWidth = lines
7436
+ .map(x => Math.ceil(x.width))
7437
+ .reduce((a, b) => Math.max(a, b));
7438
+ for (let line of lines) {
7439
+ line.x = (lineTotalWidth - line.width) / 2;
7440
+ }
7441
+ // lines, font, size, scope, pixelsPerScale
7442
+ this.label = this.atlas.addLabel(this.map, lines, this.font, this.fontSize * currentScale, this, muPerPixel);
7443
+ }
7444
+ this.created = true;
7445
+ }
7446
+ // eslint-disable-next-line class-methods-use-this
7447
+ flipIfNeeded(cameraAngle) {
7448
+ // this is done in the shader, so we will not do anything here
7449
+ // this function simply exists for parity with 'TextLabel'
7450
+ }
7451
+ removeSelf(bulk) {
7452
+ if (this.created) {
7453
+ if (this.label != null) {
7454
+ this.label.layer.remove(this.label);
7455
+ this.label = null;
7456
+ }
7457
+ if (!bulk) {
7458
+ this.map.textObjects = this.map.textObjects.filter(object => object != this);
7459
+ // Delete from textLabelsByPolygonId
7460
+ Object.keys(this.textLabelsByPolygonId).forEach(key => {
7461
+ if (this.textLabelsByPolygonId[key] == this) {
7462
+ delete this.textLabelsByPolygonId[key];
7463
+ }
7464
+ });
7465
+ }
7466
+ }
7467
+ else {
7468
+ this.doNotCreate = true;
7469
+ }
7470
+ }
7471
+ setColor(textColor) {
7472
+ const color = new Color(textColor);
7473
+ const sameColor = this.color.equals(color);
7474
+ const withLabel = Boolean(this.label?.layer);
7475
+ this.color = color;
7476
+ if (!sameColor && withLabel) {
7477
+ this.label.color = this.color;
7478
+ this.label.layout(this.map.mapClass, this.label.layer.origin, this.label.layer.size, this.label.layer.rotation, this.label.layer.uv, this.label.layer.color);
7479
+ }
7480
+ }
7481
+ setHoverColor = color => {
7482
+ this.hoverColor = new Color(color);
7483
+ };
7484
+ clearColor() {
7485
+ this.setColor(this.baseColor);
7486
+ }
7487
+ hide() {
7488
+ if (this.label) {
7489
+ this.label.layer.zero(this.label.index);
7490
+ }
7491
+ else {
7492
+ this.hideOnCreate = true;
7493
+ }
7494
+ }
7495
+ show() {
7496
+ if (this.label) {
7497
+ let layer = this.label.layer;
7498
+ let map = this.map;
7499
+ let label = this.label;
7500
+ label.layout(map.mapClass, layer.origin, layer.size, layer.rotation, layer.uv, layer.color);
7501
+ }
7502
+ else {
7503
+ this.hideOnCreate = false;
7504
+ }
7505
+ }
7506
+ toString() {
7507
+ return this.hoverLabelText;
6015
7508
  }
6016
- export default MapViewScene;
6017
7509
  }
7510
+ let textHeightCache = new Map();
7511
+ var getTextHeight = function (font) {
7512
+ // check if the font is in the cache because modifying the dom is expensive
7513
+ let height = textHeightCache[font];
7514
+ if (height != undefined) {
7515
+ return height;
7516
+ }
7517
+ let text = document.createElement('span');
7518
+ text.textContent = 'Hg';
7519
+ text.style.font = font;
7520
+ let block = document.createElement('div');
7521
+ block.style.cssText = 'display: inline-block; width: 1px; height: 0px;';
7522
+ let div = document.createElement('div');
7523
+ div.appendChild(text);
7524
+ div.appendChild(block);
7525
+ let body = document.body;
7526
+ body.appendChild(div);
7527
+ try {
7528
+ var bounding = text.getBoundingClientRect();
7529
+ }
7530
+ finally {
7531
+ div.remove();
7532
+ }
7533
+ // add the element to the cache
7534
+ if (bounding.height != undefined) {
7535
+ textHeightCache[font] = bounding.height;
7536
+ height = bounding.height;
7537
+ }
7538
+ return height;
7539
+ };
7540
+ export { Atlas, FlatLabel };
6018
7541
 
6019
7542
  declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.MapObject' {
6020
7543
  export namespace TASK_PRIORITY {
@@ -6105,7 +7628,24 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.MapObject' {
6105
7628
  loadMethodUsed: string | undefined;
6106
7629
  _dispose(objectToDispose: any): void;
6107
7630
  add(childObjectToAdd: any): void;
7631
+ /**
7632
+ * Convert lat/lon to local map position vector
7633
+ */
6108
7634
  getPositionLatLon(lat: any, lon: any): any;
7635
+ /**
7636
+ * Previously, each map was centered around 0,0,0 and scaled to fit the map.
7637
+ * With scene manager, each map is positioned and scaled relative to the base map/world
7638
+ * Since most 3D objects (like blue dot) are added to the map via `getPositionLatLon`, they already
7639
+ * have the map's matrix applied, on top of being affected as a child of the map's own transform
7640
+ * This method inverts the map's matrix to resolve the double matrix application issue.
7641
+ * TODO: investigate a better way to handle this
7642
+ */
7643
+ addToObject(child: any): void;
7644
+ /**
7645
+ * Translates objects that are added to the map (such as blue dot), assuming they are added via `getPositionLatLon`,
7646
+ * or `convertTo3DMapPosition`, where the map's matrix has already been applied.
7647
+ */
7648
+ translateChild(child: any, position: any): void;
6109
7649
  getMapScale(): null;
6110
7650
  getNorth(): null;
6111
7651
  disableAllImageFlipping(): void;
@@ -6204,3 +7744,484 @@ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.MapObject' {
6204
7744
  import { FrameTaskGroup } from "@mappedin/mappedin-js/get-venue/Mappedin.TaskScheduler";
6205
7745
  }
6206
7746
 
7747
+ declare module '@mappedin/mappedin-js/renderer/MapView.SceneManager' {
7748
+ import { MappedinMap } from '@mappedin/mappedin-js/get-venue';
7749
+ import { TCameraTransform, TCameraAnimationOptions } from '@mappedin/mappedin-js/renderer/Camera';
7750
+ import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
7751
+ import MapViewScene from '@mappedin/mappedin-js/renderer/MapView.Scene';
7752
+ export type TSceneTransitionOptions = {
7753
+ /**
7754
+ * Map to set as active during the transition. This will decide where the camera will be positioned, as well as which
7755
+ * colliders are enabled.
7756
+ */
7757
+ activeMap?: MappedinMap;
7758
+ verticalDistanceBetweenMaps?: number;
7759
+ /**
7760
+ * Camera options to use when transitioning to the new scene
7761
+ */
7762
+ cameraTransform?: TCameraTransform;
7763
+ cameraAnimationOptions?: TCameraAnimationOptions;
7764
+ /**
7765
+ * Whether to auto focus on the active map or leave the camera where it is.
7766
+ * For single building venues, this should look the same way it did with MapManager
7767
+ * For multi-building venues, this means the camera will not pan over to where the active map
7768
+ * is relative to the world, which may look like broken behavior.
7769
+ * @default true
7770
+ */
7771
+ autoFocusOnActiveMap?: boolean;
7772
+ };
7773
+ class SceneManager {
7774
+ #private;
7775
+ currentScene: MapViewScene;
7776
+ constructor(core: ICore, startingScene: MapViewScene);
7777
+ get currentMap(): MappedinMap;
7778
+ renderGrid(): void;
7779
+ transitionTo(scene: MapViewScene, transitionOptions?: TSceneTransitionOptions): Promise<void>;
7780
+ }
7781
+ export default SceneManager;
7782
+ }
7783
+
7784
+ /**
7785
+ * Camera layers that are used for rendering, which are assigned to objects
7786
+ * in the scene representation and used for multi-buffer rendering. By
7787
+ * default, all three.js objects are created on the `STATIC` layer.
7788
+ */
7789
+ const CAMERA_LAYER = {
7790
+ /// A camera layer holding all the elements that are only re-rendered on
7791
+ /// camera movement and map invalidation, such as the map itself.
7792
+ /// By default, all objects in the scene are members of this layer. If you
7793
+ /// have a scene element that has to be re-rendered with higher frequency,
7794
+ /// make sure to disable this layer on the object, and enable the
7795
+ /// `ANIMATED` layer on it instead.
7796
+ STATIC: 0,
7797
+ /// A camera layer holding elements that are re-rendered every frame that
7798
+ /// they exist, such as paths.
7799
+ ANIMATED: 1,
7800
+ /// A camera layer holding all elements that must be rendered on top of all
7801
+ /// other layers. Like the `ANIMATED` layer, these elements are re-rendered
7802
+ /// every frame that they exist. A good example object is the blue-dot object.
7803
+ ALWAYS_ON_TOP: 2
7804
+ };
7805
+ export default CAMERA_LAYER;
7806
+
7807
+ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.RenderTasks' {
7808
+ /**
7809
+ * Tasks that can be submitted to the renderer. The `STATIC_AND_ANIMATED` task
7810
+ * is equivalent to a full re-render.
7811
+ */
7812
+ enum RENDER {
7813
+ ANIMATED = "animated",
7814
+ ALWAYS_ON_TOP = "always_on_top",
7815
+ ALL = "all",
7816
+ TWEEN = "tween"
7817
+ }
7818
+ export default RENDER;
7819
+ }
7820
+
7821
+ varying vec2 vUv;
7822
+
7823
+ void main() {
7824
+ vUv = uv;
7825
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
7826
+ }
7827
+
7828
+ varying vec2 vUv;
7829
+ uniform sampler2D staticSceneColorTexture;
7830
+ uniform sampler2D staticSceneDepthTexture;
7831
+ uniform sampler2D animatedSceneColorTexture;
7832
+ uniform sampler2D animatedSceneDepthTexture;
7833
+ uniform sampler2D alwaysOnTopSceneColorTexture;
7834
+
7835
+ vec4 alphaBlend(vec4 background, vec4 foreground) {
7836
+ vec3 resultColor = (
7837
+ foreground.rgb * foreground.a +
7838
+ background.rgb * background.a * (1.0 - foreground.a)
7839
+ );
7840
+ float resultAlpha = foreground.a + background.a * (1.0 - foreground.a);
7841
+ return vec4(resultColor / resultAlpha, resultAlpha);
7842
+ }
7843
+
7844
+ vec4 alphaBlendPremultipliedAlpha(vec4 background, vec4 foreground) {
7845
+ return foreground + (background * (1.0 - foreground.a));
7846
+ }
7847
+
7848
+ void main() {
7849
+ float staticDepth = texture2D(staticSceneDepthTexture, vUv).r;
7850
+ float animatedDepth = texture2D(animatedSceneDepthTexture, vUv).r;
7851
+
7852
+ vec4 staticColor = texture2D(staticSceneColorTexture, vUv).rgba;
7853
+ vec4 animatedColor = texture2D(animatedSceneColorTexture, vUv).rgba;
7854
+
7855
+ if (staticDepth < animatedDepth) {
7856
+ // 19/06/10 Terence Dickson
7857
+ // Spoiler alert! This is to help prepare for CE-1352, where alpha
7858
+ // may be partial instead of zero. Not implementing that as part of
7859
+ // this PR, however.
7860
+ animatedColor.a *= 0.0;
7861
+ }
7862
+
7863
+ vec4 lowerColor = alphaBlend(staticColor, animatedColor);
7864
+ vec4 alwaysOnTopColor = texture2D(alwaysOnTopSceneColorTexture, vUv).rgba;
7865
+
7866
+ gl_FragColor = alphaBlendPremultipliedAlpha(lowerColor, alwaysOnTopColor);
7867
+ }
7868
+
7869
+ declare module '@mappedin/mappedin-js/renderer/internal/Mappedin.MultiFloorView' {
7870
+ export namespace VIEW_STATE {
7871
+ const SINGLE_FLOOR: string;
7872
+ const MULTI_FLOOR: string;
7873
+ }
7874
+ export namespace START {
7875
+ const TOP: string;
7876
+ const BOTTOM: string;
7877
+ }
7878
+ export namespace DIR {
7879
+ const DOWN: string;
7880
+ const UP: string;
7881
+ }
7882
+ export default MultiFloorView;
7883
+ class MultiFloorView {
7884
+ constructor(mapView: any, object: any, maps: any, options: any);
7885
+ _focusMapsStart: string;
7886
+ _focusMapsDir: string;
7887
+ _focusMapsLen: number;
7888
+ _focusAnimCurve: any;
7889
+ _focusAnimDuration: number;
7890
+ rotationAxis: any;
7891
+ mapBoundingBoxes: any[];
7892
+ _helperBoundingBoxes: any[];
7893
+ mapAxesHelpers: any[];
7894
+ mapView: any;
7895
+ object: any;
7896
+ options: any;
7897
+ padding: any;
7898
+ rotation: any;
7899
+ maps: any;
7900
+ debug: any;
7901
+ mapSpacing: number;
7902
+ mapTilt: number;
7903
+ resize(): void;
7904
+ focusOnMaps({ start, len, dir, mapIndices, duration, curve }?: {
7905
+ start?: string | undefined;
7906
+ len?: number | undefined;
7907
+ dir?: string | undefined;
7908
+ mapIndices: any;
7909
+ duration?: number | undefined;
7910
+ curve?: any;
7911
+ }): Promise<any>;
7912
+ get viewPortHeight(): number;
7913
+ get viewPortWidth(): number;
7914
+ positionMaps(): void;
7915
+ addMaps(maps: any): void;
7916
+ removeMaps(): void;
7917
+ addMapBoundingBoxes(): void;
7918
+ removeMapBoundingBoxes(): void;
7919
+ removeHelperBoundingBoxes(): void;
7920
+ addAxesHelpers(): void;
7921
+ removeAxesHelpers(): void;
7922
+ set mapTiltDegrees(arg: number);
7923
+ get mapTiltDegrees(): number;
7924
+ /**
7925
+ * Display 2D screen projections of each 3D map object in the journey. Useful for drawing 2D elements on screen.
7926
+ *
7927
+ * @attribute projections
7928
+ * @readOnly
7929
+ *
7930
+ * @returns {Array} Array for Objects with min/max x/y values
7931
+ * @example
7932
+
7933
+ projections = [{
7934
+ max: {
7935
+ x: 1062.4393974378236,
7936
+ y: 745.7583492891705
7937
+ },
7938
+ min: {
7939
+ x: 17.560602562176346,
7940
+ y: 225.0806956450056
7941
+ }
7942
+ ...
7943
+ ]
7944
+ */
7945
+ get projections(): any[];
7946
+ tiltMaps(tiltRad: any): void;
7947
+ _focusBox: any;
7948
+ _scrollWindow: number | undefined;
7949
+ tween: any;
7950
+ getFocusMaps(start: any, dir: any, len: any): any;
7951
+ getFocusBox(): any;
7952
+ getVisibleMaps(): any;
7953
+ getVisibleMapIds(): any;
7954
+ getVisibleMapIndices(): number[];
7955
+ getMapsByIndices(indices: any): any;
7956
+ get bottomMapVisible(): any;
7957
+ get topMapVisible(): any;
7958
+ scrollMapsUp(): Promise<any>;
7959
+ scrollMapsDown(): Promise<any>;
7960
+ destroy(): void;
7961
+ }
7962
+ }
7963
+
7964
+ declare module '@mappedin/mappedin-js/renderer/internal/utils' {
7965
+ /**
7966
+ * Utils function listing
7967
+ *
7968
+ * - scrubMaterial
7969
+ * - getDeviceID
7970
+ * - getSessionID
7971
+ * - getObjectID
7972
+ * - getObject
7973
+ * - getBoundingBox
7974
+ * - getBiggestBoundingBox
7975
+ * - upackBoundingBox
7976
+ * - getMapScale
7977
+ * - throttle -> taken from lodash.js
7978
+ * - getProjectionScaleFactor
7979
+ * - getZoom
7980
+ */
7981
+ export function isGatewayKey(key: any): boolean;
7982
+ export function getCombinedBoundingBox(objects: any): any;
7983
+ export function getMapsBoundingBox(maps: any, mapPadding: any): any;
7984
+ export function scrubMaterial(material: any): void;
7985
+ export function getDeviceID(): string;
7986
+ export function getSessionID(): string;
7987
+ export function getObjectId(object: any): any;
7988
+ export function getObject(obj: any, array: any): any;
7989
+ export function getBoundingBox(object: any): any;
7990
+ export function getBiggestBoundingBox(objects: any): {
7991
+ min: any;
7992
+ max: any;
7993
+ };
7994
+ export function unpackBoundingBox(boundingBox: any): any[];
7995
+ export function getMapScale(map: any): number;
7996
+ export function getNorth(map: any): number;
7997
+ export function throttle(func: any, wait: any, options: any): (...args: any[]) => any;
7998
+ export function debounce(func: any, wait: any, immediate: any): (...args: any[]) => void;
7999
+ export function flatten(list: any): any;
8000
+ export function uniq(arr: any): any;
8001
+ export function toStyleString(styles: any): string;
8002
+ /**
8003
+ /* getProjectionScaleFactor()
8004
+ /* finds the scale ratio between screen coordinates and 3D coordinates (in X-Z plane)
8005
+ /*
8006
+ * R
8007
+ * /|
8008
+ * C : Camera / |
8009
+ * PQ : Projection Plane / |
8010
+ * OR : Origin / |
8011
+ * F : FOV / |
8012
+ * Q / |
8013
+ * /| |
8014
+ * / | |
8015
+ * / | |
8016
+ * / | |
8017
+ * / | |
8018
+ * / F/2 | |
8019
+ * C ------------P------------ O
8020
+ *
8021
+ *
8022
+ * ProjectionScaleFactor = ( OR / PQ )
8023
+ * PQ = canvasHeight / 2
8024
+ * CQ = zoom
8025
+ *
8026
+ * OR / C0 = tan(F/2)
8027
+ * so OR = CO * tan(F/2)
8028
+ */
8029
+ export function getProjectionScaleFactor(FOV: any, canvasHeight: any, zoom: any): number;
8030
+ /** getZoom
8031
+ *
8032
+ * C - Camera, OP -- picture plane (canvas), S - origin,
8033
+ * QR - front side of maps Bounding Box, F: FOV
8034
+ *
8035
+ * Z-axis
8036
+ * R_____|______
8037
+ * /| | |
8038
+ * / | | |
8039
+ * P/ | | | maps BB
8040
+ * /| | | |
8041
+ * / | | | |
8042
+ * / | | | |
8043
+ * / F |E |T |S |
8044
+ * C /--------|-----|-----|-----|------ orthogonal to Y axis, midpoint of focus maps
8045
+ * \ | | | |
8046
+ * \ | | | |
8047
+ * \ | | | |
8048
+ * \ | | | |
8049
+ * \| | | |
8050
+ * O\ | | |
8051
+ * \ | | |
8052
+ * \|_____|_____|
8053
+ * Q
8054
+ *
8055
+ *
8056
+ * We want to get CS, which is the camera zoom
8057
+ *
8058
+ */
8059
+ export function getZoom(focusBox: any, focusBoxHeight: any, FOV: any): any;
8060
+ export function calculateTwoDProjections({ maps, width, height, camera }: {
8061
+ maps: any;
8062
+ width: any;
8063
+ height: any;
8064
+ camera: any;
8065
+ }): any;
8066
+ export function splitLine(startNode: any, endNode: any, segments: any): any[];
8067
+ export function isObject(item: any): any;
8068
+ export function cyrb53(str: any, seed?: number): number;
8069
+ export function addMarginMultiplierToBoundingBox(bbox: any, multiplier: any): any;
8070
+ export function getPrimaryLocationForPolygon(polygon: any, venue: any): any;
8071
+ export function determineStartingMap(venue: any, options: any): any;
8072
+ }
8073
+
8074
+ /**
8075
+ * @type {any}
8076
+ */
8077
+ let HoverLabel = function (container) {
8078
+ let scope = this;
8079
+ let hoverLabel = document.createElement('div');
8080
+ hoverLabel.style.display = 'none!important';
8081
+ hoverLabel.style.position = 'absolute';
8082
+ hoverLabel.style.top = '0px';
8083
+ hoverLabel.style.left = '0px';
8084
+ hoverLabel.style.pointerEvents = 'none';
8085
+ this.hovering = false;
8086
+ let lastX;
8087
+ let lastY;
8088
+ container.appendChild(hoverLabel);
8089
+ this.show = function (textLabel) {
8090
+ if (!scope.hovering) {
8091
+ scope.setPosition(lastX, lastY);
8092
+ }
8093
+ scope.hovering = true;
8094
+ hoverLabel.style.removeProperty('display');
8095
+ hoverLabel.textContent = textLabel.toString();
8096
+ hoverLabel.className = textLabel.hoverLabelClass;
8097
+ };
8098
+ this.hide = function () {
8099
+ if (scope.hovering) {
8100
+ scope.hovering = false;
8101
+ hoverLabel.style.setProperty('display', 'none', 'important');
8102
+ hoverLabel.textContent = '';
8103
+ }
8104
+ };
8105
+ this.setZIndex = function (z) {
8106
+ hoverLabel.style.zIndex = z;
8107
+ };
8108
+ this.setPosition = function (x, y) {
8109
+ lastX = x;
8110
+ lastY = y;
8111
+ if (!scope.hovering)
8112
+ return;
8113
+ if (y - hoverLabel.clientHeight > 0) {
8114
+ y = y - hoverLabel.clientHeight;
8115
+ if (x + hoverLabel.clientWidth > container.clientWidth) {
8116
+ x = x - hoverLabel.clientWidth;
8117
+ }
8118
+ }
8119
+ else {
8120
+ x = x - hoverLabel.clientWidth - 10;
8121
+ }
8122
+ hoverLabel.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
8123
+ };
8124
+ this.destroy = function () {
8125
+ container.removeChild(hoverLabel);
8126
+ };
8127
+ };
8128
+ HoverLabel.MODES = {
8129
+ NONE: 1,
8130
+ NO_TEXT_LABEL_ONLY: 2,
8131
+ ALL: 3
8132
+ };
8133
+ export default HoverLabel;
8134
+
8135
+ precision mediump float;
8136
+
8137
+ uniform sampler2D textureLabel;
8138
+
8139
+ varying vec2 vUV;
8140
+ varying vec3 vColor;
8141
+
8142
+ void main() {
8143
+ gl_FragColor = texture2D(textureLabel, vUV);
8144
+ gl_FragColor.rgb = vColor;
8145
+ }
8146
+
8147
+ attribute vec2 position;
8148
+ attribute vec3 origin;
8149
+ attribute vec2 size;
8150
+ attribute float rotation;
8151
+ attribute vec4 uv;
8152
+ attribute vec3 color;
8153
+
8154
+ uniform mat4 projectionMatrix;
8155
+ uniform mat4 viewMatrix;
8156
+ uniform mat4 modelMatrix;
8157
+
8158
+ varying vec2 vUV;
8159
+ varying vec3 vColor;
8160
+
8161
+ void main() {
8162
+ vec4 mapDirectionVector = vec4(0, 1, 0, 0) * viewMatrix * modelMatrix;
8163
+ float mapDirection = atan(mapDirectionVector.y, mapDirectionVector.x);
8164
+
8165
+ float cosRotation = cos(rotation);
8166
+ float sinRotation = sin(rotation);
8167
+
8168
+ mat4 rotationMatrix = mat4(
8169
+ vec4(cosRotation, -sinRotation, 0.0, 0.0),
8170
+ vec4(sinRotation, cosRotation, 0.0, 0.0),
8171
+ vec4(0.0, 0.0, 1.0, 0.0),
8172
+ vec4(0.0, 0.0, 0.0, 1.0)
8173
+ );
8174
+
8175
+ mat4 translate = mat4(
8176
+ vec4(1, 0, 0, 0),
8177
+ vec4(0, 1, 0, 0),
8178
+ vec4(0, 0, 1, 0),
8179
+ vec4(origin, 1)
8180
+ );
8181
+
8182
+ gl_Position = projectionMatrix *
8183
+ viewMatrix *
8184
+ modelMatrix *
8185
+ translate *
8186
+ rotationMatrix *
8187
+ (vec4(position * size - vec2(0, size.y / 2.0), 0, 1));
8188
+
8189
+
8190
+ vec2 uvStart = uv.xy;
8191
+ vec2 uvSize = uv.zw;
8192
+
8193
+ if (sin(mapDirection + rotation) > 0.0) {
8194
+ vUV = position * uvSize + vec2(uvStart.x, uvStart.y - uvSize.y);
8195
+ } else {
8196
+ vUV = (vec2(1, 1) - position) * uvSize + vec2(uvStart.x, uvStart.y - uvSize.y);
8197
+ }
8198
+
8199
+ vColor = color;
8200
+ }
8201
+
8202
+ declare module '@mappedin/mappedin-js/renderer/MapView.Scene' {
8203
+ import { MappedinMap } from '@mappedin/mappedin-js/get-venue';
8204
+ import { ICore } from '@mappedin/mappedin-js/renderer/Core.interface';
8205
+ import MapObject from '@mappedin/mappedin-js/renderer/internal/Mappedin.MapObject';
8206
+ import { TSceneTransitionOptions } from '@mappedin/mappedin-js/renderer/MapView.SceneManager';
8207
+ class MapViewScene {
8208
+ #private;
8209
+ maps: MappedinMap[];
8210
+ object: any;
8211
+ currentMap: MappedinMap;
8212
+ mapObjects: Map<MappedinMap['id'], MapObject>;
8213
+ constructor(maps: MappedinMap[], core: ICore);
8214
+ /**
8215
+ * Determine each maps position and rotation relative to the refernce map
8216
+ */
8217
+ determineMapPositionAndRotation(map: MappedinMap): {
8218
+ position: any[];
8219
+ scale: number[];
8220
+ rotation: number[];
8221
+ };
8222
+ /** Render scene */
8223
+ render(map: MappedinMap, transitionOptions?: TSceneTransitionOptions, isStartingScene?: boolean): Promise<void>;
8224
+ }
8225
+ export default MapViewScene;
8226
+ }
8227
+