@eturnity/eturnity_3d 7.20.1 → 7.24.0

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 (41) hide show
  1. package/package.json +2 -2
  2. package/src/EventManager/EventManager.js +48 -0
  3. package/src/Item/Item.js +12 -0
  4. package/src/Layer/Layer.js +119 -0
  5. package/src/Overlay/AirTeamOverlay.js +605 -0
  6. package/src/Overlay/ImageOverlay.js +309 -0
  7. package/src/Overlay/Overlay.js +255 -0
  8. package/src/Overlay/OverlayFactory.js +19 -0
  9. package/src/Overlay/OverlayLayer.js +36 -0
  10. package/src/components/ThreeCanvasViewer.vue +17 -6
  11. package/src/config.js +120 -17
  12. package/src/helper/UpdateRoofModuleFieldRelations.js +65 -25
  13. package/src/helper/cameraMixin.js +25 -0
  14. package/src/helper/materialMixin.js +14 -1
  15. package/src/helper/projectedMaterial.js +662 -0
  16. package/src/helper/render/base.js +5 -5
  17. package/src/helper/render/clear.js +0 -17
  18. package/src/helper/render/edge.js +2 -0
  19. package/src/helper/render/geometryHandler.js +60 -31
  20. package/src/helper/render/imageOverlay.js +25 -144
  21. package/src/helper/render/index.js +2 -0
  22. package/src/helper/render/mergedGeometry.js +11 -2
  23. package/src/helper/render/obstacle.js +2 -1
  24. package/src/helper/render/overlay.js +41 -0
  25. package/src/helper/render/projectionMaterial.js +17 -19
  26. package/src/helper/render/roof.js +49 -52
  27. package/src/helper/render/texture.js +25 -0
  28. package/src/helper/render/tile.js +84 -24
  29. package/src/helper/render/tileProjection.js +23 -14
  30. package/src/helper/renderMixin.js +22 -8
  31. package/src/helper/threeMixin.js +5 -2
  32. package/src/store/hydrateData.js +23 -11
  33. package/src/store/nodesEdgesCreation.js +78 -4
  34. package/src/store/three-d-module.js +1 -1
  35. package/dist/css/app.58568098.css +0 -1
  36. package/dist/img/reneSola_Virtus_2_JC320S_24_Bbw.85a0cb6d.png +0 -0
  37. package/dist/index.html +0 -15
  38. package/dist/js/app-legacy.aa792c98.js +0 -2
  39. package/dist/js/app-legacy.aa792c98.js.map +0 -1
  40. package/dist/js/chunk-vendors-legacy.9bb3863d.js +0 -41
  41. package/dist/js/chunk-vendors-legacy.9bb3863d.js.map +0 -1
