@eturnity/eturnity_3d 6.34.1 → 6.34.3
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/components/ThreeCanvasViewer.vue +14 -14
- package/src/helper/render/imageOverlay.js +1 -1
- package/src/helper/render/index.js +3 -1
- package/src/helper/render/mapProjection.js +7 -7
- package/src/helper/render/projectionMaterial.js +0 -3
- package/src/helper/render/roof.js +4 -3
- package/src/helper/render/tile.js +178 -26
- package/src/helper/render/tileProjection.js +124 -0
- package/src/helper/renderMixin.js +1 -1
- package/src/helper/threeMixin.js +4 -4
package/package.json
CHANGED
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
<script>
|
|
11
11
|
import { mapActions, mapState, mapGetters, mapMutations } from 'vuex'
|
|
12
12
|
import * as THREE from 'three'
|
|
13
|
-
import { addVector, multiplyVector } from '@eturnity/eturnity_maths'
|
|
14
|
-
import { updateComputedGeometryPolygon } from '@eturnity/eturnity_maths'
|
|
13
|
+
import { addVector, multiplyVector,updateComputedGeometryPolygon, normalizeVector } from '@eturnity/eturnity_maths'
|
|
15
14
|
|
|
16
15
|
import threeMixin from '../helper/threeMixin'
|
|
17
16
|
import materialMixin from '../helper/materialMixin'
|
|
@@ -31,7 +30,7 @@ export default {
|
|
|
31
30
|
1000
|
|
32
31
|
),
|
|
33
32
|
provider: null,
|
|
34
|
-
|
|
33
|
+
cameraProjection: null,
|
|
35
34
|
texture: null,
|
|
36
35
|
renderer: new THREE.WebGLRenderer({
|
|
37
36
|
antialias: true,
|
|
@@ -72,7 +71,7 @@ export default {
|
|
|
72
71
|
await this.loadPanelsTexture()
|
|
73
72
|
this.renderGeometry()
|
|
74
73
|
this.onWindowResize()
|
|
75
|
-
|
|
74
|
+
this.updateProjectionMaterials()
|
|
76
75
|
this.animate()
|
|
77
76
|
this.$root.$on('on-roofSelected', (polygon) =>
|
|
78
77
|
this.setCameraOrthogonalTo(polygon)
|
|
@@ -154,14 +153,13 @@ export default {
|
|
|
154
153
|
geometry.boundingSphere.center.z
|
|
155
154
|
]
|
|
156
155
|
let objectRadius = geometry.boundingSphere.radius
|
|
156
|
+
|
|
157
157
|
distance =
|
|
158
|
-
|
|
159
|
-
//_sphere.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );
|
|
158
|
+
5+(objectRadius) / (Math.sin(((this.camera.fov / 2) * Math.PI) / 180))
|
|
160
159
|
}
|
|
161
160
|
|
|
162
161
|
polygonRef = updateComputedGeometryPolygon(polygonRef)
|
|
163
162
|
const targetVector = polygonRef.meanPoint
|
|
164
|
-
//const target=[targetVector.x/1000,targetVector.y/1000,targetVector.z/1000]
|
|
165
163
|
let cameraMoveVector = { x: 0, y: 0, z: 0 }
|
|
166
164
|
let flatRoof =
|
|
167
165
|
polygonRef.normalVector.x == 0 && polygonRef.normalVector.y == 0
|
|
@@ -193,20 +191,22 @@ export default {
|
|
|
193
191
|
this.orthographicCamera.updateProjectionMatrix()
|
|
194
192
|
} else {
|
|
195
193
|
//street view
|
|
196
|
-
|
|
194
|
+
let horizontalVector = { ...polygonRef.normalVector, z: 0 }
|
|
195
|
+
|
|
197
196
|
if (horizontalVector.x == 0 && horizontalVector.y == 0) {
|
|
198
197
|
//if flat roof=> go south
|
|
199
198
|
horizontalVector.y = 1
|
|
200
199
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
200
|
+
horizontalVector=normalizeVector(horizontalVector)
|
|
201
|
+
// let distanceCoefficient = 2
|
|
202
|
+
// if(flatRoof){
|
|
203
|
+
// distanceCoefficient = 1.5
|
|
204
|
+
// }
|
|
205
|
+
cameraMoveVector = multiplyVector(distance * 1000 , horizontalVector)
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
const positionVector = addVector(polygonRef.meanPoint, cameraMoveVector)
|
|
209
|
-
|
|
209
|
+
positionVector.z += 1000
|
|
210
210
|
const position = [
|
|
211
211
|
positionVector.x / 1000,
|
|
212
212
|
positionVector.y / 1000 - 1,
|
|
@@ -113,7 +113,7 @@ export default {
|
|
|
113
113
|
})
|
|
114
114
|
imageOverlayProjectionMaterial.userData = {}
|
|
115
115
|
imageOverlayProjectionMaterial.userData.type = 'imageOverlayMaterial'
|
|
116
|
-
imageOverlayProjectionMaterial.
|
|
116
|
+
imageOverlayProjectionMaterial.priority = 20
|
|
117
117
|
imageOverlayProjectionMaterial.userData.url = this.imageOverlay.url
|
|
118
118
|
resolve(imageOverlayProjectionMaterial)
|
|
119
119
|
})
|
|
@@ -14,6 +14,7 @@ import mapProjection from './mapProjection'
|
|
|
14
14
|
import texture from './texture'
|
|
15
15
|
import projectionMaterial from './projectionMaterial'
|
|
16
16
|
import tile from './tile'
|
|
17
|
+
import tileProjection from './tileProjection'
|
|
17
18
|
|
|
18
19
|
export default {
|
|
19
20
|
//mixins:[node,background,clear,edge,loader,margin,moduleField,obstacle,panel,roof,base]
|
|
@@ -33,6 +34,7 @@ export default {
|
|
|
33
34
|
texture,
|
|
34
35
|
mapProjection,
|
|
35
36
|
projectionMaterial,
|
|
36
|
-
tile
|
|
37
|
+
tile,
|
|
38
|
+
tileProjection
|
|
37
39
|
]
|
|
38
40
|
}
|
|
@@ -35,7 +35,7 @@ export default {
|
|
|
35
35
|
this.mapProjectionTexture = texture
|
|
36
36
|
this.setMapProjectionCameraPosition()
|
|
37
37
|
let mapProjectionMaterial = new ProjectedMaterial({
|
|
38
|
-
camera: this.
|
|
38
|
+
camera: this.cameraProjection,
|
|
39
39
|
texture: texture,
|
|
40
40
|
transparent: true,
|
|
41
41
|
side: THREE.DoubleSide
|
|
@@ -63,12 +63,12 @@ export default {
|
|
|
63
63
|
this.backgroundImagesizeInMm =
|
|
64
64
|
this.layoutSettings.background_map_settings.sizeInMm
|
|
65
65
|
if (this.backgroundImagesizeInMm) {
|
|
66
|
-
this.
|
|
66
|
+
this.cameraProjection.aspect =
|
|
67
67
|
this.backgroundImagesizeInMm.width /
|
|
68
68
|
this.backgroundImagesizeInMm.height
|
|
69
69
|
let projectionAltitude =
|
|
70
70
|
this.backgroundImagesizeInMm.height /
|
|
71
|
-
(2 * Math.tan((this.
|
|
71
|
+
(2 * Math.tan((this.cameraProjection.fov * Math.PI) / 360))
|
|
72
72
|
|
|
73
73
|
//set projection camera over background_map_center
|
|
74
74
|
let cameraProjectionPosition = {
|
|
@@ -86,14 +86,14 @@ export default {
|
|
|
86
86
|
cameraProjectionPosition.y = positionInMm.y / 1000
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
this.
|
|
89
|
+
this.cameraProjection.position.set(
|
|
90
90
|
cameraProjectionPosition.x,
|
|
91
91
|
cameraProjectionPosition.y,
|
|
92
92
|
projectionAltitude / 1000
|
|
93
93
|
)
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
96
|
-
this.
|
|
94
|
+
this.cameraProjection.far = projectionAltitude * 1.5
|
|
95
|
+
this.cameraProjection.near = projectionAltitude * 0.5
|
|
96
|
+
this.cameraProjection.updateProjectionMatrix()
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -35,7 +35,6 @@ export default {
|
|
|
35
35
|
this.material.roof[index].dispose()
|
|
36
36
|
this.material.roof.splice(index, 1)
|
|
37
37
|
this.material.roof = [...this.material.roof]
|
|
38
|
-
this.reorderRoofMaterials()
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
index = this.material.roof.findIndex(
|
|
@@ -50,13 +49,11 @@ export default {
|
|
|
50
49
|
...this.material.roof,
|
|
51
50
|
this.imageOverlayMaterial
|
|
52
51
|
]
|
|
53
|
-
this.reorderRoofMaterials()
|
|
54
52
|
}
|
|
55
53
|
} else if (index >= 0) {
|
|
56
54
|
this.material.roof[index].dispose()
|
|
57
55
|
this.material.roof.splice(index, 1)
|
|
58
56
|
this.material.roof = [...this.material.roof]
|
|
59
|
-
this.reorderRoofMaterials()
|
|
60
57
|
}
|
|
61
58
|
this.renderImageOverlayOnBackground()
|
|
62
59
|
this.applyTextureOnRoofs()
|
|
@@ -70,18 +70,19 @@ export default {
|
|
|
70
70
|
return geometry
|
|
71
71
|
},
|
|
72
72
|
|
|
73
|
-
applyTextureOnRoofs() {
|
|
73
|
+
applyTextureOnRoofs(material = this.material.roof) {
|
|
74
|
+
this.reorderRoofMaterials()
|
|
74
75
|
this.roofs.forEach((roof) => {
|
|
75
76
|
//roofs
|
|
76
77
|
let mesh = this.meshes.roofMeshes[roof.id]
|
|
77
|
-
this.applyTextureOnMesh(
|
|
78
|
+
this.applyTextureOnMesh(material, mesh)
|
|
78
79
|
//obstacle on roof
|
|
79
80
|
roof.holes
|
|
80
81
|
.filter((p) => p.layer == 'obstacle')
|
|
81
82
|
.forEach((obstacle) => {
|
|
82
83
|
let meshObstacle =
|
|
83
84
|
this.meshes.obstacleMeshes[obstacle.id + '-' + roof.id + '_top']
|
|
84
|
-
this.applyTextureOnMesh(
|
|
85
|
+
this.applyTextureOnMesh(material, meshObstacle)
|
|
85
86
|
})
|
|
86
87
|
})
|
|
87
88
|
},
|
|
@@ -8,13 +8,14 @@ import {
|
|
|
8
8
|
latLngToTileXY,
|
|
9
9
|
tileToCorners
|
|
10
10
|
} from '@eturnity/eturnity_maths'
|
|
11
|
+
import { earthRadius } from '../../config'
|
|
11
12
|
|
|
12
|
-
import {cancellablePromise} from '../../utils/cancellablePromise'
|
|
13
|
+
import { cancellablePromise } from '../../utils/cancellablePromise'
|
|
13
14
|
|
|
14
15
|
export default {
|
|
15
16
|
data() {
|
|
16
17
|
return {
|
|
17
|
-
pendingTiles: []
|
|
18
|
+
pendingTiles: []
|
|
18
19
|
}
|
|
19
20
|
},
|
|
20
21
|
methods: {
|
|
@@ -56,14 +57,26 @@ export default {
|
|
|
56
57
|
this.backgroundMap = new THREE.Group()
|
|
57
58
|
|
|
58
59
|
let zoomLvl = this.provider.maxZoom
|
|
60
|
+
|
|
59
61
|
const latitude = this.layoutSettings.layout_latitude
|
|
60
62
|
const longitude = this.layoutSettings.layout_longitude
|
|
61
63
|
let { xMin, xMax, yMin, yMax } = this.roofsBounds
|
|
64
|
+
|
|
62
65
|
if (xMin == Infinity) {
|
|
63
66
|
xMin = 0
|
|
64
67
|
yMin = 0
|
|
65
68
|
xMax = 0
|
|
66
69
|
yMax = 0
|
|
70
|
+
} else {
|
|
71
|
+
let perimeterAtLatitude =
|
|
72
|
+
earthRadius * Math.cos((latitude * Math.PI) / 180) * 2000 * Math.PI
|
|
73
|
+
|
|
74
|
+
let optimizedZoomLvl =
|
|
75
|
+
Math.round(Math.log(perimeterAtLatitude / (xMax - xMin)) / Math.LN2) +
|
|
76
|
+
1
|
|
77
|
+
if (optimizedZoomLvl < zoomLvl) {
|
|
78
|
+
zoomLvl = optimizedZoomLvl
|
|
79
|
+
}
|
|
67
80
|
}
|
|
68
81
|
let { lat: latMin, lng: lngMin } = distanceToDeltaLatLng(
|
|
69
82
|
xMin,
|
|
@@ -92,11 +105,11 @@ export default {
|
|
|
92
105
|
let tileToRender = []
|
|
93
106
|
for (let xTile = xTileMin; xTile <= xTileMax; xTile++) {
|
|
94
107
|
for (let yTile = yTileMin; yTile <= yTileMax; yTile++) {
|
|
95
|
-
tileToRender.push({ xTile, yTile, zoomLvl })
|
|
108
|
+
tileToRender.push({ xTile, yTile, zoomLvl, isTileOnRoofBound: true })
|
|
96
109
|
}
|
|
97
110
|
}
|
|
98
111
|
|
|
99
|
-
|
|
112
|
+
while (zoomLvl > 16) {
|
|
100
113
|
xTileMin = xTileMin / 2 - 1
|
|
101
114
|
xTileMax = (xTileMax + 1) / 2
|
|
102
115
|
yTileMin = yTileMin / 2 - 1
|
|
@@ -119,7 +132,12 @@ export default {
|
|
|
119
132
|
yTile - yTileMin <= yMinOdd ||
|
|
120
133
|
yTileMax - yTile <= yMaxEven
|
|
121
134
|
) {
|
|
122
|
-
tileToRender.push({
|
|
135
|
+
tileToRender.push({
|
|
136
|
+
xTile,
|
|
137
|
+
yTile,
|
|
138
|
+
zoomLvl,
|
|
139
|
+
isTileOnRoofBound: false
|
|
140
|
+
})
|
|
123
141
|
}
|
|
124
142
|
}
|
|
125
143
|
}
|
|
@@ -129,19 +147,22 @@ export default {
|
|
|
129
147
|
let xTile = tileToRender[k].xTile
|
|
130
148
|
let yTile = tileToRender[k].yTile
|
|
131
149
|
zoomLvl = tileToRender[k].zoomLvl
|
|
132
|
-
|
|
150
|
+
let isTileOnRoofBound = tileToRender[k].isTileOnRoofBound
|
|
151
|
+
this.renderTile(xTile, yTile, zoomLvl, isTileOnRoofBound)
|
|
133
152
|
}
|
|
134
153
|
},
|
|
135
|
-
removeTileFromPending(meshId,mapLayer){
|
|
154
|
+
removeTileFromPending(meshId, mapLayer) {
|
|
136
155
|
this.pendingTiles = this.pendingTiles.filter(
|
|
137
156
|
(t) => t.meshId != meshId || t.mapLayer != mapLayer
|
|
138
157
|
)
|
|
139
158
|
},
|
|
140
|
-
async renderTile(x, y, zoomLvl) {
|
|
159
|
+
async renderTile(x, y, zoomLvl, isTileOnRoofBound = false) {
|
|
141
160
|
const meshId = 'tile_' + x + '_' + y + '_' + zoomLvl
|
|
142
161
|
const mapLayer = this.provider.mapLayer
|
|
143
162
|
if (
|
|
144
|
-
this.pendingTiles.find(
|
|
163
|
+
this.pendingTiles.find(
|
|
164
|
+
(t) => t.meshId == meshId && t.mapLayer == mapLayer
|
|
165
|
+
)
|
|
145
166
|
) {
|
|
146
167
|
return
|
|
147
168
|
}
|
|
@@ -154,15 +175,19 @@ export default {
|
|
|
154
175
|
const latitude = this.layoutSettings.layout_latitude
|
|
155
176
|
const longitude = this.layoutSettings.layout_longitude
|
|
156
177
|
let geometry, material
|
|
157
|
-
const imagePromise=cancellablePromise(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
178
|
+
const imagePromise = cancellablePromise(
|
|
179
|
+
this.provider.fetchTile(zoomLvl, x, y)
|
|
180
|
+
)
|
|
181
|
+
this.pendingTiles.push({ x, y, zoomLvl, mapLayer, meshId, imagePromise })
|
|
182
|
+
imagePromise.then((image) => {
|
|
161
183
|
if (!image) {
|
|
162
|
-
this.removeTileFromPending(meshId,mapLayer)
|
|
184
|
+
this.removeTileFromPending(meshId, mapLayer)
|
|
163
185
|
return
|
|
164
186
|
}
|
|
165
187
|
const texture = new THREE.Texture(image)
|
|
188
|
+
if (isTileOnRoofBound) {
|
|
189
|
+
this.newTileMaterial(texture, x, y, zoomLvl, mapLayer)
|
|
190
|
+
}
|
|
166
191
|
texture.generateMipmaps = false
|
|
167
192
|
texture.format = THREE.RGBAFormat
|
|
168
193
|
texture.magFilter = THREE.LinearFilter
|
|
@@ -205,10 +230,129 @@ export default {
|
|
|
205
230
|
}
|
|
206
231
|
}
|
|
207
232
|
//image.parentNode.removeChild(image);
|
|
208
|
-
this.removeTileFromPending(meshId,mapLayer)
|
|
233
|
+
this.removeTileFromPending(meshId, mapLayer)
|
|
209
234
|
})
|
|
210
235
|
},
|
|
211
|
-
renderGoogleTiles() {
|
|
236
|
+
async renderGoogleTiles() {
|
|
237
|
+
this.clearByType('tileMeshes')
|
|
238
|
+
if (this.backgroundMap) {
|
|
239
|
+
this.backgroundMap.clear()
|
|
240
|
+
this.scene.remove(this.backgroundMap)
|
|
241
|
+
this.clearThreeObjects(this.backgroundMap)
|
|
242
|
+
}
|
|
243
|
+
this.backgroundMap = new THREE.Group()
|
|
244
|
+
|
|
245
|
+
let googleMapType = 'satellite'
|
|
246
|
+
switch (this.selectedMapLayer.key) {
|
|
247
|
+
case 'googleLayerRoadmap':
|
|
248
|
+
googleMapType = 'roadmap'
|
|
249
|
+
break
|
|
250
|
+
case 'googleLayer':
|
|
251
|
+
googleMapType = 'satellite'
|
|
252
|
+
break
|
|
253
|
+
case 'googleLayerTerrain':
|
|
254
|
+
googleMapType = 'terrain'
|
|
255
|
+
break
|
|
256
|
+
}
|
|
257
|
+
let roofsBoundZoomLvl = 19
|
|
258
|
+
let { xMin, xMax, yMin, yMax } = this.roofsBounds
|
|
259
|
+
if (xMin == Infinity) {
|
|
260
|
+
xMin = 0
|
|
261
|
+
yMin = 0
|
|
262
|
+
xMax = 0
|
|
263
|
+
yMax = 0
|
|
264
|
+
}
|
|
265
|
+
let roofsBoundCenterMeter = {
|
|
266
|
+
x: (xMax + xMin) / 2000,
|
|
267
|
+
y: (yMax + yMin) / 2000
|
|
268
|
+
}
|
|
269
|
+
let deltaLatLng = distanceToDeltaLatLng(
|
|
270
|
+
roofsBoundCenterMeter.x,
|
|
271
|
+
roofsBoundCenterMeter.y,
|
|
272
|
+
this.layoutSettings.layout_latitude
|
|
273
|
+
)
|
|
274
|
+
let roofsBoundCenterLatLng = {
|
|
275
|
+
lat: this.layoutSettings.layout_latitude + deltaLatLng.lat,
|
|
276
|
+
lng: this.layoutSettings.layout_longitude + deltaLatLng.lng
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
let apiKey = process.env.VUE_APP_GOOGLE_MAP_API_KEY
|
|
280
|
+
let backgroundPlane = []
|
|
281
|
+
let size = 640
|
|
282
|
+
let planeGeometry = []
|
|
283
|
+
let planeMaterial = []
|
|
284
|
+
let texture = []
|
|
285
|
+
let zoomLevels = [
|
|
286
|
+
roofsBoundZoomLvl,
|
|
287
|
+
roofsBoundZoomLvl - 2,
|
|
288
|
+
roofsBoundZoomLvl - 4
|
|
289
|
+
]
|
|
290
|
+
|
|
291
|
+
for (
|
|
292
|
+
let indexGoogleBackground = 0;
|
|
293
|
+
indexGoogleBackground < zoomLevels.length;
|
|
294
|
+
indexGoogleBackground++
|
|
295
|
+
) {
|
|
296
|
+
let zoomLevel = zoomLevels[indexGoogleBackground]
|
|
297
|
+
let groundResolution =
|
|
298
|
+
(Math.cos((this.layoutSettings.layout_latitude * Math.PI) / 180) *
|
|
299
|
+
2 *
|
|
300
|
+
Math.PI *
|
|
301
|
+
6378137) /
|
|
302
|
+
(256 * Math.pow(2, zoomLevel))
|
|
303
|
+
let sizeInMeter = groundResolution * size
|
|
304
|
+
planeGeometry[indexGoogleBackground] = new THREE.PlaneGeometry(
|
|
305
|
+
sizeInMeter,
|
|
306
|
+
sizeInMeter * 0.9
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
//to remove attribution in bottom of the image
|
|
310
|
+
var uvs = new Float32Array([
|
|
311
|
+
0, 0.95, 1, 0.95, 0, 0.05, 1, 0.05, 0, 0.05, 1, 0.95
|
|
312
|
+
])
|
|
313
|
+
planeGeometry[indexGoogleBackground].setAttribute(
|
|
314
|
+
'uv',
|
|
315
|
+
new THREE.BufferAttribute(uvs, 2)
|
|
316
|
+
)
|
|
317
|
+
planeGeometry[indexGoogleBackground].computeVertexNormals()
|
|
318
|
+
|
|
319
|
+
let googleBackgroundUrl = `https://maps.googleapis.com/maps/api/staticmap?center=${
|
|
320
|
+
roofsBoundCenterLatLng.lat + ',' + roofsBoundCenterLatLng.lng
|
|
321
|
+
}&maptype=${googleMapType}&zoom=${zoomLevel}&size=${size}x${size}&key=${apiKey}`
|
|
322
|
+
texture[indexGoogleBackground] = await this.loader.load(
|
|
323
|
+
googleBackgroundUrl
|
|
324
|
+
)
|
|
325
|
+
texture[indexGoogleBackground].wrapS = 1 //THREE.RepeatWrapping
|
|
326
|
+
texture[indexGoogleBackground].wrapT = 1 //THREE.RepeatWrapping
|
|
327
|
+
// texture[indexGoogleBackground].offset.y += 0.1
|
|
328
|
+
|
|
329
|
+
if (indexGoogleBackground == 0) {
|
|
330
|
+
this.newGoogleTileMaterial(
|
|
331
|
+
texture[indexGoogleBackground],
|
|
332
|
+
sizeInMeter,
|
|
333
|
+
roofsBoundCenterMeter,
|
|
334
|
+
googleMapType
|
|
335
|
+
)
|
|
336
|
+
}
|
|
337
|
+
planeMaterial[indexGoogleBackground] = new THREE.MeshBasicMaterial({
|
|
338
|
+
map: texture[indexGoogleBackground],
|
|
339
|
+
side: THREE.DoubleSide
|
|
340
|
+
})
|
|
341
|
+
backgroundPlane[indexGoogleBackground] = new THREE.Mesh(
|
|
342
|
+
planeGeometry[indexGoogleBackground],
|
|
343
|
+
planeMaterial[indexGoogleBackground]
|
|
344
|
+
)
|
|
345
|
+
backgroundPlane[indexGoogleBackground].position.x =
|
|
346
|
+
roofsBoundCenterMeter.x
|
|
347
|
+
backgroundPlane[indexGoogleBackground].position.y =
|
|
348
|
+
roofsBoundCenterMeter.y
|
|
349
|
+
backgroundPlane[indexGoogleBackground].position.z =
|
|
350
|
+
-indexGoogleBackground / 2
|
|
351
|
+
this.backgroundMap.add(backgroundPlane[indexGoogleBackground])
|
|
352
|
+
}
|
|
353
|
+
this.scene.add(this.backgroundMap)
|
|
354
|
+
},
|
|
355
|
+
async renderGoogleTilesCenter() {
|
|
212
356
|
this.clearByType('tileMeshes')
|
|
213
357
|
if (this.backgroundMap) {
|
|
214
358
|
this.backgroundMap.clear()
|
|
@@ -237,6 +381,7 @@ export default {
|
|
|
237
381
|
let planeMaterial = []
|
|
238
382
|
let texture = []
|
|
239
383
|
let zoomLevels = [19, 16]
|
|
384
|
+
|
|
240
385
|
for (
|
|
241
386
|
let indexGoogleBackground = 0;
|
|
242
387
|
indexGoogleBackground < zoomLevels.length;
|
|
@@ -260,7 +405,16 @@ export default {
|
|
|
260
405
|
this.layoutSettings.layout_longitude
|
|
261
406
|
}&maptype=${googleMapType}&zoom=${zoomLevel}&size=${size}x${size}&key=${apiKey}`
|
|
262
407
|
|
|
263
|
-
texture[indexGoogleBackground] = this.loader.load(
|
|
408
|
+
texture[indexGoogleBackground] = await this.loader.load(
|
|
409
|
+
googleBackgroundUrl
|
|
410
|
+
)
|
|
411
|
+
if (indexGoogleBackground == 0) {
|
|
412
|
+
this.newGoogleTileMaterial(
|
|
413
|
+
texture[indexGoogleBackground],
|
|
414
|
+
sizeInMeter,
|
|
415
|
+
googleMapType
|
|
416
|
+
)
|
|
417
|
+
}
|
|
264
418
|
planeMaterial[indexGoogleBackground] = new THREE.MeshBasicMaterial({
|
|
265
419
|
map: texture[indexGoogleBackground],
|
|
266
420
|
side: THREE.DoubleSide
|
|
@@ -276,16 +430,14 @@ export default {
|
|
|
276
430
|
this.scene.add(this.backgroundMap)
|
|
277
431
|
}
|
|
278
432
|
},
|
|
279
|
-
watch:{
|
|
280
|
-
selectedMapLayer(newMapLayer){
|
|
281
|
-
this.pendingTiles = this.pendingTiles.filter(
|
|
282
|
-
(t)
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
return false
|
|
286
|
-
}
|
|
433
|
+
watch: {
|
|
434
|
+
selectedMapLayer(newMapLayer) {
|
|
435
|
+
this.pendingTiles = this.pendingTiles.filter((t) => {
|
|
436
|
+
if (t.mapLayer != newMapLayer.key) {
|
|
437
|
+
t.imagePromise.cancel()
|
|
438
|
+
return false
|
|
287
439
|
}
|
|
288
|
-
)
|
|
440
|
+
})
|
|
289
441
|
}
|
|
290
442
|
}
|
|
291
443
|
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
import ProjectedMaterial from 'three-projected-material'
|
|
3
|
+
import { tileToCorners } from '@eturnity/eturnity_maths'
|
|
4
|
+
import { earthRadius } from '../../config'
|
|
5
|
+
export default {
|
|
6
|
+
data() {
|
|
7
|
+
return {
|
|
8
|
+
tileProjectionTextures: [],
|
|
9
|
+
tileProjectionMaterials: []
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
methods: {
|
|
13
|
+
async newGoogleTileMaterial(texture, sizeInMeter, center, mapLayer) {
|
|
14
|
+
if (!this.material.roof) {
|
|
15
|
+
this.material.roof = []
|
|
16
|
+
}
|
|
17
|
+
const cameraProjection = new THREE.OrthographicCamera(
|
|
18
|
+
center.x - sizeInMeter / 2,
|
|
19
|
+
center.x + sizeInMeter / 2,
|
|
20
|
+
center.y + sizeInMeter / 2,
|
|
21
|
+
center.y - sizeInMeter / 2,
|
|
22
|
+
100,
|
|
23
|
+
10000
|
|
24
|
+
)
|
|
25
|
+
// cameraProjection.position.set(0, 0, 1)
|
|
26
|
+
// cameraProjection.up.set(0, 0, 1)
|
|
27
|
+
let tileProjectionMaterial = new ProjectedMaterial({
|
|
28
|
+
camera: cameraProjection,
|
|
29
|
+
texture: texture,
|
|
30
|
+
transparent: true,
|
|
31
|
+
side: THREE.DoubleSide
|
|
32
|
+
})
|
|
33
|
+
tileProjectionMaterial.userData = {}
|
|
34
|
+
tileProjectionMaterial.userData.type = 'tileProjectionMaterial'
|
|
35
|
+
tileProjectionMaterial.userData.materialId =
|
|
36
|
+
'material_' +
|
|
37
|
+
sizeInMeter +
|
|
38
|
+
'_' +
|
|
39
|
+
center.x +
|
|
40
|
+
'_' +
|
|
41
|
+
center.y +
|
|
42
|
+
'_' +
|
|
43
|
+
mapLayer
|
|
44
|
+
tileProjectionMaterial.userData.mapLayer = mapLayer
|
|
45
|
+
tileProjectionMaterial.userData.priority = 10
|
|
46
|
+
this.material.roof.push(tileProjectionMaterial)
|
|
47
|
+
this.applyTextureOnRoofs()
|
|
48
|
+
},
|
|
49
|
+
async newTileMaterial(texture, x, y, zoom, mapLayer) {
|
|
50
|
+
if (!this.material.roof) {
|
|
51
|
+
this.material.roof = []
|
|
52
|
+
}
|
|
53
|
+
const cameraProjection = new THREE.OrthographicCamera(
|
|
54
|
+
-1,
|
|
55
|
+
1,
|
|
56
|
+
-1,
|
|
57
|
+
1,
|
|
58
|
+
100,
|
|
59
|
+
10000
|
|
60
|
+
)
|
|
61
|
+
cameraProjection.position.set(0, 0, 1)
|
|
62
|
+
cameraProjection.up.set(0, 0, 1)
|
|
63
|
+
let tileProjectionMaterial = new ProjectedMaterial({
|
|
64
|
+
camera: cameraProjection,
|
|
65
|
+
texture: texture,
|
|
66
|
+
transparent: true,
|
|
67
|
+
side: THREE.DoubleSide
|
|
68
|
+
})
|
|
69
|
+
tileProjectionMaterial.userData = {}
|
|
70
|
+
tileProjectionMaterial.userData.type = 'tileProjectionMaterial'
|
|
71
|
+
tileProjectionMaterial.userData.materialId =
|
|
72
|
+
'material_' + x + '_' + y + '_' + zoom + '_' + mapLayer
|
|
73
|
+
tileProjectionMaterial.userData.mapLayer = mapLayer
|
|
74
|
+
tileProjectionMaterial.priority = 10
|
|
75
|
+
this.setTileCameraPosition(cameraProjection, x, y, zoom)
|
|
76
|
+
this.material.roof.push(tileProjectionMaterial)
|
|
77
|
+
this.applyTextureOnRoofs()
|
|
78
|
+
},
|
|
79
|
+
disposeTileMaterial(material) {
|
|
80
|
+
material.texture.dispose()
|
|
81
|
+
material.dispose()
|
|
82
|
+
},
|
|
83
|
+
disposeTileMaterialDifferentMapLayer(mapLayer) {
|
|
84
|
+
if (!this.material.roof) return
|
|
85
|
+
this.material.roof = this.material.roof.filter((m) => {
|
|
86
|
+
if (
|
|
87
|
+
m.userData.type == 'tileProjectionMaterial' &&
|
|
88
|
+
m.userData.mapLayer != mapLayer
|
|
89
|
+
) {
|
|
90
|
+
this.disposeTileMaterial(m)
|
|
91
|
+
return false
|
|
92
|
+
}
|
|
93
|
+
return true
|
|
94
|
+
})
|
|
95
|
+
},
|
|
96
|
+
setTileCameraPosition(camera, x, y, zoom) {
|
|
97
|
+
const latitude = this.layoutSettings.layout_latitude
|
|
98
|
+
const longitude = this.layoutSettings.layout_longitude
|
|
99
|
+
let corners = tileToCorners(x, y, zoom, latitude, longitude)
|
|
100
|
+
let height, width, tileCenter
|
|
101
|
+
let numberOfTiles = Math.pow(2, zoom)
|
|
102
|
+
height =
|
|
103
|
+
(2000 * Math.PI * earthRadius * Math.cos((latitude * Math.PI) / 180)) /
|
|
104
|
+
numberOfTiles
|
|
105
|
+
width = height
|
|
106
|
+
tileCenter = {
|
|
107
|
+
x: (corners[0].x + corners[2].x) / 2,
|
|
108
|
+
y: (corners[0].y + corners[2].y) / 2
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
camera.left = corners[0].x / 1000
|
|
112
|
+
camera.right = corners[2].x / 1000
|
|
113
|
+
camera.bottom = corners[0].y / 1000
|
|
114
|
+
camera.top = corners[2].y / 1000
|
|
115
|
+
|
|
116
|
+
camera.updateProjectionMatrix()
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
watch: {
|
|
120
|
+
selectedMapLayer(newMapLayer) {
|
|
121
|
+
this.disposeTileMaterialDifferentMapLayer(newMapLayer.key)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
package/src/helper/threeMixin.js
CHANGED
|
@@ -43,16 +43,16 @@ export default {
|
|
|
43
43
|
this.camera.position.set(0, -100, 50)
|
|
44
44
|
this.camera.up.set(0, 0, 1)
|
|
45
45
|
|
|
46
|
-
this.
|
|
46
|
+
this.cameraProjection = new THREE.PerspectiveCamera(
|
|
47
47
|
1,
|
|
48
48
|
300 / 300,
|
|
49
49
|
100,
|
|
50
50
|
1000
|
|
51
51
|
)
|
|
52
|
-
this.
|
|
53
|
-
this.
|
|
52
|
+
this.cameraProjection.position.set(0, 0, 24)
|
|
53
|
+
this.cameraProjection.up.set(0, 0, 1)
|
|
54
54
|
|
|
55
|
-
// const helper = new THREE.CameraHelper( this.
|
|
55
|
+
// const helper = new THREE.CameraHelper( this.cameraProjection );
|
|
56
56
|
// this.scene.add( helper );
|
|
57
57
|
|
|
58
58
|
// const axesHelper = new THREE.AxesHelper( 20 );
|