@tangram.gl/tangram-renderer 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -2
- package/dist/core.js +36923 -0
- package/dist/core.js.map +6 -0
- package/dist/index.js +32 -0
- package/dist/loaders-gl-worker.js +82 -0
- package/dist/loaders-gl-worker.js.map +6 -0
- package/dist/map-logic.js +2 -0
- package/dist/map-logic.js.map +6 -0
- package/dist/projected-basemaps-worker.js +3 -0
- package/dist/projected-basemaps-worker.js.map +6 -0
- package/dist/shader-modules.js +141 -0
- package/dist/shader-modules.js.map +6 -0
- package/dist/style-schema.js +126 -0
- package/dist/style-schema.js.map +6 -0
- package/dist/tangram-style.schema.json +882 -0
- package/dist/tangram.debug.mjs +37139 -0
- package/dist/tangram.debug.mjs.map +6 -0
- package/dist/tangram.min.mjs +4950 -0
- package/dist/types/builders/earcut.d.ts +15 -0
- package/dist/types/core.d.ts +29 -0
- package/dist/types/gl/constants.d.ts +2 -0
- package/dist/types/gl/globe_mesh.d.ts +48 -0
- package/dist/types/gl/glsl.d.ts +17 -0
- package/dist/types/gl/vertex-constants.d.ts +4 -0
- package/dist/types/gl/vertex-types.d.ts +34 -0
- package/dist/types/gl/vertex_data.d.ts +32 -0
- package/dist/types/gl/vertex_elements.d.ts +8 -0
- package/dist/types/gl/vertex_layout.d.ts +32 -0
- package/dist/types/glsl.d.ts +14 -0
- package/dist/types/gpu/luma_device_renderer.d.ts +66 -0
- package/dist/types/gpu/resource_lifecycle.d.ts +4 -0
- package/dist/types/gpu/tangram_gpu_backend.d.ts +151 -0
- package/dist/types/index.d.ts +155 -0
- package/dist/types/lights/light-definitions.d.ts +121 -0
- package/dist/types/map-logic/draped-terrain-bounds.d.ts +41 -0
- package/dist/types/map-logic/globe-terrain-preparation.d.ts +85 -0
- package/dist/types/map-logic/globe-terrain.d.ts +54 -0
- package/dist/types/map-logic/index.d.ts +33 -0
- package/dist/types/map-logic/label-identity.d.ts +22 -0
- package/dist/types/map-logic/label-placement.d.ts +32 -0
- package/dist/types/map-logic/screen-bounds.d.ts +15 -0
- package/dist/types/map-logic/terrain-data.d.ts +55 -0
- package/dist/types/map-logic/terrain-error.d.ts +51 -0
- package/dist/types/map-logic/terrain-ground-topology.d.ts +26 -0
- package/dist/types/map-logic/terrain-height-field.d.ts +59 -0
- package/dist/types/map-logic/terrain-navigation.d.ts +27 -0
- package/dist/types/map-logic/terrain-neighborhood.d.ts +5 -0
- package/dist/types/map-logic/terrain-query.d.ts +33 -0
- package/dist/types/map-logic/terrain-resource-budget.d.ts +51 -0
- package/dist/types/map-logic/terrain-transition-topology.d.ts +23 -0
- package/dist/types/map-logic/tile-build-queue.d.ts +51 -0
- package/dist/types/map-logic/tile-cache-policy.d.ts +46 -0
- package/dist/types/map-logic/tile-residency.d.ts +17 -0
- package/dist/types/map-logic/triangle-query-index.d.ts +87 -0
- package/dist/types/procedures/js-yaml.d.ts +15 -0
- package/dist/types/procedures/mesh-projector.d.ts +107 -0
- package/dist/types/procedures/mvt-dependencies.d.ts +20 -0
- package/dist/types/procedures/projected-coordinate-transform.d.ts +27 -0
- package/dist/types/procedures/projection-batch-executor.d.ts +53 -0
- package/dist/types/procedures/scene-yaml-legacy.d.ts +6 -0
- package/dist/types/procedures/terrain-draping.d.ts +165 -0
- package/dist/types/procedures/terrain-globe.d.ts +6 -0
- package/dist/types/procedures/terrain-styled-topology.d.ts +34 -0
- package/dist/types/procedures/web-mercator-legacy.d.ts +4 -0
- package/dist/types/procedures/web-mercator-math.d.ts +4 -0
- package/dist/types/scene/globals.d.ts +11 -0
- package/dist/types/scene/ground_footprint.d.ts +16 -0
- package/dist/types/scene/host_frame.d.ts +54 -0
- package/dist/types/scene/projection_math.d.ts +52 -0
- package/dist/types/scene/scene-resource-types.d.ts +177 -0
- package/dist/types/scene/scene_bundle.d.ts +69 -0
- package/dist/types/scene/visibility_adapter.d.ts +106 -0
- package/dist/types/selection/draped-terrain-surface.d.ts +78 -0
- package/dist/types/selection/terrain_surface.d.ts +149 -0
- package/dist/types/shader-modules/globe-horizon.d.ts +15 -0
- package/dist/types/shader-modules/height-decode.d.ts +13 -0
- package/dist/types/shader-modules/hillshade.d.ts +13 -0
- package/dist/types/shader-modules/index.d.ts +6 -0
- package/dist/types/shader-modules/planar.d.ts +12 -0
- package/dist/types/shader-modules/sphere-map.d.ts +13 -0
- package/dist/types/shader-modules/triplanar.d.ts +15 -0
- package/dist/types/sources/decoded_tile_store.d.ts +95 -0
- package/dist/types/sources/tile_source_metadata.d.ts +32 -0
- package/dist/types/styles/text/fontfaceobserver.d.ts +10 -0
- package/dist/types/tile/tile_id.d.ts +37 -0
- package/dist/types/tile/tile_traversal_adapter.d.ts +63 -0
- package/dist/types/types.d.ts +293 -0
- package/dist/types/utils/geo.d.ts +57 -0
- package/dist/types/utils/hash.d.ts +1 -0
- package/dist/types/utils/log.d.ts +27 -0
- package/dist/types/utils/props.d.ts +6 -0
- package/dist/types/utils/subscribe.d.ts +10 -0
- package/dist/types/utils/thread.d.ts +6 -0
- package/dist/types/utils/urls.d.ts +26 -0
- package/dist/types/utils/utils.d.ts +26 -0
- package/dist/types/utils/version.d.ts +2 -0
- package/dist/types/utils/worker-types.d.ts +68 -0
- package/dist/types/utils/worker_broker.d.ts +3 -0
- package/package.json +103 -3
- package/src/builders/common.ts +41 -0
- package/src/builders/earcut.d.ts +15 -0
- package/src/builders/geometry-types.ts +60 -0
- package/src/builders/points.ts +115 -0
- package/src/builders/polygons.ts +225 -0
- package/src/builders/polylines.ts +682 -0
- package/src/builders/wireframe.ts +31 -0
- package/src/core.d.ts +29 -0
- package/src/core.ts +33 -0
- package/src/experimental/loaders-gl-worker.ts +19 -0
- package/src/experimental/projected-basemaps-worker.ts +13 -0
- package/src/experimental/projected-mesh-cache.ts +137 -0
- package/src/experimental/projected-mesh-domain.ts +110 -0
- package/src/experimental/projected-mesh-refinement.ts +193 -0
- package/src/experimental/projected-mesh.ts +399 -0
- package/src/experimental/projected-normal.ts +26 -0
- package/src/experimental/projected-symbol-mesh.ts +74 -0
- package/src/gl/constants.ts +18 -0
- package/src/gl/context.ts +103 -0
- package/src/gl/extensions.ts +30 -0
- package/src/gl/globe_mesh.ts +285 -0
- package/src/gl/glsl.ts +257 -0
- package/src/gl/mesh-types.ts +56 -0
- package/src/gl/render_state.ts +111 -0
- package/src/gl/shader_program.ts +1310 -0
- package/src/gl/texture.ts +814 -0
- package/src/gl/uniform_buffer.ts +340 -0
- package/src/gl/vao.ts +154 -0
- package/src/gl/vbo_mesh.ts +349 -0
- package/src/gl/vertex-constants.ts +19 -0
- package/src/gl/vertex-types.ts +35 -0
- package/src/gl/vertex_data.ts +126 -0
- package/src/gl/vertex_elements.ts +54 -0
- package/src/gl/vertex_layout.ts +241 -0
- package/src/glsl.d.ts +14 -0
- package/src/gpu/luma_device_renderer.ts +579 -0
- package/src/gpu/pixel_readback.ts +51 -0
- package/src/gpu/resource_lifecycle.ts +32 -0
- package/src/gpu/tangram_gpu_backend.ts +195 -0
- package/src/index.d.ts +155 -0
- package/src/index.ts +105 -0
- package/src/labels/collision-types.ts +94 -0
- package/src/labels/collision.ts +273 -0
- package/src/labels/collision_grid.ts +61 -0
- package/src/labels/intersect.ts +30 -0
- package/src/labels/label-types.ts +91 -0
- package/src/labels/label.ts +207 -0
- package/src/labels/label_line.ts +801 -0
- package/src/labels/label_point.ts +131 -0
- package/src/labels/main-pass-types.ts +73 -0
- package/src/labels/main_pass.ts +221 -0
- package/src/labels/point_anchor.ts +100 -0
- package/src/labels/point_placement.ts +150 -0
- package/src/labels/projected-pass.ts +259 -0
- package/src/labels/repeat_group.ts +72 -0
- package/src/lights/ambient_light.glsl +18 -0
- package/src/lights/directional_light.glsl +39 -0
- package/src/lights/geographic-lights.ts +21 -0
- package/src/lights/light-definitions.ts +285 -0
- package/src/lights/light.ts +590 -0
- package/src/lights/lighting-uniforms.ts +80 -0
- package/src/lights/lighting-wgsl.ts +116 -0
- package/src/lights/material.glsl +237 -0
- package/src/lights/material.ts +145 -0
- package/src/lights/native-falloff.ts +37 -0
- package/src/lights/point_light.glsl +96 -0
- package/src/lights/spot_light.glsl +111 -0
- package/src/map-logic/draped-terrain-bounds.ts +71 -0
- package/src/map-logic/globe-terrain-preparation.ts +217 -0
- package/src/map-logic/globe-terrain.ts +296 -0
- package/src/map-logic/index.ts +37 -0
- package/src/map-logic/label-identity.ts +36 -0
- package/src/map-logic/label-placement.ts +117 -0
- package/src/map-logic/screen-bounds.ts +34 -0
- package/src/map-logic/terrain-data.ts +107 -0
- package/src/map-logic/terrain-error.ts +134 -0
- package/src/map-logic/terrain-ground-topology.ts +164 -0
- package/src/map-logic/terrain-height-field.ts +254 -0
- package/src/map-logic/terrain-navigation.ts +50 -0
- package/src/map-logic/terrain-neighborhood.ts +43 -0
- package/src/map-logic/terrain-query.ts +51 -0
- package/src/map-logic/terrain-resource-budget.ts +124 -0
- package/src/map-logic/terrain-transition-topology.ts +164 -0
- package/src/map-logic/tile-build-queue.ts +110 -0
- package/src/map-logic/tile-cache-policy.ts +89 -0
- package/src/map-logic/tile-residency.ts +50 -0
- package/src/map-logic/triangle-query-index.ts +265 -0
- package/src/procedures/js-yaml.d.ts +15 -0
- package/src/procedures/mesh-projector.ts +191 -0
- package/src/procedures/mlt-loaders.ts +55 -0
- package/src/procedures/mvt-dependencies.d.ts +20 -0
- package/src/procedures/mvt-legacy.ts +150 -0
- package/src/procedures/mvt-loaders.ts +53 -0
- package/src/procedures/mvt-parser.ts +48 -0
- package/src/procedures/mvt-properties.ts +36 -0
- package/src/procedures/mvt-tile-provider.ts +72 -0
- package/src/procedures/pmtiles-loader.ts +75 -0
- package/src/procedures/projected-coordinate-transform.ts +79 -0
- package/src/procedures/projection-batch-executor.ts +140 -0
- package/src/procedures/scene-yaml-legacy.ts +16 -0
- package/src/procedures/scene-yaml-loaders.ts +10 -0
- package/src/procedures/terrain-draping.ts +713 -0
- package/src/procedures/terrain-globe.ts +32 -0
- package/src/procedures/terrain-styled-topology.ts +184 -0
- package/src/procedures/web-mercator-legacy.ts +24 -0
- package/src/procedures/web-mercator-math.ts +50 -0
- package/src/scene/camera.ts +298 -0
- package/src/scene/camera_base.ts +116 -0
- package/src/scene/classic_scene.ts +20 -0
- package/src/scene/external_camera.ts +101 -0
- package/src/scene/globals.ts +120 -0
- package/src/scene/ground_footprint.ts +139 -0
- package/src/scene/host_frame.ts +326 -0
- package/src/scene/projected_tile_lod.ts +125 -0
- package/src/scene/projection_math.ts +142 -0
- package/src/scene/projection_shaders.ts +183 -0
- package/src/scene/renderer.ts +516 -0
- package/src/scene/scene-resource-types.ts +174 -0
- package/src/scene/scene.ts +2378 -0
- package/src/scene/scene_bundle.ts +304 -0
- package/src/scene/scene_debug.ts +129 -0
- package/src/scene/scene_loader.ts +402 -0
- package/src/scene/scene_worker.ts +528 -0
- package/src/scene/view.ts +683 -0
- package/src/scene/visibility_adapter.ts +319 -0
- package/src/scene/worker_url.ts +15 -0
- package/src/selection/draped-terrain-surface.ts +377 -0
- package/src/selection/selection-types.ts +79 -0
- package/src/selection/selection.ts +542 -0
- package/src/selection/selection_fragment.glsl +18 -0
- package/src/selection/selection_globals.glsl +9 -0
- package/src/selection/selection_pixels.ts +59 -0
- package/src/selection/selection_vertex.glsl +15 -0
- package/src/selection/terrain_surface.ts +298 -0
- package/src/shader-modules/globe-horizon.ts +52 -0
- package/src/shader-modules/height-decode.ts +41 -0
- package/src/shader-modules/hillshade.ts +70 -0
- package/src/shader-modules/index.ts +10 -0
- package/src/shader-modules/planar.ts +24 -0
- package/src/shader-modules/sphere-map.ts +38 -0
- package/src/shader-modules/triplanar.ts +45 -0
- package/src/sources/aligned_tile_source.ts +122 -0
- package/src/sources/data_source.ts +655 -0
- package/src/sources/decoded_tile_store.ts +245 -0
- package/src/sources/geojson.ts +300 -0
- package/src/sources/mvt.ts +247 -0
- package/src/sources/raster.ts +341 -0
- package/src/sources/shared_tile_source_adapter.ts +117 -0
- package/src/sources/sources.ts +10 -0
- package/src/sources/tile_source_adapter.ts +84 -0
- package/src/sources/tile_source_metadata.ts +65 -0
- package/src/sources/tile_source_state.ts +112 -0
- package/src/sources/topojson.ts +90 -0
- package/src/styles/feature_annotations.ts +16 -0
- package/src/styles/filter.ts +190 -0
- package/src/styles/geometry-style-types.ts +209 -0
- package/src/styles/globe_visibility_wgsl.ts +22 -0
- package/src/styles/layer-types.ts +45 -0
- package/src/styles/layer.ts +586 -0
- package/src/styles/lines/dasharray.ts +49 -0
- package/src/styles/lines/lines.ts +707 -0
- package/src/styles/lines/lines_wgsl.ts +224 -0
- package/src/styles/points/point-runtime-types.ts +125 -0
- package/src/styles/points/points.ts +1079 -0
- package/src/styles/points/points_fragment.glsl +126 -0
- package/src/styles/points/points_vertex.glsl +230 -0
- package/src/styles/points/points_wgsl.ts +189 -0
- package/src/styles/polygons/polygons.ts +268 -0
- package/src/styles/polygons/polygons_fragment.glsl +173 -0
- package/src/styles/polygons/polygons_vertex.glsl +213 -0
- package/src/styles/polygons/polygons_wgsl.ts +127 -0
- package/src/styles/property-types.ts +125 -0
- package/src/styles/raster/raster.ts +33 -0
- package/src/styles/raster/raster_globals.glsl +46 -0
- package/src/styles/style-mixing-types.ts +101 -0
- package/src/styles/style-runtime-types.ts +220 -0
- package/src/styles/style-schema.ts +133 -0
- package/src/styles/style.ts +1033 -0
- package/src/styles/style_globals.glsl +69 -0
- package/src/styles/style_manager.ts +464 -0
- package/src/styles/style_parser.ts +620 -0
- package/src/styles/text/font_manager.ts +180 -0
- package/src/styles/text/fontfaceobserver.d.ts +10 -0
- package/src/styles/text/text-types.ts +220 -0
- package/src/styles/text/text.ts +378 -0
- package/src/styles/text/text_canvas.ts +773 -0
- package/src/styles/text/text_labels.ts +436 -0
- package/src/styles/text/text_segments.ts +142 -0
- package/src/styles/text/text_settings.ts +228 -0
- package/src/styles/text/text_wgsl.ts +159 -0
- package/src/styles/text/text_wrap.ts +194 -0
- package/src/tile/globe_tile_preload.ts +40 -0
- package/src/tile/tangram_tileset_2d.ts +108 -0
- package/src/tile/tile-build-types.ts +155 -0
- package/src/tile/tile.ts +807 -0
- package/src/tile/tile_id.ts +172 -0
- package/src/tile/tile_manager.ts +889 -0
- package/src/tile/tile_pyramid.ts +119 -0
- package/src/tile/tile_resource_cache.ts +91 -0
- package/src/tile/tile_traversal_adapter.ts +132 -0
- package/src/types.ts +332 -0
- package/src/utils/debounce.ts +17 -0
- package/src/utils/debug_settings.ts +43 -0
- package/src/utils/errors.ts +12 -0
- package/src/utils/functions.ts +95 -0
- package/src/utils/geo.ts +364 -0
- package/src/utils/hash.ts +14 -0
- package/src/utils/log.ts +108 -0
- package/src/utils/media_capture.ts +193 -0
- package/src/utils/merge.ts +44 -0
- package/src/utils/obb.ts +134 -0
- package/src/utils/props.ts +43 -0
- package/src/utils/slice.ts +14 -0
- package/src/utils/subscribe.ts +58 -0
- package/src/utils/task.ts +154 -0
- package/src/utils/thread.ts +26 -0
- package/src/utils/urls.ts +223 -0
- package/src/utils/utils.ts +310 -0
- package/src/utils/vector.ts +197 -0
- package/src/utils/version.ts +8 -0
- package/src/utils/worker-types.ts +79 -0
- package/src/utils/worker_broker.ts +523 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
// Tangram
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) 2013-2016 Brett Camper and Mapzen
|
|
4
|
+
// Copyright (c) 2026 vis.gl contributors
|
|
5
|
+
|
|
6
|
+
import log from '../utils/log';
|
|
7
|
+
import GLSL from '../gl/glsl';
|
|
8
|
+
import * as URLs from '../utils/urls';
|
|
9
|
+
import mergeObjects from '../utils/merge';
|
|
10
|
+
import subscribeMixin from '../utils/subscribe';
|
|
11
|
+
import { getPropertyPath, setPropertyPath } from '../utils/props';
|
|
12
|
+
import { flattenGlobalProperties, applyGlobalProperties, isGlobalSubstitution } from './globals';
|
|
13
|
+
import { createSceneBundle } from './scene_bundle';
|
|
14
|
+
import { isReserved } from '../styles/layer';
|
|
15
|
+
import {normalizeSceneLights} from '../lights/light-definitions';
|
|
16
|
+
import type {SubscriptionMethods} from '../utils/subscribe';
|
|
17
|
+
import type {SceneBundle} from './scene_bundle';
|
|
18
|
+
import type {
|
|
19
|
+
SceneDefinition, SceneInput, SceneImportError, SceneLoadOptions, SceneLoadResult,
|
|
20
|
+
SceneResourceDescriptor, SceneSourceDefinition, SceneTextureNodes, LoadedScene,
|
|
21
|
+
SceneLayerDefinition, SceneMaterialChannel, SceneLoaderAPI, SceneStyleDefinition,
|
|
22
|
+
FinalizedSceneDefinition, SceneNamedLights
|
|
23
|
+
} from './scene-resource-types';
|
|
24
|
+
|
|
25
|
+
const SceneLoader = subscribeMixin<Omit<SceneLoaderAPI, keyof SubscriptionMethods>>({
|
|
26
|
+
|
|
27
|
+
// Load scenes definitions from URL & proprocess
|
|
28
|
+
async loadScene(this: SceneLoaderAPI, url: SceneInput,
|
|
29
|
+
{ path, type, cameraMode }: SceneLoadOptions = {}): Promise<LoadedScene & {texture_nodes: SceneTextureNodes}> {
|
|
30
|
+
const errors: SceneImportError[] = [];
|
|
31
|
+
const texture_nodes: SceneTextureNodes = {};
|
|
32
|
+
const scene = await this.loadSceneRecursive({ url, path, type }, null, texture_nodes, errors);
|
|
33
|
+
const {config, bundle} = this.finalize(scene, { cameraMode });
|
|
34
|
+
if (!config) {
|
|
35
|
+
// root scene failed to load, reject with first error
|
|
36
|
+
throw errors[0];
|
|
37
|
+
}
|
|
38
|
+
else if (errors.length > 0) {
|
|
39
|
+
// scene loaded, but some imports had errors
|
|
40
|
+
errors.forEach(error => {
|
|
41
|
+
const message = `Failed to import scene: ${error.url}`;
|
|
42
|
+
log('error', message, error);
|
|
43
|
+
this.trigger('error', { type: 'scene_import', message, error, url: error.url });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return { config, bundle, texture_nodes };
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// Loads scene files from URL, recursively loading 'import' scenes
|
|
50
|
+
// Optional *initial* path only (won't be passed to recursive 'import' calls)
|
|
51
|
+
// Useful for loading resources in base scene file from a separate location
|
|
52
|
+
// (e.g. in Tangram Play, when modified local scene should still refer to original resource URLs)
|
|
53
|
+
async loadSceneRecursive({ url, path, type }: SceneResourceDescriptor, parent: SceneBundle | null,
|
|
54
|
+
texture_nodes: SceneTextureNodes = {}, errors: SceneImportError[] = []): Promise<SceneLoadResult> {
|
|
55
|
+
if (!url) {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const bundle = createSceneBundle(url, path, parent, type);
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
let config = await bundle.load();
|
|
63
|
+
if (config.import == null) {
|
|
64
|
+
this.normalize(config, bundle, texture_nodes);
|
|
65
|
+
return { config, bundle };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// accept single entry or array
|
|
69
|
+
if (!Array.isArray(config.import)) {
|
|
70
|
+
config.import = [config.import]; // convert to array
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Collect URLs of scenes to import
|
|
74
|
+
const imports: SceneResourceDescriptor[] = [];
|
|
75
|
+
(config.import as SceneInput[]).forEach(url => {
|
|
76
|
+
// Inline scene objects inherit this scene's resource directory.
|
|
77
|
+
// Keep them as objects so functions survive and no blob URL
|
|
78
|
+
// obscures their base (or leaks for each editor reload).
|
|
79
|
+
if (typeof url === 'object') {
|
|
80
|
+
imports.push({url, path: bundle.container || bundle.isContainer() ? '' : bundle.path});
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const resource = bundle.resourceFor(url);
|
|
84
|
+
if (resource.url == null) {
|
|
85
|
+
const error: SceneImportError = new Error(`Scene import not found: ${url}`);
|
|
86
|
+
error.url = url; // Keep the authored archive path, not an undefined blob URL.
|
|
87
|
+
errors.push(error);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
imports.push(resource);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
delete config.import; // don't want to merge this property
|
|
95
|
+
|
|
96
|
+
// load and normalize imports
|
|
97
|
+
// Each subtree owns its texture provenance. Recursive loads already
|
|
98
|
+
// normalize their local config; re-normalizing a merged import would
|
|
99
|
+
// resolve descendant textures against the wrong bundle. Merge nodes
|
|
100
|
+
// in authored order, never asynchronous completion order.
|
|
101
|
+
const imported_nodes = imports.map((): SceneTextureNodes => ({}));
|
|
102
|
+
const queue = imports.map((resource, index) =>
|
|
103
|
+
this.loadSceneRecursive(resource, bundle, imported_nodes[index], errors));
|
|
104
|
+
const scenes = await Promise.all(queue);
|
|
105
|
+
const configs = scenes.filter(scene => scene.config).map(scene => scene.config);
|
|
106
|
+
scenes.forEach((scene, index) => {
|
|
107
|
+
if (scene.config) Object.assign(texture_nodes, imported_nodes[index]);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
this.normalize(config, bundle, texture_nodes); // last normalize parent
|
|
111
|
+
config = mergeObjects<SceneDefinition>({}, ...configs, config);
|
|
112
|
+
return { config, bundle, texture_nodes };
|
|
113
|
+
}
|
|
114
|
+
catch (caught) {
|
|
115
|
+
const error = caught as SceneImportError;
|
|
116
|
+
// Collect scene load errors as we go
|
|
117
|
+
error.url = url;
|
|
118
|
+
errors.push(error);
|
|
119
|
+
return {};
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// Normalize properties that should be adjust within each local scene file (usually by path)
|
|
124
|
+
normalize(config: SceneDefinition, bundle: SceneBundle, texture_nodes: SceneTextureNodes = {}): LoadedScene {
|
|
125
|
+
this.normalizeDataSources(config, bundle);
|
|
126
|
+
this.normalizeFonts(config, bundle);
|
|
127
|
+
this.normalizeTextures(config, bundle);
|
|
128
|
+
this.collectTextures(config, bundle, texture_nodes);
|
|
129
|
+
return { config, bundle, texture_nodes };
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
// Expand paths for data source
|
|
133
|
+
normalizeDataSources(config: SceneDefinition, bundle: SceneBundle): SceneDefinition {
|
|
134
|
+
config.sources = config.sources || {};
|
|
135
|
+
|
|
136
|
+
for (const sn in config.sources) {
|
|
137
|
+
this.normalizeDataSource(config.sources[sn], bundle);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return config;
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
normalizeDataSource(source: SceneSourceDefinition, bundle: SceneBundle): SceneSourceDefinition {
|
|
144
|
+
source.url = bundle.urlFor(source.url);
|
|
145
|
+
// Inline TileJSON is already a descriptor, not a resource URL.
|
|
146
|
+
if (typeof source.tilejson !== 'object') source.tilejson = bundle.urlFor(source.tilejson);
|
|
147
|
+
|
|
148
|
+
// composite untiled raster sources
|
|
149
|
+
if (Array.isArray(source.composite)) {
|
|
150
|
+
source.composite.forEach(c => c.url = bundle.urlFor(c.url));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// custom scripts
|
|
154
|
+
if (source.scripts) {
|
|
155
|
+
// convert legacy array-style scripts to object format (script URL is used as both key and value)
|
|
156
|
+
if (Array.isArray(source.scripts)) {
|
|
157
|
+
source.scripts = source.scripts.reduce<Record<string, string | undefined>>((val, cur) => { val[cur] = cur; return val; }, {});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// resolve URLs for external scripts
|
|
161
|
+
for (const s in source.scripts) {
|
|
162
|
+
source.scripts[s] = bundle.urlFor(source.scripts[s]);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return source;
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
// Expand paths for fonts
|
|
170
|
+
normalizeFonts(config: SceneDefinition, bundle: SceneBundle): SceneDefinition {
|
|
171
|
+
config.fonts = config.fonts || {};
|
|
172
|
+
|
|
173
|
+
// Add scene base path for URL-based fonts (skip "external" fonts referencing CSS-loaded resources)
|
|
174
|
+
const fonts = Object.values(config.fonts).filter(face => face !== 'external');
|
|
175
|
+
for (const face of fonts) {
|
|
176
|
+
const faces = (Array.isArray(face) ? face : [face]); // can be single value or array
|
|
177
|
+
faces.forEach(face => face.url = bundle.urlFor(face.url));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return config;
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
// Expand paths and centralize texture definitions for a scene object
|
|
184
|
+
normalizeTextures(config: SceneDefinition, bundle: SceneBundle): void {
|
|
185
|
+
config.textures = config.textures || {};
|
|
186
|
+
|
|
187
|
+
// Add current scene's base path to globally defined textures
|
|
188
|
+
// Only adds path for textures with relative URLs, so textures in imported scenes get the base
|
|
189
|
+
// path of their immediate scene file
|
|
190
|
+
if (config.textures) {
|
|
191
|
+
for (const tn in config.textures) {
|
|
192
|
+
const texture = config.textures[tn];
|
|
193
|
+
if (texture.url) {
|
|
194
|
+
texture.url = bundle.urlFor(texture.url);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
// Move inline (URL string) textures to the scene's top-level set of textures (config.textures).
|
|
201
|
+
// There are 4 such cases of textures:
|
|
202
|
+
// - in a style's `texture` property
|
|
203
|
+
// - in a style's `material` properties
|
|
204
|
+
// - in a style's custom uniforms (`shaders.uniforms`)
|
|
205
|
+
// - in a draw groups `texture` property
|
|
206
|
+
collectTextures(config: SceneDefinition, bundle: SceneBundle, texture_nodes: SceneTextureNodes): void {
|
|
207
|
+
const textures = config.textures!; // normalizeTextures runs before collection.
|
|
208
|
+
// Inline textures in styles
|
|
209
|
+
if (config.styles) {
|
|
210
|
+
for (const sn in config.styles) {
|
|
211
|
+
const style: SceneStyleDefinition = config.styles[sn];
|
|
212
|
+
|
|
213
|
+
// Style `texture`
|
|
214
|
+
const tex = style.texture;
|
|
215
|
+
if (typeof tex === 'string' && !textures[tex]) {
|
|
216
|
+
const path = ['styles', sn, 'texture'];
|
|
217
|
+
this.addTextureNode(path, bundle, texture_nodes);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Material
|
|
221
|
+
if (style.material) {
|
|
222
|
+
['emission', 'ambient', 'diffuse', 'specular', 'normal'].forEach(prop => {
|
|
223
|
+
// Material property has a texture
|
|
224
|
+
const tex = style.material![prop] != null &&
|
|
225
|
+
(style.material![prop] as Exclude<SceneMaterialChannel, number | string | number[]>).texture;
|
|
226
|
+
if (typeof tex === 'string' && !textures[tex]) {
|
|
227
|
+
const path = ['styles', sn, 'material', prop, 'texture'];
|
|
228
|
+
this.addTextureNode(path, bundle, texture_nodes);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Inline textures in shader uniforms
|
|
236
|
+
if (config.styles) {
|
|
237
|
+
for (const sn in config.styles) {
|
|
238
|
+
const style = config.styles[sn];
|
|
239
|
+
|
|
240
|
+
if (style.shaders && style.shaders.uniforms) {
|
|
241
|
+
GLSL.parseUniforms(style.shaders.uniforms).forEach(({ type, value, path }) => {
|
|
242
|
+
// Texture by URL (string-named texture not referencing existing texture definition)
|
|
243
|
+
if (type === 'sampler2D' && typeof value === 'string' && !textures[value]) {
|
|
244
|
+
const texture_path = ['styles', sn, 'shaders', 'uniforms', ...path];
|
|
245
|
+
this.addTextureNode(texture_path, bundle, texture_nodes);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Inline textures in draw blocks
|
|
253
|
+
if (config.layers) {
|
|
254
|
+
const stack: unknown[] = [config.layers];
|
|
255
|
+
const path_stack = [['layers']];
|
|
256
|
+
while (stack.length > 0) {
|
|
257
|
+
const layer = stack.pop();
|
|
258
|
+
const layer_path = path_stack.pop()!;
|
|
259
|
+
|
|
260
|
+
// only recurse into objects
|
|
261
|
+
if (typeof layer !== 'object' || Array.isArray(layer)) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const definition = layer as SceneLayerDefinition;
|
|
266
|
+
for (const prop in definition) {
|
|
267
|
+
if (prop === 'draw') { // process draw groups for current layer
|
|
268
|
+
const draws = definition.draw!;
|
|
269
|
+
for (const group in draws) {
|
|
270
|
+
if (draws[group].texture) {
|
|
271
|
+
const tex = draws[group].texture;
|
|
272
|
+
if (typeof tex === 'string' && !textures[tex]) {
|
|
273
|
+
const path = [...layer_path, prop, group, 'texture'];
|
|
274
|
+
this.addTextureNode(path, bundle, texture_nodes);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// special handling for outlines :(
|
|
279
|
+
if (draws[group].outline && draws[group].outline.texture) {
|
|
280
|
+
const tex = draws[group].outline.texture;
|
|
281
|
+
if (typeof tex === 'string' && !textures[tex]) {
|
|
282
|
+
const path = [...layer_path, prop, group, 'outline', 'texture'];
|
|
283
|
+
this.addTextureNode(path, bundle, texture_nodes);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
}
|
|
289
|
+
else if (isReserved(prop)) {
|
|
290
|
+
continue; // skip reserved keyword
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
stack.push(definition[prop]); // traverse sublayer
|
|
294
|
+
path_stack.push([...layer_path, prop]);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
addTextureNode (path: (string | number)[], bundle: SceneBundle, texture_nodes: SceneTextureNodes): void {
|
|
302
|
+
const pathKey = JSON.stringify(path);
|
|
303
|
+
texture_nodes[pathKey] = {
|
|
304
|
+
path,
|
|
305
|
+
bundle
|
|
306
|
+
};
|
|
307
|
+
},
|
|
308
|
+
|
|
309
|
+
// Hoist any remaining inline texture nodes that don't have a corresponding named texture
|
|
310
|
+
// base_bundle is the bundle for the root scene, for resolving textures from global properties
|
|
311
|
+
hoistTextureNodes (config: SceneDefinition, base_bundle: SceneBundle, texture_nodes: SceneTextureNodes = {}): void {
|
|
312
|
+
const textures = config.textures!; // Normalized scene owns the texture registry.
|
|
313
|
+
for(const { path, bundle } of Object.values(texture_nodes)) {
|
|
314
|
+
const curValue = getPropertyPath(config, path);
|
|
315
|
+
|
|
316
|
+
// Make sure current property values is a string to account for global property substitutions
|
|
317
|
+
// e.g. shader uniforms are ambiguous, could be replaced with string value indicating texture,
|
|
318
|
+
// but could also be a float, an array indicating vector, etc.
|
|
319
|
+
if (typeof curValue === 'string' && textures[curValue] == null) {
|
|
320
|
+
if (isGlobalSubstitution(config, path)) {
|
|
321
|
+
// global substituions are resolved against the base scene path, not the import they came from
|
|
322
|
+
const url = base_bundle.urlFor(curValue);
|
|
323
|
+
textures[curValue] = { url };
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
// non-global textures are resolved against the import they came from
|
|
327
|
+
const url = bundle.urlFor(curValue);
|
|
328
|
+
textures[String(url)] = { url }; // Preserve legacy key coercion for a missing archive resource.
|
|
329
|
+
setPropertyPath(config, path, url);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
// Substitutes global scene properties (those defined in the `config.global` object) for any style values
|
|
336
|
+
// of the form `global.`, for example `color: global.park_color` would be replaced with the value (if any)
|
|
337
|
+
// defined for the `park_color` property in `config.global.park_color`.
|
|
338
|
+
applyGlobalProperties<Config extends SceneDefinition>(config: Config): Config {
|
|
339
|
+
if (!config.global || Object.keys(config.global).length === 0) {
|
|
340
|
+
return config; // no global properties to transform
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const globals = flattenGlobalProperties(config.global); // flatten nested globals for simpler string look-ups
|
|
344
|
+
return applyGlobalProperties(globals, config);
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
// Normalize some scene-wide settings that apply to the final, merged scene
|
|
348
|
+
finalize: finalizeScene
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
/** Normalize a known scene while preserving the caller's resource resolver identity. */
|
|
352
|
+
function finalizeScene<Bundle>(scene: {config: SceneDefinition; bundle: Bundle}, options?: SceneLoadOptions):
|
|
353
|
+
{config: FinalizedSceneDefinition; bundle: Bundle};
|
|
354
|
+
/** Preserve an empty result when the root or import subtree failed to load. */
|
|
355
|
+
function finalizeScene(scene: SceneLoadResult, options?: SceneLoadOptions): SceneLoadResult;
|
|
356
|
+
function finalizeScene({config, bundle}: {config?: SceneDefinition; bundle?: unknown},
|
|
357
|
+
{cameraMode}: SceneLoadOptions = {}): {config?: SceneDefinition; bundle?: unknown} {
|
|
358
|
+
if (!config) {
|
|
359
|
+
return {};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Ensure top-level properties
|
|
363
|
+
config.global = config.global || {};
|
|
364
|
+
config.scene = config.scene || {};
|
|
365
|
+
// Internal worker policy: host cameras, not tile zoom, own billboard collision.
|
|
366
|
+
config.scene._host_screen_space_labels = cameraMode === 'external';
|
|
367
|
+
config.cameras = config.cameras || {};
|
|
368
|
+
const native_lights = Array.isArray(config.lights);
|
|
369
|
+
const lights = normalizeSceneLights(config.lights || {}) as SceneNamedLights;
|
|
370
|
+
config.lights = lights;
|
|
371
|
+
if (native_lights && Object.keys(lights).length === 0) {
|
|
372
|
+
config.scene.lighting = 'configured'; // Explicit empty arrays still select the configurable WGSL path.
|
|
373
|
+
}
|
|
374
|
+
config.styles = config.styles || {};
|
|
375
|
+
config.layers = config.layers || {};
|
|
376
|
+
|
|
377
|
+
// Host-driven scenes do not need Tangram camera configuration. Keep
|
|
378
|
+
// authored cameras intact, but do not synthesize a default camera.
|
|
379
|
+
if (cameraMode !== 'external') {
|
|
380
|
+
// If only one camera specified, set it as default
|
|
381
|
+
if (config.camera) {
|
|
382
|
+
config.cameras.default = config.camera;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// If no cameras specified, create one
|
|
386
|
+
if (Object.keys(config.cameras).length === 0) {
|
|
387
|
+
config.cameras.default = {};
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// If no lights specified, create default
|
|
392
|
+
if (!native_lights && (Object.keys(lights).length === 0 ||
|
|
393
|
+
Object.keys(lights).every(i => lights[i].visible === false))) {
|
|
394
|
+
lights.default_light = {
|
|
395
|
+
type: 'directional'
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return { config: config as FinalizedSceneDefinition, bundle };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export default SceneLoader;
|