@@ -0,0 +1,309 @@
1
+ import Overlay from './Overlay'
2
+ import { layerColors } from '../config'
3
+ import {
4
+ getDistanceBetweenPoints,
5
+ addVector,
6
+ multiplyVector,
7
+ substractVector,
8
+ getAngleInDegFromCanvasVector,
9
+ normalize2DVector,
10
+ vectorLength2D
11
+ } from '@eturnity/eturnity_maths'
12
+ let Paper
13
+ export default class ImageOverlay extends Overlay {
14
+ constructor(overlay, emit) {
15
+ super(overlay, emit)
16
+ this.url = this.resources[0].file_url
17
+ this.opacity = 1
18
+ this.imageUrl = this.resources[0].file_url
19
+ this.corners = overlay.settings.corners
20
+ this.hasScale = overlay.settings.hasScale
21
+ this.points =
22
+ overlay.settings.scaleParams && overlay.settings.scaleParams.points
23
+ ? overlay.settings.scaleParams.points
24
+ : []
25
+ this.mmPerPx =
26
+ overlay.settings.scaleParams && overlay.settings.scaleParams.mmPerPx
27
+ ? overlay.settings.scaleParams.mmPerPx
28
+ : null
29
+ this.distance =
30
+ overlay.settings.scaleParams && overlay.settings.scaleParams.distance
31
+ ? overlay.settings.scaleParams.distance
32
+ : 10000
33
+ this.initialiseImage(this.url).then((isReady) => {
34
+ this.isReady = isReady
35
+ this.version++
36
+ this.emit('overlay-is-ready', { id: this.id })
37
+ this.isReadyCallback.forEach((callback) => {
38
+ if (typeof callback === 'function') {
39
+ callback()
40
+ }
41
+ })
42
+ this.isReadyCallback = []
43
+ })
44
+ }
45
+ onLoad() {
46
+ return new Promise((resolve) => {
47
+ if (this.isReady) {
48
+ resolve(this)
49
+ } else {
50
+ this.isReadyCallback.push(resolve)
51
+ }
52
+ })
53
+ }
54
+ async initialiseImage(url) {
55
+ const img = new Image()
56
+ const _this = this
57
+ const promise = new Promise((resolve, reject) => {
58
+ img.onload = function () {
59
+ _this.width = this.width
60
+ _this.height = this.height
61
+ resolve(true)
62
+ }
63
+ img.onerror = reject
64
+ this.img = img
65
+ })
66
+ img.src = url
67
+ return promise
68
+ }
69
+ async getInitial2DCorners(mmPerPx) {
70
+ const initialWidthMm = this.width * mmPerPx
71
+ const ratio = this.height / this.width
72
+ const initialHeightMm = ratio * initialWidthMm
73
+ const cornersTopLeft = {
74
+ x: -initialWidthMm / 2,
75
+ y: initialHeightMm / 2
76
+ }
77
+ const cornersTopRight = {
78
+ x: initialWidthMm / 2,
79
+ y: initialHeightMm / 2
80
+ }
81
+ const cornersBottomLeft = {
82
+ x: -initialWidthMm / 2,
83
+ y: -initialHeightMm / 2
84
+ }
85
+ const cornersBottomRight = {
86
+ x: initialWidthMm / 2,
87
+ y: -initialHeightMm / 2
88
+ }
89
+ const corners = [
90
+ cornersTopLeft,
91
+ cornersTopRight,
92
+ cornersBottomRight,
93
+ cornersBottomLeft
94
+ ]
95
+ return corners
96
+ }
97
+ async setScale(scaleParams) {
98
+ if (!scaleParams) {
99
+ this.hasScale = false
100
+ this.version++
101
+ this.emit('overlay-scale-updated', { id: this.id })
102
+ return
103
+ }
104
+ let { points, distance, mmPerPx } = scaleParams
105
+
106
+ if (points.length < 2 || !distance) {
107
+ this.hasScale = false
108
+ this.version++
109
+ this.emit('overlay-scale-updated', { id: this.id })
110
+ return
111
+ }
112
+ this.mmPerPx = mmPerPx
113
+ this.points = points
114
+ this.distance = distance
115
+ this.hasScale = true
116
+ this.points = [{ ...this.points[0] }, { ...this.points[1] }]
117
+ this.version++
118
+ this.corners = await this.getInitial2DCorners(mmPerPx)
119
+ this.emit('overlay-scale-updated', { id: this.id })
120
+ }
121
+ renderOnPaperJS(paperJSComponent) {
122
+ Paper = paperJSComponent.paperScope
123
+ if (!this.isReady || !this.isActive || !this.corners) {
124
+ return
125
+ }
126
+ let group = paperJSComponent.paths.imageOverlays[this.id]
127
+ paperJSComponent.paperLayer['imageOverlays'].activate()
128
+
129
+ let imageOverlayPath
130
+ let handles
131
+ let isRotationHandleVisible =
132
+ paperJSComponent.selectedTool == 'selectOverlay' && this.isSelected
133
+ let corners = this.corners.map((p) => paperJSComponent.toCanvasRef(p))
134
+ if (group) {
135
+ if (group.data.url == this.url) {
136
+ imageOverlayPath = group.children[0]
137
+ } else {
138
+ imageOverlayPath = this.loadImageOverlay(this.url, corners)
139
+ paperJSComponent.clearPath(group.children[0])
140
+ group.insertChild(0, imageOverlayPath)
141
+ }
142
+ handles = this.renderImageOverlayHandles(
143
+ corners,
144
+ isRotationHandleVisible,
145
+ group.children[1]
146
+ )
147
+ this.applyRasterToCorners(imageOverlayPath, corners)
148
+ group.visible = true
149
+ } else {
150
+ group = new Paper.Group()
151
+ imageOverlayPath = this.loadImageOverlay(this.url, corners)
152
+
153
+ handles = this.renderImageOverlayHandles(corners, isRotationHandleVisible)
154
+
155
+ group.addChild(imageOverlayPath)
156
+ group.addChild(handles)
157
+ group.itemType = 'imageOverlays'
158
+ group.data.url = this.url
159
+ group.type = 'imageOverlays'
160
+ group.pathId = this.id
161
+ group.overlayId = this.id
162
+ group.visible = true
163
+ paperJSComponent.paths.imageOverlays[this.id] = group
164
+ }
165
+ imageOverlayPath.opacity = this.opacity
166
+ handles.visible = isRotationHandleVisible
167
+ }
168
+ loadImageOverlay(url, corners) {
169
+ let rasterImageOverlay = new Paper.Raster({
170
+ source: url,
171
+ crossOrigin: 'Anonymous'
172
+ })
173
+ rasterImageOverlay.onLoad = () => {
174
+ this.applyRasterToCorners(rasterImageOverlay, corners)
175
+ }
176
+ rasterImageOverlay.data.angle = 0
177
+ rasterImageOverlay.data.type = 'imageOverlayRaster'
178
+ rasterImageOverlay.data.overlayId = this.id
179
+ rasterImageOverlay.data.url = url
180
+ return rasterImageOverlay
181
+ }
182
+ applyRasterToCorners(texture, corners = this.corners) {
183
+ //remove angle of texture
184
+ let textureAngle = texture.angle || 0
185
+ texture.rotate(-textureAngle)
186
+
187
+ //make texture the same size to fit corners
188
+ const textureWidth = texture.bounds.width
189
+ const textureHeight = texture.bounds.height
190
+ const frameWidth = getDistanceBetweenPoints(corners[1], corners[0])
191
+ const frameHeight = getDistanceBetweenPoints(corners[3], corners[0])
192
+ const center = multiplyVector(0.5, addVector(corners[0], corners[2]))
193
+ if (texture.bounds.width) {
194
+ var a = frameWidth / textureWidth
195
+ var b = 0
196
+ var c = 0
197
+ var d = frameHeight / textureHeight
198
+ texture.transform(new Paper.Matrix(a, b, c, d, 0, 0))
199
+ //translate to fit top left corner
200
+ var tx = center.x - texture.bounds.center.x
201
+ var ty = center.y - texture.bounds.center.y
202
+ texture.transform(new Paper.Matrix(1, 0, 0, 1, tx, ty))
203
+ //rotate
204
+ let angle = getAngleInDegFromCanvasVector(
205
+ substractVector(corners[0], corners[3])
206
+ )
207
+
208
+ texture.angle = angle
209
+ texture.rotate(angle)
210
+ }
211
+ }
212
+ renderImageOverlayHandles(corners, rotateHandleVisible, group = null) {
213
+ let circleHandle
214
+ let hasPaths = !!group
215
+ let handles = group || new Paper.Group()
216
+ let u = normalize2DVector(substractVector(corners[1], corners[0]))
217
+ let v = normalize2DVector(substractVector(corners[0], corners[3]))
218
+
219
+ //rotation handle
220
+ let center = multiplyVector(0.5, addVector(corners[0], corners[2]))
221
+
222
+ let radius = vectorLength2D(substractVector(center, corners[0])) - 10
223
+ if (!hasPaths) {
224
+ circleHandle = new Paper.Path.Circle(center, radius)
225
+ circleHandle.fillColor = layerColors.imageOverlayHandle.fillColor
226
+ circleHandle.strokeWidth = layerColors.imageOverlayHandle.strokeWidth
227
+ circleHandle.strokeColor = layerColors.imageOverlayHandle.strokeColor
228
+ circleHandle.data.type = 'imageOverlayRotateHandle'
229
+ circleHandle.data.overlayId = this.id
230
+ circleHandle.radius = radius
231
+ handles.addChild(circleHandle)
232
+ } else {
233
+ circleHandle = handles.children[0]
234
+ let ratio = radius / circleHandle.radius
235
+ circleHandle.transform(new Paper.Matrix(ratio, 0, 0, ratio, 0, 0))
236
+ circleHandle.position = center
237
+ circleHandle.radius = radius
238
+ }
239
+
240
+ circleHandle.visible = rotateHandleVisible
241
+
242
+ //scale handle
243
+ for (let k = 0; k < 4; k++) {
244
+ let squareSize = 10
245
+ let squareHandleVertices = [
246
+ addVector(
247
+ addVector(corners[k], multiplyVector(squareSize / 2, u)),
248
+ multiplyVector(squareSize / 2, v)
249
+ ),
250
+ addVector(
251
+ addVector(corners[k], multiplyVector(-squareSize / 2, u)),
252
+ multiplyVector(squareSize / 2, v)
253
+ ),
254
+ addVector(
255
+ addVector(corners[k], multiplyVector(-squareSize / 2, u)),
256
+ multiplyVector(-squareSize / 2, v)
257
+ ),
258
+ addVector(
259
+ addVector(corners[k], multiplyVector(squareSize / 2, u)),
260
+ multiplyVector(-squareSize / 2, v)
261
+ ),
262
+ addVector(
263
+ addVector(corners[k], multiplyVector(squareSize / 2, u)),
264
+ multiplyVector(squareSize / 2, v)
265
+ )
266
+ ]
267
+ let squareHandle
268
+
269
+ if (hasPaths) {
270
+ squareHandle = handles.children[k + 1]
271
+ squareHandle.position = corners[k]
272
+ //squareHandle.rotate()
273
+ for (let index in squareHandleVertices) {
274
+ let vertex = squareHandleVertices[index]
275
+ squareHandle.segments[index].point = vertex
276
+ }
277
+ } else {
278
+ squareHandle = new Paper.Path()
279
+
280
+ for (let vertex of squareHandleVertices) {
281
+ squareHandle.add(vertex)
282
+ }
283
+
284
+ squareHandle.fillColor = layerColors.imageOverlayHandle.fillColor
285
+ squareHandle.strokeWidth = layerColors.imageOverlayHandle.strokeWidth
286
+ squareHandle.strokeColor = layerColors.imageOverlayHandle.strokeColor
287
+ squareHandle.data.type = 'handle'
288
+ squareHandle.data.index = k
289
+
290
+ handles.addChild(squareHandle)
291
+ }
292
+ squareHandle.visible = false
293
+ }
294
+ return handles
295
+ }
296
+ renderOnThreeJS(threeJSComponent) {}
297
+ serializeSettings() {
298
+ return {
299
+ hasScale: this.hasScale,
300
+ scaleParams: {
301
+ points: this.points,
302
+ distance: this.distance,
303
+ mmPerPx: this.mmPerPx
304
+ },
305
+ corners: this.corners,
306
+ version: this.version
307
+ }
308
+ }
309
+ }
@@ -0,0 +1,255 @@
1
+ import { v4 as uuidv4 } from 'uuid'
2
+ import Item from '../Item/Item'
3
+ import {
4
+ multiplyVector,
5
+ addVector,
6
+ rotateTransformation,
7
+ substractVector,
8
+ getDistanceBetweenPoints,
9
+ getAngleInDegFromCanvasVector
10
+ } from '@eturnity/eturnity_maths'
11
+ import {
12
+ updateBufferRoofGeometry,
13
+ getBufferRoofGeometry
14
+ } from '../helper/render/geometryHandler'
15
+ import * as THREE from 'three'
16
+ import ProjectedMaterial from 'three-projected-material'
17
+ export default class Overlay extends Item {
18
+ constructor(overlay, emit) {
19
+ super(emit)
20
+ this.id = overlay.layouting_overlay_uuid
21
+ ? overlay.layouting_overlay_uuid.toString()
22
+ : uuidv4()
23
+ this.actionsAvailable.push('setOpacity')
24
+ this.isActive = overlay.is_active
25
+ this.isReady = false
26
+ this.resources = overlay.resources
27
+ this.type = overlay.type
28
+ this.corners = overlay.settings.corners
29
+ this.placeHolderCorners = [
30
+ { x: 10000, y: 7000 },
31
+ { x: 10000, y: -7000 },
32
+ { x: -10000, y: -7000 },
33
+ { x: -10000, y: 7000 }
34
+ ]
35
+ this.positionOffset = overlay.settings.positionOffset || {
36
+ x: 0,
37
+ y: 0,
38
+ z: 0
39
+ }
40
+ this.angleOffset = overlay.settings.angleOffset || 0
41
+ this.imageUrl = null
42
+ this.imageOverlayProjectionMaterial = null
43
+ this.settings = overlay.settings
44
+ this.version = this.settings.version || 0
45
+ this.overlayProjectionCamera = new THREE.OrthographicCamera(
46
+ -20,
47
+ 20,
48
+ 20,
49
+ -20,
50
+ 1,
51
+ 1000
52
+ )
53
+ this.backgroundGeometry = null
54
+ this.overlayProjectionCamera.up.set(0, 1, 0)
55
+ this.isSelected = false
56
+ this.isReadyCallback = []
57
+ }
58
+ getCenter() {
59
+ let center = multiplyVector(
60
+ 0.5,
61
+ addVector(this.corners[0], this.corners[2])
62
+ )
63
+ return center
64
+ }
65
+ setOpacity(opacity) {
66
+ this.opacity = opacity
67
+ this.emit('item-updated', this)
68
+ }
69
+ translateBy(shift) {
70
+ this.version++
71
+ let newCorners = []
72
+ for (let cornerIndex in this.corners) {
73
+ let corner = this.corners[cornerIndex]
74
+ newCorners[cornerIndex] = {}
75
+ newCorners[cornerIndex].x = corner.x + shift.x
76
+ newCorners[cornerIndex].y = corner.y + shift.y
77
+ newCorners[cornerIndex].z = corner.z + shift.z
78
+ }
79
+ this.positionOffset.x += shift.x
80
+ this.positionOffset.y += shift.y
81
+ this.positionOffset.z += shift.z
82
+ this.corners = newCorners
83
+ this.emit('item-updated', this)
84
+ }
85
+ translate(newPositionOffset) {
86
+ this.version++
87
+ let newCorners = []
88
+ let shift = substractVector(newPositionOffset, this.positionOffset)
89
+ for (let cornerIndex in this.corners) {
90
+ let corner = this.corners[cornerIndex]
91
+ newCorners[cornerIndex] = {}
92
+ newCorners[cornerIndex].x = corner.x + shift.x
93
+ newCorners[cornerIndex].y = corner.y + shift.y
94
+ newCorners[cornerIndex].z = corner.z + shift.z
95
+ }
96
+ this.positionOffset = newPositionOffset
97
+ this.corners = newCorners
98
+ this.emit('item-updated', this)
99
+ }
100
+ rotateBy(deltaAngle) {
101
+ this.version++
102
+ const newCorners = this.corners
103
+ let center = multiplyVector(
104
+ 0.5,
105
+ addVector(this.corners[0], this.corners[2])
106
+ )
107
+ for (let k in this.corners) {
108
+ let corner = this.corners[k]
109
+ newCorners[k] = rotateTransformation(corner, deltaAngle, center)
110
+ newCorners[k].z = this.corners[k].z
111
+ }
112
+ this.angleOffset += deltaAngle
113
+ this.corners = newCorners
114
+ this.emit('item-updated', this)
115
+ }
116
+ rotate(newAngle) {
117
+ this.version++
118
+ const newCorners = this.corners
119
+ let center = multiplyVector(
120
+ 0.5,
121
+ addVector(this.corners[0], this.corners[2])
122
+ )
123
+ for (let k in this.corners) {
124
+ let corner = this.corners[k]
125
+ newCorners[k] = rotateTransformation(
126
+ corner,
127
+ newAngle - this.angleOffset,
128
+ center
129
+ )
130
+ newCorners[k].z = this.corners[k].z
131
+ }
132
+ this.angleOffset = newAngle
133
+ this.corners = newCorners
134
+ this.emit('item-updated', this)
135
+ }
136
+ async getProjectionMaterial() {
137
+ if (!this.isReady || !this.corners) {
138
+ return null
139
+ }
140
+ const url = this.imageUrl
141
+ return new Promise((resolve) => {
142
+ if (this.imageOverlayProjectionMaterial) {
143
+ const cameraChanged = this.setImageOverlayCameraPosition()
144
+ if (cameraChanged) {
145
+ this.imageOverlayProjectionMaterial.userData.version++
146
+ }
147
+ this.imageOverlayProjectionMaterial.opacity = this.opacity
148
+ resolve(this.imageOverlayProjectionMaterial)
149
+ return
150
+ }
151
+ const loader = new THREE.TextureLoader()
152
+ loader.load(url, (texture) => {
153
+ this.setImageOverlayCameraPosition()
154
+ let imageOverlayProjectionMaterial = new ProjectedMaterial({
155
+ camera: this.overlayProjectionCamera,
156
+ texture,
157
+ transparent: true,
158
+ side: THREE.DoubleSide
159
+ })
160
+
161
+ imageOverlayProjectionMaterial.userData = {}
162
+ imageOverlayProjectionMaterial.userData.type = 'overlayMaterial'
163
+ imageOverlayProjectionMaterial.userData.version = 0
164
+ imageOverlayProjectionMaterial.priority = 30
165
+ imageOverlayProjectionMaterial.userData.url = url
166
+ imageOverlayProjectionMaterial.opacity = this.opacity
167
+ this.imageOverlayProjectionMaterial = imageOverlayProjectionMaterial
168
+ resolve(imageOverlayProjectionMaterial)
169
+ })
170
+ })
171
+ }
172
+ getBackgroundGeometry() {
173
+ const outline = this.corners.map((p) => {
174
+ return { ...p, z: 100 }
175
+ })
176
+ if (this.backgroundGeometry) {
177
+ this.backgroundGeometry = updateBufferRoofGeometry(
178
+ outline,
179
+ [],
180
+ this.backgroundGeometry
181
+ )
182
+ } else {
183
+ this.backgroundGeometry = getBufferRoofGeometry(outline, [])
184
+ }
185
+ return this.backgroundGeometry
186
+ }
187
+ setImageOverlayCameraPosition() {
188
+ let cameraChanged = false
189
+ const boxCenter = multiplyVector(
190
+ 0.5,
191
+ addVector(this.corners[0], this.corners[2])
192
+ )
193
+ boxCenter.z = 0
194
+ const boxSize = {
195
+ x: getDistanceBetweenPoints(this.corners[0], this.corners[1]) / 1000,
196
+ y: getDistanceBetweenPoints(this.corners[1], this.corners[2]) / 1000,
197
+ z: 0
198
+ }
199
+ if (
200
+ this.overlayProjectionCamera.left != -boxSize.x / 2 ||
201
+ this.overlayProjectionCamera.right != boxSize.x / 2 ||
202
+ this.overlayProjectionCamera.top != boxSize.y / 2 ||
203
+ this.overlayProjectionCamera.bottom != -boxSize.y / 2
204
+ ) {
205
+ cameraChanged = true
206
+ }
207
+ this.overlayProjectionCamera.left = -boxSize.x / 2
208
+ this.overlayProjectionCamera.right = boxSize.x / 2
209
+ this.overlayProjectionCamera.top = boxSize.y / 2
210
+ this.overlayProjectionCamera.bottom = -boxSize.y / 2
211
+
212
+ let zAngle = getAngleInDegFromCanvasVector(
213
+ substractVector(this.corners[3], this.corners[0])
214
+ )
215
+ if (this.overlayProjectionCamera.rotation.z != (zAngle * Math.PI) / 180) {
216
+ cameraChanged = true
217
+ }
218
+ this.overlayProjectionCamera.rotation.set(0, 0, (zAngle * Math.PI) / 180)
219
+ if (
220
+ this.overlayProjectionCamera.position.x != boxCenter.x / 1000 ||
221
+ this.overlayProjectionCamera.position.y != boxCenter.y / 1000 ||
222
+ this.overlayProjectionCamera.position.z != boxCenter.z / 1000 + 50
223
+ ) {
224
+ cameraChanged = true
225
+ }
226
+ this.overlayProjectionCamera.position.set(
227
+ boxCenter.x / 1000,
228
+ boxCenter.y / 1000,
229
+ boxCenter.z / 1000 + 50
230
+ )
231
+ this.overlayProjectionCamera.updateProjectionMatrix()
232
+ return cameraChanged
233
+ }
234
+ serialize() {
235
+ const serializedOverlay = {
236
+ layouting_overlay_uuid: this.id,
237
+ settings: {
238
+ ...this.settings,
239
+ positionOffset: this.positionOffset,
240
+ angleOffset: this.angleOffset,
241
+ ...this.serializeSettings()
242
+ },
243
+ type: this.type,
244
+ is_active: this.isActive,
245
+ resources: this.resources
246
+ }
247
+ return serializedOverlay
248
+ }
249
+
250
+ renderOnPaperJS(paperJSComponent) {}
251
+ renderOnThreeJS(threeJSComponent) {}
252
+ serializeSettings() {
253
+ return {}
254
+ }
255
+ }
@@ -0,0 +1,19 @@
1
+ import Overlay from './Overlay'
2
+ import AirTeamOverlay from './AirTeamOverlay'
3
+ import ImageOverlay from './ImageOverlay'
4
+
5
+ const OverlayFactory = {
6
+ createOverlay(serializedOverlay, emit, origin = { lat: null, lng: null }) {
7
+ let overlayInstance
8
+ if (serializedOverlay.type == 'airteam') {
9
+ overlayInstance = new AirTeamOverlay(serializedOverlay, emit, origin)
10
+ } else if (serializedOverlay.type == 'image_overlay') {
11
+ overlayInstance = new ImageOverlay(serializedOverlay, emit)
12
+ } else {
13
+ overlayInstance = new Overlay(serializedOverlay, emit)
14
+ }
15
+ return overlayInstance
16
+ }
17
+ }
18
+
19
+ export default OverlayFactory
@@ -0,0 +1,36 @@
1
+ import OverlayFactory from './OverlayFactory'
2
+ import LayerManager from '../Layer/Layer'
3
+ class OverlayLayer extends LayerManager {
4
+ constructor() {
5
+ super()
6
+ this.id = Math.random().toString(36) // Unique ID for instance
7
+ this.availableEvents.push(
8
+ 'items-updated',
9
+ 'overlay-scale-updated',
10
+ 'overlay-is-ready',
11
+ 'overlay-offset-position-error',
12
+ 'overlay-three-loaded'
13
+ )
14
+ }
15
+ addOrUpdateSerializedItems(
16
+ serializedOverlays,
17
+ origin = { lat: null, lng: null }
18
+ ) {
19
+ let addedOverlays = []
20
+ serializedOverlays.forEach((serializedOverlay) => {
21
+ let overlayInstance = OverlayFactory.createOverlay(
22
+ serializedOverlay,
23
+ (...arg) => {
24
+ return this.emit.call(this, ...arg)
25
+ },
26
+ origin
27
+ )
28
+ addedOverlays.push(overlayInstance)
29
+ this.addOrUpdateItem(overlayInstance)
30
+ })
31
+ return addedOverlays
32
+ }
33
+ }
34
+
35
+ const OverlayLayerInstance = new OverlayLayer()
36
+ export default OverlayLayerInstance
@@ -15,7 +15,7 @@ import {
15
15
  updateComputedGeometryPolygon,
16
16
  normalizeVector
17
17
  } from '@eturnity/eturnity_maths'
