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.
- package/package.json +12 -0
- package/src/common/index.ts +24 -0
- package/src/common/useLine2.ts +87 -0
- package/src/common/useLoader.ts +184 -0
- package/src/common/useLocationCalculator.ts +145 -0
- package/src/common/useMark.ts +42 -0
- package/src/common/useTween.ts +86 -0
- package/src/core/basic/camera.ts +28 -0
- package/src/core/basic/clock.ts +11 -0
- package/src/core/basic/control.ts +32 -0
- package/src/core/basic/index.ts +35 -0
- package/src/core/basic/labelRenderer.ts +26 -0
- package/src/core/basic/light.ts +63 -0
- package/src/core/basic/renderer.ts +37 -0
- package/src/core/basic/scene.ts +11 -0
- package/src/core/basic/stats.ts +16 -0
- package/src/core/event.ts +74 -0
- package/src/core/index.ts +11 -0
- package/src/core/main.ts +389 -0
- package/src/draco/README.md +32 -0
- package/src/draco/draco_decoder.js +34 -0
- package/src/draco/draco_decoder.wasm +0 -0
- package/src/draco/draco_encoder.js +33 -0
- package/src/draco/draco_wasm_wrapper.js +117 -0
- package/src/draco/gltf/draco_decoder.js +33 -0
- package/src/draco/gltf/draco_decoder.wasm +0 -0
- package/src/draco/gltf/draco_encoder.js +33 -0
- package/src/draco/gltf/draco_wasm_wrapper.js +116 -0
- package/src/tileRenderer/base/Tile.d.ts +50 -0
- package/src/tileRenderer/base/TileBase.d.ts +76 -0
- package/src/tileRenderer/base/TileInternal.d.ts +36 -0
- package/src/tileRenderer/base/TilesRendererBase.d.ts +35 -0
- package/src/tileRenderer/base/TilesRendererBase.js +847 -0
- package/src/tileRenderer/base/Tileset.d.ts +66 -0
- package/src/tileRenderer/base/constants.d.ts +6 -0
- package/src/tileRenderer/base/constants.js +16 -0
- package/src/tileRenderer/base/loaders/B3DMLoaderBase.d.ts +18 -0
- package/src/tileRenderer/base/loaders/B3DMLoaderBase.js +85 -0
- package/src/tileRenderer/base/loaders/CMPTLoaderBase.d.ts +22 -0
- package/src/tileRenderer/base/loaders/CMPTLoaderBase.js +61 -0
- package/src/tileRenderer/base/loaders/I3DMLoaderBase.d.ts +21 -0
- package/src/tileRenderer/base/loaders/I3DMLoaderBase.js +130 -0
- package/src/tileRenderer/base/loaders/LoaderBase.d.ts +10 -0
- package/src/tileRenderer/base/loaders/LoaderBase.js +73 -0
- package/src/tileRenderer/base/loaders/PNTSLoaderBase.d.ts +17 -0
- package/src/tileRenderer/base/loaders/PNTSLoaderBase.js +82 -0
- package/src/tileRenderer/base/plugins/ImplicitTilingPlugin.js +12 -0
- package/src/tileRenderer/base/traverseFunctions.js +468 -0
- package/src/tileRenderer/gltf.js +144 -0
- package/src/tileRenderer/index.d.ts +41 -0
- package/src/tileRenderer/index.js +44 -0
- package/src/tileRenderer/plugins/README.md +578 -0
- package/src/tileRenderer/plugins/base/ImplicitTilingPlugin.d.ts +2 -0
- package/src/tileRenderer/plugins/base/ImplicitTilingPlugin.js +84 -0
- package/src/tileRenderer/plugins/base/SUBTREELoader.js +876 -0
- package/src/tileRenderer/plugins/index.d.ts +17 -0
- package/src/tileRenderer/plugins/index.js +17 -0
- package/src/tileRenderer/plugins/three/CesiumIonAuthPlugin.d.ts +9 -0
- package/src/tileRenderer/plugins/three/CesiumIonAuthPlugin.js +175 -0
- package/src/tileRenderer/plugins/three/DebugTilesPlugin.d.ts +29 -0
- package/src/tileRenderer/plugins/three/DebugTilesPlugin.js +677 -0
- package/src/tileRenderer/plugins/three/GLTFExtensionsPlugin.d.ts +18 -0
- package/src/tileRenderer/plugins/three/GLTFExtensionsPlugin.js +86 -0
- package/src/tileRenderer/plugins/three/GoogleAttributionsManager.js +62 -0
- package/src/tileRenderer/plugins/three/GoogleCloudAuthPlugin.d.ts +5 -0
- package/src/tileRenderer/plugins/three/GoogleCloudAuthPlugin.js +200 -0
- package/src/tileRenderer/plugins/three/ReorientationPlugin.d.ts +12 -0
- package/src/tileRenderer/plugins/three/ReorientationPlugin.js +136 -0
- package/src/tileRenderer/plugins/three/TileCompressionPlugin.d.ts +18 -0
- package/src/tileRenderer/plugins/three/TileCompressionPlugin.js +223 -0
- package/src/tileRenderer/plugins/three/UpdateOnChangePlugin.d.ts +5 -0
- package/src/tileRenderer/plugins/three/UpdateOnChangePlugin.js +87 -0
- package/src/tileRenderer/plugins/three/fade/FadeManager.js +370 -0
- package/src/tileRenderer/plugins/three/fade/TilesFadePlugin.d.ts +9 -0
- package/src/tileRenderer/plugins/three/fade/TilesFadePlugin.js +318 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFCesiumRTCExtension.d.ts +5 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFCesiumRTCExtension.js +27 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFMeshFeaturesExtension.d.ts +30 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFMeshFeaturesExtension.js +76 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFStructuralMetadataExtension.d.ts +49 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFStructuralMetadataExtension.js +147 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/ClassProperty.js +149 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/MeshFeatures.js +215 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyAttributeAccessor.js +107 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertySetAccessor.js +45 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyTableAccessor.js +209 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyTextureAccessor.js +244 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/StructuralMetadata.js +202 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/math/Matrix2.js +55 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/utilities/ClassPropertyHelpers.js +495 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/utilities/TexCoordUtilities.js +72 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/utilities/TextureReadUtility.js +154 -0
- package/src/tileRenderer/plugins/three/objects/EllipsoidRegionHelper.js +186 -0
- package/src/tileRenderer/plugins/three/objects/SphereHelper.js +55 -0
- package/src/tileRenderer/r3f/README.md +238 -0
- package/src/tileRenderer/r3f/components/CameraControls.jsx +132 -0
- package/src/tileRenderer/r3f/components/CameraTransition.jsx +177 -0
- package/src/tileRenderer/r3f/components/CanvasDOMOverlay.jsx +54 -0
- package/src/tileRenderer/r3f/components/CompassGizmo.jsx +260 -0
- package/src/tileRenderer/r3f/components/TilesAttributionOverlay.jsx +110 -0
- package/src/tileRenderer/r3f/components/TilesRenderer.jsx +239 -0
- package/src/tileRenderer/r3f/index.jsx +6 -0
- package/src/tileRenderer/r3f/utilities/useForceUpdate.jsx +8 -0
- package/src/tileRenderer/r3f/utilities/useObjectDep.jsx +59 -0
- package/src/tileRenderer/r3f/utilities/useOptions.jsx +143 -0
- package/src/tileRenderer/three/DebugTilesRenderer.d.ts +28 -0
- package/src/tileRenderer/three/DebugTilesRenderer.js +58 -0
- package/src/tileRenderer/three/TilesGroup.d.ts +9 -0
- package/src/tileRenderer/three/TilesGroup.js +91 -0
- package/src/tileRenderer/three/TilesRenderer.d.ts +37 -0
- package/src/tileRenderer/three/TilesRenderer.js +1049 -0
- package/src/tileRenderer/three/controls/CameraTransitionManager.js +305 -0
- package/src/tileRenderer/three/controls/EnvironmentControls.js +1295 -0
- package/src/tileRenderer/three/controls/GlobeControls.js +684 -0
- package/src/tileRenderer/three/controls/PivotPointMesh.js +104 -0
- package/src/tileRenderer/three/controls/PointerTracker.js +257 -0
- package/src/tileRenderer/three/controls/utils.js +113 -0
- package/src/tileRenderer/three/loaders/B3DMLoader.d.ts +26 -0
- package/src/tileRenderer/three/loaders/B3DMLoader.js +85 -0
- package/src/tileRenderer/three/loaders/CMPTLoader.d.ts +19 -0
- package/src/tileRenderer/three/loaders/CMPTLoader.js +97 -0
- package/src/tileRenderer/three/loaders/GLTFExtensionLoader.d.ts +11 -0
- package/src/tileRenderer/three/loaders/GLTFExtensionLoader.js +68 -0
- package/src/tileRenderer/three/loaders/I3DMLoader.d.ts +26 -0
- package/src/tileRenderer/three/loaders/I3DMLoader.js +256 -0
- package/src/tileRenderer/three/loaders/PNTSLoader.d.ts +25 -0
- package/src/tileRenderer/three/loaders/PNTSLoader.js +202 -0
- package/src/tileRenderer/three/loaders/gltf/GLTFCesiumRTCExtension.js +12 -0
- package/src/tileRenderer/three/loaders/gltf/GLTFMeshFeaturesExtension.js +12 -0
- package/src/tileRenderer/three/loaders/gltf/GLTFStructuralMetadataExtension.js +12 -0
- package/src/tileRenderer/three/math/Ellipsoid.d.ts +31 -0
- package/src/tileRenderer/three/math/Ellipsoid.js +337 -0
- package/src/tileRenderer/three/math/EllipsoidRegion.d.ts +23 -0
- package/src/tileRenderer/three/math/EllipsoidRegion.js +178 -0
- package/src/tileRenderer/three/math/ExtendedFrustum.js +65 -0
- package/src/tileRenderer/three/math/GeoConstants.d.ts +4 -0
- package/src/tileRenderer/three/math/GeoConstants.js +5 -0
- package/src/tileRenderer/three/math/GeoUtils.d.ts +9 -0
- package/src/tileRenderer/three/math/GeoUtils.js +106 -0
- package/src/tileRenderer/three/math/OBB.js +179 -0
- package/src/tileRenderer/three/math/TileBoundingVolume.js +272 -0
- package/src/tileRenderer/three/plugins/CesiumIonAuthPlugin.js +12 -0
- package/src/tileRenderer/three/plugins/DebugTilesPlugin.js +26 -0
- package/src/tileRenderer/three/plugins/GoogleCloudAuthPlugin.js +12 -0
- package/src/tileRenderer/three/raycastTraverse.js +178 -0
- package/src/tileRenderer/three/renderers/CesiumIonTilesRenderer.d.ts +14 -0
- package/src/tileRenderer/three/renderers/CesiumIonTilesRenderer.js +21 -0
- package/src/tileRenderer/three/renderers/GoogleTilesRenderer.d.ts +43 -0
- package/src/tileRenderer/three/renderers/GoogleTilesRenderer.js +48 -0
- package/src/tileRenderer/three/utilities.js +54 -0
- package/src/tileRenderer/utilities/BatchTable.d.ts +24 -0
- package/src/tileRenderer/utilities/BatchTable.js +82 -0
- package/src/tileRenderer/utilities/BatchTableHierarchyExtension.js +127 -0
- package/src/tileRenderer/utilities/FeatureTable.d.ts +30 -0
- package/src/tileRenderer/utilities/FeatureTable.js +159 -0
- package/src/tileRenderer/utilities/LRUCache.d.ts +8 -0
- package/src/tileRenderer/utilities/LRUCache.js +385 -0
- package/src/tileRenderer/utilities/PriorityQueue.d.ts +16 -0
- package/src/tileRenderer/utilities/PriorityQueue.js +137 -0
- package/src/tileRenderer/utilities/arrayToString.js +7 -0
- package/src/tileRenderer/utilities/readMagicBytes.js +29 -0
- package/src/tileRenderer/utilities/rgb565torgb.js +22 -0
- package/src/tileRenderer/utilities/urlExtension.js +34 -0
- package/tsconfig.json +42 -0
- package/tsconfig.node.json +11 -0
- 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
|
+
});
|