easy-three-utils 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/package.json +12 -0
  2. package/src/common/index.ts +24 -0
  3. package/src/common/useLine2.ts +87 -0
  4. package/src/common/useLoader.ts +184 -0
  5. package/src/common/useLocationCalculator.ts +145 -0
  6. package/src/common/useMark.ts +42 -0
  7. package/src/common/useTween.ts +86 -0
  8. package/src/core/basic/camera.ts +28 -0
  9. package/src/core/basic/clock.ts +11 -0
  10. package/src/core/basic/control.ts +32 -0
  11. package/src/core/basic/index.ts +35 -0
  12. package/src/core/basic/labelRenderer.ts +26 -0
  13. package/src/core/basic/light.ts +63 -0
  14. package/src/core/basic/renderer.ts +37 -0
  15. package/src/core/basic/scene.ts +11 -0
  16. package/src/core/basic/stats.ts +16 -0
  17. package/src/core/event.ts +74 -0
  18. package/src/core/index.ts +11 -0
  19. package/src/core/main.ts +389 -0
  20. package/src/draco/README.md +32 -0
  21. package/src/draco/draco_decoder.js +34 -0
  22. package/src/draco/draco_decoder.wasm +0 -0
  23. package/src/draco/draco_encoder.js +33 -0
  24. package/src/draco/draco_wasm_wrapper.js +117 -0
  25. package/src/draco/gltf/draco_decoder.js +33 -0
  26. package/src/draco/gltf/draco_decoder.wasm +0 -0
  27. package/src/draco/gltf/draco_encoder.js +33 -0
  28. package/src/draco/gltf/draco_wasm_wrapper.js +116 -0
  29. package/src/tileRenderer/base/Tile.d.ts +50 -0
  30. package/src/tileRenderer/base/TileBase.d.ts +76 -0
  31. package/src/tileRenderer/base/TileInternal.d.ts +36 -0
  32. package/src/tileRenderer/base/TilesRendererBase.d.ts +35 -0
  33. package/src/tileRenderer/base/TilesRendererBase.js +847 -0
  34. package/src/tileRenderer/base/Tileset.d.ts +66 -0
  35. package/src/tileRenderer/base/constants.d.ts +6 -0
  36. package/src/tileRenderer/base/constants.js +16 -0
  37. package/src/tileRenderer/base/loaders/B3DMLoaderBase.d.ts +18 -0
  38. package/src/tileRenderer/base/loaders/B3DMLoaderBase.js +85 -0
  39. package/src/tileRenderer/base/loaders/CMPTLoaderBase.d.ts +22 -0
  40. package/src/tileRenderer/base/loaders/CMPTLoaderBase.js +61 -0
  41. package/src/tileRenderer/base/loaders/I3DMLoaderBase.d.ts +21 -0
  42. package/src/tileRenderer/base/loaders/I3DMLoaderBase.js +130 -0
  43. package/src/tileRenderer/base/loaders/LoaderBase.d.ts +10 -0
  44. package/src/tileRenderer/base/loaders/LoaderBase.js +73 -0
  45. package/src/tileRenderer/base/loaders/PNTSLoaderBase.d.ts +17 -0
  46. package/src/tileRenderer/base/loaders/PNTSLoaderBase.js +82 -0
  47. package/src/tileRenderer/base/plugins/ImplicitTilingPlugin.js +12 -0
  48. package/src/tileRenderer/base/traverseFunctions.js +468 -0
  49. package/src/tileRenderer/gltf.js +144 -0
  50. package/src/tileRenderer/index.d.ts +41 -0
  51. package/src/tileRenderer/index.js +44 -0
  52. package/src/tileRenderer/plugins/README.md +578 -0
  53. package/src/tileRenderer/plugins/base/ImplicitTilingPlugin.d.ts +2 -0
  54. package/src/tileRenderer/plugins/base/ImplicitTilingPlugin.js +84 -0
  55. package/src/tileRenderer/plugins/base/SUBTREELoader.js +876 -0
  56. package/src/tileRenderer/plugins/index.d.ts +17 -0
  57. package/src/tileRenderer/plugins/index.js +17 -0
  58. package/src/tileRenderer/plugins/three/CesiumIonAuthPlugin.d.ts +9 -0
  59. package/src/tileRenderer/plugins/three/CesiumIonAuthPlugin.js +175 -0
  60. package/src/tileRenderer/plugins/three/DebugTilesPlugin.d.ts +29 -0
  61. package/src/tileRenderer/plugins/three/DebugTilesPlugin.js +677 -0
  62. package/src/tileRenderer/plugins/three/GLTFExtensionsPlugin.d.ts +18 -0
  63. package/src/tileRenderer/plugins/three/GLTFExtensionsPlugin.js +86 -0
  64. package/src/tileRenderer/plugins/three/GoogleAttributionsManager.js +62 -0
  65. package/src/tileRenderer/plugins/three/GoogleCloudAuthPlugin.d.ts +5 -0
  66. package/src/tileRenderer/plugins/three/GoogleCloudAuthPlugin.js +200 -0
  67. package/src/tileRenderer/plugins/three/ReorientationPlugin.d.ts +12 -0
  68. package/src/tileRenderer/plugins/three/ReorientationPlugin.js +136 -0
  69. package/src/tileRenderer/plugins/three/TileCompressionPlugin.d.ts +18 -0
  70. package/src/tileRenderer/plugins/three/TileCompressionPlugin.js +223 -0
  71. package/src/tileRenderer/plugins/three/UpdateOnChangePlugin.d.ts +5 -0
  72. package/src/tileRenderer/plugins/three/UpdateOnChangePlugin.js +87 -0
  73. package/src/tileRenderer/plugins/three/fade/FadeManager.js +370 -0
  74. package/src/tileRenderer/plugins/three/fade/TilesFadePlugin.d.ts +9 -0
  75. package/src/tileRenderer/plugins/three/fade/TilesFadePlugin.js +318 -0
  76. package/src/tileRenderer/plugins/three/gltf/GLTFCesiumRTCExtension.d.ts +5 -0
  77. package/src/tileRenderer/plugins/three/gltf/GLTFCesiumRTCExtension.js +27 -0
  78. package/src/tileRenderer/plugins/three/gltf/GLTFMeshFeaturesExtension.d.ts +30 -0
  79. package/src/tileRenderer/plugins/three/gltf/GLTFMeshFeaturesExtension.js +76 -0
  80. package/src/tileRenderer/plugins/three/gltf/GLTFStructuralMetadataExtension.d.ts +49 -0
  81. package/src/tileRenderer/plugins/three/gltf/GLTFStructuralMetadataExtension.js +147 -0
  82. package/src/tileRenderer/plugins/three/gltf/metadata/classes/ClassProperty.js +149 -0
  83. package/src/tileRenderer/plugins/three/gltf/metadata/classes/MeshFeatures.js +215 -0
  84. package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyAttributeAccessor.js +107 -0
  85. package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertySetAccessor.js +45 -0
  86. package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyTableAccessor.js +209 -0
  87. package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyTextureAccessor.js +244 -0
  88. package/src/tileRenderer/plugins/three/gltf/metadata/classes/StructuralMetadata.js +202 -0
  89. package/src/tileRenderer/plugins/three/gltf/metadata/math/Matrix2.js +55 -0
  90. package/src/tileRenderer/plugins/three/gltf/metadata/utilities/ClassPropertyHelpers.js +495 -0
  91. package/src/tileRenderer/plugins/three/gltf/metadata/utilities/TexCoordUtilities.js +72 -0
  92. package/src/tileRenderer/plugins/three/gltf/metadata/utilities/TextureReadUtility.js +154 -0
  93. package/src/tileRenderer/plugins/three/objects/EllipsoidRegionHelper.js +186 -0
  94. package/src/tileRenderer/plugins/three/objects/SphereHelper.js +55 -0
  95. package/src/tileRenderer/r3f/README.md +238 -0
  96. package/src/tileRenderer/r3f/components/CameraControls.jsx +132 -0
  97. package/src/tileRenderer/r3f/components/CameraTransition.jsx +177 -0
  98. package/src/tileRenderer/r3f/components/CanvasDOMOverlay.jsx +54 -0
  99. package/src/tileRenderer/r3f/components/CompassGizmo.jsx +260 -0
  100. package/src/tileRenderer/r3f/components/TilesAttributionOverlay.jsx +110 -0
  101. package/src/tileRenderer/r3f/components/TilesRenderer.jsx +239 -0
  102. package/src/tileRenderer/r3f/index.jsx +6 -0
  103. package/src/tileRenderer/r3f/utilities/useForceUpdate.jsx +8 -0
  104. package/src/tileRenderer/r3f/utilities/useObjectDep.jsx +59 -0
  105. package/src/tileRenderer/r3f/utilities/useOptions.jsx +143 -0
  106. package/src/tileRenderer/three/DebugTilesRenderer.d.ts +28 -0
  107. package/src/tileRenderer/three/DebugTilesRenderer.js +58 -0
  108. package/src/tileRenderer/three/TilesGroup.d.ts +9 -0
  109. package/src/tileRenderer/three/TilesGroup.js +91 -0
  110. package/src/tileRenderer/three/TilesRenderer.d.ts +37 -0
  111. package/src/tileRenderer/three/TilesRenderer.js +1049 -0
  112. package/src/tileRenderer/three/controls/CameraTransitionManager.js +305 -0
  113. package/src/tileRenderer/three/controls/EnvironmentControls.js +1295 -0
  114. package/src/tileRenderer/three/controls/GlobeControls.js +684 -0
  115. package/src/tileRenderer/three/controls/PivotPointMesh.js +104 -0
  116. package/src/tileRenderer/three/controls/PointerTracker.js +257 -0
  117. package/src/tileRenderer/three/controls/utils.js +113 -0
  118. package/src/tileRenderer/three/loaders/B3DMLoader.d.ts +26 -0
  119. package/src/tileRenderer/three/loaders/B3DMLoader.js +85 -0
  120. package/src/tileRenderer/three/loaders/CMPTLoader.d.ts +19 -0
  121. package/src/tileRenderer/three/loaders/CMPTLoader.js +97 -0
  122. package/src/tileRenderer/three/loaders/GLTFExtensionLoader.d.ts +11 -0
  123. package/src/tileRenderer/three/loaders/GLTFExtensionLoader.js +68 -0
  124. package/src/tileRenderer/three/loaders/I3DMLoader.d.ts +26 -0
  125. package/src/tileRenderer/three/loaders/I3DMLoader.js +256 -0
  126. package/src/tileRenderer/three/loaders/PNTSLoader.d.ts +25 -0
  127. package/src/tileRenderer/three/loaders/PNTSLoader.js +202 -0
  128. package/src/tileRenderer/three/loaders/gltf/GLTFCesiumRTCExtension.js +12 -0
  129. package/src/tileRenderer/three/loaders/gltf/GLTFMeshFeaturesExtension.js +12 -0
  130. package/src/tileRenderer/three/loaders/gltf/GLTFStructuralMetadataExtension.js +12 -0
  131. package/src/tileRenderer/three/math/Ellipsoid.d.ts +31 -0
  132. package/src/tileRenderer/three/math/Ellipsoid.js +337 -0
  133. package/src/tileRenderer/three/math/EllipsoidRegion.d.ts +23 -0
  134. package/src/tileRenderer/three/math/EllipsoidRegion.js +178 -0
  135. package/src/tileRenderer/three/math/ExtendedFrustum.js +65 -0
  136. package/src/tileRenderer/three/math/GeoConstants.d.ts +4 -0
  137. package/src/tileRenderer/three/math/GeoConstants.js +5 -0
  138. package/src/tileRenderer/three/math/GeoUtils.d.ts +9 -0
  139. package/src/tileRenderer/three/math/GeoUtils.js +106 -0
  140. package/src/tileRenderer/three/math/OBB.js +179 -0
  141. package/src/tileRenderer/three/math/TileBoundingVolume.js +272 -0
  142. package/src/tileRenderer/three/plugins/CesiumIonAuthPlugin.js +12 -0
  143. package/src/tileRenderer/three/plugins/DebugTilesPlugin.js +26 -0
  144. package/src/tileRenderer/three/plugins/GoogleCloudAuthPlugin.js +12 -0
  145. package/src/tileRenderer/three/raycastTraverse.js +178 -0
  146. package/src/tileRenderer/three/renderers/CesiumIonTilesRenderer.d.ts +14 -0
  147. package/src/tileRenderer/three/renderers/CesiumIonTilesRenderer.js +21 -0
  148. package/src/tileRenderer/three/renderers/GoogleTilesRenderer.d.ts +43 -0
  149. package/src/tileRenderer/three/renderers/GoogleTilesRenderer.js +48 -0
  150. package/src/tileRenderer/three/utilities.js +54 -0
  151. package/src/tileRenderer/utilities/BatchTable.d.ts +24 -0
  152. package/src/tileRenderer/utilities/BatchTable.js +82 -0
  153. package/src/tileRenderer/utilities/BatchTableHierarchyExtension.js +127 -0
  154. package/src/tileRenderer/utilities/FeatureTable.d.ts +30 -0
  155. package/src/tileRenderer/utilities/FeatureTable.js +159 -0
  156. package/src/tileRenderer/utilities/LRUCache.d.ts +8 -0
  157. package/src/tileRenderer/utilities/LRUCache.js +385 -0
  158. package/src/tileRenderer/utilities/PriorityQueue.d.ts +16 -0
  159. package/src/tileRenderer/utilities/PriorityQueue.js +137 -0
  160. package/src/tileRenderer/utilities/arrayToString.js +7 -0
  161. package/src/tileRenderer/utilities/readMagicBytes.js +29 -0
  162. package/src/tileRenderer/utilities/rgb565torgb.js +22 -0
  163. package/src/tileRenderer/utilities/urlExtension.js +34 -0
  164. package/tsconfig.json +42 -0
  165. package/tsconfig.node.json +11 -0
  166. package/typings/three.d.ts +27 -0
