itowns 2.43.2-next.24 → 2.43.2-next.26
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/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/dist/itowns_widgets.js +1 -1
- package/examples/3dtiles_loader.html +150 -0
- package/examples/config.json +4 -0
- package/examples/jsm/.eslintrc.cjs +38 -0
- package/examples/jsm/OGC3DTilesHelper.js +105 -0
- package/examples/misc_instancing.html +2 -1
- package/lib/Core/View.js +3 -0
- package/lib/Layer/C3DTilesLayer.js +1 -1
- package/lib/Layer/OGC3DTilesLayer.js +386 -0
- package/lib/Main.js +6 -1
- package/lib/Parser/B3dmParser.js +11 -22
- package/lib/Parser/deprecated/LegacyGLTFLoader.js +25 -5
- package/lib/Parser/iGLTFLoader.js +169 -0
- package/lib/Provider/3dTilesProvider.js +4 -2
- package/lib/Renderer/PointsMaterial.js +7 -3
- package/lib/Source/OGC3DTilesGoogleSource.js +32 -0
- package/lib/Source/OGC3DTilesIonSource.js +37 -0
- package/lib/Source/OGC3DTilesSource.js +24 -0
- package/package.json +4 -3
- package/lib/Parser/GLTFParser.js +0 -88
|
@@ -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;
|
|
@@ -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,7 +30,7 @@ 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
|
}
|
|
@@ -2,7 +2,7 @@ import * as THREE from 'three';
|
|
|
2
2
|
/* babel-plugin-inline-import './Shader/PointsVS.glsl' */
|
|
3
3
|
const PointsVS = "#include <common>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec4 vColor; // color_pars_vertex\n\n#ifdef USE_POINTS_UV\n varying vec2 vUv;\n uniform mat3 uvTransform;\n#endif\n\n#define NB_CLASS 8.\n\nuniform float size;\nuniform float scale;\n\nuniform bool picking;\nuniform int mode;\n\nuniform vec2 elevationRange;\nuniform vec2 intensityRange;\nuniform vec2 angleRange;\n\nuniform sampler2D classificationTexture;\nuniform sampler2D discreteTexture;\nuniform sampler2D gradientTexture;\nuniform int sizeMode;\nuniform float minAttenuatedSize;\nuniform float maxAttenuatedSize;\n\nattribute vec4 unique_id;\nattribute float intensity;\nattribute float classification;\nattribute float pointSourceID;\n\nattribute float returnNumber;\nattribute float numberOfReturns;\nattribute float scanAngle;\n\nvoid main() {\n vColor = vec4(1.0);\n if (picking) {\n vColor = unique_id;\n } else {\n if (mode == PNTS_MODE_CLASSIFICATION) {\n vec2 uv = vec2(classification/255., 0.5);\n vColor = texture2D(classificationTexture, uv);\n } else if (mode == PNTS_MODE_NORMAL) {\n vColor.rgb = abs(normal);\n } else if (mode == PNTS_MODE_COLOR) {\n#if defined(USE_COLOR)\n vColor.rgb = color.rgb;\n#elif defined(USE_COLOR_ALPHA)\n vColor = color;\n#endif\n } else if (mode == PNTS_MODE_RETURN_NUMBER) {\n vec2 uv = vec2(returnNumber/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_RETURN_TYPE) {\n float returnType;\n if (returnNumber > numberOfReturns) {\n returnType = 4.;\n } else if (returnNumber == 1.) {\n if (numberOfReturns == 1.) {\n // single\n returnType = 0.;\n } else {\n // first\n returnType = 1.;\n }\n } else {\n if (returnNumber == numberOfReturns) {\n // last\n returnType = 3.;\n } else {\n // intermediate\n returnType = 2.;\n }\n }\n vec2 uv = vec2(returnType/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_RETURN_COUNT) {\n vec2 uv = vec2(numberOfReturns/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_POINT_SOURCE_ID) {\n vec2 uv = vec2(mod(pointSourceID, NB_CLASS)/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_SCAN_ANGLE) {\n float i = (scanAngle - angleRange.x) / (angleRange.y - angleRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n } else if (mode == PNTS_MODE_INTENSITY) {\n float i = (intensity - intensityRange.x) / (intensityRange.y - intensityRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n } else if (mode == PNTS_MODE_ELEVATION) {\n float z = (modelMatrix * vec4(position, 1.0)).z;\n float i = (z - elevationRange.x) / (elevationRange.y - elevationRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n }\n }\n\n#define USE_COLOR_ALPHA\n#include <morphcolor_vertex>\n#include <begin_vertex>\n#include <morphtarget_vertex>\n#include <project_vertex>\n\n gl_PointSize = size;\n\n if (sizeMode == PNTS_SIZE_MODE_ATTENUATED) {\n bool isPerspective = isPerspectiveMatrix(projectionMatrix);\n\n if (isPerspective) {\n gl_PointSize *= scale / -mvPosition.z;\n gl_PointSize = clamp(gl_PointSize, minAttenuatedSize, maxAttenuatedSize);\n }\n }\n\n#include <logdepthbuf_vertex>\n#include <clipping_planes_vertex>\n#include <worldpos_vertex>\n#include <fog_vertex>\n}\n";
|
|
4
4
|
/* babel-plugin-inline-import './Shader/PointsFS.glsl' */
|
|
5
|
-
const PointsFS = "#define USE_COLOR_ALPHA\n\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nuniform vec3 diffuse;\nuniform float opacity;\n\nuniform bool picking;\nuniform int shape;\n\nvoid main() {\n\n// Early discard (clipping planes and shape)\n#include <clipping_planes_pars_fragment>\n if (shape == PNTS_SHAPE_CIRCLE) {\n //circular rendering in glsl\n if ((length(gl_PointCoord - 0.5) > 0.5)
|
|
5
|
+
const PointsFS = "#define USE_COLOR_ALPHA\n\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nuniform vec3 diffuse;\nuniform float opacity;\n\nuniform bool picking;\nuniform int shape;\n\nvoid main() {\n\n// Early discard (clipping planes and shape)\n#include <clipping_planes_pars_fragment>\n if (shape == PNTS_SHAPE_CIRCLE) {\n //circular rendering in glsl\n if ((length(gl_PointCoord - 0.5) > 0.5)) {\n discard;\n }\n }\n\n#include <logdepthbuf_fragment>\n\n vec4 diffuseColor = vec4(diffuse, opacity);\n#include <map_particle_fragment>\n#include <color_fragment>\n\n#include <alphatest_fragment>\n#include <alphahash_fragment>\n\n vec3 outgoingLight = diffuseColor.rgb;\n#include <opaque_fragment> // gl_FragColor\n#include <tonemapping_fragment>\n#include <fog_fragment>\n#include <premultiplied_alpha_fragment>\n\n}\n";
|
|
6
6
|
import CommonMaterial from "./CommonMaterial.js";
|
|
7
7
|
import Gradients from "../Utils/Gradients.js";
|
|
8
8
|
export const PNTS_MODE = {
|
|
@@ -250,7 +250,7 @@ function recomputeTexture(scheme, texture, nbClass) {
|
|
|
250
250
|
data[j + 1] = parseInt(255 * color.g, 10);
|
|
251
251
|
data[j + 2] = parseInt(255 * color.b, 10);
|
|
252
252
|
data[j + 3] = visible ? parseInt(255 * opacity, 10) : 0;
|
|
253
|
-
needTransparency = needTransparency || opacity < 1;
|
|
253
|
+
needTransparency = needTransparency || opacity < 1 || !visible;
|
|
254
254
|
}
|
|
255
255
|
texture.needsUpdate = true;
|
|
256
256
|
return needTransparency;
|
|
@@ -261,7 +261,7 @@ class PointsMaterial extends THREE.ShaderMaterial {
|
|
|
261
261
|
* @param {object} [options={}] The options
|
|
262
262
|
* @param {number} [options.size=0] size point
|
|
263
263
|
* @param {number} [options.mode=PNTS_MODE.COLOR] display mode.
|
|
264
|
-
* @param {number} [options.
|
|
264
|
+
* @param {number} [options.shape=PNTS_SHAPE.CIRCLE] rendered points shape.
|
|
265
265
|
* @param {THREE.Vector4} [options.overlayColor=new THREE.Vector4(0, 0, 0, 0)] overlay color.
|
|
266
266
|
* @param {THREE.Vector2} [options.intensityRange=new THREE.Vector2(1, 65536)] intensity range.
|
|
267
267
|
* @param {THREE.Vector2} [options.elevationRange=new THREE.Vector2(0, 1000)] elevation range.
|
|
@@ -373,6 +373,9 @@ class PointsMaterial extends THREE.ShaderMaterial {
|
|
|
373
373
|
* @returns {this}
|
|
374
374
|
*/
|
|
375
375
|
copy(source) {
|
|
376
|
+
// Manually copy this needTransparency if source doesn't have one. Prevents losing it when copying a three
|
|
377
|
+
// PointsMaterial into this PointsMaterial
|
|
378
|
+
const needTransparency = source.userData.needTransparency !== undefined ? source.userData.needTransparency : this.userData.needTransparency;
|
|
376
379
|
if (source.isShaderMaterial) {
|
|
377
380
|
super.copy(source);
|
|
378
381
|
} else {
|
|
@@ -386,6 +389,7 @@ class PointsMaterial extends THREE.ShaderMaterial {
|
|
|
386
389
|
this.size = source.size;
|
|
387
390
|
this.sizeAttenuation = source.sizeAttenuation;
|
|
388
391
|
this.fog = source.fog;
|
|
392
|
+
this.userData.needTransparency = needTransparency;
|
|
389
393
|
return this;
|
|
390
394
|
}
|
|
391
395
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import OGC3DTilesSource from "./OGC3DTilesSource.js";
|
|
2
|
+
class OGC3DTilesGoogleSource extends OGC3DTilesSource {
|
|
3
|
+
/**
|
|
4
|
+
* @classdesc
|
|
5
|
+
* An object defining the source connection to a 3D Tiles asset from [Google Tiles API](https://tile.googleapis.com).
|
|
6
|
+
*
|
|
7
|
+
* @extends OGC3DTilesSource
|
|
8
|
+
*
|
|
9
|
+
* @property {boolean} isOGC3DTilesGoogleSource - Used to check if this source is an OGC3DTilesGoogleSource. Set to true.
|
|
10
|
+
* You should not change this, as it is used internally for optimisation.
|
|
11
|
+
* @property {string} url - The URL to the tileset json.
|
|
12
|
+
* @property {string} baseUrl - The base URL to access tiles.
|
|
13
|
+
*
|
|
14
|
+
* @constructor
|
|
15
|
+
*
|
|
16
|
+
* @property {boolean} isOGC3DTilesGoogleSource - Used to check if this source is an OGC3DTilesGoogleSource. Set to
|
|
17
|
+
* true. You should not change this, as it is used internally for optimisation.
|
|
18
|
+
* @param {Object} source An object that can contain all properties of an OGC3DTilesGoogleSource and {@link Source}.
|
|
19
|
+
* @param {String} source.key Your google tiles map API access key
|
|
20
|
+
*/
|
|
21
|
+
constructor(source) {
|
|
22
|
+
if (!source.key) {
|
|
23
|
+
throw new Error('[OGC3DTilesGoogleSource]: A API key for the google map tiles API is required');
|
|
24
|
+
}
|
|
25
|
+
// URL to the root tileset
|
|
26
|
+
source.url = `https://tile.googleapis.com/v1/3dtiles/root.json?key=${source.key}`;
|
|
27
|
+
super(source);
|
|
28
|
+
this.isOGC3DTilesGoogleSource = true;
|
|
29
|
+
this.key = source.key;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export default OGC3DTilesGoogleSource;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import OGC3DTilesSource from "./OGC3DTilesSource.js";
|
|
2
|
+
class OGC3DTilesIonSource extends OGC3DTilesSource {
|
|
3
|
+
/**
|
|
4
|
+
* @classdesc
|
|
5
|
+
* An object defining the source connection to a 3DTiles asset of a [Cesium ion server](https://cesium.com/learn/ion/).
|
|
6
|
+
*
|
|
7
|
+
* @extends Source
|
|
8
|
+
*
|
|
9
|
+
* @property {boolean} isOGC3DTilesIonSource - Used to check if this source is an OGC3DTilesIonSource. Set to true.
|
|
10
|
+
* You should not change this, as it is used internally for optimisation.
|
|
11
|
+
* @property {string} accessToken - The Cesium ion access token used to retrieve the resource.
|
|
12
|
+
* @property {string} assetId - The id of the asset on Cesium ion.
|
|
13
|
+
*
|
|
14
|
+
* @constructor
|
|
15
|
+
*
|
|
16
|
+
* @param {Object} source An object that can contain all properties of an OGC3DTilesIonSource and {@link Source}.
|
|
17
|
+
* Only `accessToken` and `assetId` are mandatory.
|
|
18
|
+
* @param {string} source.accessToken - The Cesium ion access token used to retrieve the resource.
|
|
19
|
+
* @param {string} source.assetId - The id of the asset on Cesium ion.
|
|
20
|
+
*/
|
|
21
|
+
constructor(source) {
|
|
22
|
+
if (!source.accessToken) {
|
|
23
|
+
throw new Error('[OGC3DTilesIonSource]: accessToken is required');
|
|
24
|
+
}
|
|
25
|
+
if (!source.assetId) {
|
|
26
|
+
throw new Error('[OGC3DTilesIonSource]: assetId is required');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Url to query cesium ion the first time to retrieve metadata of the asset with assetId
|
|
30
|
+
source.url = `https://api.cesium.com/v1/assets/${source.assetId}/endpoint?access_token=${source.accessToken}`;
|
|
31
|
+
super(source);
|
|
32
|
+
this.isOGC3DTilesIonSource = true;
|
|
33
|
+
this.accessToken = source.accessToken;
|
|
34
|
+
this.assetId = source.assetId;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export default OGC3DTilesIonSource;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Source from "./Source.js";
|
|
2
|
+
class OGC3DTilesSource extends Source {
|
|
3
|
+
/**
|
|
4
|
+
* @classdesc
|
|
5
|
+
* An object defining the source connection to a 3DTiles dataset from a web server.
|
|
6
|
+
*
|
|
7
|
+
* @extends Source
|
|
8
|
+
*
|
|
9
|
+
* @property {boolean} isOGC3DTilesSource - Used to check if this source is an isOGC3DTilesSource. Set to true.
|
|
10
|
+
* You should not change this, as it is used internally for optimisation.
|
|
11
|
+
* @property {string} url - The URL of the tileset json.
|
|
12
|
+
*
|
|
13
|
+
* @constructor
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} source An object that can contain all properties of OGC3DTilesSource and of {@link Source}.
|
|
16
|
+
* Only `url` is mandatory.
|
|
17
|
+
* @param {string} source.url - The URL of the tileset json.
|
|
18
|
+
*/
|
|
19
|
+
constructor(source) {
|
|
20
|
+
super(source);
|
|
21
|
+
this.isOGC3DTilesSource = true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export default OGC3DTilesSource;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "itowns",
|
|
3
|
-
"version": "2.43.2-next.
|
|
3
|
+
"version": "2.43.2-next.26",
|
|
4
4
|
"description": "A JS/WebGL framework for 3D geospatial data visualization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/Main.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"test-functional": "mocha -t 100000 --require test/hooks_functional.js --recursive test/functional",
|
|
19
19
|
"test-with-coverage": "c8 -n src -r html cross-env npm run test-unit",
|
|
20
20
|
"test-with-coverage_lcov": "c8 -n src --reporter=lcov cross-env npm run test-unit",
|
|
21
|
-
"base-test-unit": "cross-env BABEL_DISABLE_CACHE=1 mocha --file test/unit/bootstrap.js --
|
|
21
|
+
"base-test-unit": "cross-env BABEL_DISABLE_CACHE=1 mocha --file test/unit/bootstrap.js --import=./config/babel-register/register.mjs",
|
|
22
22
|
"build": "cross-env NODE_ENV=production webpack",
|
|
23
23
|
"build-dev": "cross-env NODE_ENV=development webpack",
|
|
24
24
|
"transpile": "cross-env BABEL_DISABLE_CACHE=1 babel src --out-dir lib",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"@mapbox/vector-tile": "^2.0.3",
|
|
62
62
|
"@tmcw/togeojson": "^5.8.1",
|
|
63
63
|
"@tweenjs/tween.js": "^23.1.2",
|
|
64
|
+
"3d-tiles-renderer": "^0.3.37",
|
|
64
65
|
"brotli-compress": "^1.3.3",
|
|
65
66
|
"copc": "^0.0.6",
|
|
66
67
|
"earcut": "^3.0.0",
|
|
@@ -88,7 +89,6 @@
|
|
|
88
89
|
"babel-plugin-minify-replace": "^0.5.0",
|
|
89
90
|
"babel-plugin-module-extension-resolver": "^1.0.0",
|
|
90
91
|
"babel-plugin-module-resolver": "^5.0.2",
|
|
91
|
-
"babel-register-esm": "^1.2.5",
|
|
92
92
|
"c8": "^10.1.2",
|
|
93
93
|
"chalk": "^5.3.0",
|
|
94
94
|
"chart.js": "^4.4.3",
|
|
@@ -116,6 +116,7 @@
|
|
|
116
116
|
"sinon": "^18.0.0",
|
|
117
117
|
"three": "^0.165.0",
|
|
118
118
|
"typescript": "^5.5.2",
|
|
119
|
+
"webgl-mock": "^0.1.7",
|
|
119
120
|
"webpack": "^5.93.0",
|
|
120
121
|
"webpack-cli": "^5.1.4",
|
|
121
122
|
"webpack-dev-server": "^5.0.4"
|
package/lib/Parser/GLTFParser.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import { GLTFLoader } from "../ThreeExtended/loaders/GLTFLoader.js";
|
|
3
|
-
import { DRACOLoader } from "../ThreeExtended/loaders/DRACOLoader.js";
|
|
4
|
-
import { KTX2Loader } from "../ThreeExtended/loaders/KTX2Loader.js";
|
|
5
|
-
import LegacyGLTFLoader from "./deprecated/LegacyGLTFLoader.js";
|
|
6
|
-
const matrixChangeUpVectorYtoZ = new THREE.Matrix4().makeRotationX(Math.PI / 2);
|
|
7
|
-
export const glTFLoader = new GLTFLoader();
|
|
8
|
-
export const legacyGLTFLoader = new LegacyGLTFLoader();
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @module GLTFParser
|
|
12
|
-
* @description Parses [glTF](https://www.khronos.org/gltf/) 1.0 and 2.0 files.
|
|
13
|
-
*
|
|
14
|
-
* Under the hood, glTF 2.0 files are parsed with THREE.GltfLoader() and GLTF 1.0 are parsed with the previous THREE
|
|
15
|
-
* GltfLoader (for 1.0 glTF) that has been kept and maintained in iTowns.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Enable loading gltf files with [Draco](https://google.github.io/draco/) geometry extension.
|
|
20
|
-
*
|
|
21
|
-
* @param {String} path path to draco library folder containing the JS and WASM decoder libraries. They can be found in
|
|
22
|
-
* [itowns examples](https://github.com/iTowns/itowns/tree/master/examples/libs/draco).
|
|
23
|
-
* @param {Object} [config] optional configuration for Draco decoder (see threejs'
|
|
24
|
-
* [setDecoderConfig](https://threejs.org/docs/index.html?q=draco#examples/en/loaders/DRACOLoader.setDecoderConfig) that
|
|
25
|
-
* is called under the hood with this configuration for details.
|
|
26
|
-
*/
|
|
27
|
-
export function enableDracoLoader(path, config) {
|
|
28
|
-
if (!path) {
|
|
29
|
-
throw new Error('Path to draco folder is mandatory');
|
|
30
|
-
}
|
|
31
|
-
const dracoLoader = new DRACOLoader();
|
|
32
|
-
dracoLoader.setDecoderPath(path);
|
|
33
|
-
if (config) {
|
|
34
|
-
dracoLoader.setDecoderConfig(config);
|
|
35
|
-
}
|
|
36
|
-
glTFLoader.setDRACOLoader(dracoLoader);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Enable loading gltf files with [KTX2](https://www.khronos.org/ktx/) texture extension.
|
|
41
|
-
*
|
|
42
|
-
* @param {String} path path to ktx2 library folder containing the JS and WASM decoder libraries. They can be found in
|
|
43
|
-
* [itowns examples](https://github.com/iTowns/itowns/tree/master/examples/libs/basis).
|
|
44
|
-
* @param {THREE.WebGLRenderer} renderer the threejs renderer
|
|
45
|
-
*/
|
|
46
|
-
export function enableKtx2Loader(path, renderer) {
|
|
47
|
-
if (!path || !renderer) {
|
|
48
|
-
throw new Error('Path to ktx2 folder and renderer are mandatory');
|
|
49
|
-
}
|
|
50
|
-
const ktx2Loader = new KTX2Loader();
|
|
51
|
-
ktx2Loader.setTranscoderPath(path);
|
|
52
|
-
ktx2Loader.detectSupport(renderer);
|
|
53
|
-
glTFLoader.setKTX2Loader(ktx2Loader);
|
|
54
|
-
}
|
|
55
|
-
export default {
|
|
56
|
-
/** Parses a gltf buffer to an object with threejs structures and applies a y-up to z-up conversion to align with
|
|
57
|
-
* itowns convention. Essentially calls THREE.GltfLoader.parse() for glTF 2.0 files and the legacy threejs parser
|
|
58
|
-
* for gtTF 1.0 files.
|
|
59
|
-
* @param {ArrayBuffer} buffer - the glTF asset to parse, as an ArrayBuffer, JSON string or object.
|
|
60
|
-
* @param {String} path - the base path from which to find subsequent glTF resources such as textures and .bin data files.
|
|
61
|
-
* @return {Promise} - a promise that resolves with an object containing an Object that contains loaded parts:
|
|
62
|
-
* .scene, .scenes, .cameras, .animations, and .asset.
|
|
63
|
-
*/
|
|
64
|
-
parse(buffer, path) {
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
if (!buffer || !path) {
|
|
67
|
-
reject(new Error('[GLTFParser]: Buffer and path are mandatory to parse a glTF.'));
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Apply y-up (gltf convention) to z-up (itowns convention) conversion
|
|
72
|
-
const onload = gltf => {
|
|
73
|
-
gltf.scene.applyMatrix4(matrixChangeUpVectorYtoZ);
|
|
74
|
-
resolve(gltf);
|
|
75
|
-
};
|
|
76
|
-
const onError = e => {
|
|
77
|
-
reject(new Error(`[GLTFParser]: Failed to parse gltf with error: ${e}`));
|
|
78
|
-
};
|
|
79
|
-
const headerView = new DataView(buffer, 0, 20);
|
|
80
|
-
const version = headerView.getUint32(4, true);
|
|
81
|
-
if (version === 1) {
|
|
82
|
-
legacyGLTFLoader.parse(buffer, path, onload, onError);
|
|
83
|
-
} else {
|
|
84
|
-
glTFLoader.parse(buffer, path, onload, onError);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
};
|