itowns 2.44.3-next.22 → 2.44.3-next.24
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/debug.js +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/itowns.js +1 -1
- package/dist/itowns.js.map +1 -1
- package/examples/layers/JSONLayers/GeoidMNT.json +3 -1
- package/examples/source_file_geojson_3d.html +0 -1
- package/examples/source_stream_wfs_raster.html +0 -7
- package/lib/Converter/Feature2Texture.js +3 -1
- package/lib/Converter/convertToTile.js +3 -3
- package/lib/Core/Prefab/Globe/Atmosphere.js +4 -2
- package/lib/Core/Prefab/Globe/GlobeLayer.js +19 -11
- package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +111 -0
- package/lib/Core/Prefab/Planar/PlanarLayer.js +15 -8
- package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +43 -43
- package/lib/Core/Prefab/TileBuilder.js +27 -32
- package/lib/Core/Prefab/computeBufferTileGeometry.js +189 -130
- package/lib/Core/TileGeometry.js +112 -28
- package/lib/Layer/C3DTilesLayer.js +7 -4
- package/lib/Layer/ColorLayer.js +35 -9
- package/lib/Layer/CopcLayer.js +5 -0
- package/lib/Layer/ElevationLayer.js +39 -7
- package/lib/Layer/EntwinePointTileLayer.js +12 -5
- package/lib/Layer/FeatureGeometryLayer.js +20 -6
- package/lib/Layer/GeometryLayer.js +42 -11
- package/lib/Layer/LabelLayer.js +11 -5
- package/lib/Layer/Layer.js +83 -57
- package/lib/Layer/OGC3DTilesLayer.js +3 -2
- package/lib/Layer/OrientedImageLayer.js +12 -4
- package/lib/Layer/PointCloudLayer.js +69 -23
- package/lib/Layer/Potree2Layer.js +7 -2
- package/lib/Layer/PotreeLayer.js +8 -3
- package/lib/Layer/RasterLayer.js +12 -2
- package/lib/Layer/TiledGeometryLayer.js +69 -13
- package/lib/Provider/Fetcher.js +5 -1
- package/lib/Renderer/OBB.js +9 -11
- package/package.json +1 -1
- package/lib/Core/Prefab/Globe/BuilderEllipsoidTile.js +0 -110
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
"updateStrategy": {
|
|
5
5
|
"type": 0
|
|
6
6
|
},
|
|
7
|
-
"
|
|
7
|
+
"clampValues": {
|
|
8
|
+
"min": -12000
|
|
9
|
+
},
|
|
8
10
|
"source": {
|
|
9
11
|
"url": "https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/geoid/geoid/bil/%TILEMATRIX/geoid_%COL_%ROW.bil",
|
|
10
12
|
"format": "image/x-bil;bits=32",
|
|
@@ -53,12 +53,6 @@
|
|
|
53
53
|
itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
|
|
54
54
|
itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
|
|
55
55
|
|
|
56
|
-
function isValidData(data) {
|
|
57
|
-
if(data.features[0].geometries.length < 1000) {
|
|
58
|
-
return data;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
56
|
var wfsBuildingSource = new itowns.WFSSource({
|
|
63
57
|
url: 'https://data.geopf.fr/wfs/ows?',
|
|
64
58
|
version: '2.0.0',
|
|
@@ -102,7 +96,6 @@
|
|
|
102
96
|
width: 2.0,
|
|
103
97
|
},
|
|
104
98
|
},
|
|
105
|
-
isValidData: isValidData,
|
|
106
99
|
source: wfsBuildingSource,
|
|
107
100
|
zoom: { max: 20, min: 13 },
|
|
108
101
|
});
|
|
@@ -114,7 +114,9 @@ export default {
|
|
|
114
114
|
coord.crs = extent.crs;
|
|
115
115
|
c.width = sizeTexture;
|
|
116
116
|
c.height = sizeTexture;
|
|
117
|
-
const ctx = c.getContext('2d'
|
|
117
|
+
const ctx = c.getContext('2d', {
|
|
118
|
+
willReadFrequently: true
|
|
119
|
+
});
|
|
118
120
|
if (backgroundColor) {
|
|
119
121
|
ctx.fillStyle = backgroundColor.getStyle();
|
|
120
122
|
ctx.fillRect(0, 0, sizeTexture, sizeTexture);
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import * as THREE from 'three';
|
|
7
7
|
import TileMesh from "../Core/TileMesh.js";
|
|
8
8
|
import LayeredMaterial from "../Renderer/LayeredMaterial.js";
|
|
9
|
-
import newTileGeometry from "../Core/Prefab/TileBuilder.js";
|
|
9
|
+
import { newTileGeometry } from "../Core/Prefab/TileBuilder.js";
|
|
10
10
|
import ReferLayerProperties from "../Layer/ReferencingLayerProperties.js";
|
|
11
11
|
import { geoidLayerIsVisible } from "../Layer/GeoidLayer.js";
|
|
12
12
|
const dimensions = new THREE.Vector2();
|
|
@@ -42,14 +42,14 @@ export default {
|
|
|
42
42
|
};
|
|
43
43
|
return newTileGeometry(builder, paramsGeometry).then(result => {
|
|
44
44
|
// build tile mesh
|
|
45
|
-
result.geometry.
|
|
45
|
+
result.geometry.increaseRefCount();
|
|
46
46
|
const crsCount = layer.tileMatrixSets.length;
|
|
47
47
|
const material = new LayeredMaterial(layer.materialOptions, crsCount);
|
|
48
48
|
ReferLayerProperties(material, layer);
|
|
49
49
|
const tile = new TileMesh(result.geometry, material, layer, extent, level);
|
|
50
50
|
if (parent && parent.isTileMesh) {
|
|
51
51
|
// get parent extent transformation
|
|
52
|
-
const pTrans = builder.
|
|
52
|
+
const pTrans = builder.computeShareableExtent(parent.extent);
|
|
53
53
|
// place relative to his parent
|
|
54
54
|
result.position.sub(pTrans.position).applyQuaternion(pTrans.quaternion.invert());
|
|
55
55
|
result.quaternion.premultiply(pTrans.quaternion);
|
|
@@ -31,6 +31,10 @@ const colorSky = new THREE.Color();
|
|
|
31
31
|
const spaceColor = new THREE.Color(0x030508);
|
|
32
32
|
const limitAlti = 600000;
|
|
33
33
|
const mfogDistance = ellipsoidSizes.x * 160.0;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @extends GeometryLayer
|
|
37
|
+
*/
|
|
34
38
|
class Atmosphere extends GeometryLayer {
|
|
35
39
|
/**
|
|
36
40
|
* It's layer to simulate Globe atmosphere.
|
|
@@ -40,8 +44,6 @@ class Atmosphere extends GeometryLayer {
|
|
|
40
44
|
* * [Atmosphere Shader From Space (Atmospheric scattering)](http://stainlessbeer.weebly.com/planets-9-atmospheric-scattering.html)
|
|
41
45
|
* * [Accurate Atmospheric Scattering (NVIDIA GPU Gems 2)](https://developer.nvidia.com/gpugems/gpugems2/part-ii-shading-lighting-and-shadows/chapter-16-accurate-atmospheric-scattering).
|
|
42
46
|
*
|
|
43
|
-
* @extends GeometryLayer
|
|
44
|
-
*
|
|
45
47
|
* @param {string} id - The id of the layer Atmosphere.
|
|
46
48
|
* @param {Object} [options] - options layer.
|
|
47
49
|
* @param {number} [options.Kr] - `Kr` is the rayleigh scattering constant.
|
|
@@ -2,7 +2,7 @@ import * as THREE from 'three';
|
|
|
2
2
|
import TiledGeometryLayer from "../../../Layer/TiledGeometryLayer.js";
|
|
3
3
|
import { ellipsoidSizes } from "../../Math/Ellipsoid.js";
|
|
4
4
|
import { globalExtentTMS, schemeTiles } from "../../Tile/TileGrid.js";
|
|
5
|
-
import
|
|
5
|
+
import { GlobeTileBuilder } from "./GlobeTileBuilder.js";
|
|
6
6
|
|
|
7
7
|
// matrix to convert sphere to ellipsoid
|
|
8
8
|
const worldToScaledEllipsoid = new THREE.Matrix4();
|
|
@@ -17,18 +17,18 @@ const scaledHorizonCullingPoint = new THREE.Vector3();
|
|
|
17
17
|
* @property {boolean} isGlobeLayer - Used to checkout whether this layer is a
|
|
18
18
|
* GlobeLayer. Default is true. You should not change this, as it is used
|
|
19
19
|
* internally for optimisation.
|
|
20
|
+
*
|
|
21
|
+
* @extends TiledGeometryLayer
|
|
20
22
|
*/
|
|
21
23
|
class GlobeLayer extends TiledGeometryLayer {
|
|
22
24
|
/**
|
|
23
25
|
* A {@link TiledGeometryLayer} to use with a {@link GlobeView}. It has
|
|
24
26
|
* specific method for updating and subdivising its grid.
|
|
25
27
|
*
|
|
26
|
-
* @extends TiledGeometryLayer
|
|
27
|
-
*
|
|
28
28
|
* @param {string} id - The id of the layer, that should be unique. It is
|
|
29
29
|
* not mandatory, but an error will be emitted if this layer is added a
|
|
30
30
|
* {@link View} that already has a layer going by that id.
|
|
31
|
-
* @param {THREE.
|
|
31
|
+
* @param {THREE.Object3D} [object3d=THREE.Group] - The object3d used to
|
|
32
32
|
* contain the geometry of the TiledGeometryLayer. It is usually a
|
|
33
33
|
* `THREE.Group`, but it can be anything inheriting from a `THREE.Object3d`.
|
|
34
34
|
* @param {Object} [config] - Optional configuration, all elements in it
|
|
@@ -47,22 +47,30 @@ class GlobeLayer extends TiledGeometryLayer {
|
|
|
47
47
|
*/
|
|
48
48
|
constructor(id, object3d) {
|
|
49
49
|
let config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
50
|
+
const {
|
|
51
|
+
minSubdivisionLevel = 2,
|
|
52
|
+
maxSubdivisionLevel = 19,
|
|
53
|
+
...tiledConfig
|
|
54
|
+
} = config;
|
|
55
|
+
|
|
50
56
|
// Configure tiles
|
|
51
57
|
const scheme = schemeTiles.get('EPSG:4326');
|
|
52
58
|
const schemeTile = globalExtentTMS.get('EPSG:4326').subdivisionByScheme(scheme);
|
|
53
59
|
|
|
54
60
|
// Supported tile matrix set for color/elevation layer
|
|
55
|
-
|
|
56
|
-
const uvCount =
|
|
57
|
-
const builder = new
|
|
58
|
-
crs: 'EPSG:4978',
|
|
61
|
+
const tileMatrixSets = ['EPSG:4326', 'EPSG:3857'];
|
|
62
|
+
const uvCount = tileMatrixSets.length;
|
|
63
|
+
const builder = new GlobeTileBuilder({
|
|
59
64
|
uvCount
|
|
60
65
|
});
|
|
61
|
-
super(id, object3d || new THREE.Group(), schemeTile, builder,
|
|
66
|
+
super(id, object3d || new THREE.Group(), schemeTile, builder, {
|
|
67
|
+
tileMatrixSets,
|
|
68
|
+
...tiledConfig
|
|
69
|
+
});
|
|
62
70
|
this.isGlobeLayer = true;
|
|
63
71
|
this.options.defaultPickingRadius = 5;
|
|
64
|
-
this.minSubdivisionLevel =
|
|
65
|
-
this.maxSubdivisionLevel =
|
|
72
|
+
this.minSubdivisionLevel = minSubdivisionLevel;
|
|
73
|
+
this.maxSubdivisionLevel = maxSubdivisionLevel;
|
|
66
74
|
this.extent = this.schemeTile[0].clone();
|
|
67
75
|
for (let i = 1; i < this.schemeTile.length; i++) {
|
|
68
76
|
this.extent.union(this.schemeTile[i]);
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import Coordinates from "../../Geographic/Coordinates.js";
|
|
3
|
+
import Extent from "../../Geographic/Extent.js";
|
|
4
|
+
const PI_OV_FOUR = Math.PI / 4;
|
|
5
|
+
const INV_TWO_PI = 1.0 / (Math.PI * 2);
|
|
6
|
+
const axisZ = new THREE.Vector3(0, 0, 1);
|
|
7
|
+
const axisY = new THREE.Vector3(0, 1, 0);
|
|
8
|
+
const quatToAlignLongitude = new THREE.Quaternion();
|
|
9
|
+
const quatToAlignLatitude = new THREE.Quaternion();
|
|
10
|
+
const quatNormalToZ = new THREE.Quaternion();
|
|
11
|
+
|
|
12
|
+
/** Transforms a WGS84 latitude into a usable texture offset. */
|
|
13
|
+
function WGS84ToOneSubY(latitude) {
|
|
14
|
+
return 1.0 - (0.5 - Math.log(Math.tan(PI_OV_FOUR + THREE.MathUtils.degToRad(latitude) * 0.5)) * INV_TWO_PI);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Specialized parameters for the [GlobeTileBuilder]. */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* TileBuilder implementation for the purpose of generating globe (or more
|
|
21
|
+
* precisely ellipsoidal) tile arrangements.
|
|
22
|
+
*/
|
|
23
|
+
export class GlobeTileBuilder {
|
|
24
|
+
static _crs = 'EPSG:4978';
|
|
25
|
+
static _computeExtraOffset(params) {
|
|
26
|
+
const t = WGS84ToOneSubY(params.coordinates.latitude) * params.nbRow;
|
|
27
|
+
return (!isFinite(t) ? 0 : t) - params.deltaUV1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Buffer holding information about the tile/vertex currently being
|
|
32
|
+
* processed.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
get crs() {
|
|
36
|
+
return GlobeTileBuilder._crs;
|
|
37
|
+
}
|
|
38
|
+
constructor(options) {
|
|
39
|
+
this._transform = {
|
|
40
|
+
coords: [new Coordinates('EPSG:4326', 0, 0), new Coordinates('EPSG:4326', 0, 0)],
|
|
41
|
+
position: new THREE.Vector3(),
|
|
42
|
+
dimension: new THREE.Vector2()
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// UV: Normalized coordinates (from degree) on the entire tile
|
|
46
|
+
// EPSG:4326
|
|
47
|
+
// Offset: Float row coordinate from Pseudo mercator coordinates
|
|
48
|
+
// EPSG:3857
|
|
49
|
+
if (options.uvCount > 1) {
|
|
50
|
+
this.computeExtraOffset = GlobeTileBuilder._computeExtraOffset;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
prepare(params) {
|
|
54
|
+
const nbRow = 2 ** (params.level + 1.0);
|
|
55
|
+
let st1 = WGS84ToOneSubY(params.extent.south);
|
|
56
|
+
if (!isFinite(st1)) {
|
|
57
|
+
st1 = 0;
|
|
58
|
+
}
|
|
59
|
+
const start = st1 % (1.0 / nbRow);
|
|
60
|
+
const newParams = {
|
|
61
|
+
nbRow,
|
|
62
|
+
deltaUV1: (st1 - start) * nbRow,
|
|
63
|
+
// transformation to align tile's normal to z axis
|
|
64
|
+
quatNormalToZ: quatNormalToZ.setFromAxisAngle(axisY, -(Math.PI * 0.5 - THREE.MathUtils.degToRad(params.extent.center().latitude))),
|
|
65
|
+
// let's avoid building too much temp objects
|
|
66
|
+
coordinates: new Coordinates(this.crs)
|
|
67
|
+
};
|
|
68
|
+
params.extent.planarDimensions(this._transform.dimension);
|
|
69
|
+
return {
|
|
70
|
+
...params,
|
|
71
|
+
...newParams
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
center(extent) {
|
|
75
|
+
return extent.center(this._transform.coords[0]).as(this.crs, this._transform.coords[1]).toVector3();
|
|
76
|
+
}
|
|
77
|
+
vertexPosition(coordinates) {
|
|
78
|
+
return this._transform.coords[0].setFromValues(coordinates.x, coordinates.y).as(this.crs, this._transform.coords[1]).toVector3(this._transform.position);
|
|
79
|
+
}
|
|
80
|
+
vertexNormal() {
|
|
81
|
+
return this._transform.coords[1].geodesicNormal;
|
|
82
|
+
}
|
|
83
|
+
uProject(u, extent) {
|
|
84
|
+
return extent.west + u * this._transform.dimension.x;
|
|
85
|
+
}
|
|
86
|
+
vProject(v, extent) {
|
|
87
|
+
return extent.south + v * this._transform.dimension.y;
|
|
88
|
+
}
|
|
89
|
+
computeShareableExtent(extent) {
|
|
90
|
+
// NOTE: It should be possible to take advantage of equatorial plane
|
|
91
|
+
// symmetry, for which we'd have to reverse the tile's UVs.
|
|
92
|
+
// This would halve the memory requirement when viewing a full globe,
|
|
93
|
+
// but that case is not that relevant for iTowns' usual use cases and
|
|
94
|
+
// the globe mesh memory usage is already inconsequential.
|
|
95
|
+
const sizeLongitude = Math.abs(extent.west - extent.east) / 2;
|
|
96
|
+
const shareableExtent = new Extent(extent.crs, -sizeLongitude, sizeLongitude, extent.south, extent.north);
|
|
97
|
+
|
|
98
|
+
// Compute rotation to transform the tile to position on the ellispoid.
|
|
99
|
+
// This transformation takes the parents' transformation into account.
|
|
100
|
+
const rotLon = THREE.MathUtils.degToRad(extent.west - shareableExtent.west);
|
|
101
|
+
const rotLat = THREE.MathUtils.degToRad(90 - extent.center(this._transform.coords[0]).latitude);
|
|
102
|
+
quatToAlignLongitude.setFromAxisAngle(axisZ, rotLon);
|
|
103
|
+
quatToAlignLatitude.setFromAxisAngle(axisY, rotLat);
|
|
104
|
+
quatToAlignLongitude.multiply(quatToAlignLatitude);
|
|
105
|
+
return {
|
|
106
|
+
shareableExtent,
|
|
107
|
+
quaternion: quatToAlignLongitude.clone(),
|
|
108
|
+
position: this.center(extent)
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import TiledGeometryLayer from "../../../Layer/TiledGeometryLayer.js";
|
|
3
3
|
import { globalExtentTMS } from "../../Tile/TileGrid.js";
|
|
4
|
-
import PlanarTileBuilder from "./PlanarTileBuilder.js";
|
|
4
|
+
import { PlanarTileBuilder } from "./PlanarTileBuilder.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @property {boolean} isPlanarLayer - Used to checkout whether this layer is a
|
|
8
8
|
* PlanarLayer. Default is true. You should not change this, as it is used
|
|
9
9
|
* internally for optimisation.
|
|
10
|
+
* @extends TiledGeometryLayer
|
|
10
11
|
*/
|
|
11
12
|
class PlanarLayer extends TiledGeometryLayer {
|
|
12
13
|
/**
|
|
13
14
|
* A {@link TiledGeometryLayer} to use with a {@link PlanarView}. It has
|
|
14
15
|
* specific method for updating and subdivising its grid.
|
|
15
16
|
*
|
|
16
|
-
* @extends TiledGeometryLayer
|
|
17
|
-
*
|
|
18
17
|
* @param {string} id - The id of the layer, that should be unique. It is
|
|
19
18
|
* not mandatory, but an error will be emitted if this layer is added a
|
|
20
19
|
* {@link View} that already has a layer going by that id.
|
|
@@ -34,19 +33,27 @@ class PlanarLayer extends TiledGeometryLayer {
|
|
|
34
33
|
*/
|
|
35
34
|
constructor(id, extent, object3d) {
|
|
36
35
|
let config = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
36
|
+
const {
|
|
37
|
+
minSubdivisionLevel = 0,
|
|
38
|
+
maxSubdivisionLevel = 5,
|
|
39
|
+
...tiledConfig
|
|
40
|
+
} = config;
|
|
37
41
|
const tileMatrixSets = [extent.crs];
|
|
38
42
|
if (!globalExtentTMS.get(extent.crs)) {
|
|
39
43
|
// Add new global extent for this new crs projection.
|
|
40
44
|
globalExtentTMS.set(extent.crs, extent);
|
|
41
45
|
}
|
|
42
|
-
|
|
43
|
-
super(id, object3d || new THREE.Group(), [extent], new PlanarTileBuilder({
|
|
46
|
+
const builder = new PlanarTileBuilder({
|
|
44
47
|
crs: extent.crs
|
|
45
|
-
})
|
|
48
|
+
});
|
|
49
|
+
super(id, object3d || new THREE.Group(), [extent], builder, {
|
|
50
|
+
tileMatrixSets,
|
|
51
|
+
...tiledConfig
|
|
52
|
+
});
|
|
46
53
|
this.isPlanarLayer = true;
|
|
47
54
|
this.extent = extent;
|
|
48
|
-
this.minSubdivisionLevel =
|
|
49
|
-
this.maxSubdivisionLevel =
|
|
55
|
+
this.minSubdivisionLevel = minSubdivisionLevel;
|
|
56
|
+
this.maxSubdivisionLevel = maxSubdivisionLevel;
|
|
50
57
|
}
|
|
51
58
|
}
|
|
52
59
|
export default PlanarLayer;
|
|
@@ -3,70 +3,70 @@ import Coordinates from "../../Geographic/Coordinates.js";
|
|
|
3
3
|
import Extent from "../../Geographic/Extent.js";
|
|
4
4
|
const quaternion = new THREE.Quaternion();
|
|
5
5
|
const center = new THREE.Vector3();
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
|
|
7
|
+
/** Specialized parameters for the [PlanarTileBuilder]. */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* TileBuilder implementation for the purpose of generating planar
|
|
11
|
+
* tile arrangements.
|
|
12
|
+
*/
|
|
13
|
+
export class PlanarTileBuilder {
|
|
14
|
+
constructor(options) {
|
|
10
15
|
if (options.projection) {
|
|
11
|
-
console.warn('PlanarTileBuilder projection parameter is deprecated, use crs instead.');
|
|
12
|
-
options.crs
|
|
13
|
-
}
|
|
14
|
-
if (options.crs) {
|
|
15
|
-
this.crs = options.crs;
|
|
16
|
-
} else {
|
|
17
|
-
throw new Error('options.crs is mandatory for PlanarTileBuilder');
|
|
16
|
+
console.warn('PlanarTileBuilder projection parameter is deprecated,' + ' use crs instead.');
|
|
17
|
+
options.crs ??= options.projection;
|
|
18
18
|
}
|
|
19
|
-
this.
|
|
19
|
+
this._crs = options.crs;
|
|
20
|
+
this._transform = {
|
|
20
21
|
coords: new Coordinates('EPSG:4326', 0, 0),
|
|
21
22
|
position: new THREE.Vector3(),
|
|
22
23
|
normal: new THREE.Vector3(0, 0, 1)
|
|
23
24
|
};
|
|
24
|
-
this.
|
|
25
|
+
this._uvCount = options.uvCount ?? 1;
|
|
26
|
+
}
|
|
27
|
+
get uvCount() {
|
|
28
|
+
return this._uvCount;
|
|
29
|
+
}
|
|
30
|
+
get crs() {
|
|
31
|
+
return this._crs;
|
|
25
32
|
}
|
|
26
|
-
// prepare params
|
|
27
|
-
// init projected object -> params.projected
|
|
28
33
|
prepare(params) {
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
const newParams = params;
|
|
35
|
+
newParams.nbRow = 2 ** (params.level + 1.0);
|
|
36
|
+
newParams.coordinates = new Coordinates(this.crs);
|
|
37
|
+
return newParams;
|
|
31
38
|
}
|
|
32
|
-
|
|
33
|
-
// get center tile in cartesian 3D
|
|
34
39
|
center(extent) {
|
|
35
|
-
extent.center(this.
|
|
36
|
-
center.set(this.
|
|
40
|
+
extent.center(this._transform.coords);
|
|
41
|
+
center.set(this._transform.coords.x, this._transform.coords.y, 0);
|
|
37
42
|
return center;
|
|
38
43
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
this.tmp.position.set(params.projected.x, params.projected.y, 0);
|
|
43
|
-
return this.tmp.position;
|
|
44
|
+
vertexPosition(coordinates) {
|
|
45
|
+
this._transform.position.set(coordinates.x, coordinates.y, 0);
|
|
46
|
+
return this._transform.position;
|
|
44
47
|
}
|
|
45
|
-
|
|
46
|
-
// get normal for last vertex
|
|
47
48
|
vertexNormal() {
|
|
48
|
-
return this.
|
|
49
|
+
return this._transform.normal;
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
uProjecte(u, params) {
|
|
53
|
-
params.projected.x = params.extent.west + u * (params.extent.east - params.extent.west);
|
|
51
|
+
uProject(u, extent) {
|
|
52
|
+
return extent.west + u * (extent.east - extent.west);
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
vProjecte(v, params) {
|
|
58
|
-
params.projected.y = params.extent.south + v * (params.extent.north - params.extent.south);
|
|
54
|
+
vProject(v, extent) {
|
|
55
|
+
return extent.south + v * (extent.north - extent.south);
|
|
59
56
|
}
|
|
60
|
-
|
|
61
|
-
// compute
|
|
57
|
+
computeShareableExtent(extent) {
|
|
58
|
+
// compute shareable extent to pool the geometries
|
|
62
59
|
// the geometry in common extent is identical to the existing input
|
|
63
60
|
// with a translation
|
|
64
|
-
const sharableExtent = new Extent(extent.crs, 0, Math.abs(extent.west - extent.east), 0, Math.abs(extent.north - extent.south));
|
|
65
61
|
return {
|
|
66
|
-
|
|
62
|
+
shareableExtent: new Extent(extent.crs, {
|
|
63
|
+
west: 0,
|
|
64
|
+
east: Math.abs(extent.west - extent.east),
|
|
65
|
+
south: 0,
|
|
66
|
+
north: Math.abs(extent.north - extent.south)
|
|
67
|
+
}),
|
|
67
68
|
quaternion,
|
|
68
69
|
position: this.center(extent).clone()
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
|
-
}
|
|
72
|
-
export default PlanarTileBuilder;
|
|
72
|
+
}
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
import TileGeometry from "../TileGeometry.js";
|
|
2
|
+
import { TileGeometry } from "../TileGeometry.js";
|
|
3
3
|
import Cache from "../Scheduler/Cache.js";
|
|
4
|
-
import computeBuffers from "./computeBufferTileGeometry.js";
|
|
4
|
+
import { computeBuffers } from "./computeBufferTileGeometry.js";
|
|
5
5
|
import OBB from "../../Renderer/OBB.js";
|
|
6
6
|
const cacheBuffer = new Map();
|
|
7
7
|
const cacheTile = new Cache();
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reference to a tile's extent with rigid transformations.
|
|
11
|
+
* Enables reuse of geometry, saving a bit of memory.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export function newTileGeometry(builder, params) {
|
|
9
15
|
const {
|
|
10
|
-
|
|
16
|
+
shareableExtent,
|
|
11
17
|
quaternion,
|
|
12
18
|
position
|
|
13
|
-
} = builder.
|
|
14
|
-
const south =
|
|
19
|
+
} = builder.computeShareableExtent(params.extent);
|
|
20
|
+
const south = shareableExtent.south.toFixed(6);
|
|
15
21
|
const bufferKey = `${builder.crs}_${params.disableSkirt ? 0 : 1}_${params.segments}`;
|
|
16
22
|
let promiseGeometry = cacheTile.get(south, params.level, bufferKey);
|
|
17
23
|
|
|
@@ -22,49 +28,38 @@ export default function newTileGeometry(builder, params) {
|
|
|
22
28
|
resolve = r;
|
|
23
29
|
});
|
|
24
30
|
cacheTile.set(promiseGeometry, south, params.level, bufferKey);
|
|
25
|
-
params.extent =
|
|
31
|
+
params.extent = shareableExtent;
|
|
26
32
|
params.center = builder.center(params.extent).clone();
|
|
27
|
-
// Read previously cached values (index and uv.wgs84 only
|
|
33
|
+
// Read previously cached values (index and uv.wgs84 only
|
|
34
|
+
// depend on the # of triangles)
|
|
28
35
|
let cachedBuffers = cacheBuffer.get(bufferKey);
|
|
29
36
|
params.buildIndexAndUv_0 = !cachedBuffers;
|
|
30
|
-
params.builder = builder;
|
|
31
37
|
let buffers;
|
|
32
38
|
try {
|
|
33
|
-
buffers = computeBuffers(params);
|
|
39
|
+
buffers = computeBuffers(builder, params);
|
|
34
40
|
} catch (e) {
|
|
35
41
|
return Promise.reject(e);
|
|
36
42
|
}
|
|
37
43
|
if (!cachedBuffers) {
|
|
38
44
|
cachedBuffers = {};
|
|
45
|
+
// We know the fields will exist due to the condition
|
|
46
|
+
// matching with the one for buildIndexAndUv_0.
|
|
47
|
+
// TODO: Make this brain-based check compiler-based.
|
|
39
48
|
cachedBuffers.index = new THREE.BufferAttribute(buffers.index, 1);
|
|
40
49
|
cachedBuffers.uv = new THREE.BufferAttribute(buffers.uvs[0], 2);
|
|
41
50
|
|
|
42
51
|
// Update cacheBuffer
|
|
43
52
|
cacheBuffer.set(bufferKey, cachedBuffers);
|
|
44
53
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
buffers.uvs[1] = new THREE.BufferAttribute(buffers.uvs[1], 1);
|
|
51
|
-
}
|
|
52
|
-
const geometry = new TileGeometry(params, buffers);
|
|
53
|
-
geometry.OBB = new OBB(geometry.boundingBox.min, geometry.boundingBox.max);
|
|
54
|
-
geometry._count = 0;
|
|
55
|
-
geometry.dispose = () => {
|
|
56
|
-
geometry._count--;
|
|
57
|
-
if (geometry._count <= 0) {
|
|
58
|
-
// To avoid remove index buffer and attribute buffer uv
|
|
59
|
-
// error un-bound buffer in webgl with VAO rendering.
|
|
60
|
-
// Could be removed if the attribute buffer deleting is
|
|
61
|
-
// taken into account in the buffer binding state (in THREE.WebGLBindingStates code).
|
|
62
|
-
geometry.index = null;
|
|
63
|
-
delete geometry.attributes.uv;
|
|
64
|
-
THREE.BufferGeometry.prototype.dispose.call(geometry);
|
|
65
|
-
cacheTile.delete(south, params.level, bufferKey);
|
|
66
|
-
}
|
|
54
|
+
const gpuBuffers = {
|
|
55
|
+
index: cachedBuffers.index,
|
|
56
|
+
uvs: [cachedBuffers.uv, ...(buffers.uvs[1] !== undefined ? [new THREE.BufferAttribute(buffers.uvs[1], 1)] : [])],
|
|
57
|
+
position: new THREE.BufferAttribute(buffers.position, 3),
|
|
58
|
+
normal: new THREE.BufferAttribute(buffers.normal, 3)
|
|
67
59
|
};
|
|
60
|
+
const geometry = new TileGeometry(builder, params, gpuBuffers);
|
|
61
|
+
geometry.OBB = new OBB(geometry.boundingBox.min, geometry.boundingBox.max);
|
|
62
|
+
geometry.initRefCount(cacheTile, [south, params.level, bufferKey]);
|
|
68
63
|
resolve(geometry);
|
|
69
64
|
return Promise.resolve({
|
|
70
65
|
geometry,
|