@@ -0,0 +1,1049 @@
1
+ import { TilesRendererBase } from '../base/TilesRendererBase.js';
2
+ import { B3DMLoader } from './loaders/B3DMLoader.js';
3
+ import { PNTSLoader } from './loaders/PNTSLoader.js';
4
+ import { I3DMLoader } from './loaders/I3DMLoader.js';
5
+ import { CMPTLoader } from './loaders/CMPTLoader.js';
6
+ import { GLTFExtensionLoader } from './loaders/GLTFExtensionLoader.js';
7
+ import { TilesGroup } from './TilesGroup.js';
8
+ import {
9
+ Matrix4,
10
+ Vector3,
11
+ Vector2,
12
+ Euler,
13
+ LoadingManager,
14
+ EventDispatcher,
15
+ REVISION,
16
+ } from 'three';
17
+ import { raycastTraverse, raycastTraverseFirstHit } from './raycastTraverse.js';
18
+ import { readMagicBytes } from '../utilities/readMagicBytes.js';
19
+ import { TileBoundingVolume } from './math/TileBoundingVolume.js';
20
+ import { ExtendedFrustum } from './math/ExtendedFrustum.js';
21
+ import { estimateBytesUsed } from './utilities.js';
22
+ import { WGS84_ELLIPSOID } from './math/GeoConstants.js';
23
+
24
+ const _mat = new Matrix4();
25
+ const _euler = new Euler();
26
+
27
+ // In three.js r165 and higher raycast traversal can be ended early
28
+ const REVISION_LESS_165 = parseInt(REVISION) < 165;
29
+ const INITIAL_FRUSTUM_CULLED = Symbol('INITIAL_FRUSTUM_CULLED');
30
+ const tempMat = new Matrix4();
31
+ const tempMat2 = new Matrix4();
32
+ const tempVector = new Vector3();
33
+ const tempVector2 = new Vector2();
34
+
35
+ const X_AXIS = new Vector3(1, 0, 0);
36
+ const Y_AXIS = new Vector3(0, 1, 0);
37
+
38
+ function updateFrustumCulled(object, toInitialValue) {
39
+
40
+ object.traverse(c => {
41
+
42
+ c.frustumCulled = c[INITIAL_FRUSTUM_CULLED] && toInitialValue;
43
+
44
+ });
45
+
46
+ }
47
+
48
+ export class TilesRenderer extends TilesRendererBase {
49
+
50
+ get autoDisableRendererCulling() {
51
+
52
+ return this._autoDisableRendererCulling;
53
+
54
+ }
55
+
56
+ set autoDisableRendererCulling(value) {
57
+
58
+ if (this._autoDisableRendererCulling !== value) {
59
+
60
+ super._autoDisableRendererCulling = value;
61
+ this.forEachLoadedModel((scene) => {
62
+
63
+ updateFrustumCulled(scene, !value);
64
+
65
+ });
66
+
67
+ }
68
+
69
+ }
70
+
71
+ constructor(...args) {
72
+
73
+ super(...args);
74
+ this.group = new TilesGroup(this);
75
+ this.ellipsoid = WGS84_ELLIPSOID.clone();
76
+ this.cameras = [];
77
+ this.cameraMap = new Map();
78
+ this.cameraInfo = [];
79
+ this.activeTiles = new Set();
80
+ this.visibleTiles = new Set();
81
+ this.optimizeRaycast = true;
82
+ this._eventDispatcher = new EventDispatcher();
83
+ this._upRotationMatrix = new Matrix4();
84
+
85
+ this.lruCache.computeMemoryUsageCallback = tile => tile.cached.bytesUsed ?? null;
86
+
87
+ // flag indicating whether frustum culling should be disabled
88
+ this._autoDisableRendererCulling = true;
89
+
90
+ // flag indicating whether tiles are actively loading so events can be fired
91
+ this._loadingTiles = false;
92
+
93
+ const manager = new LoadingManager();
94
+ manager.setURLModifier(url => {
95
+ if (this.preprocessURL) {
96
+
97
+ return this.preprocessURL(url);
98
+
99
+ } else {
100
+
101
+ return url;
102
+
103
+ }
104
+
105
+ });
106
+ this.manager = manager;
107
+
108
+ if (REVISION_LESS_165) {
109
+
110
+ // Setting up the override raycasting function to be used by
111
+ // 3D objects created by this renderer
112
+ const tilesRenderer = this;
113
+ this._overridenRaycast = function (raycaster, intersects) {
114
+
115
+ if (!tilesRenderer.optimizeRaycast) {
116
+
117
+ Object.getPrototypeOf(this).raycast.call(this, raycaster, intersects);
118
+
119
+ }
120
+
121
+ };
122
+
123
+ }
124
+
125
+ }
126
+
127
+ addEventListener(...args) {
128
+
129
+ this._eventDispatcher.addEventListener(...args);
130
+
131
+ }
132
+
133
+ hasEventListener(...args) {
134
+
135
+ this._eventDispatcher.hasEventListener(...args);
136
+
137
+ }
138
+
139
+ removeEventListener(...args) {
140
+
141
+ this._eventDispatcher.removeEventListener(...args);
142
+
143
+ }
144
+
145
+ dispatchEvent(...args) {
146
+
147
+ this._eventDispatcher.dispatchEvent(...args);
148
+
149
+ }
150
+
151
+ /* Public API */
152
+ getBounds(...args) {
153
+
154
+ console.warn('TilesRenderer: getBounds has been renamed to getBoundingBox.');
155
+ return this.getBoundingBox(...args);
156
+
157
+ }
158
+
159
+ getOrientedBounds(...args) {
160
+
161
+ console.warn('TilesRenderer: getOrientedBounds has been renamed to getOrientedBoundingBox.');
162
+ return this.getOrientedBoundingBox(...args);
163
+
164
+ }
165
+
166
+ getBoundingBox(target) {
167
+
168
+ if (!this.root) {
169
+
170
+ return false;
171
+
172
+ }
173
+
174
+ const boundingVolume = this.root.cached.boundingVolume;
175
+ if (boundingVolume) {
176
+
177
+ boundingVolume.getAABB(target);
178
+ return true;
179
+
180
+ } else {
181
+
182
+ return false;
183
+
184
+ }
185
+
186
+ }
187
+
188
+ getOrientedBoundingBox(targetBox, targetMatrix) {
189
+
190
+ if (!this.root) {
191
+
192
+ return false;
193
+
194
+ }
195
+
196
+ const boundingVolume = this.root.cached.boundingVolume;
197
+ if (boundingVolume) {
198
+
199
+ boundingVolume.getOBB(targetBox, targetMatrix);
200
+ return true;
201
+
202
+ } else {
203
+
204
+ return false;
205
+
206
+ }
207
+
208
+ }
209
+
210
+ getBoundingSphere(target) {
211
+
212
+ if (!this.root) {
213
+
214
+ return false;
215
+
216
+ }
217
+
218
+ const boundingVolume = this.root.cached.boundingVolume;
219
+ if (boundingVolume) {
220
+
221
+ boundingVolume.getSphere(target);
222
+ return true;
223
+
224
+ } else {
225
+
226
+ return false;
227
+
228
+ }
229
+
230
+ }
231
+
232
+ forEachLoadedModel(callback) {
233
+
234
+ this.traverse(tile => {
235
+
236
+ const scene = tile.cached.scene;
237
+ if (scene) {
238
+
239
+ callback(scene, tile);
240
+
241
+ }
242
+
243
+ });
244
+
245
+ }
246
+
247
+ raycast(raycaster, intersects) {
248
+
249
+ if (!this.root) {
250
+
251
+ return;
252
+
253
+ }
254
+
255
+ if (raycaster.firstHitOnly) {
256
+
257
+ const hit = raycastTraverseFirstHit(this, this.root, raycaster);
258
+ if (hit) {
259
+
260
+ intersects.push(hit);
261
+
262
+ }
263
+
264
+ } else {
265
+
266
+ raycastTraverse(this, this.root, raycaster, intersects);
267
+
268
+ }
269
+
270
+ }
271
+
272
+ hasCamera(camera) {
273
+
274
+ return this.cameraMap.has(camera);
275
+
276
+ }
277
+
278
+ setCamera(camera) {
279
+
280
+ const cameras = this.cameras;
281
+ const cameraMap = this.cameraMap;
282
+ if (!cameraMap.has(camera)) {
283
+
284
+ cameraMap.set(camera, new Vector2());
285
+ cameras.push(camera);
286
+ this.dispatchEvent({ type: 'add-camera', camera });
287
+
288
+ return true;
289
+
290
+ }
291
+ return false;
292
+
293
+ }
294
+
295
+ setResolution(camera, xOrVec, y) {
296
+
297
+ const cameraMap = this.cameraMap;
298
+ if (!cameraMap.has(camera)) {
299
+
300
+ return false;
301
+
302
+ }
303
+
304
+ const width = xOrVec.isVector2 ? xOrVec.x : xOrVec;
305
+ const height = xOrVec.isVector2 ? xOrVec.y : y;
306
+ const cameraVec = cameraMap.get(camera);
307
+
308
+ if (cameraVec.width !== width || cameraVec.height !== height) {
309
+
310
+ cameraVec.set(width, height);
311
+ this.dispatchEvent({ type: 'camera-resolution-change' });
312
+
313
+ }
314
+
315
+ return true;
316
+
317
+ }
318
+
319
+ setResolutionFromRenderer(camera, renderer) {
320
+
321
+ renderer
322
+ .getSize(tempVector2)
323
+ .multiplyScalar(renderer.getPixelRatio());
324
+
325
+ return this.setResolution(camera, tempVector2.x, tempVector2.y);
326
+
327
+ }
328
+
329
+ deleteCamera(camera) {
330
+
331
+ const cameras = this.cameras;
332
+ const cameraMap = this.cameraMap;
333
+ if (cameraMap.has(camera)) {
334
+
335
+ const index = cameras.indexOf(camera);
336
+ cameras.splice(index, 1);
337
+ cameraMap.delete(camera);
338
+ this.dispatchEvent({ type: 'delete-camera', camera });
339
+
340
+ return true;
341
+
342
+ }
343
+ return false;
344
+
345
+ }
346
+
347
+ /* Overriden */
348
+ preprocessTileSet(json, url, tile) {
349
+
350
+ super.preprocessTileSet(json, url, tile);
351
+
352
+ queueMicrotask(() => {
353
+
354
+ this.dispatchEvent({
355
+ type: 'load-tile-set',
356
+ tileSet: json,
357
+ url,
358
+ });
359
+
360
+ });
361
+
362
+ }
363
+
364
+ loadRootTileSet(...args) {
365
+
366
+ return super.loadRootTileSet(...args)
367
+ .then(() => {
368
+
369
+ // cache the gltf tile set rotation matrix
370
+ const upAxis = this.rootTileSet.asset && this.rootTileSet.asset.gltfUpAxis || 'y';
371
+ switch (upAxis.toLowerCase()) {
372
+
373
+ case 'x':
374
+ this._upRotationMatrix.makeRotationAxis(Y_AXIS, - Math.PI / 2);
375
+ break;
376
+
377
+ case 'y':
378
+ this._upRotationMatrix.makeRotationAxis(X_AXIS, Math.PI / 2);
379
+ break;
380
+
381
+ }
382
+
383
+ this.dispatchEvent({ type: 'load-content' });
384
+
385
+ });
386
+
387
+ }
388
+
389
+ update() {
390
+
391
+ // check if the plugins that can block the tile updates require it
392
+ let needsUpdate = null;
393
+ this.invokeAllPlugins(plugin => {
394
+
395
+ if (plugin.doTilesNeedUpdate) {
396
+
397
+ const res = plugin.doTilesNeedUpdate();
398
+ needsUpdate = needsUpdate === null ? res : needsUpdate || res;
399
+
400
+ }
401
+
402
+ });
403
+
404
+ if (needsUpdate === false) {
405
+
406
+ this.dispatchEvent({ type: 'update-before' });
407
+ this.dispatchEvent({ type: 'update-after' });
408
+ return;
409
+
410
+ }
411
+
412
+ // follow through with the update
413
+ this.dispatchEvent({ type: 'update-before' });
414
+
415
+ const group = this.group;
416
+ const cameras = this.cameras;
417
+ const cameraMap = this.cameraMap;
418
+ const cameraInfo = this.cameraInfo;
419
+
420
+ if (cameras.length === 0) {
421
+
422
+ console.warn('TilesRenderer: no cameras defined. Cannot update 3d tiles.');
423
+ return;
424
+
425
+ }
426
+
427
+ // automatically scale the array of cameraInfo to match the cameras
428
+ while (cameraInfo.length > cameras.length) {
429
+
430
+ cameraInfo.pop();
431
+
432
+ }
433
+
434
+ while (cameraInfo.length < cameras.length) {
435
+
436
+ cameraInfo.push({
437
+
438
+ frustum: new ExtendedFrustum(),
439
+ isOrthographic: false,
440
+ sseDenominator: - 1, // used if isOrthographic:false
441
+ position: new Vector3(),
442
+ invScale: - 1,
443
+ pixelSize: 0, // used if isOrthographic:true
444
+
445
+ });
446
+
447
+ }
448
+
449
+ // extract scale of group container
450
+ tempMat2.copy(group.matrixWorld).invert();
451
+
452
+ tempVector.setFromMatrixScale(tempMat2);
453
+ if (Math.abs(Math.max(tempVector.x - tempVector.y, tempVector.x - tempVector.z)) > 1e-6) {
454
+
455
+ console.warn('ThreeTilesRenderer : Non uniform scale used for tile which may cause issues when calculating screen space error.');
456
+
457
+ }
458
+
459
+ // store the camera cameraInfo in the 3d tiles root frame
460
+ for (let i = 0, l = cameraInfo.length; i < l; i++) {
461
+
462
+ const camera = cameras[i];
463
+ const info = cameraInfo[i];
464
+ const frustum = info.frustum;
465
+ const position = info.position;
466
+ const resolution = cameraMap.get(camera);
467
+
468
+ if (resolution.width === 0 || resolution.height === 0) {
469
+
470
+ console.warn('TilesRenderer: resolution for camera error calculation is not set.');
471
+
472
+ }
473
+
474
+ // Read the calculated projection matrix directly to support custom Camera implementations
475
+ const projection = camera.projectionMatrix.elements;
476
+
477
+ // The last element of the projection matrix is 1 for orthographic, 0 for perspective
478
+ info.isOrthographic = projection[15] === 1;
479
+
480
+ if (info.isOrthographic) {
481
+
482
+ // See OrthographicCamera.updateProjectionMatrix and Matrix4.makeOrthographic:
483
+ // the view width and height are used to populate matrix elements 0 and 5.
484
+ const w = 2 / projection[0];
485
+ const h = 2 / projection[5];
486
+ info.pixelSize = Math.max(h / resolution.height, w / resolution.width);
487
+
488
+ } else {
489
+
490
+ // See PerspectiveCamera.updateProjectionMatrix and Matrix4.makePerspective:
491
+ // the vertical FOV is used to populate matrix element 5.
492
+ info.sseDenominator = (2 / projection[5]) / resolution.height;
493
+
494
+ }
495
+
496
+ // get frustum in group root frame
497
+ tempMat.copy(group.matrixWorld);
498
+ tempMat.premultiply(camera.matrixWorldInverse);
499
+ tempMat.premultiply(camera.projectionMatrix);
500
+
501
+ frustum.setFromProjectionMatrix(tempMat);
502
+
503
+ // get transform position in group root frame
504
+ position.set(0, 0, 0);
505
+ position.applyMatrix4(camera.matrixWorld);
506
+ position.applyMatrix4(tempMat2);
507
+
508
+ }
509
+
510
+ super.update();
511
+
512
+ this.dispatchEvent({ type: 'update-after' });
513
+
514
+ }
515
+
516
+ preprocessNode(tile, tileSetDir, parentTile = null) {
517
+
518
+ super.preprocessNode(tile, tileSetDir, parentTile);
519
+
520
+ const transform = new Matrix4();
521
+ if (tile.transform) {
522
+
523
+ const transformArr = tile.transform;
524
+ for (let i = 0; i < 16; i++) {
525
+
526
+ transform.elements[i] = transformArr[i];
527
+
528
+ }
529
+
530
+ }
531
+
532
+ if (parentTile) {
533
+
534
+ transform.premultiply(parentTile.cached.transform);
535
+
536
+ }
537
+
538
+ const transformInverse = new Matrix4().copy(transform).invert();
539
+ const boundingVolume = new TileBoundingVolume();
540
+ if ('sphere' in tile.boundingVolume) {
541
+
542
+ boundingVolume.setSphereData(...tile.boundingVolume.sphere, transform);
543
+
544
+ }
545
+
546
+ if ('box' in tile.boundingVolume) {
547
+
548
+ boundingVolume.setObbData(tile.boundingVolume.box, transform);
549
+
550
+ }
551
+
552
+ if ('region' in tile.boundingVolume) {
553
+
554
+ boundingVolume.setRegionData(this.ellipsoid, ...tile.boundingVolume.region);
555
+
556
+ }
557
+
558
+ tile.cached = {
559
+
560
+ _loadIndex: 0,
561
+ transform,
562
+ transformInverse,
563
+
564
+ active: false,
565
+
566
+ boundingVolume,
567
+
568
+ metadata: null,
569
+ scene: null,
570
+ geometry: null,
571
+ materials: null,
572
+ textures: null,
573
+
574
+ };
575
+
576
+ }
577
+
578
+ async requestTileContents(...args) {
579
+
580
+ await super.requestTileContents(...args);
581
+ this.dispatchEvent({ type: 'load-content' });
582
+
583
+ }
584
+
585
+ async parseTile(buffer, tile, extension, uri) {
586
+
587
+ const cached = tile.cached;
588
+ cached._loadIndex++;
589
+
590
+ const uriSplits = uri.split(/[\\/]/g);
591
+ uriSplits.pop();
592
+ const workingPath = uriSplits.join('/');
593
+ const fetchOptions = this.fetchOptions;
594
+
595
+ const manager = this.manager;
596
+ const loadIndex = cached._loadIndex;
597
+ let promise = null;
598
+
599
+ const cachedTransform = cached.transform;
600
+ const upRotationMatrix = this._upRotationMatrix;
601
+ const fileType = (readMagicBytes(buffer) || extension).toLowerCase();
602
+ switch (fileType) {
603
+
604
+ case 'b3dm': {
605
+
606
+ const loader = new B3DMLoader(manager);
607
+ loader.workingPath = workingPath;
608
+ loader.fetchOptions = fetchOptions;
609
+
610
+ loader.adjustmentTransform.copy(upRotationMatrix);
611
+
612
+ promise = loader.parse(buffer);
613
+ break;
614
+
615
+ }
616
+
617
+ case 'pnts': {
618
+
619
+ const loader = new PNTSLoader(manager);
620
+ loader.workingPath = workingPath;
621
+ loader.fetchOptions = fetchOptions;
622
+ promise = loader.parse(buffer);
623
+ break;
624
+
625
+ }
626
+
627
+ case 'i3dm': {
628
+
629
+ const loader = new I3DMLoader(manager);
630
+ loader.workingPath = workingPath;
631
+ loader.fetchOptions = fetchOptions;
632
+
633
+ loader.adjustmentTransform.copy(upRotationMatrix);
634
+ loader.ellipsoid.copy(this.ellipsoid);
635
+
636
+ promise = loader.parse(buffer);
637
+ break;
638
+
639
+ }
640
+
641
+ case 'cmpt': {
642
+
643
+ const loader = new CMPTLoader(manager);
644
+ loader.workingPath = workingPath;
645
+ loader.fetchOptions = fetchOptions;
646
+
647
+ loader.adjustmentTransform.copy(upRotationMatrix);
648
+ loader.ellipsoid.copy(this.ellipsoid);
649
+
650
+ promise = loader
651
+ .parse(buffer)
652
+ .then(res => res.scene);
653
+ break;
654
+
655
+ }
656
+
657
+ // 3DTILES_content_gltf
658
+ case 'gltf':
659
+ case 'glb': {
660
+
661
+ const loader = new GLTFExtensionLoader(manager);
662
+ loader.workingPath = workingPath;
663
+ loader.fetchOptions = fetchOptions;
664
+ promise = loader.parse(buffer);
665
+ break;
666
+
667
+ }
668
+
669
+ default:
670
+ console.warn(`TilesRenderer: Content type "${fileType}" not supported.`);
671
+ promise = Promise.resolve(null);
672
+ break;
673
+
674
+ }
675
+
676
+ // check if this is the beginning of a new set of tiles to load and dispatch and event
677
+ const stats = this.stats;
678
+ if (this._loadingTiles === false && stats.parsing + stats.downloading > 0) {
679
+
680
+ this.dispatchEvent({ type: 'tiles-load-start' });
681
+ this._loadingTiles = true;
682
+
683
+ }
684
+
685
+ // wait for the tile to load
686
+ const result = await promise;
687
+
688
+ // get the scene data
689
+ let scene;
690
+ let metadata;
691
+ if (result.isObject3D) {
692
+
693
+ scene = result;
694
+ metadata = null;
695
+
696
+ } else {
697
+
698
+ scene = result.scene;
699
+ metadata = result;
700
+
701
+ }
702
+
703
+ // wait for extra processing by plugins if needed
704
+ await this.invokeAllPlugins(plugin => {
705
+
706
+ return plugin.processTileModel && plugin.processTileModel(scene, tile);
707
+
708
+ });
709
+
710
+ // exit early if a new request has already started
711
+ if (cached._loadIndex !== loadIndex) {
712
+
713
+ return;
714
+
715
+ }
716
+
717
+ // ensure the matrix is up to date in case the scene has a transform applied
718
+ scene.updateMatrix();
719
+
720
+ // apply the local up-axis correction rotation
721
+ // GLTFLoader seems to never set a transformation on the root scene object so
722
+ // any transformations applied to it can be assumed to be applied after load
723
+ // (such as applying RTC_CENTER) meaning they should happen _after_ the z-up
724
+ // rotation fix which is why "multiply" happens here.
725
+ if (fileType === 'glb' || fileType === 'gltf') {
726
+
727
+ scene.matrix.multiply(upRotationMatrix);
728
+
729
+ }
730
+
731
+ scene.matrix.premultiply(cachedTransform);
732
+ scene.matrix.decompose(scene.position, scene.quaternion, scene.scale);
733
+ scene.traverse(c => {
734
+
735
+ c[INITIAL_FRUSTUM_CULLED] = c.frustumCulled;
736
+
737
+ });
738
+ updateFrustumCulled(scene, !this.autoDisableRendererCulling);
739
+
740
+ if (REVISION_LESS_165) {
741
+
742
+ // We handle raycasting in a custom way so remove it from here
743
+ scene.traverse(c => {
744
+
745
+ c.raycast = this._overridenRaycast;
746
+
747
+ });
748
+
749
+ }
750
+
751
+ const materials = [];
752
+ const geometry = [];
753
+ const textures = [];
754
+ scene.traverse(c => {
755
+
756
+ if (c.geometry) {
757
+
758
+ geometry.push(c.geometry);
759
+
760
+ }
761
+
762
+ if (c.material) {
763
+
764
+ const material = c.material;
765
+ materials.push(c.material);
766
+
767
+ for (const key in material) {
768
+
769
+ const value = material[key];
770
+ if (value && value.isTexture) {
771
+
772
+ textures.push(value);
773
+
774
+ }
775
+
776
+ }
777
+
778
+ }
779
+
780
+ });
781
+
782
+ cached.materials = materials;
783
+ cached.geometry = geometry;
784
+ cached.textures = textures;
785
+ cached.scene = scene;
786
+ cached.metadata = metadata;
787
+ cached.bytesUsed = estimateBytesUsed(scene);
788
+
789
+ // dispatch an event indicating that this model has completed
790
+ this.dispatchEvent({
791
+ type: 'load-model',
792
+ scene,
793
+ tile,
794
+ });
795
+
796
+ // dispatch an "end" event if all tiles have finished loading
797
+ if (this._loadingTiles === true && stats.parsing + stats.downloading === 1) {
798
+
799
+ this.dispatchEvent({ type: 'tiles-load-end' });
800
+ this._loadingTiles = false;
801
+
802
+ }
803
+
804
+ }
805
+
806
+ disposeTile(tile) {
807
+
808
+ super.disposeTile(tile);
809
+
810
+ // This could get called before the tile has finished downloading
811
+ const cached = tile.cached;
812
+ if (cached.scene) {
813
+
814
+ const materials = cached.materials;
815
+ const geometry = cached.geometry;
816
+ const textures = cached.textures;
817
+ const parent = cached.scene.parent;
818
+
819
+ // dispose of any textures required by the mesh features extension
820
+ cached.scene.traverse(child => {
821
+
822
+ if (child.userData.meshFeatures) {
823
+
824
+ child.userData.meshFeatures.dispose();
825
+
826
+ }
827
+
828
+ if (child.userData.structuralMetadata) {
829
+
830
+ child.userData.structuralMetadata.dispose();
831
+
832
+ }
833
+
834
+ });
835
+
836
+ for (let i = 0, l = geometry.length; i < l; i++) {
837
+
838
+ geometry[i].dispose();
839
+
840
+ }
841
+
842
+ for (let i = 0, l = materials.length; i < l; i++) {
843
+
844
+ materials[i].dispose();
845
+
846
+ }
847
+
848
+ for (let i = 0, l = textures.length; i < l; i++) {
849
+
850
+ const texture = textures[i];
851
+
852
+ if (texture.image instanceof ImageBitmap) {
853
+
854
+ texture.image.close();
855
+
856
+ }
857
+
858
+ texture.dispose();
859
+
860
+ }
861
+
862
+ if (parent) {
863
+
864
+ parent.remove(cached.scene);
865
+
866
+ }
867
+
868
+ this.dispatchEvent({
869
+ type: 'dispose-model',
870
+ scene: cached.scene,
871
+ tile,
872
+ });
873
+
874
+ cached.scene = null;
875
+ cached.materials = null;
876
+ cached.textures = null;
877
+ cached.geometry = null;
878
+ cached.metadata = null;
879
+
880
+ }
881
+
882
+ cached._loadIndex++;
883
+
884
+ }
885
+
886
+ setTileVisible(tile, visible) {
887
+
888
+ const scene = tile.cached.scene;
889
+ const visibleTiles = this.visibleTiles;
890
+ const group = this.group;
891
+ if (visible) {
892
+
893
+ group.add(scene);
894
+ visibleTiles.add(tile);
895
+ scene.updateMatrixWorld(true);
896
+
897
+ } else {
898
+
899
+ group.remove(scene);
900
+ visibleTiles.delete(tile);
901
+
902
+ }
903
+
904
+ this.dispatchEvent({
905
+ type: 'tile-visibility-change',
906
+ scene,
907
+ tile,
908
+ visible,
909
+ });
910
+
911
+ }
912
+
913
+ setTileActive(tile, active) {
914
+
915
+ const activeTiles = this.activeTiles;
916
+ if (active) {
917
+
918
+ activeTiles.add(tile);
919
+
920
+ } else {
921
+
922
+ activeTiles.delete(tile);
923
+
924
+ }
925
+
926
+ }
927
+
928
+ calculateError(tile) {
929
+
930
+ const cached = tile.cached;
931
+ const cameras = this.cameras;
932
+ const cameraInfo = this.cameraInfo;
933
+ const boundingVolume = cached.boundingVolume;
934
+
935
+ let maxError = - Infinity;
936
+ let minDistance = Infinity;
937
+
938
+ for (let i = 0, l = cameras.length; i < l; i++) {
939
+
940
+ // transform camera position into local frame of the tile bounding box
941
+ const info = cameraInfo[i];
942
+ let error;
943
+ if (info.isOrthographic) {
944
+
945
+ const pixelSize = info.pixelSize;
946
+ error = tile.geometricError / pixelSize;
947
+
948
+ } else {
949
+
950
+ const distance = boundingVolume.distanceToPoint(info.position);
951
+ const sseDenominator = info.sseDenominator;
952
+ error = tile.geometricError / (distance * sseDenominator);
953
+
954
+ minDistance = Math.min(minDistance, distance);
955
+
956
+ }
957
+
958
+ maxError = Math.max(maxError, error);
959
+
960
+ }
961
+
962
+ tile.__distanceFromCamera = minDistance;
963
+ tile.__error = maxError;
964
+
965
+ }
966
+
967
+ tileInView(tile) {
968
+
969
+ const cached = tile.cached;
970
+ const boundingVolume = cached.boundingVolume;
971
+ const cameraInfo = this.cameraInfo;
972
+ for (let i = 0, l = cameraInfo.length; i < l; i++) {
973
+
974
+ // Track which camera frustums this tile is in so we can use it
975
+ // to ignore the error calculations for cameras that can't see it
976
+ const frustum = cameraInfo[i].frustum;
977
+ if (boundingVolume.intersectsFrustum(frustum)) {
978
+
979
+ return true;
980
+
981
+ }
982
+
983
+ }
984
+
985
+ return false;
986
+
987
+ }
988
+
989
+ // TODO: deprecate this function and provide a plugin to help with this
990
+ // adjust the rotation of the group such that Y is altitude, X is North, and Z is East
991
+ setLatLonToYUp(lat, lon) {
992
+
993
+ const { ellipsoid, group } = this;
994
+
995
+ _euler.set(Math.PI / 2, Math.PI / 2, 0);
996
+ _mat.makeRotationFromEuler(_euler);
997
+
998
+ ellipsoid.getEastNorthUpFrame(lat, lon, group.matrix)
999
+ .multiply(_mat)
1000
+ .invert()
1001
+ .decompose(
1002
+ group.position,
1003
+ group.quaternion,
1004
+ group.scale,
1005
+ );
1006
+
1007
+ group.updateMatrixWorld(true);
1008
+
1009
+ }
1010
+
1011
+ }
1012
+
1013
+
1014
+ [
1015
+ ['onLoadTileSet', 'load-tile-set'],
1016
+ ['onLoadModel', 'load-model'],
1017
+ ['onDisposeModel', 'dispose-model'],
1018
+ ['onTileVisibilityChange', 'tile-visibility-change'],
1019
+ ].forEach(([methodName, eventName]) => {
1020
+
1021
+ const cachedName = Symbol(methodName);
1022
+ Object.defineProperty(
1023
+ TilesRenderer.prototype,
1024
+ methodName,
1025
+ {
1026
+ get() {
1027
+
1028
+ return this[cachedName] || null;
1029
+
1030
+ },
1031
+
1032
+ set(cb) {
1033
+
1034
+ console.warn(`TilesRenderer: "${methodName}" has been deprecated in favor of the "${eventName}" event.`);
1035
+
1036
+ if (this[cachedName]) {
1037
+
1038
+ this.removeEventListener(eventName, this[cachedName]);
1039
+
1040
+ }
1041
+
1042
+ this[cachedName] = cb;
1043
+ this.addEventListener(eventName, cb);
1044
+
1045
+ }
1046
+ }
1047
+ );
1048
+
1049
+ });