itowns 2.45.1-next.0 → 2.45.1-next.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/dist/455.js +2 -0
- package/dist/455.js.map +1 -0
- package/dist/debug.js +3 -0
- package/dist/debug.js.LICENSE.txt +13 -0
- package/dist/debug.js.map +1 -0
- package/dist/itowns.js +3 -0
- package/dist/itowns.js.LICENSE.txt +5 -0
- package/dist/itowns.js.map +1 -0
- package/dist/itowns_lasparser.js +2 -0
- package/dist/itowns_lasparser.js.map +1 -0
- package/dist/itowns_lasworker.js +2 -0
- package/dist/itowns_lasworker.js.map +1 -0
- package/dist/itowns_potree2worker.js +2 -0
- package/dist/itowns_potree2worker.js.map +1 -0
- package/dist/itowns_widgets.js +2 -0
- package/dist/itowns_widgets.js.map +1 -0
- package/lib/Controls/FirstPersonControls.js +308 -0
- package/lib/Controls/FlyControls.js +175 -0
- package/lib/Controls/GlobeControls.js +1178 -0
- package/lib/Controls/PlanarControls.js +1025 -0
- package/lib/Controls/StateControl.js +432 -0
- package/lib/Controls/StreetControls.js +392 -0
- package/lib/Converter/Feature2Mesh.js +612 -0
- package/lib/Converter/Feature2Texture.js +174 -0
- package/lib/Converter/convertToTile.js +70 -0
- package/lib/Converter/textureConverter.js +43 -0
- package/lib/Core/3DTiles/C3DTBatchTable.js +131 -0
- package/lib/Core/3DTiles/C3DTBatchTableHierarchyExtension.js +96 -0
- package/lib/Core/3DTiles/C3DTBoundingVolume.js +156 -0
- package/lib/Core/3DTiles/C3DTExtensions.js +97 -0
- package/lib/Core/3DTiles/C3DTFeature.js +110 -0
- package/lib/Core/3DTiles/C3DTilesEnums.js +20 -0
- package/lib/Core/3DTiles/C3DTileset.js +99 -0
- package/lib/Core/3DTiles/utils/BinaryPropertyAccessor.js +100 -0
- package/lib/Core/AnimationPlayer.js +142 -0
- package/lib/Core/CopcNode.js +174 -0
- package/lib/Core/Deprecated/Undeprecator.js +74 -0
- package/lib/Core/EntwinePointTileNode.js +126 -0
- package/lib/Core/Feature.js +488 -0
- package/lib/Core/Geographic/GeoidGrid.js +108 -0
- package/lib/Core/Label.js +222 -0
- package/lib/Core/MainLoop.js +209 -0
- package/lib/Core/Picking.js +255 -0
- package/lib/Core/PointCloudNode.js +42 -0
- package/lib/Core/Potree2Node.js +206 -0
- package/lib/Core/Potree2PointAttributes.js +139 -0
- package/lib/Core/PotreeNode.js +101 -0
- package/lib/Core/Prefab/Globe/Atmosphere.js +293 -0
- package/lib/Core/Prefab/Globe/GlobeLayer.js +152 -0
- package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +110 -0
- package/lib/Core/Prefab/Globe/SkyShader.js +78 -0
- package/lib/Core/Prefab/GlobeView.js +155 -0
- package/lib/Core/Prefab/Planar/PlanarLayer.js +59 -0
- package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +71 -0
- package/lib/Core/Prefab/PlanarView.js +62 -0
- package/lib/Core/Prefab/TileBuilder.js +82 -0
- package/lib/Core/Prefab/computeBufferTileGeometry.js +248 -0
- package/lib/Core/Scheduler/Cache.js +17 -0
- package/lib/Core/Scheduler/CancelledCommandException.js +15 -0
- package/lib/Core/Scheduler/Scheduler.js +294 -0
- package/lib/Core/Style.js +660 -0
- package/lib/Core/StyleOptions.js +486 -0
- package/lib/Core/System/Capabilities.js +63 -0
- package/lib/Core/Tile/Tile.js +205 -0
- package/lib/Core/Tile/TileGrid.js +49 -0
- package/lib/Core/TileGeometry.js +124 -0
- package/lib/Core/TileMesh.js +108 -0
- package/lib/Core/View.js +1115 -0
- package/lib/Layer/C3DTilesLayer.js +459 -0
- package/lib/Layer/ColorLayer.js +154 -0
- package/lib/Layer/CopcLayer.js +63 -0
- package/lib/Layer/ElevationLayer.js +139 -0
- package/lib/Layer/EntwinePointTileLayer.js +71 -0
- package/lib/Layer/FeatureGeometryLayer.js +77 -0
- package/lib/Layer/GeoidLayer.js +80 -0
- package/lib/Layer/GeometryLayer.js +233 -0
- package/lib/Layer/InfoLayer.js +64 -0
- package/lib/Layer/LabelLayer.js +469 -0
- package/lib/Layer/Layer.js +335 -0
- package/lib/Layer/LayerUpdateState.js +89 -0
- package/lib/Layer/LayerUpdateStrategy.js +80 -0
- package/lib/Layer/OGC3DTilesLayer.js +543 -0
- package/lib/Layer/OrientedImageLayer.js +227 -0
- package/lib/Layer/PointCloudLayer.js +405 -0
- package/lib/Layer/Potree2Layer.js +171 -0
- package/lib/Layer/PotreeLayer.js +72 -0
- package/lib/Layer/RasterLayer.js +37 -0
- package/lib/Layer/ReferencingLayerProperties.js +62 -0
- package/lib/Layer/TiledGeometryLayer.js +459 -0
- package/lib/Loader/LASLoader.js +193 -0
- package/lib/Loader/Potree2BrotliLoader.js +261 -0
- package/lib/Loader/Potree2Loader.js +207 -0
- package/lib/Main.js +113 -0
- package/lib/MainBundle.js +4 -0
- package/lib/Parser/B3dmParser.js +174 -0
- package/lib/Parser/CameraCalibrationParser.js +94 -0
- package/lib/Parser/GDFParser.js +72 -0
- package/lib/Parser/GTXParser.js +75 -0
- package/lib/Parser/GeoJsonParser.js +212 -0
- package/lib/Parser/GpxParser.js +25 -0
- package/lib/Parser/ISGParser.js +71 -0
- package/lib/Parser/KMLParser.js +25 -0
- package/lib/Parser/LASParser.js +137 -0
- package/lib/Parser/MapBoxUrlParser.js +83 -0
- package/lib/Parser/PntsParser.js +131 -0
- package/lib/Parser/Potree2BinParser.js +92 -0
- package/lib/Parser/PotreeBinParser.js +106 -0
- package/lib/Parser/PotreeCinParser.js +29 -0
- package/lib/Parser/ShapefileParser.js +78 -0
- package/lib/Parser/VectorTileParser.js +215 -0
- package/lib/Parser/XbilParser.js +120 -0
- package/lib/Parser/deprecated/LegacyGLTFLoader.js +1386 -0
- package/lib/Parser/iGLTFLoader.js +168 -0
- package/lib/Process/3dTilesProcessing.js +304 -0
- package/lib/Process/FeatureProcessing.js +76 -0
- package/lib/Process/LayeredMaterialNodeProcessing.js +229 -0
- package/lib/Process/ObjectRemovalHelper.js +97 -0
- package/lib/Process/handlerNodeError.js +23 -0
- package/lib/Provider/3dTilesProvider.js +149 -0
- package/lib/Provider/DataSourceProvider.js +24 -0
- package/lib/Provider/Fetcher.js +233 -0
- package/lib/Provider/PointCloudProvider.js +45 -0
- package/lib/Provider/TileProvider.js +16 -0
- package/lib/Provider/URLBuilder.js +116 -0
- package/lib/Renderer/Camera.js +281 -0
- package/lib/Renderer/Color.js +56 -0
- package/lib/Renderer/ColorLayersOrdering.js +115 -0
- package/lib/Renderer/CommonMaterial.js +31 -0
- package/lib/Renderer/Label2DRenderer.js +192 -0
- package/lib/Renderer/LayeredMaterial.js +243 -0
- package/lib/Renderer/OBB.js +150 -0
- package/lib/Renderer/OrientedImageCamera.js +118 -0
- package/lib/Renderer/OrientedImageMaterial.js +167 -0
- package/lib/Renderer/PointsMaterial.js +485 -0
- package/lib/Renderer/RasterTile.js +243 -0
- package/lib/Renderer/RenderMode.js +31 -0
- package/lib/Renderer/Shader/ShaderChunk.js +160 -0
- package/lib/Renderer/Shader/ShaderUtils.js +47 -0
- package/lib/Renderer/SphereHelper.js +17 -0
- package/lib/Renderer/WebXR.js +51 -0
- package/lib/Renderer/c3DEngine.js +214 -0
- package/lib/Source/C3DTilesGoogleSource.js +74 -0
- package/lib/Source/C3DTilesIonSource.js +54 -0
- package/lib/Source/C3DTilesSource.js +30 -0
- package/lib/Source/CopcSource.js +126 -0
- package/lib/Source/EntwinePointTileSource.js +72 -0
- package/lib/Source/FileSource.js +188 -0
- package/lib/Source/OGC3DTilesGoogleSource.js +29 -0
- package/lib/Source/OGC3DTilesIonSource.js +34 -0
- package/lib/Source/OGC3DTilesSource.js +21 -0
- package/lib/Source/OrientedImageSource.js +59 -0
- package/lib/Source/Potree2Source.js +167 -0
- package/lib/Source/PotreeSource.js +82 -0
- package/lib/Source/Source.js +202 -0
- package/lib/Source/TMSSource.js +144 -0
- package/lib/Source/VectorTilesSource.js +182 -0
- package/lib/Source/WFSSource.js +170 -0
- package/lib/Source/WMSSource.js +167 -0
- package/lib/Source/WMTSSource.js +92 -0
- package/lib/ThreeExtended/capabilities/WebGL.js +69 -0
- package/lib/ThreeExtended/libs/ktx-parse.module.js +506 -0
- package/lib/ThreeExtended/libs/zstddec.module.js +29 -0
- package/lib/ThreeExtended/loaders/DDSLoader.js +200 -0
- package/lib/ThreeExtended/loaders/DRACOLoader.js +400 -0
- package/lib/ThreeExtended/loaders/GLTFLoader.js +2879 -0
- package/lib/ThreeExtended/loaders/KTX2Loader.js +709 -0
- package/lib/ThreeExtended/math/ColorSpaces.js +59 -0
- package/lib/ThreeExtended/utils/BufferGeometryUtils.js +846 -0
- package/lib/ThreeExtended/utils/WorkerPool.js +70 -0
- package/lib/Utils/CameraUtils.js +554 -0
- package/lib/Utils/DEMUtils.js +350 -0
- package/lib/Utils/FeaturesUtils.js +156 -0
- package/lib/Utils/Gradients.js +16 -0
- package/lib/Utils/ThreeUtils.js +115 -0
- package/lib/Utils/gui/C3DTilesStyle.js +218 -0
- package/lib/Utils/gui/Main.js +7 -0
- package/lib/Utils/gui/Minimap.js +152 -0
- package/lib/Utils/gui/Navigation.js +245 -0
- package/lib/Utils/gui/Scale.js +104 -0
- package/lib/Utils/gui/Searchbar.js +234 -0
- package/lib/Utils/gui/Widget.js +80 -0
- package/lib/Utils/placeObjectOnGround.js +136 -0
- package/lib/Worker/LASLoaderWorker.js +19 -0
- package/lib/Worker/Potree2Worker.js +21 -0
- package/package.json +2 -2
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import RasterLayer from "./RasterLayer.js";
|
|
2
|
+
import { updateLayeredMaterialNodeElevation } from "../Process/LayeredMaterialNodeProcessing.js";
|
|
3
|
+
import { RasterElevationTile } from "../Renderer/RasterTile.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @property {boolean} isElevationLayer - Used to checkout whether this layer is
|
|
7
|
+
* an ElevationLayer. Default is true. You should not change this, as it is used
|
|
8
|
+
* internally for optimisation.
|
|
9
|
+
* @property {number} noDataValue - Used to specify a **null** or **no data value** in the elevation terrain.
|
|
10
|
+
* @property {number} [zmin] - Used to specify a minimum value for the elevation terrain (if the data goes lower, it will be clamped).
|
|
11
|
+
* @property {number} [zmax] - Used to specify a maximum value for the elevation terrain (if the data goes higher, it will be clamped)
|
|
12
|
+
* @property {number} scale - Used to apply a scale on the elevation value. It
|
|
13
|
+
* can be used for exageration of the elevation, like in [this
|
|
14
|
+
* example](https://www.itowns-project.org/itowns/examples/#plugins_pyramidal_tiff).
|
|
15
|
+
* @property {boolean} useColorTextureElevation - the elevation is computed with one color texture channel,
|
|
16
|
+
* `this.colorTextureElevationMaxZ` and `this.colorTextureElevationMinZ`.
|
|
17
|
+
*
|
|
18
|
+
* The formula is:
|
|
19
|
+
*
|
|
20
|
+
* ```js
|
|
21
|
+
* elevation = color.r * (this.colorTextureElevationMaxZ - this.colorTextureElevationMinZ) + this.colorTextureElevationMinZ
|
|
22
|
+
* ```
|
|
23
|
+
* @property {number} colorTextureElevationMinZ - elevation minimum in `useColorTextureElevation` mode.
|
|
24
|
+
* @property {number} colorTextureElevationMaxZ - elevation maximum in `useColorTextureElevation` mode.
|
|
25
|
+
*
|
|
26
|
+
* @extends RasterLayer
|
|
27
|
+
*/
|
|
28
|
+
class ElevationLayer extends RasterLayer {
|
|
29
|
+
/**
|
|
30
|
+
* A simple layer, managing an elevation texture to add some reliefs on the
|
|
31
|
+
* plane or globe view for example.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} id - The id of the layer, that should be unique. It is
|
|
34
|
+
* not mandatory, but an error will be emitted if this layer is added a
|
|
35
|
+
* {@link View} that already has a layer going by that id.
|
|
36
|
+
* @param {Object} [config] - Optional configuration, all elements in it
|
|
37
|
+
* will be merged as is in the layer. For example, if the configuration
|
|
38
|
+
* contains three elements `name, protocol, extent`, these elements will be
|
|
39
|
+
* available using `layer.name` or something else depending on the property
|
|
40
|
+
* name.
|
|
41
|
+
* @param {number} [config.noDataValue] The value coding the noData in the data set
|
|
42
|
+
* @param {Object} [config.clampValues] - Optional information for clamping
|
|
43
|
+
* the elevation between a minimum and a maximum value
|
|
44
|
+
* @param {number} [config.clampValues.min] The minimum value to clamp the elevation
|
|
45
|
+
* @param {number} [config.clampValues.max] The maximum value to clamp the elevation
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // Create an ElevationLayer
|
|
49
|
+
* const elevation = new ElevationLayer('IGN_MNT', {
|
|
50
|
+
* source: new WMTSSource({
|
|
51
|
+
* "url": "https://data.geopf.fr/wmts?",
|
|
52
|
+
* "crs": "EPSG:4326",
|
|
53
|
+
* "format": "image/x-bil;bits=32",
|
|
54
|
+
* "name": "ELEVATION.ELEVATIONGRIDCOVERAGE",
|
|
55
|
+
* }),
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* // Add the layer
|
|
59
|
+
* view.addLayer(elevation);
|
|
60
|
+
*/
|
|
61
|
+
constructor(id) {
|
|
62
|
+
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
63
|
+
const {
|
|
64
|
+
scale = 1.0,
|
|
65
|
+
noDataValue,
|
|
66
|
+
clampValues,
|
|
67
|
+
useRgbaTextureElevation,
|
|
68
|
+
useColorTextureElevation,
|
|
69
|
+
colorTextureElevationMinZ,
|
|
70
|
+
colorTextureElevationMaxZ,
|
|
71
|
+
bias,
|
|
72
|
+
mode,
|
|
73
|
+
...rasterConfig
|
|
74
|
+
} = config;
|
|
75
|
+
super(id, rasterConfig);
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @type {boolean}
|
|
79
|
+
* @readonly
|
|
80
|
+
*/
|
|
81
|
+
this.isElevationLayer = true;
|
|
82
|
+
this.noDataValue = noDataValue;
|
|
83
|
+
if (config.zmin || config.zmax) {
|
|
84
|
+
console.warn('Config using zmin and zmax are deprecated, use {clampValues: {min, max}} structure.');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @type {number | undefined}
|
|
89
|
+
*/
|
|
90
|
+
this.zmin = clampValues?.min ?? config.zmin;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @type {number | undefined}
|
|
94
|
+
*/
|
|
95
|
+
this.zmax = clampValues?.max ?? config.zmax;
|
|
96
|
+
this.defineLayerProperty('scale', scale);
|
|
97
|
+
this.useRgbaTextureElevation = useRgbaTextureElevation;
|
|
98
|
+
this.useColorTextureElevation = useColorTextureElevation;
|
|
99
|
+
this.colorTextureElevationMinZ = colorTextureElevationMinZ;
|
|
100
|
+
this.colorTextureElevationMaxZ = colorTextureElevationMaxZ;
|
|
101
|
+
this.bias = bias;
|
|
102
|
+
this.mode = mode;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Setup RasterElevationTile added to TileMesh. This RasterElevationTile handles
|
|
107
|
+
* the elevation texture to displace TileMesh vertices.
|
|
108
|
+
*
|
|
109
|
+
* @param {TileMesh} node The node to apply new RasterElevationTile;
|
|
110
|
+
* @return {RasterElevationTile} The raster elevation node added.
|
|
111
|
+
*/
|
|
112
|
+
setupRasterNode(node) {
|
|
113
|
+
const rasterElevationNode = new RasterElevationTile(node.material, this);
|
|
114
|
+
node.material.addLayer(rasterElevationNode);
|
|
115
|
+
node.material.setSequenceElevation(this.id);
|
|
116
|
+
// bounding box initialisation
|
|
117
|
+
const updateBBox = () => node.setBBoxZ({
|
|
118
|
+
min: rasterElevationNode.min,
|
|
119
|
+
max: rasterElevationNode.max,
|
|
120
|
+
scale: this.scale
|
|
121
|
+
});
|
|
122
|
+
updateBBox();
|
|
123
|
+
|
|
124
|
+
// listen elevation updating
|
|
125
|
+
rasterElevationNode.addEventListener('rasterElevationLevelChanged', updateBBox);
|
|
126
|
+
|
|
127
|
+
// listen scaling elevation updating
|
|
128
|
+
this.addEventListener('scale-property-changed', updateBBox);
|
|
129
|
+
// remove scaling elevation updating if node is removed
|
|
130
|
+
node.addEventListener('dispose', () => {
|
|
131
|
+
this.removeEventListener('scale-property-changed', updateBBox);
|
|
132
|
+
});
|
|
133
|
+
return rasterElevationNode;
|
|
134
|
+
}
|
|
135
|
+
update(context, layer, node, parent) {
|
|
136
|
+
return updateLayeredMaterialNodeElevation(context, this, node, parent);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export default ElevationLayer;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import EntwinePointTileNode from "../Core/EntwinePointTileNode.js";
|
|
3
|
+
import PointCloudLayer from "./PointCloudLayer.js";
|
|
4
|
+
import { Extent } from '@itowns/geographic';
|
|
5
|
+
const bboxMesh = new THREE.Mesh();
|
|
6
|
+
const box3 = new THREE.Box3();
|
|
7
|
+
bboxMesh.geometry.boundingBox = box3;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @property {boolean} isEntwinePointTileLayer - Used to checkout whether this
|
|
11
|
+
* layer is a EntwinePointTileLayer. Default is `true`. You should not change
|
|
12
|
+
* this, as it is used internally for optimisation.
|
|
13
|
+
*
|
|
14
|
+
* @extends PointCloudLayer
|
|
15
|
+
*/
|
|
16
|
+
class EntwinePointTileLayer extends PointCloudLayer {
|
|
17
|
+
/**
|
|
18
|
+
* Constructs a new instance of Entwine Point Tile layer.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Create a new point cloud layer
|
|
22
|
+
* const points = new EntwinePointTileLayer('EPT',
|
|
23
|
+
* {
|
|
24
|
+
* source: new EntwinePointTileSource({
|
|
25
|
+
* url: 'https://server.geo/ept-dataset',
|
|
26
|
+
* }
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* View.prototype.addLayer.call(view, points);
|
|
30
|
+
*
|
|
31
|
+
* @param {string} id - The id of the layer, that should be unique. It is
|
|
32
|
+
* not mandatory, but an error will be emitted if this layer is added a
|
|
33
|
+
* {@link View} that already has a layer going by that id.
|
|
34
|
+
* @param {Object} config - Configuration, all elements in it
|
|
35
|
+
* will be merged as is in the layer. For example, if the configuration
|
|
36
|
+
* contains three elements `name, protocol, extent`, these elements will be
|
|
37
|
+
* available using `layer.name` or something else depending on the property
|
|
38
|
+
* name. See the list of properties to know which one can be specified.
|
|
39
|
+
* @param {string} [config.crs='ESPG:4326'] - The CRS of the {@link View} this
|
|
40
|
+
* layer will be attached to. This is used to determine the extent of this
|
|
41
|
+
* layer. Default to `EPSG:4326`.
|
|
42
|
+
*/
|
|
43
|
+
constructor(id, config) {
|
|
44
|
+
super(id, config);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @type {boolean}
|
|
48
|
+
* @readonly
|
|
49
|
+
*/
|
|
50
|
+
this.isEntwinePointTileLayer = true;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @type {THREE.Vector3}
|
|
54
|
+
*/
|
|
55
|
+
this.scale = new THREE.Vector3(1, 1, 1);
|
|
56
|
+
const resolve = this.addInitializationStep();
|
|
57
|
+
this.whenReady = this.source.whenReady.then(() => {
|
|
58
|
+
this.root = new EntwinePointTileNode(0, 0, 0, 0, this, -1);
|
|
59
|
+
this.root.bbox.min.fromArray(this.source.boundsConforming, 0);
|
|
60
|
+
this.root.bbox.max.fromArray(this.source.boundsConforming, 3);
|
|
61
|
+
this.minElevationRange = this.minElevationRange ?? this.source.boundsConforming[2];
|
|
62
|
+
this.maxElevationRange = this.maxElevationRange ?? this.source.boundsConforming[5];
|
|
63
|
+
this.extent = Extent.fromBox3(config.crs || 'EPSG:4326', this.root.bbox);
|
|
64
|
+
return this.root.loadOctree().then(resolve);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
get spacing() {
|
|
68
|
+
return this.source.spacing;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export default EntwinePointTileLayer;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Group } from 'three';
|
|
2
|
+
import GeometryLayer from "./GeometryLayer.js";
|
|
3
|
+
import FeatureProcessing from "../Process/FeatureProcessing.js";
|
|
4
|
+
import Feature2Mesh from "../Converter/Feature2Mesh.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `FeatureGeometryLayer` displays geographic vector data (geojson, kml...) in object 3D.
|
|
8
|
+
* `FeatureGeometryLayer` is a pre-configured `GeometryLayer` to load and convert vector data.
|
|
9
|
+
* In deed, `GeometryLayer` allows customizing data loading (`update` method)
|
|
10
|
+
* and their conversion (`convert` method),
|
|
11
|
+
*
|
|
12
|
+
* @property {boolean} isFeatureGeometryLayer - Used to checkout whether this layer is
|
|
13
|
+
* a FeatureGeometryLayer. Default is true. You should not change this, as it is used
|
|
14
|
+
* internally for optimisation.
|
|
15
|
+
*
|
|
16
|
+
* @extends GeometryLayer
|
|
17
|
+
*/
|
|
18
|
+
class FeatureGeometryLayer extends GeometryLayer {
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {string} id - The id of the layer, that should be unique. It is
|
|
22
|
+
* not mandatory, but an error will be emitted if this layer is added a
|
|
23
|
+
* {@link View} that already has a layer going by that id.
|
|
24
|
+
* @param {Object} [options] - Optional configuration, all elements in it
|
|
25
|
+
* will be merged as is in the layer.
|
|
26
|
+
* @param {function} [options.batchId] - optional function to create batchId attribute.
|
|
27
|
+
* It is passed the feature property and the feature index.
|
|
28
|
+
* As the batchId is using an unsigned int structure on 32 bits, the batchId could be between 0 and 4,294,967,295.
|
|
29
|
+
* @param {THREE.Object3D} [options.object3d=new THREE.Group()] root object3d layer.
|
|
30
|
+
* @param {function} [options.onMeshCreated] this callback is called when the mesh is created. The callback parameters are the
|
|
31
|
+
* `mesh` and the `context`.
|
|
32
|
+
* @param {function} [options.filter] callback which filters the features of
|
|
33
|
+
* this layer. It takes an object with a `properties` property as argument
|
|
34
|
+
* and shall return a boolean.
|
|
35
|
+
* @param {boolean} [options.accurate=TRUE] If `accurate` is `true`, data are re-projected with maximum geographical accuracy.
|
|
36
|
+
* With `true`, `proj4` is used to transform data source.
|
|
37
|
+
*
|
|
38
|
+
* If `accurate` is `false`, re-projecting is faster but less accurate.
|
|
39
|
+
* With `false`, an affine transformation is used to transform data source.
|
|
40
|
+
* This method is an approximation. The error increases with the extent
|
|
41
|
+
* dimension of the object or queries.
|
|
42
|
+
*
|
|
43
|
+
* For example :
|
|
44
|
+
* * for a **100** meter dimension, there's a difference of **0.001** meter with the accurate method
|
|
45
|
+
* * for a **500** meter dimension, there's a difference of **0.05** meter with the accurate method
|
|
46
|
+
* * for a **20000** meter dimension, there's a difference of **40** meter with the accurate method
|
|
47
|
+
*
|
|
48
|
+
* **WARNING** If the source is `VectorTilesSource` then `accurate` is always false.
|
|
49
|
+
*/
|
|
50
|
+
constructor(id) {
|
|
51
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
52
|
+
const {
|
|
53
|
+
object3d,
|
|
54
|
+
batchId,
|
|
55
|
+
onMeshCreated,
|
|
56
|
+
accurate = true,
|
|
57
|
+
filter,
|
|
58
|
+
...geometryOptions
|
|
59
|
+
} = options;
|
|
60
|
+
super(id, object3d || new Group(), geometryOptions);
|
|
61
|
+
this.update = FeatureProcessing.update;
|
|
62
|
+
this.convert = Feature2Mesh.convert({
|
|
63
|
+
batchId
|
|
64
|
+
});
|
|
65
|
+
this.onMeshCreated = onMeshCreated;
|
|
66
|
+
this.isFeatureGeometryLayer = true;
|
|
67
|
+
this.accurate = accurate;
|
|
68
|
+
this.buildExtent = !this.accurate;
|
|
69
|
+
this.filter = filter;
|
|
70
|
+
}
|
|
71
|
+
preUpdate(context, sources) {
|
|
72
|
+
if (sources.has(this.parent)) {
|
|
73
|
+
this.object3d.clear();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export default FeatureGeometryLayer;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import Layer from "./Layer.js";
|
|
2
|
+
import LayerUpdateState from "./LayerUpdateState.js";
|
|
3
|
+
export function geoidLayerIsVisible(tilelayer) {
|
|
4
|
+
return tilelayer?.attachedLayers.filter(l => l.isGeoidLayer)[0]?.visible;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `GeoidLayer` is a specific `{@link Layer}` which supports geoid height data. When added to a `{@link View}`, it
|
|
9
|
+
* vertically translates each of the view's tiles by a proper geoid height value. For a given tile, the geoid height
|
|
10
|
+
* value used for translation is the geoid height computed at the center of the tile.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Create a GeoidLayer from a GTX geoid heights file.
|
|
14
|
+
* const geoidLayer = new GeoidLayer('geoid', {
|
|
15
|
+
* source: new FileSource({
|
|
16
|
+
* url: 'url-to-some-GTX-geoid-heights-file.gtx',
|
|
17
|
+
* crs: 'EPSG:4326',
|
|
18
|
+
* format: 'application/gtx',
|
|
19
|
+
* }),
|
|
20
|
+
* });
|
|
21
|
+
*/
|
|
22
|
+
class GeoidLayer extends Layer {
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new instance of `GeoidLayer`.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} id An unique identifier for the layer.
|
|
27
|
+
* @param {Object} config The layer configuration. All elements in it will be merged as is in the
|
|
28
|
+
* layer. For example, if the configuration contains three elements `name,
|
|
29
|
+
* protocol, extent`, these elements will be available using `layer.name` or
|
|
30
|
+
* something else depending on the property name. Only `config.source`
|
|
31
|
+
* parameter is mandatory.
|
|
32
|
+
* @param {Object} config.source The source of the geoid data displayed by the `GeoidLayer`. It is mandatory
|
|
33
|
+
* that the source data for a `GeoidLayer` be parsed into a
|
|
34
|
+
* `{@link GeoidGrid}`. You can refer to `{@link GTXParser}`,
|
|
35
|
+
* `{@link GDFParser}` and `{@link ISGParser}` to see how three standard
|
|
36
|
+
* geoid height grid file formats are parsed into `{@link GeoidGrid}`.
|
|
37
|
+
*/
|
|
38
|
+
constructor(id) {
|
|
39
|
+
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
40
|
+
super(id, config);
|
|
41
|
+
this.isGeoidLayer = true;
|
|
42
|
+
this.defineLayerProperty('visible', true);
|
|
43
|
+
}
|
|
44
|
+
updateNodeZ(node) {
|
|
45
|
+
node.material.geoidHeight = this.visible ? node.geoidHeight : 0;
|
|
46
|
+
node.obb.updateZ({
|
|
47
|
+
geoidHeight: node.material.geoidHeight
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
update(context, layer, node, parent) {
|
|
51
|
+
if (!parent || !node.material) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Don't update tile if its zoom is not within the layer's zoom limits
|
|
56
|
+
const extentsDestination = node.getExtentsByProjection(layer.crs);
|
|
57
|
+
const zoom = extentsDestination[0].zoom;
|
|
58
|
+
if (zoom > layer.zoom.max || zoom < layer.zoom.min) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (node.layerUpdateState[layer.id] === undefined) {
|
|
62
|
+
node.layerUpdateState[layer.id] = new LayerUpdateState();
|
|
63
|
+
const updateNodeZ = () => this.updateNodeZ(node);
|
|
64
|
+
layer.addEventListener('visible-property-changed', updateNodeZ);
|
|
65
|
+
node.addEventListener('dispose', () => {
|
|
66
|
+
layer.removeEventListener('visible-property-changed', updateNodeZ);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (layer.frozen || !layer.visible || !node.material.visible || !node.layerUpdateState[layer.id].canTryUpdate()) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
node.layerUpdateState[layer.id].newTry();
|
|
73
|
+
return this.getData(node.extent, extentsDestination).then(result => {
|
|
74
|
+
node.geoidHeight = result.getHeightAtCoordinates(node.extent.center());
|
|
75
|
+
this.updateNodeZ(node);
|
|
76
|
+
node.layerUpdateState[layer.id].noMoreUpdatePossible();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export default GeoidLayer;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import Layer from "./Layer.js";
|
|
2
|
+
import Picking from "../Core/Picking.js";
|
|
3
|
+
import { CACHE_POLICIES } from "../Core/Scheduler/Cache.js";
|
|
4
|
+
import ObjectRemovalHelper from "../Process/ObjectRemovalHelper.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Fires when the opacity of the layer has changed.
|
|
8
|
+
* @event GeometryLayer#opacity-property-changed
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @property {boolean} isGeometryLayer - Used to checkout whether this layer is
|
|
13
|
+
* a GeometryLayer. Default is true. You should not change this, as it is used
|
|
14
|
+
* internally for optimisation.
|
|
15
|
+
* @property {number} [zoom.max=Infinity] - this is the maximum zoom beyond which it'll be hidden.
|
|
16
|
+
* The `max` is constant and the value is `Infinity` because there's no maximum display level after which it is hidden.
|
|
17
|
+
* This property is used only if the layer is attached to {@link TiledGeometryLayer}.
|
|
18
|
+
* @property {number} [zoom.min=0] - this is the minimum zoom from which it'll be visible.
|
|
19
|
+
* This property is used only if the layer is attached to {@link TiledGeometryLayer}.
|
|
20
|
+
*/
|
|
21
|
+
class GeometryLayer extends Layer {
|
|
22
|
+
/**
|
|
23
|
+
* A layer usually managing a geometry to display on a view. For example, it
|
|
24
|
+
* can be a layer of buildings extruded from a a WFS stream.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} id - The id of the layer, that should be unique. It is
|
|
27
|
+
* not mandatory, but an error will be emitted if this layer is added a
|
|
28
|
+
* {@link View} that already has a layer going by that id.
|
|
29
|
+
* @param {THREE.Object3D} object3d - The object3D used to contain the
|
|
30
|
+
* geometry of the GeometryLayer. It is usually a `THREE.Group`, but it can
|
|
31
|
+
* be anything inheriting from a `THREE.Object3D`.
|
|
32
|
+
* @param {Object} [config] - Optional configuration, all elements in it
|
|
33
|
+
* will be merged as is in the layer. For example, if the configuration
|
|
34
|
+
* contains three elements `name, protocol, extent`, these elements will be
|
|
35
|
+
* available using `layer.name` or something else depending on the property
|
|
36
|
+
* name.
|
|
37
|
+
* @param {Source} config.source - Description and options of the source.
|
|
38
|
+
* @param {number} [config.cacheLifeTime=Infinity] - set life time value in cache.
|
|
39
|
+
* This value is used for [Cache]{@link Cache} expiration mechanism.
|
|
40
|
+
* @param {boolean} [config.visible]
|
|
41
|
+
*
|
|
42
|
+
* @throws {Error} `object3d` must be a valid `THREE.Object3d`.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // Create a GeometryLayer
|
|
46
|
+
* const geometry = new GeometryLayer('buildings', new THREE.Object3D(), {
|
|
47
|
+
* source: {
|
|
48
|
+
* url: 'http://server.geo/wfs?',
|
|
49
|
+
* protocol: 'wfs',
|
|
50
|
+
* format: 'application/json'
|
|
51
|
+
* },
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* // Add the layer
|
|
55
|
+
* view.addLayer(geometry);
|
|
56
|
+
*/
|
|
57
|
+
constructor(id, object3d) {
|
|
58
|
+
let config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
59
|
+
const {
|
|
60
|
+
cacheLifeTime = CACHE_POLICIES.GEOMETRY,
|
|
61
|
+
visible = true,
|
|
62
|
+
opacity = 1.0,
|
|
63
|
+
...layerConfig
|
|
64
|
+
} = config;
|
|
65
|
+
super(id, {
|
|
66
|
+
...layerConfig,
|
|
67
|
+
cacheLifeTime
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @type {boolean}
|
|
72
|
+
* @readonly
|
|
73
|
+
*/
|
|
74
|
+
this.isGeometryLayer = true;
|
|
75
|
+
if (!object3d || !object3d.isObject3D) {
|
|
76
|
+
throw new Error(`Missing/Invalid object3d parameter (must be a
|
|
77
|
+
three.js Object3D instance)`);
|
|
78
|
+
}
|
|
79
|
+
if (object3d.type === 'Group' && object3d.name === '') {
|
|
80
|
+
object3d.name = id;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @type {THREE.Object3D}
|
|
85
|
+
* @readonly
|
|
86
|
+
*/
|
|
87
|
+
this.object3d = object3d;
|
|
88
|
+
Object.defineProperty(this, 'object3d', {
|
|
89
|
+
writable: false,
|
|
90
|
+
configurable: true
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @type {number}
|
|
95
|
+
*/
|
|
96
|
+
this.opacity = opacity;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @type {boolean}
|
|
100
|
+
*/
|
|
101
|
+
this.wireframe = false;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @type {Layer[]}
|
|
105
|
+
*/
|
|
106
|
+
this.attachedLayers = [];
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @type {boolean}
|
|
110
|
+
*/
|
|
111
|
+
this.visible = visible;
|
|
112
|
+
Object.defineProperty(this.zoom, 'max', {
|
|
113
|
+
value: Infinity,
|
|
114
|
+
writable: false
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Feature options
|
|
118
|
+
this.filteringExtent = !this.source.isFileSource;
|
|
119
|
+
this.structure = '3d';
|
|
120
|
+
}
|
|
121
|
+
get visible() {
|
|
122
|
+
return this.object3d.visible;
|
|
123
|
+
}
|
|
124
|
+
set visible(value) {
|
|
125
|
+
if (this.object3d.visible !== value) {
|
|
126
|
+
const event = {
|
|
127
|
+
type: 'visible-property-changed',
|
|
128
|
+
previous: {},
|
|
129
|
+
new: {}
|
|
130
|
+
};
|
|
131
|
+
event.previous.visible = this.object3d.visible;
|
|
132
|
+
event.new.visible = value;
|
|
133
|
+
this.dispatchEvent(event);
|
|
134
|
+
this.object3d.visible = value;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Attached layers expect to receive the visual representation of a
|
|
139
|
+
// layer (= THREE object with a material). So if a layer's update
|
|
140
|
+
// function don't process this kind of object, the layer must provide a
|
|
141
|
+
// getObjectToUpdateForAttachedLayers function that returns the correct
|
|
142
|
+
// object to update for attached layer.
|
|
143
|
+
// See 3dtilesLayer or PotreeLayer for examples.
|
|
144
|
+
// eslint-disable-next-line arrow-body-style
|
|
145
|
+
getObjectToUpdateForAttachedLayers(obj) {
|
|
146
|
+
if (obj.parent && obj.material) {
|
|
147
|
+
return {
|
|
148
|
+
element: obj,
|
|
149
|
+
parent: obj.parent
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Placeholder
|
|
155
|
+
// eslint-disable-next-line
|
|
156
|
+
postUpdate() {}
|
|
157
|
+
|
|
158
|
+
// Placeholder
|
|
159
|
+
// eslint-disable-next-line
|
|
160
|
+
culling() {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Attach another layer to this one. Layers attached to a GeometryLayer will
|
|
166
|
+
* be available in `geometryLayer.attachedLayers`.
|
|
167
|
+
*
|
|
168
|
+
* @param {Layer} layer - The layer to attach, that must have an `update`
|
|
169
|
+
* method.
|
|
170
|
+
*/
|
|
171
|
+
attach(layer) {
|
|
172
|
+
if (!layer.update) {
|
|
173
|
+
throw new Error(`Missing 'update' function -> can't attach layer
|
|
174
|
+
${layer.id}`);
|
|
175
|
+
}
|
|
176
|
+
this.attachedLayers.push(layer);
|
|
177
|
+
// To traverse GeometryLayer object3d attached
|
|
178
|
+
layer.parent = this;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Detach a layer attached to this one. See {@link attach} to learn how to
|
|
183
|
+
* attach a layer.
|
|
184
|
+
*
|
|
185
|
+
* @param {Layer} layer - The layer to detach.
|
|
186
|
+
*
|
|
187
|
+
* @return {boolean} Confirmation of the detachment of the layer.
|
|
188
|
+
*/
|
|
189
|
+
detach(layer) {
|
|
190
|
+
const count = this.attachedLayers.length;
|
|
191
|
+
this.attachedLayers = this.attachedLayers.filter(attached => attached.id != layer.id);
|
|
192
|
+
layer.parent = undefined;
|
|
193
|
+
return this.attachedLayers.length < count;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* All layer's 3D objects are removed from the scene and disposed from the video device.
|
|
198
|
+
* @param {boolean} [clearCache=false] Whether to clear the layer cache or not
|
|
199
|
+
*/
|
|
200
|
+
delete(clearCache) {
|
|
201
|
+
if (clearCache) {
|
|
202
|
+
this.cache.clear();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// if Layer is attached
|
|
206
|
+
if (this.parent) {
|
|
207
|
+
ObjectRemovalHelper.removeChildrenAndCleanupRecursively(this, this.parent.object3d);
|
|
208
|
+
}
|
|
209
|
+
if (this.object3d.parent) {
|
|
210
|
+
this.object3d.parent.remove(this.object3d);
|
|
211
|
+
}
|
|
212
|
+
ObjectRemovalHelper.removeChildrenAndCleanupRecursively(this, this.object3d);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Picking method for this layer.
|
|
217
|
+
*
|
|
218
|
+
* @param {View} view - The view instance.
|
|
219
|
+
* @param {Object} coordinates - The coordinates to pick in the view. It
|
|
220
|
+
* should have at least `x` and `y` properties.
|
|
221
|
+
* @param {number} radius - Radius of the picking circle.
|
|
222
|
+
* @param {Array} target - target to push result.
|
|
223
|
+
*
|
|
224
|
+
* @return {Array} An array containing all targets picked under the
|
|
225
|
+
* specified coordinates.
|
|
226
|
+
*/
|
|
227
|
+
pickObjectsAt(view, coordinates) {
|
|
228
|
+
let radius = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.options.defaultPickingRadius;
|
|
229
|
+
let target = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
|
|
230
|
+
return Picking.pickObjectsAt(view, coordinates, radius, this.object3d, target);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
export default GeometryLayer;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Extent } from '@itowns/geographic';
|
|
2
|
+
export default class InfoLayer {
|
|
3
|
+
constructor(layer) {
|
|
4
|
+
this.layer = layer;
|
|
5
|
+
}
|
|
6
|
+
// eslint-disable-next-line
|
|
7
|
+
clear() {}
|
|
8
|
+
// eslint-disable-next-line
|
|
9
|
+
update() {}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* InfoTiledGeometryLayer that provides some states layer informations. These
|
|
14
|
+
* informations are displayed tiles, displayed {@link ColorLayer} and {@link
|
|
15
|
+
* ElevationLayer} and extent of displayed tiles.
|
|
16
|
+
*
|
|
17
|
+
* @class InfoTiledGeometryLayer
|
|
18
|
+
*
|
|
19
|
+
* @property {object} displayed
|
|
20
|
+
* @property {Layer[]} displayed.layers - Displayed {@link ColorLayer} and {@link ElevationLayer}.
|
|
21
|
+
* @property {Extent} displayed.extent - {@link Extent} of displayed tiles.
|
|
22
|
+
* @property {Set} displayed.tiles - Set of displayed tiles.
|
|
23
|
+
*/
|
|
24
|
+
export class InfoTiledGeometryLayer extends InfoLayer {
|
|
25
|
+
constructor(tiledGeometryLayer) {
|
|
26
|
+
super(tiledGeometryLayer);
|
|
27
|
+
this.displayed = {
|
|
28
|
+
tiles: new Set()
|
|
29
|
+
};
|
|
30
|
+
Object.defineProperty(this.displayed, 'layers', {
|
|
31
|
+
get: () => {
|
|
32
|
+
let layers = [];
|
|
33
|
+
this.displayed.tiles.forEach(tile => {
|
|
34
|
+
const m = tile.material;
|
|
35
|
+
layers = [...new Set([...layers, ...m.colorLayerIds.filter(id => m.getLayer(id)), ...m.elevationLayerIds])];
|
|
36
|
+
});
|
|
37
|
+
return this.layer.attachedLayers.filter(l => layers.includes(l.id));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
Object.defineProperty(this.displayed, 'extent', {
|
|
41
|
+
get: () => {
|
|
42
|
+
const extent = new Extent(this.layer.extent.crs, Infinity, -Infinity, Infinity, -Infinity);
|
|
43
|
+
extent.min = +Infinity;
|
|
44
|
+
extent.max = -Infinity;
|
|
45
|
+
this.displayed.tiles.forEach(tile => {
|
|
46
|
+
extent.union(tile.extent);
|
|
47
|
+
extent.min = Math.min(tile.obb.z.min, extent.min);
|
|
48
|
+
extent.max = Math.max(tile.obb.z.max, extent.max);
|
|
49
|
+
});
|
|
50
|
+
return extent;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
clear() {
|
|
55
|
+
this.displayed.tiles.clear();
|
|
56
|
+
}
|
|
57
|
+
update(tile) {
|
|
58
|
+
if (tile.material.visible) {
|
|
59
|
+
this.displayed.tiles.add(tile);
|
|
60
|
+
} else {
|
|
61
|
+
this.displayed.tiles.delete(tile);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|