itowns 2.44.3-next.4 → 2.44.3-next.40
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/CODING.md +1 -1
- package/CONTRIBUTORS.md +1 -0
- package/dist/debug.js +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/itowns.js +1 -1
- package/dist/itowns.js.LICENSE.txt +0 -2
- package/dist/itowns.js.map +1 -1
- package/dist/itowns_widgets.js +1 -1
- package/dist/itowns_widgets.js.map +1 -1
- package/examples/3dtiles_loader.html +123 -48
- package/examples/config.json +3 -10
- package/examples/copc_simple_loader.html +15 -5
- package/examples/effects_stereo.html +2 -2
- package/examples/entwine_3d_loader.html +3 -1
- package/examples/entwine_simple_loader.html +1 -1
- package/examples/images/itowns_logo.svg +123 -0
- package/examples/js/plugins/COGParser.js +1 -1
- package/examples/jsm/OGC3DTilesHelper.js +6 -1
- package/examples/layers/JSONLayers/GeoidMNT.json +3 -1
- package/examples/misc_collada.html +2 -2
- package/examples/source_file_geojson_3d.html +0 -1
- package/examples/source_file_kml_raster_usgs.html +0 -1
- package/examples/source_stream_wfs_raster.html +0 -7
- package/examples/vector_tile_mapbox_raster.html +91 -0
- package/examples/view_3d_map_webxr.html +3 -1
- package/examples/view_multi_25d.html +2 -2
- package/lib/Controls/GlobeControls.js +45 -28
- package/lib/Controls/StateControl.js +5 -2
- package/lib/Converter/Feature2Mesh.js +10 -4
- package/lib/Converter/Feature2Texture.js +6 -1
- package/lib/Converter/convertToTile.js +3 -8
- package/lib/Converter/textureConverter.js +4 -5
- package/lib/Core/Deprecated/Undeprecator.js +0 -1
- package/lib/Core/Feature.js +3 -4
- package/lib/Core/Geographic/Coordinates.js +143 -132
- package/lib/Core/Geographic/Crs.js +140 -145
- package/lib/Core/Geographic/Extent.js +221 -397
- package/lib/Core/Geographic/GeoidGrid.js +1 -1
- package/lib/Core/MainLoop.js +1 -3
- package/lib/Core/Math/Ellipsoid.js +62 -21
- package/lib/Core/Prefab/Globe/Atmosphere.js +4 -8
- package/lib/Core/Prefab/Globe/GlobeLayer.js +22 -15
- package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +111 -0
- package/lib/Core/Prefab/GlobeView.js +2 -7
- package/lib/Core/Prefab/Planar/PlanarLayer.js +17 -11
- package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +43 -43
- package/lib/Core/Prefab/TileBuilder.js +42 -40
- package/lib/Core/Prefab/computeBufferTileGeometry.js +195 -130
- package/lib/Core/Scheduler/Cache.js +1 -240
- package/lib/Core/Style.js +34 -495
- package/lib/Core/StyleOptions.js +486 -0
- package/lib/Core/Tile/Tile.js +207 -0
- package/lib/Core/Tile/TileGrid.js +49 -0
- package/lib/Core/TileGeometry.js +112 -28
- package/lib/Core/TileMesh.js +3 -3
- package/lib/Core/View.js +15 -8
- package/lib/Layer/C3DTilesLayer.js +20 -16
- package/lib/Layer/ColorLayer.js +35 -9
- package/lib/Layer/CopcLayer.js +7 -2
- package/lib/Layer/ElevationLayer.js +39 -7
- package/lib/Layer/EntwinePointTileLayer.js +14 -7
- package/lib/Layer/FeatureGeometryLayer.js +20 -6
- package/lib/Layer/GeometryLayer.js +42 -11
- package/lib/Layer/LabelLayer.js +45 -27
- package/lib/Layer/Layer.js +92 -61
- package/lib/Layer/OGC3DTilesLayer.js +212 -56
- package/lib/Layer/OrientedImageLayer.js +11 -5
- package/lib/Layer/PointCloudLayer.js +76 -30
- package/lib/Layer/Potree2Layer.js +9 -2
- package/lib/Layer/PotreeLayer.js +10 -3
- package/lib/Layer/RasterLayer.js +12 -2
- package/lib/Layer/TiledGeometryLayer.js +69 -13
- package/lib/Main.js +2 -2
- package/lib/Parser/GeoJsonParser.js +1 -1
- package/lib/Parser/VectorTileParser.js +42 -29
- package/lib/Parser/XbilParser.js +14 -2
- package/lib/Provider/Fetcher.js +5 -1
- package/lib/Provider/URLBuilder.js +22 -11
- package/lib/Renderer/Camera.js +1 -1
- package/lib/Renderer/Label2DRenderer.js +9 -7
- package/lib/Renderer/OBB.js +11 -13
- package/lib/Renderer/PointsMaterial.js +5 -5
- package/lib/Renderer/RasterTile.js +1 -2
- package/lib/Renderer/SphereHelper.js +0 -6
- package/lib/Source/CopcSource.js +13 -2
- package/lib/Source/EntwinePointTileSource.js +14 -4
- package/lib/Source/FileSource.js +9 -10
- package/lib/Source/OrientedImageSource.js +2 -2
- package/lib/Source/Source.js +26 -46
- package/lib/Source/TMSSource.js +10 -9
- package/lib/Source/VectorTilesSource.js +38 -34
- package/lib/Source/WFSSource.js +18 -13
- package/lib/Source/WMSSource.js +56 -18
- package/lib/Source/WMTSSource.js +13 -7
- package/lib/ThreeExtended/libs/ktx-parse.module.js +310 -274
- package/lib/ThreeExtended/loaders/DRACOLoader.js +3 -2
- package/lib/ThreeExtended/loaders/GLTFLoader.js +6 -3
- package/lib/ThreeExtended/loaders/KTX2Loader.js +144 -60
- package/lib/ThreeExtended/math/ColorSpaces.js +59 -0
- package/lib/Utils/CameraUtils.js +1 -1
- package/lib/Utils/gui/C3DTilesStyle.js +2 -3
- package/lib/Utils/placeObjectOnGround.js +0 -1
- package/package.json +10 -8
- package/examples/3dtiles_25d.html +0 -120
- package/examples/3dtiles_basic.html +0 -94
- package/examples/3dtiles_batch_table.html +0 -86
- package/examples/3dtiles_ion.html +0 -126
- package/examples/3dtiles_pointcloud.html +0 -95
- package/lib/Core/Prefab/Globe/BuilderEllipsoidTile.js +0 -110
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
import TileGeometry from "../TileGeometry.js";
|
|
3
|
-
import
|
|
4
|
-
import computeBuffers from "./computeBufferTileGeometry.js";
|
|
2
|
+
import { TileGeometry } from "../TileGeometry.js";
|
|
3
|
+
import { LRUCache } from 'lru-cache';
|
|
4
|
+
import { computeBuffers } from "./computeBufferTileGeometry.js";
|
|
5
5
|
import OBB from "../../Renderer/OBB.js";
|
|
6
6
|
const cacheBuffer = new Map();
|
|
7
|
-
const cacheTile = new
|
|
8
|
-
|
|
7
|
+
const cacheTile = new LRUCache({
|
|
8
|
+
max: 500
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Reference to a tile's extent with rigid transformations.
|
|
13
|
+
* Enables reuse of geometry, saving a bit of memory.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export function newTileGeometry(builder, params) {
|
|
9
17
|
const {
|
|
10
|
-
|
|
18
|
+
shareableExtent,
|
|
11
19
|
quaternion,
|
|
12
20
|
position
|
|
13
|
-
} = builder.
|
|
14
|
-
const south =
|
|
21
|
+
} = builder.computeShareableExtent(params.extent);
|
|
22
|
+
const south = shareableExtent.south.toFixed(6);
|
|
15
23
|
const bufferKey = `${builder.crs}_${params.disableSkirt ? 0 : 1}_${params.segments}`;
|
|
16
|
-
|
|
24
|
+
const key = `s${south}l${params.level}bK${bufferKey}`;
|
|
25
|
+
let promiseGeometry = cacheTile.get(key);
|
|
17
26
|
|
|
18
27
|
// build geometry if doesn't exist
|
|
19
28
|
if (!promiseGeometry) {
|
|
@@ -21,50 +30,43 @@ export default function newTileGeometry(builder, params) {
|
|
|
21
30
|
promiseGeometry = new Promise(r => {
|
|
22
31
|
resolve = r;
|
|
23
32
|
});
|
|
24
|
-
cacheTile.set(
|
|
25
|
-
params.extent =
|
|
33
|
+
cacheTile.set(key, promiseGeometry);
|
|
34
|
+
params.extent = shareableExtent;
|
|
26
35
|
params.center = builder.center(params.extent).clone();
|
|
27
|
-
// Read previously cached values (index and uv.wgs84 only
|
|
36
|
+
// Read previously cached values (index and uv.wgs84 only
|
|
37
|
+
// depend on the # of triangles)
|
|
28
38
|
let cachedBuffers = cacheBuffer.get(bufferKey);
|
|
29
|
-
params.buildIndexAndUv_0 = !cachedBuffers;
|
|
30
|
-
params.builder = builder;
|
|
31
39
|
let buffers;
|
|
32
40
|
try {
|
|
33
|
-
buffers = computeBuffers(params
|
|
41
|
+
buffers = computeBuffers(builder, params, cachedBuffers !== undefined ? {
|
|
42
|
+
index: cachedBuffers.index.array,
|
|
43
|
+
uv: cachedBuffers.uv.array
|
|
44
|
+
} : undefined);
|
|
34
45
|
} catch (e) {
|
|
35
46
|
return Promise.reject(e);
|
|
36
47
|
}
|
|
37
48
|
if (!cachedBuffers) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
49
|
+
// We know the fields will exist due to the condition
|
|
50
|
+
// matching with the one for buildIndexAndUv_0.
|
|
51
|
+
// TODO: Make this brain-based check compiler-based.
|
|
52
|
+
|
|
53
|
+
cachedBuffers = {
|
|
54
|
+
index: new THREE.BufferAttribute(buffers.index, 1),
|
|
55
|
+
uv: new THREE.BufferAttribute(buffers.uvs[0], 2)
|
|
56
|
+
};
|
|
41
57
|
|
|
42
58
|
// Update cacheBuffer
|
|
43
59
|
cacheBuffer.set(bufferKey, cachedBuffers);
|
|
44
60
|
}
|
|
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
|
-
}
|
|
61
|
+
const gpuBuffers = {
|
|
62
|
+
index: cachedBuffers.index,
|
|
63
|
+
uvs: [cachedBuffers.uv, ...(buffers.uvs[1] !== undefined ? [new THREE.BufferAttribute(buffers.uvs[1], 1)] : [])],
|
|
64
|
+
position: new THREE.BufferAttribute(buffers.position, 3),
|
|
65
|
+
normal: new THREE.BufferAttribute(buffers.normal, 3)
|
|
67
66
|
};
|
|
67
|
+
const geometry = new TileGeometry(builder, params, gpuBuffers);
|
|
68
|
+
geometry.OBB = new OBB(geometry.boundingBox.min, geometry.boundingBox.max);
|
|
69
|
+
geometry.initRefCount(cacheTile, key);
|
|
68
70
|
resolve(geometry);
|
|
69
71
|
return Promise.resolve({
|
|
70
72
|
geometry,
|
|
@@ -3,14 +3,55 @@ export function getBufferIndexSize(segments, noSkirt) {
|
|
|
3
3
|
const triangles = segments * segments * 2 + (noSkirt ? 0 : 4 * segments * 2);
|
|
4
4
|
return triangles * 3;
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
function getUintArrayConstructor(highestValue) {
|
|
7
|
+
let picked = null;
|
|
8
|
+
if (highestValue < 2 ** 8) {
|
|
9
|
+
picked = Uint8Array;
|
|
10
|
+
} else if (highestValue < 2 ** 16) {
|
|
11
|
+
picked = Uint16Array;
|
|
12
|
+
} else if (highestValue < 2 ** 32) {
|
|
13
|
+
picked = Uint32Array;
|
|
14
|
+
} else {
|
|
15
|
+
throw new Error('Value is too high');
|
|
16
|
+
}
|
|
17
|
+
return picked;
|
|
18
|
+
}
|
|
19
|
+
function allocateIndexBuffer(nVertex, nSeg, params, cache) {
|
|
20
|
+
const indexBufferSize = getBufferIndexSize(nSeg, params.disableSkirt);
|
|
21
|
+
const indexConstructor = getUintArrayConstructor(nVertex);
|
|
22
|
+
const tileLen = indexBufferSize;
|
|
23
|
+
const skirtLen = 4 * nSeg;
|
|
24
|
+
if (cache !== undefined) {
|
|
25
|
+
return {
|
|
26
|
+
index: cache,
|
|
27
|
+
skirt: cache.subarray(tileLen, tileLen + skirtLen)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const indexBuffer = new ArrayBuffer((
|
|
31
|
+
// Tile
|
|
32
|
+
tileLen
|
|
33
|
+
// Skirt
|
|
34
|
+
+ (params.disableSkirt ? 0 : skirtLen)) * indexConstructor.BYTES_PER_ELEMENT);
|
|
35
|
+
const index = new indexConstructor(indexBuffer);
|
|
36
|
+
const skirt = !params.disableSkirt ? index.subarray(tileLen, tileLen + skirtLen) : undefined;
|
|
37
|
+
return {
|
|
38
|
+
index,
|
|
39
|
+
skirt
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function allocateBuffers(nVertex, nSeg, builder, params, cache) {
|
|
43
|
+
const {
|
|
44
|
+
index,
|
|
45
|
+
skirt
|
|
46
|
+
} = allocateIndexBuffer(nVertex, nSeg, params, cache?.index);
|
|
47
|
+
return {
|
|
48
|
+
index,
|
|
49
|
+
skirt,
|
|
50
|
+
position: new Float32Array(nVertex * 3),
|
|
51
|
+
normal: new Float32Array(nVertex * 3),
|
|
52
|
+
// 2 UV set per tile: wgs84 (uv[0]) and pseudo-mercator (pm, uv[1])
|
|
53
|
+
// - wgs84: 1 texture per tile because tiles are using wgs84
|
|
54
|
+
// projection
|
|
14
55
|
// - pm: use multiple textures per tile.
|
|
15
56
|
// +-------------------------+
|
|
16
57
|
// | |
|
|
@@ -24,142 +65,160 @@ export default function computeBuffers(params) {
|
|
|
24
65
|
// +-------------------------+
|
|
25
66
|
// * u = wgs84.u
|
|
26
67
|
// * v = textureid + v in builder texture
|
|
27
|
-
uvs: []
|
|
68
|
+
uvs: [cache?.uv ?? new Float32Array(nVertex * 2), builder.computeExtraOffset !== undefined ? new Float32Array(nVertex) : undefined]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function computeUv0(uv, id, u, v) {
|
|
72
|
+
uv[id * 2 + 0] = u;
|
|
73
|
+
uv[id * 2 + 1] = v;
|
|
74
|
+
}
|
|
75
|
+
function initComputeUv1(value) {
|
|
76
|
+
return (uv, id) => {
|
|
77
|
+
uv[id] = value;
|
|
28
78
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
79
|
+
}
|
|
80
|
+
/** Compute buffers describing a tile according to a builder and its params. */
|
|
81
|
+
// TODO: Split this even further into subfunctions
|
|
82
|
+
export function computeBuffers(builder, params, cache) {
|
|
83
|
+
// n seg, n+1 vert + <- skirt, n verts per side
|
|
84
|
+
// <---------------> / |
|
|
85
|
+
// +---+---+---+---+ |
|
|
86
|
+
// | / | / | / | / | | Vertices:
|
|
87
|
+
// +---+---+---+---+ - + tile = (n + 1)^2
|
|
88
|
+
// | / | / | / | / | | skirt = 4n
|
|
89
|
+
// +---+---+---+---+ - +
|
|
90
|
+
// | / | / | / | / | | Segments:
|
|
91
|
+
// +---+---+---+---+ - + tile = 2 * n * (n + 1) + n^2
|
|
92
|
+
// | / | / | / | / | | skirt = 2n * 4
|
|
93
|
+
// +---+---+---+---+ |
|
|
94
|
+
const nSeg = Math.max(2, params.segments);
|
|
95
|
+
const nVertex = nSeg + 1;
|
|
96
|
+
const nTileVertex = nVertex ** 2;
|
|
97
|
+
const nSkirtVertex = params.disableSkirt ? 0 : 4 * nSeg;
|
|
98
|
+
const nTotalVertex = nTileVertex + nSkirtVertex;
|
|
99
|
+
|
|
100
|
+
// Computer should combust before this happens
|
|
101
|
+
if (nTotalVertex > 2 ** 32) {
|
|
37
102
|
throw new Error('Tile segments count is too big');
|
|
38
103
|
}
|
|
39
|
-
outBuffers
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (params.buildIndexAndUv_0) {
|
|
48
|
-
if (nVertex < 2 ** 8) {
|
|
49
|
-
outBuffers.index = new Uint8Array(bufferIndexSize);
|
|
50
|
-
} else if (nVertex < 2 ** 16) {
|
|
51
|
-
outBuffers.index = new Uint16Array(bufferIndexSize);
|
|
52
|
-
} else if (nVertex < 2 ** 32) {
|
|
53
|
-
outBuffers.index = new Uint32Array(bufferIndexSize);
|
|
54
|
-
}
|
|
55
|
-
outBuffers.uvs[0] = new Float32Array(nVertex * 2);
|
|
56
|
-
computeUvs[0] = (id, u, v) => {
|
|
57
|
-
outBuffers.uvs[0][id * 2 + 0] = u;
|
|
58
|
-
outBuffers.uvs[0][id * 2 + 1] = v;
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
const widthSegments = Math.max(2, Math.floor(nSeg) || 2);
|
|
62
|
-
const heightSegments = Math.max(2, Math.floor(nSeg) || 2);
|
|
63
|
-
let idVertex = 0;
|
|
64
|
-
const vertices = [];
|
|
65
|
-
let skirt = [];
|
|
66
|
-
const skirtEnd = [];
|
|
67
|
-
builder.prepare(params);
|
|
68
|
-
for (let y = 0; y <= heightSegments; y++) {
|
|
69
|
-
const verticesRow = [];
|
|
70
|
-
const v = y / heightSegments;
|
|
71
|
-
builder.vProjecte(v, params);
|
|
72
|
-
if (uvCount > 1) {
|
|
73
|
-
const u = builder.computeUvs[1](params);
|
|
74
|
-
computeUvs[1] = id => {
|
|
75
|
-
outBuffers.uvs[1][id] = u;
|
|
76
|
-
};
|
|
104
|
+
const outBuffers = allocateBuffers(nTotalVertex, nSeg, builder, params, cache);
|
|
105
|
+
const computeUvs = [cache === undefined ? computeUv0 : () => {}];
|
|
106
|
+
params = builder.prepare(params);
|
|
107
|
+
for (let y = 0; y <= nSeg; y++) {
|
|
108
|
+
const v = y / nSeg;
|
|
109
|
+
params.coordinates.y = builder.vProject(v, params.extent);
|
|
110
|
+
if (builder.computeExtraOffset !== undefined) {
|
|
111
|
+
computeUvs[1] = initComputeUv1(builder.computeExtraOffset(params));
|
|
77
112
|
}
|
|
78
|
-
for (let x = 0; x <=
|
|
79
|
-
const u = x /
|
|
80
|
-
const id_m3 =
|
|
81
|
-
builder.
|
|
82
|
-
const vertex = builder.vertexPosition(params
|
|
83
|
-
const normal = builder.vertexNormal(
|
|
113
|
+
for (let x = 0; x <= nSeg; x++) {
|
|
114
|
+
const u = x / nSeg;
|
|
115
|
+
const id_m3 = (y * nVertex + x) * 3;
|
|
116
|
+
params.coordinates.x = builder.uProject(u, params.extent);
|
|
117
|
+
const vertex = builder.vertexPosition(params.coordinates);
|
|
118
|
+
const normal = builder.vertexNormal();
|
|
84
119
|
|
|
85
120
|
// move geometry to center world
|
|
86
121
|
vertex.sub(params.center);
|
|
87
122
|
|
|
88
123
|
// align normal to z axis
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
124
|
+
// HACK: this check style is not great
|
|
125
|
+
if ('quatNormalToZ' in params) {
|
|
126
|
+
const quat = params.quatNormalToZ;
|
|
127
|
+
vertex.applyQuaternion(quat);
|
|
128
|
+
normal.applyQuaternion(quat);
|
|
92
129
|
}
|
|
93
130
|
vertex.toArray(outBuffers.position, id_m3);
|
|
94
131
|
normal.toArray(outBuffers.normal, id_m3);
|
|
95
|
-
for (const computeUv of computeUvs) {
|
|
96
|
-
computeUv
|
|
97
|
-
|
|
98
|
-
if (!params.disableSkirt) {
|
|
99
|
-
if (y !== 0 && y !== heightSegments) {
|
|
100
|
-
if (x === widthSegments) {
|
|
101
|
-
skirt.push(idVertex);
|
|
102
|
-
} else if (x === 0) {
|
|
103
|
-
skirtEnd.push(idVertex);
|
|
104
|
-
}
|
|
132
|
+
for (const [index, computeUv] of computeUvs.entries()) {
|
|
133
|
+
if (computeUv !== undefined) {
|
|
134
|
+
computeUv(outBuffers.uvs[index], y * nVertex + x, u, v);
|
|
105
135
|
}
|
|
106
136
|
}
|
|
107
|
-
verticesRow.push(idVertex);
|
|
108
|
-
idVertex++;
|
|
109
|
-
}
|
|
110
|
-
vertices.push(verticesRow);
|
|
111
|
-
if (y === 0) {
|
|
112
|
-
skirt = skirt.concat(verticesRow);
|
|
113
|
-
} else if (y === heightSegments) {
|
|
114
|
-
skirt = skirt.concat(verticesRow.slice().reverse());
|
|
115
137
|
}
|
|
116
138
|
}
|
|
117
|
-
|
|
118
|
-
|
|
139
|
+
|
|
140
|
+
// Fill skirt index buffer
|
|
141
|
+
if (cache === undefined && !params.disableSkirt) {
|
|
142
|
+
for (let x = 0; x < nVertex; x++) {
|
|
143
|
+
// -------->
|
|
144
|
+
// 0---1---2
|
|
145
|
+
// | / | / | [0-9] = assign order
|
|
146
|
+
// +---+---+
|
|
147
|
+
// | / | / |
|
|
148
|
+
// +---+---+
|
|
149
|
+
outBuffers.skirt[x] = x;
|
|
150
|
+
// +---+---+
|
|
151
|
+
// | / | / | [0-9] = assign order
|
|
152
|
+
// +---+---x x = skipped for now
|
|
153
|
+
// | / | / |
|
|
154
|
+
// 0---1---2
|
|
155
|
+
// <--------
|
|
156
|
+
outBuffers.skirt[2 * nVertex - 2 + x] = nVertex ** 2 - (x + 1);
|
|
157
|
+
}
|
|
158
|
+
for (let y = 1; y < nVertex - 1; y++) {
|
|
159
|
+
// +---+---s |
|
|
160
|
+
// | / | / | | o = stored vertices
|
|
161
|
+
// +---+---o | s = already stored
|
|
162
|
+
// | / | / | |
|
|
163
|
+
// +---+---s v
|
|
164
|
+
outBuffers.skirt[nVertex - 1 + y] = y * nVertex + (nVertex - 1);
|
|
165
|
+
// ^ s---+---+
|
|
166
|
+
// | | / | / | o = stored vertices
|
|
167
|
+
// | o---+---+ s = already stored
|
|
168
|
+
// | | / | / |
|
|
169
|
+
// | s---+---+
|
|
170
|
+
outBuffers.skirt[3 * nVertex - 3 + y] = nVertex * (nVertex - 1 - y);
|
|
171
|
+
}
|
|
119
172
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
outBuffers.index[
|
|
124
|
-
|
|
173
|
+
|
|
174
|
+
/** Copy passed indices at the desired index of the output index buffer. */
|
|
175
|
+
function bufferizeTri(id, va, vb, vc) {
|
|
176
|
+
outBuffers.index[id + 0] = va;
|
|
177
|
+
outBuffers.index[id + 1] = vb;
|
|
178
|
+
outBuffers.index[id + 2] = vc;
|
|
125
179
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
180
|
+
if (cache === undefined) {
|
|
181
|
+
for (let y = 0; y < nSeg; y++) {
|
|
182
|
+
for (let x = 0; x < nSeg; x++) {
|
|
183
|
+
const v1 = y * nVertex + (x + 1);
|
|
184
|
+
const v2 = y * nVertex + x;
|
|
185
|
+
const v3 = (y + 1) * nVertex + x;
|
|
186
|
+
const v4 = (y + 1) * nVertex + (x + 1);
|
|
187
|
+
const id = (y * nSeg + x) * 6;
|
|
188
|
+
bufferizeTri(id, /**/v4, v2, v1);
|
|
189
|
+
bufferizeTri(id + 3, v4, v3, v2);
|
|
136
190
|
}
|
|
137
191
|
}
|
|
138
192
|
}
|
|
139
|
-
const iStart = idVertex;
|
|
140
193
|
|
|
141
|
-
//
|
|
142
|
-
// The size of the skirt is now a ratio of the size of the tile.
|
|
143
|
-
// To be perfect it should depend on the real elevation delta but too heavy
|
|
194
|
+
// PERF: Beware skirt's size influences performance
|
|
195
|
+
// INFO: The size of the skirt is now a ratio of the size of the tile.
|
|
196
|
+
// To be perfect it should depend on the real elevation delta but too heavy
|
|
197
|
+
// to compute
|
|
144
198
|
if (!params.disableSkirt) {
|
|
145
|
-
// We compute the actual size of tile segment to use later for
|
|
199
|
+
// We compute the actual size of tile segment to use later for
|
|
200
|
+
// the skirt.
|
|
146
201
|
const segmentSize = new THREE.Vector3().fromArray(outBuffers.position).distanceTo(new THREE.Vector3().fromArray(outBuffers.position, 3));
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
id
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
202
|
+
const buildSkirt = cache === undefined ? {
|
|
203
|
+
index: (id, v1, v2, v3, v4) => {
|
|
204
|
+
bufferizeTri(id, v1, v2, v3);
|
|
205
|
+
bufferizeTri(id + 3, v1, v3, v4);
|
|
206
|
+
return id + 6;
|
|
207
|
+
},
|
|
208
|
+
uv: (buf, idTo, idFrom) => {
|
|
209
|
+
buf[idTo * 2 + 0] = buf[idFrom * 2 + 0];
|
|
210
|
+
buf[idTo * 2 + 1] = buf[idFrom * 2 + 1];
|
|
211
|
+
}
|
|
212
|
+
} : {
|
|
213
|
+
index: () => {},
|
|
214
|
+
uv: () => {}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// Alias for readability
|
|
218
|
+
const start = nTileVertex;
|
|
219
|
+
for (let i = 0; i < outBuffers.skirt.length; i++) {
|
|
220
|
+
const id = outBuffers.skirt[i];
|
|
221
|
+
const id_m3 = (start + i) * 3;
|
|
163
222
|
const id2_m3 = id * 3;
|
|
164
223
|
outBuffers.position[id_m3 + 0] = outBuffers.position[id2_m3 + 0] - outBuffers.normal[id2_m3 + 0] * segmentSize;
|
|
165
224
|
outBuffers.position[id_m3 + 1] = outBuffers.position[id2_m3 + 1] - outBuffers.normal[id2_m3 + 1] * segmentSize;
|
|
@@ -167,17 +226,23 @@ export default function computeBuffers(params) {
|
|
|
167
226
|
outBuffers.normal[id_m3 + 0] = outBuffers.normal[id2_m3 + 0];
|
|
168
227
|
outBuffers.normal[id_m3 + 1] = outBuffers.normal[id2_m3 + 1];
|
|
169
228
|
outBuffers.normal[id_m3 + 2] = outBuffers.normal[id2_m3 + 2];
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
outBuffers.uvs[1][
|
|
229
|
+
buildSkirt.uv(outBuffers.uvs[0], start + i, id);
|
|
230
|
+
if (outBuffers.uvs[1] !== undefined) {
|
|
231
|
+
outBuffers.uvs[1][start + i] = outBuffers.uvs[1][id];
|
|
173
232
|
}
|
|
174
|
-
const idf = (i + 1) % skirt.length;
|
|
175
|
-
const v2 =
|
|
176
|
-
const v3 = idf === 0 ?
|
|
177
|
-
const v4 = skirt[idf];
|
|
178
|
-
|
|
179
|
-
idVertex++;
|
|
233
|
+
const idf = (i + 1) % outBuffers.skirt.length;
|
|
234
|
+
const v2 = start + i;
|
|
235
|
+
const v3 = idf === 0 ? start : start + i + 1;
|
|
236
|
+
const v4 = outBuffers.skirt[idf];
|
|
237
|
+
buildSkirt.index(6 * nSeg ** 2 + i * 6, id, v2, v3, v4);
|
|
180
238
|
}
|
|
181
239
|
}
|
|
182
|
-
|
|
240
|
+
|
|
241
|
+
// Dropping skirt view
|
|
242
|
+
return {
|
|
243
|
+
index: outBuffers.index,
|
|
244
|
+
position: outBuffers.position,
|
|
245
|
+
uvs: outBuffers.uvs,
|
|
246
|
+
normal: outBuffers.normal
|
|
247
|
+
};
|
|
183
248
|
}
|