@eturnity/eturnity_3d 9.13.0-google3dTile.0 → 9.13.0-google3dTile.2
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 +1 -1
- package/src/Overlay/Google3DTilesOverlay.js +306 -76
package/package.json
CHANGED
|
@@ -20,20 +20,6 @@ import {
|
|
|
20
20
|
TileCompressionPlugin,
|
|
21
21
|
} from '3d-tiles-renderer/plugins'
|
|
22
22
|
|
|
23
|
-
/** Set DoubleSide on every mesh material in a loaded 3D Tiles scene */
|
|
24
|
-
function applyDoubleSideToTileScene(scene) {
|
|
25
|
-
if (!scene) return
|
|
26
|
-
scene.traverse((object) => {
|
|
27
|
-
if (!object.isMesh || !object.material) return
|
|
28
|
-
const materials = Array.isArray(object.material)
|
|
29
|
-
? object.material
|
|
30
|
-
: [object.material]
|
|
31
|
-
for (const mat of materials) {
|
|
32
|
-
if (mat) mat.side = THREE.DoubleSide
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
23
|
/**
|
|
38
24
|
* Max screen-space error for tile refinement (3d-tiles-renderer).
|
|
39
25
|
* Lower = finer meshes for tiles inside {@link Google3DTilesOverlay#_tilesCamera}'s frustum.
|
|
@@ -41,6 +27,15 @@ function applyDoubleSideToTileScene(scene) {
|
|
|
41
27
|
*/
|
|
42
28
|
const TILES_FRUSTUM_ERROR_TARGET = 4
|
|
43
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Draw after merged base / roofs (renderOrder 10) and edges (15) so transparent
|
|
32
|
+
* tiles blend with geometry already in the color buffer instead of hiding it.
|
|
33
|
+
*/
|
|
34
|
+
const GOOGLE_TILES_RENDER_ORDER = 25
|
|
35
|
+
|
|
36
|
+
/** Extra meters padded on each side of roof AABB for tile loading frustum */
|
|
37
|
+
const ROOFS_BOUNDS_MARGIN_M = 5
|
|
38
|
+
|
|
44
39
|
/** Same rhythm as ThreeDModelOverlay.animatePlaceholder (sin² on time) */
|
|
45
40
|
function placeholderBounceScale(timeSeconds) {
|
|
46
41
|
const baseRadius = 0.65
|
|
@@ -67,28 +62,30 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
67
62
|
// Dedicated camera for tile loading and resolution so the user's camera does not affect which tiles load
|
|
68
63
|
// Orthographic camera looking down (Z up), covering -50 to +50 meters in X and Y
|
|
69
64
|
this._tilesCamera = new THREE.OrthographicCamera(
|
|
70
|
-
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
65
|
+
-10,
|
|
66
|
+
10,
|
|
67
|
+
10,
|
|
68
|
+
-10,
|
|
74
69
|
0.1,
|
|
75
70
|
10000
|
|
76
71
|
)
|
|
77
72
|
this._tilesCamera.position.set(0, 0, -100)
|
|
78
73
|
this._tilesCamera.lookAt(0, 0, 0)
|
|
79
74
|
this._tilesCamera.updateMatrixWorld(true)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
this.
|
|
75
|
+
/** @type {{ xMin: number, xMax: number, yMin: number, yMax: number, zMin?: number, zMax?: number } | null} mm — same shape as Vuex getRoofsBounds (three-d-module) */
|
|
76
|
+
this.roofsBound = null
|
|
77
|
+
/** Padded roof-bounds center (m), same as tile camera look-at XY — placeholder sits at (cx, cy, 0) */
|
|
78
|
+
this._placeholderCenterX = 0
|
|
79
|
+
this._placeholderCenterY = 0
|
|
80
|
+
this._rayDirDown = new THREE.Vector3(0, 0, 1)
|
|
81
|
+
this._defaultTilesCamZ = -100
|
|
82
|
+
this._defaultOrthoHalfExtentM = 10
|
|
87
83
|
this.sphereMesh = null
|
|
88
84
|
/** Transparent bouncing sphere at origin; removed once ground align settles */
|
|
89
85
|
this._groundAlignPlaceholderMesh = null
|
|
90
86
|
/** True when raycast tile bbox min.z is within ±10 after stick-to-ground */
|
|
91
|
-
this.
|
|
87
|
+
this.tilesFullyLoaded = false
|
|
88
|
+
this.scene = null
|
|
92
89
|
}
|
|
93
90
|
getOverlayMeshForRaycast() {
|
|
94
91
|
return this.tilesData?.tiles.group
|
|
@@ -98,24 +95,95 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
98
95
|
return true
|
|
99
96
|
}
|
|
100
97
|
|
|
98
|
+
_roofsBoundsAreEqual(a, b) {
|
|
99
|
+
if (a === b) return true
|
|
100
|
+
if (!a || !b) return false
|
|
101
|
+
return (
|
|
102
|
+
a.xMin === b.xMin &&
|
|
103
|
+
a.xMax === b.xMax &&
|
|
104
|
+
a.yMin === b.yMin &&
|
|
105
|
+
a.yMax === b.yMax
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
101
109
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
110
|
+
* Store roof AABB (mm) and fit {@link #_tilesCamera} to it (ortho frustum in m).
|
|
111
|
+
* Bounds shape matches Vuex `getRoofsBounds` in `three-d-module.js`.
|
|
112
|
+
* Camera sits above the bounds center; left/right/top/bottom are set so the world XY
|
|
113
|
+
* footprint matches [xMin,xMax]×[yMin,yMax] in meters (same convention as ThreeCanvas orthographic).
|
|
114
|
+
*
|
|
115
|
+
* @param {{ xMin: number, xMax: number, yMin: number, yMax: number, zMin?: number, zMax?: number } | null | undefined} boundsMm
|
|
104
116
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
updateRoofsBound(boundsMm) {
|
|
118
|
+
this._tilesGroundAligned = false
|
|
119
|
+
if (
|
|
120
|
+
!boundsMm ||
|
|
121
|
+
!Number.isFinite(boundsMm.xMin) ||
|
|
122
|
+
boundsMm.xMin === Infinity
|
|
123
|
+
) {
|
|
124
|
+
this.roofsBound = null
|
|
125
|
+
const h = this._defaultOrthoHalfExtentM
|
|
126
|
+
const cam = this._tilesCamera
|
|
127
|
+
const z = this._defaultTilesCamZ
|
|
128
|
+
cam.position.set(0, 0, z)
|
|
129
|
+
cam.left = -h
|
|
130
|
+
cam.right = h
|
|
131
|
+
cam.top = h
|
|
132
|
+
cam.bottom = -h
|
|
133
|
+
cam.lookAt(0, 0, 0)
|
|
134
|
+
cam.updateProjectionMatrix()
|
|
135
|
+
cam.updateMatrixWorld(true)
|
|
136
|
+
this._placeholderCenterX = 0
|
|
137
|
+
this._placeholderCenterY = 0
|
|
138
|
+
this._syncPlaceholderWorldXY()
|
|
139
|
+
return
|
|
140
|
+
}
|
|
110
141
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
142
|
+
this.roofsBound = {
|
|
143
|
+
xMin: boundsMm.xMin,
|
|
144
|
+
xMax: boundsMm.xMax,
|
|
145
|
+
yMin: boundsMm.yMin,
|
|
146
|
+
yMax: boundsMm.yMax,
|
|
147
|
+
zMin: boundsMm.zMin,
|
|
148
|
+
zMax: boundsMm.zMax,
|
|
117
149
|
}
|
|
118
|
-
|
|
150
|
+
|
|
151
|
+
const m = ROOFS_BOUNDS_MARGIN_M
|
|
152
|
+
const xMinM = boundsMm.xMin / 1000 - m
|
|
153
|
+
const xMaxM = boundsMm.xMax / 1000 + m
|
|
154
|
+
const yMinM = boundsMm.yMin / 1000 - m
|
|
155
|
+
const yMaxM = boundsMm.yMax / 1000 + m
|
|
156
|
+
|
|
157
|
+
const cx = (xMinM + xMaxM) / 2
|
|
158
|
+
const cy = (yMinM + yMaxM) / 2
|
|
159
|
+
|
|
160
|
+
let halfW = (xMaxM - xMinM) / 2
|
|
161
|
+
let halfH = (yMaxM - yMinM) / 2
|
|
162
|
+
const minHalf = 100
|
|
163
|
+
if (halfW < minHalf) halfW = minHalf
|
|
164
|
+
if (halfH < minHalf) halfH = minHalf
|
|
165
|
+
|
|
166
|
+
const cam = this._tilesCamera
|
|
167
|
+
const z = this._defaultTilesCamZ
|
|
168
|
+
cam.position.set(cx, cy, z)
|
|
169
|
+
cam.left = xMinM - cx
|
|
170
|
+
cam.right = xMaxM - cx
|
|
171
|
+
cam.top = yMaxM - cy
|
|
172
|
+
cam.bottom = yMinM - cy
|
|
173
|
+
cam.lookAt(cx, cy, 0)
|
|
174
|
+
cam.updateProjectionMatrix()
|
|
175
|
+
cam.updateMatrixWorld(true)
|
|
176
|
+
|
|
177
|
+
this._placeholderCenterX = cx
|
|
178
|
+
this._placeholderCenterY = cy
|
|
179
|
+
this._syncPlaceholderWorldXY()
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
_syncPlaceholderWorldXY() {
|
|
183
|
+
const mesh = this._groundAlignPlaceholderMesh
|
|
184
|
+
if (!mesh) return
|
|
185
|
+
mesh.position.x = this._placeholderCenterX
|
|
186
|
+
mesh.position.y = this._placeholderCenterY
|
|
119
187
|
}
|
|
120
188
|
|
|
121
189
|
_getOrCreateTilesData() {
|
|
@@ -144,21 +212,28 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
144
212
|
// Prefer loading tiles that intersect _tilesCamera before prefetch / out-of-frustum work
|
|
145
213
|
tiles.optimizedLoadStrategy = true
|
|
146
214
|
|
|
147
|
-
tiles.addEventListener('load-model', ({ scene }) => {
|
|
148
|
-
applyDoubleSideToTileScene(scene)
|
|
149
|
-
})
|
|
150
|
-
|
|
151
215
|
tiles.lruCache.minSize = 400
|
|
152
216
|
tiles.lruCache.maxSize = 800
|
|
153
217
|
tiles.parseQueue.maxJobs = 4
|
|
154
218
|
|
|
155
219
|
const tilesWrapper = new THREE.Group()
|
|
156
220
|
tilesWrapper.name = 'Google3DTilesOverlay'
|
|
221
|
+
tilesWrapper.renderOrder = GOOGLE_TILES_RENDER_ORDER
|
|
157
222
|
tilesWrapper.rotation.x = Math.PI / 2
|
|
158
223
|
tilesWrapper.rotation.y = Math.PI
|
|
159
224
|
tilesWrapper.add(tiles.group)
|
|
160
|
-
tilesWrapper.position.z =
|
|
225
|
+
tilesWrapper.position.z = 0
|
|
161
226
|
this.tilesData = { tiles, tilesWrapper }
|
|
227
|
+
|
|
228
|
+
tiles.addEventListener('load-model', ({ scene, tile }) => {
|
|
229
|
+
console.log('tile size loading', tiles.loadingTiles.size)
|
|
230
|
+
this.tilesFullyLoaded = tiles.loadingTiles.size == 0
|
|
231
|
+
if (this.tilesFullyLoaded) {
|
|
232
|
+
this._applyGoogleTilesShadowProperty(tilesWrapper)
|
|
233
|
+
this.stickObjectToTheGround(scene)
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
|
|
162
237
|
return this.tilesData
|
|
163
238
|
}
|
|
164
239
|
|
|
@@ -183,7 +258,7 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
183
258
|
const mesh = new THREE.Mesh(geometry, material)
|
|
184
259
|
mesh.name = 'Google3DTilesGroundAlignPlaceholder'
|
|
185
260
|
mesh.userData.googleTilesGroundAlignPlaceholder = true
|
|
186
|
-
mesh.position.set(
|
|
261
|
+
mesh.position.set(this._placeholderCenterX, this._placeholderCenterY, 0)
|
|
187
262
|
mesh.scale.setScalar(1)
|
|
188
263
|
scene.add(mesh)
|
|
189
264
|
this._groundAlignPlaceholderMesh = mesh
|
|
@@ -204,10 +279,10 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
204
279
|
const t = performance.now() * 0.001
|
|
205
280
|
const scale = placeholderBounceScale(t)
|
|
206
281
|
mesh.scale.setScalar(scale)
|
|
282
|
+
mesh.position.x = this._placeholderCenterX
|
|
283
|
+
mesh.position.y = this._placeholderCenterY
|
|
207
284
|
// Light Z bob so it reads as a bounce (Z up)
|
|
208
285
|
mesh.position.z = 0.2 * Math.sin(t * 1.4 * Math.PI) ** 2
|
|
209
|
-
mesh.position.x = 0
|
|
210
|
-
mesh.position.y = 0
|
|
211
286
|
mesh.material.opacity = 0.06 + 0.22 * Math.sin(t * 0.85 * Math.PI) ** 2
|
|
212
287
|
}
|
|
213
288
|
|
|
@@ -227,52 +302,207 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
227
302
|
|
|
228
303
|
_syncGroundAlignPlaceholder(threeJSComponent) {
|
|
229
304
|
if (!threeJSComponent?.scene) return
|
|
230
|
-
if (this.
|
|
305
|
+
if (this.tilesFullyLoaded) {
|
|
231
306
|
this._removeGroundAlignPlaceholder(threeJSComponent)
|
|
232
307
|
} else {
|
|
233
308
|
this._ensureGroundAlignPlaceholder(threeJSComponent)
|
|
234
309
|
}
|
|
235
310
|
}
|
|
236
|
-
|
|
237
|
-
|
|
311
|
+
getBoundingBoxOfTiles(tileGroups) {
|
|
312
|
+
let mergedBoundingBox = new THREE.Box3()
|
|
313
|
+
tileGroups.forEach((tileGroup) => {
|
|
314
|
+
const tileMesh = tileGroup.children[0]
|
|
315
|
+
if (tileGroup.visible && tileMesh.geometry && tileMesh.visible) {
|
|
316
|
+
//create random color
|
|
317
|
+
const boundingBox = this.getBoundingBoxOfTile(tileMesh)
|
|
318
|
+
//compute bounding box in world coordinates
|
|
319
|
+
mergedBoundingBox.union(boundingBox)
|
|
320
|
+
}
|
|
321
|
+
})
|
|
322
|
+
return mergedBoundingBox
|
|
323
|
+
}
|
|
324
|
+
stickObjectToTheGround(scene) {
|
|
238
325
|
const { tiles, tilesWrapper } = this.tilesData || {}
|
|
239
326
|
if (!tiles || !tilesWrapper) {
|
|
240
327
|
this._tilesGroundAligned = false
|
|
241
328
|
return
|
|
242
329
|
}
|
|
243
330
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
331
|
+
//merge all bounding boxes of the tiles
|
|
332
|
+
const boundingBox = this.getBoundingBoxOfTiles(
|
|
333
|
+
tilesWrapper.children[0].children
|
|
334
|
+
)
|
|
335
|
+
tilesWrapper.position.z -= boundingBox.min.z
|
|
336
|
+
tilesWrapper.updateMatrixWorld(true)
|
|
337
|
+
this._tilesGroundAligned = true
|
|
338
|
+
}
|
|
339
|
+
getBoundingBoxOfTile(tileMesh) {
|
|
340
|
+
const extremePoints = []
|
|
341
|
+
let minX = Infinity,
|
|
342
|
+
maxX = -Infinity,
|
|
343
|
+
minY = Infinity,
|
|
344
|
+
maxY = -Infinity,
|
|
345
|
+
minZ = Infinity,
|
|
346
|
+
maxZ = -Infinity
|
|
347
|
+
//use for instead of forEach as the array doesn't contain points but indices
|
|
348
|
+
for (
|
|
349
|
+
let i = 300;
|
|
350
|
+
i < tileMesh.geometry.attributes.position.array.length;
|
|
351
|
+
i += 3
|
|
352
|
+
) {
|
|
353
|
+
const x = tileMesh.geometry.attributes.position.array[i]
|
|
354
|
+
const y = tileMesh.geometry.attributes.position.array[i + 1]
|
|
355
|
+
const z = tileMesh.geometry.attributes.position.array[i + 2]
|
|
356
|
+
let point = new THREE.Vector3(x, y, z)
|
|
357
|
+
point.applyMatrix4(tileMesh.matrixWorld)
|
|
358
|
+
minX = Math.min(minX, point.x)
|
|
359
|
+
maxX = Math.max(maxX, point.x)
|
|
360
|
+
minY = Math.min(minY, point.y)
|
|
361
|
+
maxY = Math.max(maxY, point.y)
|
|
362
|
+
minZ = Math.min(minZ, point.z)
|
|
363
|
+
maxZ = Math.max(maxZ, point.z)
|
|
248
364
|
}
|
|
249
365
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
366
|
+
extremePoints.push(new THREE.Vector3(maxX, maxY, maxZ))
|
|
367
|
+
extremePoints.push(new THREE.Vector3(minX, maxY, minZ))
|
|
368
|
+
extremePoints.push(new THREE.Vector3(maxX, minY, minZ))
|
|
369
|
+
extremePoints.push(new THREE.Vector3(minX, maxY, maxZ))
|
|
370
|
+
extremePoints.push(new THREE.Vector3(maxX, minY, maxZ))
|
|
371
|
+
extremePoints.push(new THREE.Vector3(minX, minY, maxZ))
|
|
372
|
+
extremePoints.push(new THREE.Vector3(maxX, maxY, minZ))
|
|
373
|
+
|
|
374
|
+
const boundingBox = new THREE.Box3(
|
|
375
|
+
new THREE.Vector3(minX, minY, minZ),
|
|
376
|
+
new THREE.Vector3(maxX, maxY, maxZ)
|
|
377
|
+
)
|
|
378
|
+
return boundingBox
|
|
379
|
+
}
|
|
257
380
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
381
|
+
/**
|
|
382
|
+
* Apply global overlay opacity to all tile mesh materials (base Overlay.setOpacity only updates state + emit).
|
|
383
|
+
*/
|
|
384
|
+
/**
|
|
385
|
+
* Replace MeshBasicMaterial with MeshPhongMaterial for lit/shadow rendering.
|
|
386
|
+
* Textures are reused by reference. Caller must re-run TilesFadePlugin material prep after batch swap.
|
|
387
|
+
*/
|
|
388
|
+
_convertGoogleTileBasicToPhong(basic) {
|
|
389
|
+
const phong = new THREE.MeshPhongMaterial()
|
|
390
|
+
//THREE.Material.prototype.copy.call(phong, basic)
|
|
391
|
+
phong.color = new THREE.Color(0xffffff)
|
|
392
|
+
phong.map = basic.map
|
|
393
|
+
phong.side = THREE.DoubleSide
|
|
394
|
+
phong.transparent = false
|
|
395
|
+
phong.opacity = 1
|
|
396
|
+
phong.shadowSide = THREE.DoubleSide
|
|
397
|
+
phong.flatShading = true
|
|
398
|
+
// phong.lightMap = basic.lightMap
|
|
399
|
+
// phong.lightMapIntensity = basic.lightMapIntensity
|
|
400
|
+
// phong.aoMap = basic.aoMap
|
|
401
|
+
// phong.aoMapIntensity = basic.aoMapIntensity
|
|
402
|
+
// phong.specularMap = basic.specularMap
|
|
403
|
+
// phong.alphaMap = basic.alphaMap
|
|
404
|
+
// phong.envMap = basic.envMap
|
|
405
|
+
// phong.envMapRotation.copy(basic.envMapRotation)
|
|
406
|
+
// phong.combine = basic.combine
|
|
407
|
+
basic.dispose()
|
|
408
|
+
return phong
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* New materials after Basic→Phong swap must be wrapped for TilesFadePlugin dither fade.
|
|
413
|
+
* Uses FADE_TILES_PLUGIN internals (prepareScene); coupled to 3d-tiles-renderer version.
|
|
414
|
+
*/
|
|
415
|
+
_reregisterGoogleTilesFadeMaterials(wrapper) {
|
|
416
|
+
const tiles = this.tilesData?.tiles
|
|
417
|
+
const fadePlugin = tiles?.getPluginByName?.('FADE_TILES_PLUGIN')
|
|
418
|
+
fadePlugin?._fadeMaterialManager?.prepareScene?.(wrapper)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
_applyGoogleTilesOpacity(wrapper) {
|
|
422
|
+
if (!wrapper) return
|
|
423
|
+
const opacity = this.opacity
|
|
424
|
+
const isTransparent = opacity < 1 - 1e-6
|
|
425
|
+
wrapper.renderOrder = GOOGLE_TILES_RENDER_ORDER
|
|
426
|
+
wrapper.visible = Boolean(this.isActive) && opacity > 0
|
|
427
|
+
wrapper.traverse((object) => {
|
|
428
|
+
if (!object.isMesh || !object.material) return
|
|
429
|
+
object.renderOrder = GOOGLE_TILES_RENDER_ORDER
|
|
430
|
+
const materials = Array.isArray(object.material)
|
|
431
|
+
? object.material
|
|
432
|
+
: [object.material]
|
|
433
|
+
for (const mat of materials) {
|
|
434
|
+
if (mat) {
|
|
435
|
+
mat.transparent = isTransparent
|
|
436
|
+
mat.opacity = opacity
|
|
437
|
+
// Avoid writing depth when semi-transparent so merged base (base.js) and
|
|
438
|
+
// other geometry drawn earlier remain visible through the tiles.
|
|
439
|
+
mat.depthWrite = !isTransparent
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
})
|
|
443
|
+
}
|
|
444
|
+
_applyGoogleTilesShadowProperty(wrapper) {
|
|
445
|
+
if (!wrapper) return
|
|
446
|
+
wrapper.traverse((object) => {
|
|
447
|
+
if (!object.isMesh || !object.material) return
|
|
448
|
+
if (Array.isArray(object.material)) {
|
|
449
|
+
object.material = object.material.map((mat) =>
|
|
450
|
+
this._convertGoogleTileBasicToPhong(mat)
|
|
451
|
+
)
|
|
452
|
+
} else {
|
|
453
|
+
object.material = this._convertGoogleTileBasicToPhong(object.material)
|
|
454
|
+
}
|
|
455
|
+
})
|
|
456
|
+
// this._reregisterGoogleTilesFadeMaterials(wrapper)
|
|
457
|
+
wrapper.traverse((object) => {
|
|
458
|
+
if (!object.isMesh) return
|
|
459
|
+
object.castShadow = true
|
|
460
|
+
object.receiveShadow = true
|
|
461
|
+
object.needsUpdate = true
|
|
462
|
+
})
|
|
463
|
+
}
|
|
464
|
+
setOpacity(opacity) {
|
|
465
|
+
super.setOpacity(opacity)
|
|
466
|
+
const wrapper = this.overlayMesh || this.tilesData?.tilesWrapper
|
|
467
|
+
if (wrapper) {
|
|
468
|
+
this._applyGoogleTilesOpacity(wrapper)
|
|
266
469
|
}
|
|
470
|
+
}
|
|
267
471
|
|
|
268
|
-
|
|
472
|
+
setIsActive(isActive) {
|
|
473
|
+
this.isActive = Boolean(isActive)
|
|
474
|
+
const wrapper = this.overlayMesh || this.tilesData?.tilesWrapper
|
|
475
|
+
if (wrapper) {
|
|
476
|
+
this._applyGoogleTilesOpacity(wrapper)
|
|
477
|
+
}
|
|
478
|
+
this.emit('item-updated', this)
|
|
269
479
|
}
|
|
480
|
+
|
|
270
481
|
async renderOnThreeJS(threeJSComponent) {
|
|
482
|
+
const rb = threeJSComponent?.roofsBounds
|
|
483
|
+
if (rb && !this._roofsBoundsAreEqual(this.roofsBound, rb)) {
|
|
484
|
+
this.updateRoofsBound(rb)
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (!this.isActive) {
|
|
488
|
+
this._removeGroundAlignPlaceholder(threeJSComponent)
|
|
489
|
+
const tilesWrapper =
|
|
490
|
+
this.tilesData?.tilesWrapper ||
|
|
491
|
+
threeJSComponent.meshes.overlayMeshes[this.id]
|
|
492
|
+
if (tilesWrapper) {
|
|
493
|
+
tilesWrapper.visible = false
|
|
494
|
+
threeJSComponent.meshes.overlayMeshes[this.id] = tilesWrapper
|
|
495
|
+
this.overlayMesh = tilesWrapper
|
|
496
|
+
}
|
|
497
|
+
return tilesWrapper || null
|
|
498
|
+
}
|
|
499
|
+
|
|
271
500
|
const tilesData = this._getOrCreateTilesData()
|
|
272
501
|
if (!tilesData) return null
|
|
273
502
|
|
|
274
503
|
const { tiles, tilesWrapper } = tilesData
|
|
275
504
|
const { renderer, scene } = threeJSComponent
|
|
505
|
+
this.scene = scene
|
|
276
506
|
tiles.setCamera(this._tilesCamera)
|
|
277
507
|
tiles.setResolutionFromRenderer(this._tilesCamera, renderer)
|
|
278
508
|
|
|
@@ -280,21 +510,19 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
280
510
|
tilesWrapper.userData.meshId = this.id
|
|
281
511
|
tilesWrapper.userData.version = this.version
|
|
282
512
|
|
|
283
|
-
this.stickObjectToTheGround()
|
|
284
513
|
this._syncGroundAlignPlaceholder(threeJSComponent)
|
|
285
|
-
if (this.
|
|
514
|
+
if (!this.tilesFullyLoaded) {
|
|
286
515
|
this._tickGroundAlignPlaceholderAnimation()
|
|
287
516
|
}
|
|
288
517
|
|
|
289
518
|
tilesWrapper.userData.update = () => {
|
|
290
|
-
if (!tiles || !renderer) return
|
|
519
|
+
if (!this.isActive || !tiles || !renderer) return
|
|
291
520
|
tiles.errorTarget = TILES_FRUSTUM_ERROR_TARGET
|
|
292
521
|
tiles.setCamera(this._tilesCamera)
|
|
293
522
|
tiles.setResolutionFromRenderer(this._tilesCamera, renderer)
|
|
294
523
|
tiles.update()
|
|
295
|
-
this.stickObjectToTheGround()
|
|
296
524
|
this._syncGroundAlignPlaceholder(threeJSComponent)
|
|
297
|
-
if (this.
|
|
525
|
+
if (!this.tilesFullyLoaded) {
|
|
298
526
|
this._tickGroundAlignPlaceholderAnimation()
|
|
299
527
|
}
|
|
300
528
|
}
|
|
@@ -306,6 +534,7 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
306
534
|
|
|
307
535
|
threeJSComponent.meshes.overlayMeshes[this.id] = tilesWrapper
|
|
308
536
|
this.overlayMesh = tilesWrapper
|
|
537
|
+
this._applyGoogleTilesOpacity(tilesWrapper)
|
|
309
538
|
return tilesWrapper
|
|
310
539
|
}
|
|
311
540
|
|
|
@@ -338,6 +567,7 @@ export default class Google3DTilesOverlay extends ThreeDModelOverlay {
|
|
|
338
567
|
}
|
|
339
568
|
this.tilesData = null
|
|
340
569
|
this.overlayMesh = null
|
|
570
|
+
this.roofsBound = null
|
|
341
571
|
this._initPromise = null
|
|
342
572
|
this._tilesGroundAligned = false
|
|
343
573
|
}
|