itowns 2.43.2-next.9 → 2.44.1-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTORS.md +1 -0
- package/changelog.md +107 -0
- package/dist/455.js +2 -0
- package/dist/455.js.map +1 -0
- package/dist/debug.js +1 -1
- package/dist/debug.js.LICENSE.txt +2 -2
- package/dist/debug.js.map +1 -1
- package/dist/itowns.js +1 -1
- package/dist/itowns.js.LICENSE.txt +1 -22
- package/dist/itowns.js.map +1 -1
- 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 +1 -1
- package/dist/itowns_widgets.js.map +1 -1
- package/examples/3dtiles_loader.html +150 -0
- package/examples/config.json +5 -0
- package/examples/jsm/.eslintrc.cjs +38 -0
- package/examples/jsm/OGC3DTilesHelper.js +105 -0
- package/examples/misc_instancing.html +2 -1
- package/examples/potree2_25d_map.html +127 -0
- package/lib/Core/3DTiles/C3DTFeature.js +6 -6
- package/lib/Core/Potree2Node.js +206 -0
- package/lib/Core/Potree2PointAttributes.js +139 -0
- package/lib/Core/Scheduler/Scheduler.js +1 -1
- package/lib/Core/Style.js +52 -49
- package/lib/Core/View.js +3 -0
- package/lib/Layer/C3DTilesLayer.js +6 -6
- package/lib/Layer/OGC3DTilesLayer.js +386 -0
- package/lib/Layer/PointCloudLayer.js +1 -1
- package/lib/Layer/Potree2Layer.js +165 -0
- package/lib/Layer/ReferencingLayerProperties.js +5 -0
- package/lib/Layer/TiledGeometryLayer.js +4 -1
- package/lib/Loader/Potree2BrotliLoader.js +261 -0
- package/lib/Loader/Potree2Loader.js +207 -0
- package/lib/Main.js +9 -2
- package/lib/Parser/B3dmParser.js +11 -22
- package/lib/Parser/LASParser.js +48 -16
- package/lib/Parser/Potree2BinParser.js +92 -0
- package/lib/Parser/ShapefileParser.js +2 -2
- package/lib/Parser/deprecated/LegacyGLTFLoader.js +25 -5
- package/lib/Parser/iGLTFLoader.js +169 -0
- package/lib/Process/3dTilesProcessing.js +2 -1
- package/lib/Provider/3dTilesProvider.js +6 -4
- package/lib/Renderer/PointsMaterial.js +128 -94
- package/lib/Source/FileSource.js +1 -1
- package/lib/Source/OGC3DTilesGoogleSource.js +32 -0
- package/lib/Source/OGC3DTilesIonSource.js +37 -0
- package/lib/Source/OGC3DTilesSource.js +24 -0
- package/lib/Source/Potree2Source.js +172 -0
- package/lib/ThreeExtended/loaders/DRACOLoader.js +5 -3
- package/lib/ThreeExtended/loaders/GLTFLoader.js +38 -2
- package/lib/ThreeExtended/loaders/KTX2Loader.js +17 -10
- package/lib/ThreeExtended/utils/BufferGeometryUtils.js +32 -30
- package/lib/Worker/LASLoaderWorker.js +19 -0
- package/lib/Worker/Potree2Worker.js +21 -0
- package/package.json +33 -31
- package/lib/Parser/GLTFParser.js +0 -88
- /package/lib/{Parser → Loader}/LASLoader.js +0 -0
package/lib/Main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const conf = {
|
|
2
|
-
version: '2.
|
|
2
|
+
version: '2.44.0'
|
|
3
3
|
};
|
|
4
4
|
export const REVISION = conf.version;
|
|
5
5
|
|
|
@@ -51,7 +51,9 @@ export { default as GeometryLayer } from "./Layer/GeometryLayer.js";
|
|
|
51
51
|
export { default as FeatureGeometryLayer } from "./Layer/FeatureGeometryLayer.js";
|
|
52
52
|
export { default as PointCloudLayer } from "./Layer/PointCloudLayer.js";
|
|
53
53
|
export { default as PotreeLayer } from "./Layer/PotreeLayer.js";
|
|
54
|
+
export { default as Potree2Layer } from "./Layer/Potree2Layer.js";
|
|
54
55
|
export { default as C3DTilesLayer, C3DTILES_LAYER_EVENTS } from "./Layer/C3DTilesLayer.js";
|
|
56
|
+
export { default as OGC3DTilesLayer, OGC3DTILES_LAYER_EVENTS, enableDracoLoader, enableKtx2Loader } from "./Layer/OGC3DTilesLayer.js";
|
|
55
57
|
export { default as TiledGeometryLayer } from "./Layer/TiledGeometryLayer.js";
|
|
56
58
|
export { default as OrientedImageLayer } from "./Layer/OrientedImageLayer.js";
|
|
57
59
|
export { STRATEGY_MIN_NETWORK_TRAFFIC, STRATEGY_GROUP, STRATEGY_PROGRESSIVE, STRATEGY_DICHOTOMY } from "./Layer/LayerUpdateStrategy.js";
|
|
@@ -75,9 +77,13 @@ export { default as WMTSSource } from "./Source/WMTSSource.js";
|
|
|
75
77
|
export { default as VectorTilesSource } from "./Source/VectorTilesSource.js";
|
|
76
78
|
export { default as OrientedImageSource } from "./Source/OrientedImageSource.js";
|
|
77
79
|
export { default as PotreeSource } from "./Source/PotreeSource.js";
|
|
80
|
+
export { default as Potree2Source } from "./Source/Potree2Source.js";
|
|
78
81
|
export { default as C3DTilesSource } from "./Source/C3DTilesSource.js";
|
|
79
82
|
export { default as C3DTilesIonSource } from "./Source/C3DTilesIonSource.js";
|
|
80
83
|
export { default as C3DTilesGoogleSource } from "./Source/C3DTilesGoogleSource.js";
|
|
84
|
+
export { default as OGC3DTilesSource } from "./Source/OGC3DTilesSource.js";
|
|
85
|
+
export { default as OGC3DTilesIonSource } from "./Source/OGC3DTilesIonSource.js";
|
|
86
|
+
export { default as OGC3DTilesGoogleSource } from "./Source/OGC3DTilesGoogleSource.js";
|
|
81
87
|
export { default as EntwinePointTileSource } from "./Source/EntwinePointTileSource.js";
|
|
82
88
|
export { default as CopcSource } from "./Source/CopcSource.js";
|
|
83
89
|
|
|
@@ -93,7 +99,8 @@ export { default as LASParser } from "./Parser/LASParser.js";
|
|
|
93
99
|
export { default as ISGParser } from "./Parser/ISGParser.js";
|
|
94
100
|
export { default as GDFParser } from "./Parser/GDFParser.js";
|
|
95
101
|
export { default as GTXParser } from "./Parser/GTXParser.js";
|
|
96
|
-
export { default as
|
|
102
|
+
export { default as B3dmParser } from "./Parser/B3dmParser.js";
|
|
103
|
+
export { default as iGLTFLoader } from "./Parser/iGLTFLoader.js";
|
|
97
104
|
|
|
98
105
|
// 3D Tiles classes and extensions
|
|
99
106
|
// Exported to allow one to implement its own 3D Tiles extension which needs to
|
package/lib/Parser/B3dmParser.js
CHANGED
|
@@ -5,8 +5,10 @@ import { MeshBasicMaterial } from 'three';
|
|
|
5
5
|
import disposeThreeMaterial from "../Utils/ThreeUtils.js";
|
|
6
6
|
import shaderUtils from "../Renderer/Shader/ShaderUtils.js";
|
|
7
7
|
import ReferLayerProperties from "../Layer/ReferencingLayerProperties.js";
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
// A bit weird but temporary until we remove this deprecated parser. Mainly to benefit from the enableDracoLoader and enableKtx2Loader
|
|
9
|
+
// methods.
|
|
10
|
+
import { itownsGLTFLoader } from "../Layer/OGC3DTilesLayer.js";
|
|
11
|
+
const matrixChangeUpVectorYtoZ = new THREE.Matrix4().makeRotationX(Math.PI / 2);
|
|
10
12
|
const matrixChangeUpVectorXtoZ = new THREE.Matrix4().makeRotationZ(-Math.PI / 2);
|
|
11
13
|
const utf8Decoder = new TextDecoder();
|
|
12
14
|
|
|
@@ -34,18 +36,15 @@ function filterUnsupportedSemantics(obj) {
|
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* gltf file to have it z-up in the end).
|
|
39
|
+
* Transforms loaded gltf model to z-up (either from y-up or from the up axis defined in gltfUpAxis). Note that
|
|
40
|
+
* gltfUpAxis was an attribut of pre-1.0 3D Tiles and is now deprecated.
|
|
40
41
|
* @param {THREE.Object3D} gltfScene - the parsed glTF scene
|
|
41
42
|
* @param {String} gltfUpAxis - the gltfUpAxis parameter
|
|
42
43
|
*/
|
|
43
|
-
function
|
|
44
|
-
if (gltfUpAxis === '
|
|
45
|
-
|
|
46
|
-
gltfScene.applyMatrix4(matrixChangeUpVectorYtoZInv);
|
|
44
|
+
function transformToZUp(gltfScene, gltfUpAxis) {
|
|
45
|
+
if (!gltfUpAxis || gltfUpAxis === 'Y') {
|
|
46
|
+
gltfScene.applyMatrix4(matrixChangeUpVectorYtoZ);
|
|
47
47
|
} else if (gltfUpAxis === 'X') {
|
|
48
|
-
gltfScene.applyMatrix4(matrixChangeUpVectorYtoZInv);
|
|
49
48
|
gltfScene.applyMatrix4(matrixChangeUpVectorXtoZ);
|
|
50
49
|
}
|
|
51
50
|
}
|
|
@@ -127,7 +126,6 @@ export default {
|
|
|
127
126
|
}
|
|
128
127
|
const posGltf = headerByteLength + b3dmHeader.FTJSONLength + b3dmHeader.FTBinaryLength + b3dmHeader.BTJSONLength + b3dmHeader.BTBinaryLength;
|
|
129
128
|
const gltfBuffer = buffer.slice(posGltf);
|
|
130
|
-
const headerView = new DataView(gltfBuffer, 0, 20);
|
|
131
129
|
const init_mesh = function (mesh) {
|
|
132
130
|
mesh.frustumCulled = frustumCulled;
|
|
133
131
|
if (mesh.material) {
|
|
@@ -147,11 +145,11 @@ export default {
|
|
|
147
145
|
ReferLayerProperties(mesh.material, options.layer);
|
|
148
146
|
}
|
|
149
147
|
};
|
|
150
|
-
promises.push(
|
|
148
|
+
promises.push(itownsGLTFLoader.parseAsync(gltfBuffer, options).then(gltf => {
|
|
151
149
|
for (const scene of gltf.scenes) {
|
|
152
150
|
scene.traverse(filterUnsupportedSemantics);
|
|
153
151
|
}
|
|
154
|
-
|
|
152
|
+
transformToZUp(gltf.scene, options.gltfUpAxis);
|
|
155
153
|
const shouldBePatchedForLogDepthSupport = Capabilities.isLogDepthBufferSupported() && !options.doNotPatchMaterial;
|
|
156
154
|
if (options.frustumCulling === false || options.overrideMaterials || shouldBePatchedForLogDepthSupport || options.layer) {
|
|
157
155
|
gltf.scene.traverse(init_mesh);
|
|
@@ -159,15 +157,6 @@ export default {
|
|
|
159
157
|
|
|
160
158
|
// Apply relative center from Feature table.
|
|
161
159
|
gltf.scene.position.copy(FT_RTC);
|
|
162
|
-
|
|
163
|
-
// Apply relative center from gltf json.
|
|
164
|
-
const contentArray = new Uint8Array(gltfBuffer, 20, headerView.getUint32(12, true));
|
|
165
|
-
const content = utf8Decoder.decode(new Uint8Array(contentArray));
|
|
166
|
-
const json = JSON.parse(content);
|
|
167
|
-
if (json.extensions && json.extensions.CESIUM_RTC) {
|
|
168
|
-
gltf.scene.position.fromArray(json.extensions.CESIUM_RTC.center);
|
|
169
|
-
gltf.scene.updateMatrixWorld(true);
|
|
170
|
-
}
|
|
171
160
|
return gltf;
|
|
172
161
|
}).catch(e => {
|
|
173
162
|
throw new Error(e);
|
package/lib/Parser/LASParser.js
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import { spawn, Thread, Transfer } from 'threads';
|
|
3
|
+
let _lazPerf;
|
|
4
|
+
let _thread;
|
|
5
|
+
function workerInstance() {
|
|
6
|
+
return new Worker( /* webpackChunkName: "itowns_lasparser" */
|
|
7
|
+
new URL('../Worker/LASLoaderWorker.js', import.meta.url), {
|
|
8
|
+
type: 'module'
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
async function loader() {
|
|
12
|
+
if (_thread) {
|
|
13
|
+
return _thread;
|
|
14
|
+
}
|
|
15
|
+
_thread = await spawn(workerInstance());
|
|
16
|
+
if (_lazPerf) {
|
|
17
|
+
_thread.lazPerf(_lazPerf);
|
|
18
|
+
}
|
|
19
|
+
return _thread;
|
|
20
|
+
}
|
|
4
21
|
function buildBufferGeometry(attributes) {
|
|
5
22
|
const geometry = new THREE.BufferGeometry();
|
|
6
23
|
const positionBuffer = new THREE.BufferAttribute(attributes.position, 3);
|
|
@@ -42,7 +59,16 @@ export default {
|
|
|
42
59
|
if (!path) {
|
|
43
60
|
throw new Error('Path to laz-perf is mandatory');
|
|
44
61
|
}
|
|
45
|
-
|
|
62
|
+
_lazPerf = path;
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* Terminate all worker instances.
|
|
66
|
+
* @returns {Promise<void>}
|
|
67
|
+
*/
|
|
68
|
+
terminate() {
|
|
69
|
+
const currentThread = _thread;
|
|
70
|
+
_thread = undefined;
|
|
71
|
+
return Thread.terminate(currentThread);
|
|
46
72
|
},
|
|
47
73
|
/**
|
|
48
74
|
* Parses a chunk of a LAS or LAZ (LASZip) and returns the corresponding
|
|
@@ -66,13 +92,18 @@ export default {
|
|
|
66
92
|
* @return {Promise<THREE.BufferGeometry>} A promise resolving with a
|
|
67
93
|
* `THREE.BufferGeometry`.
|
|
68
94
|
*/
|
|
69
|
-
parseChunk(data) {
|
|
95
|
+
async parseChunk(data) {
|
|
70
96
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
97
|
+
const lasLoader = await loader();
|
|
98
|
+
const parsedData = await lasLoader.parseChunk(Transfer(data), {
|
|
99
|
+
pointCount: options.in.pointCount,
|
|
100
|
+
header: options.in.header,
|
|
101
|
+
eb: options.eb,
|
|
102
|
+
colorDepth: options.in.colorDepth
|
|
75
103
|
});
|
|
104
|
+
const geometry = buildBufferGeometry(parsedData.attributes);
|
|
105
|
+
geometry.computeBoundingBox();
|
|
106
|
+
return geometry;
|
|
76
107
|
},
|
|
77
108
|
/**
|
|
78
109
|
* Parses a LAS file or a LAZ (LASZip) file and return the corresponding
|
|
@@ -88,18 +119,19 @@ export default {
|
|
|
88
119
|
* @return {Promise} A promise resolving with a `THREE.BufferGeometry`. The
|
|
89
120
|
* header of the file is contained in `userData`.
|
|
90
121
|
*/
|
|
91
|
-
parse(data) {
|
|
122
|
+
async parse(data) {
|
|
92
123
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
93
124
|
if (options.out?.skip) {
|
|
94
125
|
console.warn("Warning: options 'skip' not supported anymore");
|
|
95
126
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
geometry.userData.header = parsedData.header;
|
|
101
|
-
geometry.computeBoundingBox();
|
|
102
|
-
return geometry;
|
|
127
|
+
const input = options.in;
|
|
128
|
+
const lasLoader = await loader();
|
|
129
|
+
const parsedData = await lasLoader.parseFile(Transfer(data), {
|
|
130
|
+
colorDepth: input?.colorDepth
|
|
103
131
|
});
|
|
132
|
+
const geometry = buildBufferGeometry(parsedData.attributes);
|
|
133
|
+
geometry.userData.header = parsedData.header;
|
|
134
|
+
geometry.computeBoundingBox();
|
|
135
|
+
return geometry;
|
|
104
136
|
}
|
|
105
137
|
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { spawn, Thread, Transfer } from 'threads';
|
|
3
|
+
let _thread;
|
|
4
|
+
function workerInstance() {
|
|
5
|
+
return new Worker( /* webpackChunkName: "itowns_potree2worker" */
|
|
6
|
+
new URL('../Worker/Potree2Worker.js', import.meta.url), {
|
|
7
|
+
type: 'module'
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
async function loader() {
|
|
11
|
+
if (_thread) {
|
|
12
|
+
return _thread;
|
|
13
|
+
}
|
|
14
|
+
_thread = await spawn(workerInstance());
|
|
15
|
+
return _thread;
|
|
16
|
+
}
|
|
17
|
+
function decoder(w, metadata) {
|
|
18
|
+
return metadata.encoding === 'BROTLI' ? w.parseBrotli : w.parse;
|
|
19
|
+
}
|
|
20
|
+
export default {
|
|
21
|
+
/**
|
|
22
|
+
* @return {Promise<void>}
|
|
23
|
+
*/
|
|
24
|
+
terminate() {
|
|
25
|
+
const currentThread = _thread;
|
|
26
|
+
_thread = undefined;
|
|
27
|
+
return Thread.terminate(currentThread);
|
|
28
|
+
},
|
|
29
|
+
/** @module Potree2BinParser */
|
|
30
|
+
/** Parse .bin PotreeConverter 2.0 format and convert to a THREE.BufferGeometry
|
|
31
|
+
* @function parse
|
|
32
|
+
* @param {ArrayBuffer} buffer - the bin buffer.
|
|
33
|
+
* @param {Object} options
|
|
34
|
+
* @param {string[]} options.in.pointAttributes - the point attributes information contained in metadata.js
|
|
35
|
+
* @return {Promise} - a promise that resolves with a THREE.BufferGeometry.
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
38
|
+
parse: async function (buffer, options) {
|
|
39
|
+
const metadata = options.in.source.metadata;
|
|
40
|
+
const layer = options.out;
|
|
41
|
+
const pointAttributes = layer.pointAttributes;
|
|
42
|
+
const scale = metadata.scale;
|
|
43
|
+
const box = options.in.bbox;
|
|
44
|
+
const min = box.min;
|
|
45
|
+
const size = box.max.clone().sub(box.min);
|
|
46
|
+
const max = box.max;
|
|
47
|
+
const offset = metadata.offset;
|
|
48
|
+
const numPoints = options.in.numPoints;
|
|
49
|
+
const potreeLoader = await loader();
|
|
50
|
+
const decode = decoder(potreeLoader, metadata);
|
|
51
|
+
const data = await decode(Transfer(buffer), {
|
|
52
|
+
pointAttributes,
|
|
53
|
+
scale,
|
|
54
|
+
min,
|
|
55
|
+
max,
|
|
56
|
+
size,
|
|
57
|
+
offset,
|
|
58
|
+
numPoints
|
|
59
|
+
});
|
|
60
|
+
const buffers = data.attributeBuffers;
|
|
61
|
+
const geometry = new THREE.BufferGeometry();
|
|
62
|
+
Object.keys(buffers).forEach(property => {
|
|
63
|
+
const buffer = buffers[property].buffer;
|
|
64
|
+
if (property === 'position') {
|
|
65
|
+
geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(buffer), 3));
|
|
66
|
+
} else if (property === 'rgba') {
|
|
67
|
+
geometry.setAttribute('color', new THREE.BufferAttribute(new Uint8Array(buffer), 4, true));
|
|
68
|
+
} else if (property === 'NORMAL') {
|
|
69
|
+
geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buffer), 3));
|
|
70
|
+
} else if (property === 'INDICES') {
|
|
71
|
+
const bufferAttribute = new THREE.BufferAttribute(new Uint8Array(buffer), 4);
|
|
72
|
+
bufferAttribute.normalized = true;
|
|
73
|
+
geometry.setAttribute('indices', bufferAttribute);
|
|
74
|
+
} else {
|
|
75
|
+
const bufferAttribute = new THREE.BufferAttribute(new Float32Array(buffer), 1);
|
|
76
|
+
const batchAttribute = buffers[property].attribute;
|
|
77
|
+
bufferAttribute.potree = {
|
|
78
|
+
offset: buffers[property].offset,
|
|
79
|
+
scale: buffers[property].scale,
|
|
80
|
+
preciseBuffer: buffers[property].preciseBuffer,
|
|
81
|
+
range: batchAttribute.range
|
|
82
|
+
};
|
|
83
|
+
geometry.setAttribute(property, bufferAttribute);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
geometry.computeBoundingBox();
|
|
87
|
+
return {
|
|
88
|
+
geometry,
|
|
89
|
+
density: data.density
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
};
|
|
@@ -68,9 +68,9 @@ export default {
|
|
|
68
68
|
|
|
69
69
|
// If a zip is present, don't read anything else
|
|
70
70
|
if (data.zip) {
|
|
71
|
-
result = shp
|
|
71
|
+
result = shp(data.zip);
|
|
72
72
|
} else if (data.shp && data.shx && data.dbf) {
|
|
73
|
-
result =
|
|
73
|
+
result = shp(data);
|
|
74
74
|
}
|
|
75
75
|
options.in = options.in || {};
|
|
76
76
|
options.in.crs = data.prj ? proj4(data.prj).oProj.datumName : options.in.crs;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
-
//
|
|
2
|
+
// LegacyGLTFLoader for loading gltf 1.0 files taken from THREE v110 because it was removed in THREE v111 and maintained
|
|
3
|
+
// since
|
|
3
4
|
import * as THREE from 'three';
|
|
4
5
|
const threeExamples = {};
|
|
5
6
|
/**
|
|
@@ -45,6 +46,9 @@ threeExamples.LegacyGLTFLoader = function () {
|
|
|
45
46
|
if (json.extensionsUsed && json.extensionsUsed.indexOf(EXTENSIONS.KHR_MATERIALS_COMMON) >= 0) {
|
|
46
47
|
extensions[EXTENSIONS.KHR_MATERIALS_COMMON] = new GLTFMaterialsCommonExtension(json);
|
|
47
48
|
}
|
|
49
|
+
if (json.extensionsUsed && json.extensionsUsed.indexOf(EXTENSIONS.CESIUM_RTC) >= 0) {
|
|
50
|
+
extensions[EXTENSIONS.CESIUM_RTC] = new CesiumRTCExtension(json);
|
|
51
|
+
}
|
|
48
52
|
var parser = new GLTFParser(json, extensions, {
|
|
49
53
|
crossOrigin: this.crossOrigin,
|
|
50
54
|
manager: this.manager,
|
|
@@ -175,7 +179,8 @@ threeExamples.LegacyGLTFLoader = function () {
|
|
|
175
179
|
|
|
176
180
|
var EXTENSIONS = {
|
|
177
181
|
KHR_BINARY_GLTF: 'KHR_binary_glTF',
|
|
178
|
-
KHR_MATERIALS_COMMON: 'KHR_materials_common'
|
|
182
|
+
KHR_MATERIALS_COMMON: 'KHR_materials_common',
|
|
183
|
+
CESIUM_RTC: 'CESIUM_RTC'
|
|
179
184
|
};
|
|
180
185
|
|
|
181
186
|
/* MATERIALS COMMON EXTENSION */
|
|
@@ -247,6 +252,17 @@ threeExamples.LegacyGLTFLoader = function () {
|
|
|
247
252
|
return THREE.LoaderUtils.decodeText(array);
|
|
248
253
|
};
|
|
249
254
|
|
|
255
|
+
// Ref spec https://github.com/KhronosGroup/glTF/blob/main/extensions/1.0/Vendor/CESIUM_RTC/README.md
|
|
256
|
+
// Only the json storage method is implemented since it is the only one we've seen out there and since this extension
|
|
257
|
+
// is specific to deprecated 3D tiles with GLTF 1.0
|
|
258
|
+
function CesiumRTCExtension(json) {
|
|
259
|
+
this.name = EXTENSIONS.CESIUM_RTC;
|
|
260
|
+
this.center = [0, 0, 0];
|
|
261
|
+
if (json.extensions && json.extensions[EXTENSIONS.CESIUM_RTC] && json.extensions[EXTENSIONS.CESIUM_RTC].center && json.extensions[EXTENSIONS.CESIUM_RTC].center.length === 3) {
|
|
262
|
+
this.center = json.extensions[EXTENSIONS.CESIUM_RTC].center;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
250
266
|
/*********************************/
|
|
251
267
|
/********** INTERNALS ************/
|
|
252
268
|
/*********************************/
|
|
@@ -526,9 +542,9 @@ threeExamples.LegacyGLTFLoader = function () {
|
|
|
526
542
|
}
|
|
527
543
|
|
|
528
544
|
/**
|
|
529
|
-
* Verifies if the shaders are Cesium specific: if they contain attributes, uniforms or functions starting with
|
|
530
|
-
* `czm_`. The cesium gltf-pipeline (the ancestor of cesium ion) used to create 3D Tiles tilesets they are only
|
|
531
|
-
* defined in Cesium.
|
|
545
|
+
* Verifies if the shaders are Cesium specific: if they contain attributes, uniforms or functions starting with
|
|
546
|
+
* `czm_`. The cesium gltf-pipeline (the ancestor of cesium ion) used to create 3D Tiles tilesets they are only
|
|
547
|
+
* defined in Cesium.
|
|
532
548
|
* @param {Object} shaders
|
|
533
549
|
*/
|
|
534
550
|
function areShadersCesiumSpecific(shaders) {
|
|
@@ -1323,6 +1339,7 @@ threeExamples.LegacyGLTFLoader = function () {
|
|
|
1323
1339
|
};
|
|
1324
1340
|
GLTFParser.prototype.loadScenes = function () {
|
|
1325
1341
|
var json = this.json;
|
|
1342
|
+
var extensions = this.extensions;
|
|
1326
1343
|
|
|
1327
1344
|
// scene node hierachy builder
|
|
1328
1345
|
|
|
@@ -1357,6 +1374,9 @@ threeExamples.LegacyGLTFLoader = function () {
|
|
|
1357
1374
|
};
|
|
1358
1375
|
}
|
|
1359
1376
|
});
|
|
1377
|
+
if (extensions[EXTENSIONS.CESIUM_RTC]) {
|
|
1378
|
+
_scene.position.fromArray(extensions[EXTENSIONS.CESIUM_RTC].center);
|
|
1379
|
+
}
|
|
1360
1380
|
return _scene;
|
|
1361
1381
|
});
|
|
1362
1382
|
});
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import LegacyGLTFLoader from "./deprecated/LegacyGLTFLoader.js";
|
|
3
|
+
import { GLTFLoader } from "../ThreeExtended/loaders/GLTFLoader.js";
|
|
4
|
+
class iGLTFLoader extends THREE.Loader {
|
|
5
|
+
/**
|
|
6
|
+
* Parses [glTF](https://www.khronos.org/gltf/) 1.0 and 2.0 files.
|
|
7
|
+
*
|
|
8
|
+
* Under the hood, glTF 2.0 files are parsed with THREE.GLTFLoader and GLTF 1.0 are parsed with the previous THREE
|
|
9
|
+
* GltfLoader (for 1.0 glTF) that has been kept and maintained in iTowns.
|
|
10
|
+
*
|
|
11
|
+
* Beware that gltf convention is y-up while itowns is z-up. You can apply a PI/2 rotation around the X axis to the
|
|
12
|
+
* loaded model to transform from y-up to z-up. Note that you can also use Coordinates.geodesicNormal to get the normal
|
|
13
|
+
* to a position on the globe (i.e. in GlobeView) to correctly orient a model on a GlobeView.
|
|
14
|
+
*
|
|
15
|
+
* @constructor
|
|
16
|
+
* @param {THREE.LoadingManager} [manager] - The loadingManager for the loader to use. Default is THREE.DefaultLoadingManager.
|
|
17
|
+
*/
|
|
18
|
+
constructor(manager) {
|
|
19
|
+
super(manager);
|
|
20
|
+
this.legacyGLTFLoader = new LegacyGLTFLoader();
|
|
21
|
+
this.glTFLoader = new GLTFLoader();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Loads a gltf model from url and call the callback function with the parsed response content.
|
|
26
|
+
* Adapted from threejs.
|
|
27
|
+
* @param {String} url - the path/URL of the .gltf or .glb file.
|
|
28
|
+
* @param {Function} onLoad - A function to be called after the loading is successfully completed. The function
|
|
29
|
+
* receives the loaded JSON response returned from {@link parse}.
|
|
30
|
+
* @param {Function} onProgress
|
|
31
|
+
* @param {Function} onError
|
|
32
|
+
*/
|
|
33
|
+
load(url, onLoad, onProgress, onError) {
|
|
34
|
+
const scope = this;
|
|
35
|
+
let resourcePath;
|
|
36
|
+
if (this.resourcePath !== '') {
|
|
37
|
+
resourcePath = this.resourcePath;
|
|
38
|
+
} else if (this.path !== '') {
|
|
39
|
+
// If a base path is set, resources will be relative paths from that plus the relative path of the gltf file
|
|
40
|
+
// Example path = 'https://my-cnd-server.com/', url = 'assets/models/model.gltf'
|
|
41
|
+
// resourcePath = 'https://my-cnd-server.com/assets/models/'
|
|
42
|
+
// referenced resource 'model.bin' will be loaded from 'https://my-cnd-server.com/assets/models/model.bin'
|
|
43
|
+
// referenced resource '../textures/texture.png' will be loaded from 'https://my-cnd-server.com/assets/textures/texture.png'
|
|
44
|
+
const relativeUrl = THREE.LoaderUtils.extractUrlBase(url);
|
|
45
|
+
resourcePath = THREE.LoaderUtils.resolveURL(relativeUrl, this.path);
|
|
46
|
+
} else {
|
|
47
|
+
resourcePath = THREE.LoaderUtils.extractUrlBase(url);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Tells the LoadingManager to track an extra item, which resolves after
|
|
51
|
+
// the model is fully loaded. This means the count of items loaded will
|
|
52
|
+
// be incorrect, but ensures manager.onLoad() does not fire early.
|
|
53
|
+
this.manager.itemStart(url);
|
|
54
|
+
const _onError = e => {
|
|
55
|
+
if (onError) {
|
|
56
|
+
onError(e);
|
|
57
|
+
} else {
|
|
58
|
+
console.error(e);
|
|
59
|
+
}
|
|
60
|
+
scope.manager.itemError(url);
|
|
61
|
+
scope.manager.itemEnd(url);
|
|
62
|
+
};
|
|
63
|
+
const loader = new THREE.FileLoader(this.manager);
|
|
64
|
+
loader.setPath(this.path);
|
|
65
|
+
loader.setResponseType('arraybuffer');
|
|
66
|
+
loader.setRequestHeader(this.requestHeader);
|
|
67
|
+
loader.setWithCredentials(this.withCredentials);
|
|
68
|
+
loader.load(url, data => {
|
|
69
|
+
try {
|
|
70
|
+
scope.parse(data, resourcePath, gltf => {
|
|
71
|
+
onLoad(gltf);
|
|
72
|
+
scope.manager.itemEnd(url);
|
|
73
|
+
}, _onError);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
_onError(e);
|
|
76
|
+
}
|
|
77
|
+
}, onProgress, _onError);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Sets the draco loader instance for this gltf parser. Enable loading files with
|
|
82
|
+
* [Draco](https://google.github.io/draco/) geometry extension. See Threejs
|
|
83
|
+
* [DracoLoader](https://threejs.org/docs/index.html#examples/en/loaders/DRACOLoader) for more information.
|
|
84
|
+
* Only works for GLTF 2.0 files.
|
|
85
|
+
* @param {THREE.DracoLoader} dracoLoader - the threejs DracoLoader instance.
|
|
86
|
+
*/
|
|
87
|
+
setDRACOLoader(dracoLoader) {
|
|
88
|
+
this.glTFLoader.setDRACOLoader(dracoLoader);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Sets the KTX2 loader instance for this gltf parser. Enable loading files with
|
|
93
|
+
* [KTX2](https://www.khronos.org/ktx/) texture extension. See Threejs
|
|
94
|
+
* [KTX2Loader](https://threejs.org/docs/index.html?q=KTX2#examples/en/loaders/KTX2Loader) for more information.
|
|
95
|
+
* Only works for GLTF 2.0 files.
|
|
96
|
+
* @param {THREE.KTX2Loader} ktx2Loader - the threejs KTX2Loader instance.
|
|
97
|
+
*/
|
|
98
|
+
setKTX2Loader(ktx2Loader) {
|
|
99
|
+
this.glTFLoader.setKTX2Loader(ktx2Loader);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Sets the Mesh Optimizer decoder instance for this gltf parser. Enable loading files with
|
|
104
|
+
* [MeshOptimizer](https://meshoptimizer.org/) geometry extension.
|
|
105
|
+
* Only works for GLTF 2.0 files.
|
|
106
|
+
* @param {Object} meshoptDecoder - the threejs meshopt decoder instance.
|
|
107
|
+
*/
|
|
108
|
+
setMeshoptDecoder(meshoptDecoder) {
|
|
109
|
+
this.glTFLoader.setMeshoptDecoder(meshoptDecoder);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Registers a callback to load specific unknown or not standard GLTF extensions.
|
|
114
|
+
* See Threejs [GltfLoader](https://threejs.org/docs/?q=gltflo#examples/en/loaders/GLTFLoader) for more
|
|
115
|
+
* information.
|
|
116
|
+
* @param {Function} callback - the callback function
|
|
117
|
+
*/
|
|
118
|
+
register(callback) {
|
|
119
|
+
this.glTFLoader.register(callback);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Unregisters a load callback.
|
|
124
|
+
* See Threejs [GltfLoader](https://threejs.org/docs/?q=gltflo#examples/en/loaders/GLTFLoader) for more
|
|
125
|
+
* information.
|
|
126
|
+
* @param {Function} callback - the callback function
|
|
127
|
+
*/
|
|
128
|
+
unregister(callback) {
|
|
129
|
+
this.glTFLoader.unregister(callback);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Parse a glTF-based ArrayBuffer, JSON string or object and fire onLoad callback when complete.
|
|
133
|
+
* Calls Threejs [GLTFLoader.parse](https://threejs.org/docs/?q=gltflo#examples/en/loaders/GLTFLoader.parse) for
|
|
134
|
+
* glTF 2.0 files and LegacyGLTFLoader.parse for gtTF 1.0 files.
|
|
135
|
+
* @param {ArrayBuffer|String|Object} buffer - the glTF asset to parse, as an ArrayBuffer, JSON string or object.
|
|
136
|
+
* @param {String} path - the base path from which to find subsequent glTF resources such as textures and .bin data files.
|
|
137
|
+
* @param {Function} onLoad — A function to be called when parse completes. The argument to the onLoad function will
|
|
138
|
+
* be an Object that contains loaded parts: .scene, .scenes, .cameras, .animations, and .asset.
|
|
139
|
+
* @param {Function} [onError] — A function to be called if an error occurs during parsing. The function receives error as an argument.
|
|
140
|
+
*/
|
|
141
|
+
parse(buffer, path, onLoad, onError) {
|
|
142
|
+
if (!buffer || !path) {
|
|
143
|
+
onError('[iGLTFLoader]: Buffer and path are mandatory to parse a glTF.');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const headerView = new DataView(buffer, 0, 20);
|
|
147
|
+
const version = headerView.getUint32(4, true);
|
|
148
|
+
if (version === 1) {
|
|
149
|
+
this.legacyGLTFLoader.parse(buffer, path, onLoad, onError);
|
|
150
|
+
} else {
|
|
151
|
+
this.glTFLoader.parse(buffer, path, onLoad, onError);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Async promise-based parsing of a glTF-based ArrayBuffer, JSON string or object.
|
|
157
|
+
* @param {ArrayBuffer|String|Object} data - the glTF asset to parse, as an ArrayBuffer, JSON string or object.
|
|
158
|
+
* @param {String} path - the base path from which to find subsequent glTF resources such as textures and .bin data files.
|
|
159
|
+
* @returns {Promise<Object>} A promise that resolves an Object that contains loaded parts:
|
|
160
|
+
* .scene, .scenes, .cameras, .animations, and .asset, when parsing is done.
|
|
161
|
+
*/
|
|
162
|
+
parseAsync(data, path) {
|
|
163
|
+
const scope = this;
|
|
164
|
+
return new Promise((resolve, reject) => {
|
|
165
|
+
scope.parse(data, path, resolve, reject);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
export default iGLTFLoader;
|
|
@@ -160,10 +160,11 @@ function cleanup3dTileset(layer, n) {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
// this is a layer
|
|
163
|
-
export function pre3dTilesUpdate() {
|
|
163
|
+
export function pre3dTilesUpdate(context) {
|
|
164
164
|
if (!this.visible) {
|
|
165
165
|
return [];
|
|
166
166
|
}
|
|
167
|
+
this.scale = context.camera._preSSE;
|
|
167
168
|
|
|
168
169
|
// Elements removed are added in the layer._cleanableTiles list.
|
|
169
170
|
// Since we simply push in this array, the first item is always
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import B3dmParser from "../Parser/B3dmParser.js";
|
|
3
3
|
import PntsParser from "../Parser/PntsParser.js";
|
|
4
|
-
import GLTFParser from "../Parser/GLTFParser.js";
|
|
5
4
|
import Fetcher from "./Fetcher.js";
|
|
6
5
|
import ReferLayerProperties from "../Layer/ReferencingLayerProperties.js";
|
|
7
6
|
import PointsMaterial from "../Renderer/PointsMaterial.js";
|
|
7
|
+
// A bit weird but temporary until we remove this deprecated provider. Mainly to benefit from the enableDracoLoader and enableKtx2Loader
|
|
8
|
+
// methods.
|
|
9
|
+
import { itownsGLTFLoader } from "../Layer/OGC3DTilesLayer.js";
|
|
8
10
|
const utf8Decoder = new TextDecoder();
|
|
9
11
|
function b3dmToMesh(data, layer, url) {
|
|
10
12
|
const urlBase = THREE.LoaderUtils.extractUrlBase(url);
|
|
@@ -28,17 +30,17 @@ function b3dmToMesh(data, layer, url) {
|
|
|
28
30
|
}
|
|
29
31
|
function gltfToMesh(data, layer, url) {
|
|
30
32
|
const urlBase = THREE.LoaderUtils.extractUrlBase(url);
|
|
31
|
-
return
|
|
33
|
+
return itownsGLTFLoader.parseAsync(data, urlBase).then(result => ({
|
|
32
34
|
object3d: result.scene
|
|
33
35
|
}));
|
|
34
36
|
}
|
|
35
37
|
function pntsParse(data, layer) {
|
|
36
38
|
return PntsParser.parse(data, layer.registeredExtensions).then(result => {
|
|
37
39
|
const material = layer.material ? layer.material.clone() : new PointsMaterial({
|
|
38
|
-
size:
|
|
40
|
+
size: 1,
|
|
39
41
|
mode: layer.pntsMode,
|
|
40
42
|
shape: layer.pntsShape,
|
|
41
|
-
|
|
43
|
+
classificationScheme: layer.classification,
|
|
42
44
|
sizeMode: layer.pntsSizeMode,
|
|
43
45
|
minAttenuatedSize: layer.pntsMinAttenuatedSize,
|
|
44
46
|
maxAttenuatedSize: layer.pntsMaxAttenuatedSize
|