18
-
18
+ import OverlayLayer from '../Overlay/OverlayLayer.js'
19
19
  import threeMixin from '../helper/threeMixin'
20
20
 
21
21
  export default {
@@ -34,6 +34,10 @@ export default {
34
34
  beforeDestroy() {
35
35
  clearInterval(this.intervalId)
36
36
  cancelAnimationFrame(this.animationFrameId)
37
+ OverlayLayer.removeEventListener(
38
+ 'overlay-is-ready',
39
+ this.updateOverlayRendering
40
+ )
37
41
  },
38
42
  mixins: [threeMixin],
39
43
  async mounted() {
@@ -72,8 +76,12 @@ export default {
72
76
  this.setCamera(polygon, this.view_mode)
73
77
  }
74
78
  this.isReady.geometry = true
75
- this.render()
76
79
  this.intervalId = setInterval(() => this.render(), 500)
80
+ OverlayLayer.addEventListener(
81
+ 'overlay-is-ready',
82
+ this.updateOverlayRendering
83
+ )
84
+ this.render()
77
85
  },
78
86
  computed: {
79
87
  ...mapState({
@@ -190,8 +198,11 @@ export default {
190
198
  distance =
191
199
  5 + objectRadius / Math.sin(((this.camera.fov / 2) * Math.PI) / 180)
192
200
  }
193
-
194
- polygonRef = updateComputedGeometryPolygon(polygonRef)
201
+ try {
202
+ polygonRef = updateComputedGeometryPolygon(polygonRef)
203
+ } catch (err) {
204
+ console.error(err)
205
+ }
195
206
  const targetVector = polygonRef.meanPoint
196
207
  //const target=[targetVector.x/1000,targetVector.y/1000,targetVector.z/1000]
197
208
  let cameraMoveVector = { x: 0, y: 0, z: 0 }
@@ -292,11 +303,11 @@ export default {
292
303
  watch: {
293
304
  isReady: {
294
305
  handler() {
306
+ const overlayReady = OverlayLayer.getItems().length == 0 || this.isReady.overlay
295
307
  if (
296
308
  this.isReady.texturesToLoad == this.isReady.texturesLoaded &&
297
309
  this.isReady.geometry &&
298
- this.isReady.threeMap &&
299
- this.isReady.camera
310
+ overlayReady
300
311
  ) {
301
312
  var event = new CustomEvent('screenshotable')
302
313
  // dispatch the custom event