@eturnity/eturnity_3d 8.16.0 → 8.16.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_3d",
3
3
  "private": false,
4
- "version": "8.16.0",
4
+ "version": "8.16.2",
5
5
  "files": [
6
6
  "dist",
7
7
  "src"
@@ -16,7 +16,7 @@
16
16
  "merge-remote-master": "node scripts/merge-remote-master.js"
17
17
  },
18
18
  "dependencies": {
19
- "@eturnity/eturnity_maths": "8.16.0",
19
+ "@eturnity/eturnity_maths": "8.16.1",
20
20
  "@originjs/vite-plugin-commonjs": "1.0.3",
21
21
  "core-js": "3.30.2",
22
22
  "cors": "2.8.5",
@@ -9,7 +9,6 @@ import {
9
9
  normalize2DVector,
10
10
  vectorLength2D,
11
11
  } from '@eturnity/eturnity_maths'
12
- let Paper
13
12
  export default class ImageOverlay extends Overlay {
14
13
  constructor(overlay, emit) {
15
14
  super(overlay, emit)
@@ -42,15 +41,6 @@ export default class ImageOverlay extends Overlay {
42
41
  this.isReadyCallback = []
43
42
  })
44
43
  }
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
44
  async initialiseImage(url) {
55
45
  const img = new Image()
56
46
  img.crossOrigin = 'Anonymous'
@@ -120,7 +110,7 @@ export default class ImageOverlay extends Overlay {
120
110
  this.emit('overlay-scale-updated', { id: this.id })
121
111
  }
122
112
  renderOnPaperJS(paperJSComponent) {
123
- Paper = paperJSComponent.paperScope
113
+ this.Paper = paperJSComponent.paperScope
124
114
  if (!this.isReady || !this.isActive || !this.corners) {
125
115
  return
126
116
  }
@@ -131,28 +121,27 @@ export default class ImageOverlay extends Overlay {
131
121
  let handles
132
122
  let isRotationHandleVisible =
133
123
  paperJSComponent.selectedTool == 'selectOverlay' && this.isSelected
134
- let corners = this.corners.map((p) => paperJSComponent.toCanvasRef(p))
124
+ const getCorners = () =>
125
+ this.corners.map((p) => paperJSComponent.toCanvasRef(p))
126
+ let corners = getCorners()
135
127
  if (group) {
136
128
  if (group.data.url == this.url) {
137
129
  imageOverlayPath = group.children[0]
138
130
  } else {
139
- imageOverlayPath = this.loadImageOverlay(this.url, corners)
131
+ imageOverlayPath = this.loadImageOverlay(this.url, getCorners)
140
132
  paperJSComponent.clearPath(group.children[0])
141
133
  group.insertChild(0, imageOverlayPath)
142
134
  }
143
- handles = this.renderImageOverlayHandles(
135
+ this.renderImageOverlayHandles(
144
136
  corners,
145
137
  isRotationHandleVisible,
146
138
  group.children[1]
147
139
  )
148
140
  this.applyRasterToCorners(imageOverlayPath, corners)
149
- group.visible = true
150
141
  } else {
151
- group = new Paper.Group()
152
- imageOverlayPath = this.loadImageOverlay(this.url, corners)
153
-
142
+ group = new this.Paper.Group()
143
+ imageOverlayPath = this.loadImageOverlay(this.url, getCorners)
154
144
  handles = this.renderImageOverlayHandles(corners, isRotationHandleVisible)
155
-
156
145
  group.addChild(imageOverlayPath)
157
146
  group.addChild(handles)
158
147
  group.itemType = 'imageOverlays'
@@ -160,21 +149,23 @@ export default class ImageOverlay extends Overlay {
160
149
  group.type = 'imageOverlays'
161
150
  group.pathId = this.id
162
151
  group.overlayId = this.id
163
- group.visible = true
164
152
  paperJSComponent.paths.imageOverlays[this.id] = group
165
153
  }
154
+ group.visible = true
166
155
  imageOverlayPath.opacity = this.opacity
167
- handles.visible = isRotationHandleVisible
156
+ // handles.visible = isRotationHandleVisible
168
157
  }
169
- loadImageOverlay(url, corners) {
158
+ loadImageOverlay(url, getCorners = () => {}) {
170
159
  let rasterImageOverlay = this.img
171
- ? new Paper.Raster(this.img)
172
- : new Paper.Raster({
160
+ ? new this.Paper.Raster(this.img)
161
+ : new this.Paper.Raster({
173
162
  source: url,
174
163
  crossOrigin: 'Anonymous',
175
164
  })
165
+ rasterImageOverlay.visible = false
176
166
  rasterImageOverlay.onLoad = () => {
177
- this.applyRasterToCorners(rasterImageOverlay, corners)
167
+ this.applyRasterToCorners(rasterImageOverlay, getCorners())
168
+ rasterImageOverlay.visible = true
178
169
  }
179
170
  rasterImageOverlay.data.angle = 0
180
171
  rasterImageOverlay.data.type = 'imageOverlayRaster'
@@ -182,120 +173,6 @@ export default class ImageOverlay extends Overlay {
182
173
  rasterImageOverlay.data.url = url
183
174
  return rasterImageOverlay
184
175
  }
185
- applyRasterToCorners(texture, corners = this.corners) {
186
- //remove angle of texture
187
- let textureAngle = texture.angle || 0
188
- texture.rotate(-textureAngle)
189
-
190
- //make texture the same size to fit corners
191
- const textureWidth = texture.bounds.width
192
- const textureHeight = texture.bounds.height
193
- const frameWidth = getDistanceBetweenPoints(corners[1], corners[0])
194
- const frameHeight = getDistanceBetweenPoints(corners[3], corners[0])
195
- const center = multiplyVector(0.5, addVector(corners[0], corners[2]))
196
- if (texture.bounds.width) {
197
- var a = frameWidth / textureWidth
198
- var b = 0
199
- var c = 0
200
- var d = frameHeight / textureHeight
201
- texture.transform(new Paper.Matrix(a, b, c, d, 0, 0))
202
- //translate to fit top left corner
203
- var tx = center.x - texture.bounds.center.x
204
- var ty = center.y - texture.bounds.center.y
205
- texture.transform(new Paper.Matrix(1, 0, 0, 1, tx, ty))
206
- //rotate
207
- let angle = getAngleInDegFromCanvasVector(
208
- substractVector(corners[0], corners[3])
209
- )
210
-
211
- texture.angle = angle
212
- texture.rotate(angle)
213
- }
214
- }
215
- renderImageOverlayHandles(corners, rotateHandleVisible, group = null) {
216
- let circleHandle
217
- let hasPaths = !!group
218
- let handles = group || new Paper.Group()
219
- let u = normalize2DVector(substractVector(corners[1], corners[0]))
220
- let v = normalize2DVector(substractVector(corners[0], corners[3]))
221
-
222
- //rotation handle
223
- let center = multiplyVector(0.5, addVector(corners[0], corners[2]))
224
-
225
- let radius = vectorLength2D(substractVector(center, corners[0])) - 10
226
- if (!hasPaths) {
227
- circleHandle = new Paper.Path.Circle(center, radius)
228
- circleHandle.fillColor = layerColors.imageOverlayHandle.fillColor
229
- circleHandle.strokeWidth = layerColors.imageOverlayHandle.strokeWidth
230
- circleHandle.strokeColor = layerColors.imageOverlayHandle.strokeColor
231
- circleHandle.data.type = 'imageOverlayRotateHandle'
232
- circleHandle.data.overlayId = this.id
233
- circleHandle.radius = radius
234
- handles.addChild(circleHandle)
235
- } else {
236
- circleHandle = handles.children[0]
237
- let ratio = radius / circleHandle.radius
238
- circleHandle.transform(new Paper.Matrix(ratio, 0, 0, ratio, 0, 0))
239
- circleHandle.position = center
240
- circleHandle.radius = radius
241
- }
242
-
243
- circleHandle.visible = rotateHandleVisible
244
-
245
- //scale handle
246
- for (let k = 0; k < 4; k++) {
247
- let squareSize = 10
248
- let squareHandleVertices = [
249
- addVector(
250
- addVector(corners[k], multiplyVector(squareSize / 2, u)),
251
- multiplyVector(squareSize / 2, v)
252
- ),
253
- addVector(
254
- addVector(corners[k], multiplyVector(-squareSize / 2, u)),
255
- multiplyVector(squareSize / 2, v)
256
- ),
257
- addVector(
258
- addVector(corners[k], multiplyVector(-squareSize / 2, u)),
259
- multiplyVector(-squareSize / 2, v)
260
- ),
261
- addVector(
262
- addVector(corners[k], multiplyVector(squareSize / 2, u)),
263
- multiplyVector(-squareSize / 2, v)
264
- ),
265
- addVector(
266
- addVector(corners[k], multiplyVector(squareSize / 2, u)),
267
- multiplyVector(squareSize / 2, v)
268
- ),
269
- ]
270
- let squareHandle
271
-
272
- if (hasPaths) {
273
- squareHandle = handles.children[k + 1]
274
- squareHandle.position = corners[k]
275
- //squareHandle.rotate()
276
- for (let index in squareHandleVertices) {
277
- let vertex = squareHandleVertices[index]
278
- squareHandle.segments[index].point = vertex
279
- }
280
- } else {
281
- squareHandle = new Paper.Path()
282
-
283
- for (let vertex of squareHandleVertices) {
284
- squareHandle.add(vertex)
285
- }
286
-
287
- squareHandle.fillColor = layerColors.imageOverlayHandle.fillColor
288
- squareHandle.strokeWidth = layerColors.imageOverlayHandle.strokeWidth
289
- squareHandle.strokeColor = layerColors.imageOverlayHandle.strokeColor
290
- squareHandle.data.type = 'handle'
291
- squareHandle.data.index = k
292
-
293
- handles.addChild(squareHandle)
294
- }
295
- squareHandle.visible = false
296
- }
297
- return handles
298
- }
299
176
  renderOnThreeJS(threeJSComponent) {}
300
177
  serializeSettings() {
301
178
  return {
@@ -1,5 +1,6 @@
1
1
  import { v4 as uuidv4 } from 'uuid'
2
2
  import Item from '../Item/Item'
3
+ import { layerColors } from '../config'
3
4
  import {
4
5
  multiplyVector,
5
6
  addVector,
@@ -7,6 +8,7 @@ import {
7
8
  substractVector,
8
9
  getDistanceBetweenPoints,
9
10
  getAngleInDegFromCanvasVector,
11
+ vectorLength2D,
10
12
  } from '@eturnity/eturnity_maths'
11
13
  import {
12
14
  updateBufferRoofGeometry,
@@ -14,6 +16,7 @@ import {
14
16
  } from '../helper/render/geometryHandler'
15
17
  import * as THREE from 'three'
16
18
  import ProjectedMaterial from '../helper/projectedMaterial'
19
+
17
20
  export default class Overlay extends Item {
18
21
  constructor(overlay, emit) {
19
22
  super(emit)
@@ -21,6 +24,7 @@ export default class Overlay extends Item {
21
24
  ? overlay.layouting_overlay_uuid.toString()
22
25
  : uuidv4()
23
26
  this.actionsAvailable.push('setOpacity')
27
+ this.hasToBeSavedInBE = true
24
28
  this.isActive = overlay.is_active
25
29
  this.isReady = false
26
30
  this.resources = overlay.resources
@@ -54,6 +58,16 @@ export default class Overlay extends Item {
54
58
  this.overlayProjectionCamera.up.set(0, 1, 0)
55
59
  this.isSelected = false
56
60
  this.isReadyCallback = []
61
+ this.projectionMaterialPriority = 30
62
+ }
63
+ onLoad() {
64
+ return new Promise((resolve) => {
65
+ if (this.isReady) {
66
+ resolve(this)
67
+ } else {
68
+ this.isReadyCallback.push(resolve)
69
+ }
70
+ })
57
71
  }
58
72
  getCenter() {
59
73
  let center = multiplyVector(
@@ -133,17 +147,67 @@ export default class Overlay extends Item {
133
147
  this.corners = newCorners
134
148
  this.emit('item-updated', this)
135
149
  }
150
+ loadImageOverlay(url, getCorners = () => {}) {
151
+ let rasterImageOverlay = new this.Paper.Raster({
152
+ source: url,
153
+ crossOrigin: 'Anonymous',
154
+ })
155
+ rasterImageOverlay.visible = false
156
+ rasterImageOverlay.onLoad = () => {
157
+ this.applyRasterToCorners(rasterImageOverlay, getCorners())
158
+ rasterImageOverlay.visible = true
159
+ }
160
+ rasterImageOverlay.data.angle = 0
161
+ rasterImageOverlay.data.type = 'imageOverlayRaster'
162
+ rasterImageOverlay.data.overlayId = this.id
163
+ rasterImageOverlay.data.url = url
164
+ return rasterImageOverlay
165
+ }
166
+ applyRasterToCorners(texture, corners = this.corners) {
167
+ //remove angle of texture
168
+ let textureAngle = texture.angle || 0
169
+ texture.rotate(-textureAngle)
170
+
171
+ //make texture the same size to fit corners
172
+ const textureWidth = texture.bounds.width
173
+ const textureHeight = texture.bounds.height
174
+ const frameWidth = getDistanceBetweenPoints(corners[1], corners[0])
175
+ const frameHeight = getDistanceBetweenPoints(corners[3], corners[0])
176
+ const center = multiplyVector(0.5, addVector(corners[0], corners[2]))
177
+ if (texture.bounds.width) {
178
+ var a = frameWidth / textureWidth
179
+ var b = 0
180
+ var c = 0
181
+ var d = frameHeight / textureHeight
182
+ texture.transform(new this.Paper.Matrix(a, b, c, d, 0, 0))
183
+ //translate to fit top left corner
184
+ var tx = center.x - texture.bounds.center.x
185
+ var ty = center.y - texture.bounds.center.y
186
+ texture.transform(new this.Paper.Matrix(1, 0, 0, 1, tx, ty))
187
+ //rotate
188
+ let angle = getAngleInDegFromCanvasVector(
189
+ substractVector(corners[0], corners[3])
190
+ )
191
+
192
+ texture.angle = angle
193
+ texture.rotate(angle)
194
+ }
195
+ }
136
196
  async getProjectionMaterial() {
137
- if (!this.isReady || !this.corners) {
197
+ if (!this.isReady || !this.isActive || !this.corners) {
138
198
  return null
139
199
  }
140
200
  const url = this.imageUrl
141
201
  return new Promise((resolve) => {
142
- if (this.imageOverlayProjectionMaterial) {
202
+ if (
203
+ this.imageOverlayProjectionMaterial &&
204
+ this.version == this.imageOverlayProjectionMaterial.userData.version
205
+ ) {
143
206
  const cameraChanged = this.setImageOverlayCameraPosition()
144
207
  if (cameraChanged) {
145
208
  this.imageOverlayProjectionMaterial.userData.version++
146
209
  }
210
+ this.imageOverlayProjectionMaterial.userData.version = this.version
147
211
  this.imageOverlayProjectionMaterial.opacity = this.opacity
148
212
  resolve(this.imageOverlayProjectionMaterial)
149
213
  return
@@ -164,14 +228,15 @@ export default class Overlay extends Item {
164
228
 
165
229
  imageOverlayProjectionMaterial.userData = {}
166
230
  imageOverlayProjectionMaterial.userData.type = 'overlayMaterial'
231
+ imageOverlayProjectionMaterial.userData.overlayType = this.type
167
232
  imageOverlayProjectionMaterial.userData.version = 0
168
- imageOverlayProjectionMaterial.priority = 30
233
+ imageOverlayProjectionMaterial.priority =
234
+ this.projectionMaterialPriority
169
235
  imageOverlayProjectionMaterial.userData.url = url
170
236
  imageOverlayProjectionMaterial.opacity = this.opacity
171
237
  this.imageOverlayProjectionMaterial = imageOverlayProjectionMaterial
172
238
  resolve(imageOverlayProjectionMaterial)
173
239
  }
174
-
175
240
  if (this.img) {
176
241
  callback(new THREE.Texture(this.img))
177
242
  } else {
@@ -198,7 +263,7 @@ export default class Overlay extends Item {
198
263
  setImageOverlayCameraPosition() {
199
264
  let cameraChanged = false
200
265
  const boxCenter = multiplyVector(
201
- 0.5,
266
+ 0.0005,
202
267
  addVector(this.corners[0], this.corners[2])
203
268
  )
204
269
  boxCenter.z = 0
@@ -229,21 +294,60 @@ export default class Overlay extends Item {
229
294
  this.overlayProjectionCamera.rotation.set(0, 0, (zAngle * Math.PI) / 180)
230
295
  const CAMERA_HEIGHT_OFFSET = 50
231
296
  if (
232
- this.overlayProjectionCamera.position.x != boxCenter.x / 1000 ||
233
- this.overlayProjectionCamera.position.y != boxCenter.y / 1000 ||
297
+ this.overlayProjectionCamera.position.x != boxCenter.x ||
298
+ this.overlayProjectionCamera.position.y != boxCenter.y ||
234
299
  this.overlayProjectionCamera.position.z !=
235
- boxCenter.z / 1000 + CAMERA_HEIGHT_OFFSET
300
+ boxCenter.z + CAMERA_HEIGHT_OFFSET
236
301
  ) {
237
302
  cameraChanged = true
238
303
  }
239
304
  this.overlayProjectionCamera.position.set(
240
- boxCenter.x / 1000,
241
- boxCenter.y / 1000,
242
- boxCenter.z / 1000 + CAMERA_HEIGHT_OFFSET
305
+ boxCenter.x,
306
+ boxCenter.y,
307
+ boxCenter.z + CAMERA_HEIGHT_OFFSET
243
308
  )
244
309
  this.overlayProjectionCamera.updateProjectionMatrix()
245
310
  return cameraChanged
246
311
  }
312
+ renderImageOverlayHandles(corners, rotateHandleVisible, group = null) {
313
+ let circleHandle
314
+ const hasPaths = group?.children?.length > 0
315
+ const handles = group || new this.Paper.Group()
316
+ // rotation handle
317
+ const center = multiplyVector(0.5, addVector(corners[0], corners[2]))
318
+ const radius = vectorLength2D(substractVector(center, corners[0])) - 10
319
+ if (!hasPaths) {
320
+ circleHandle = new this.Paper.Path.Circle(center, radius)
321
+ circleHandle.fillColor = layerColors.imageOverlayHandle.fillColor
322
+ circleHandle.strokeWidth = layerColors.imageOverlayHandle.strokeWidth
323
+ circleHandle.strokeColor = layerColors.imageOverlayHandle.strokeColor
324
+ circleHandle.data.type = 'imageOverlayRotateHandle'
325
+ circleHandle.data.overlayId = this.id
326
+ circleHandle.radius = radius
327
+ handles.addChild(circleHandle)
328
+ } else {
329
+ circleHandle = handles.children[0]
330
+ let ratio = radius / circleHandle.radius
331
+ circleHandle.transform(new this.Paper.Matrix(ratio, 0, 0, ratio, 0, 0))
332
+ circleHandle.position = center
333
+ circleHandle.radius = radius
334
+ }
335
+
336
+ circleHandle.visible = rotateHandleVisible
337
+ return handles
338
+ }
339
+ createCanvas() {
340
+ const canvas = document.createElement('canvas')
341
+ canvas.width = this.canvasWidth
342
+ canvas.height = this.canvasHeight
343
+ canvas.style.position = 'fixed'
344
+ canvas.style.top = '100px'
345
+ canvas.style.left = '50px'
346
+ canvas.style.zIndex = 0
347
+ return canvas
348
+ }
349
+ renderOnPaperJS(paperJSComponent) {}
350
+ renderOnThreeJS(threeJSComponent) {}
247
351
  serialize() {
248
352
  const serializedOverlay = {
249
353
  layouting_overlay_uuid: this.id,
@@ -259,9 +363,6 @@ export default class Overlay extends Item {
259
363
  }
260
364
  return serializedOverlay
261
365
  }
262
-
263
- renderOnPaperJS(paperJSComponent) {}
264
- renderOnThreeJS(threeJSComponent) {}
265
366
  serializeSettings() {
266
367
  return {}
267
368
  }
@@ -1,6 +1,7 @@
1
1
  import Overlay from './Overlay'
2
2
  import GLBOverlay from './GLBOverlay'
3
3
  import ImageOverlay from './ImageOverlay'
4
+ import YearlySunShadingOverlay from './YearlySunShadingOverlay'
4
5
 
5
6
  const OverlayFactory = {
6
7
  createOverlay(serializedOverlay, emit, origin = { lat: null, lng: null }) {
@@ -9,6 +10,8 @@ const OverlayFactory = {
9
10
  overlayInstance = new GLBOverlay(serializedOverlay, emit, origin)
10
11
  } else if (serializedOverlay.type == 'image_overlay') {
11
12
  overlayInstance = new ImageOverlay(serializedOverlay, emit)
13
+ } else if (serializedOverlay.type == 'yearly_sun_shading') {
14
+ overlayInstance = new YearlySunShadingOverlay(serializedOverlay, emit)
12
15
  } else {
13
16
  overlayInstance = new Overlay(serializedOverlay, emit)
14
17
  }
@@ -12,6 +12,12 @@ class OverlayLayer extends LayerManager {
12
12
  'overlay-three-loaded'
13
13
  )
14
14
  }
15
+ getItemsToSaveInBE() {
16
+ return this.items.filter((item) => item.hasToBeSavedInBE)
17
+ }
18
+ getUserItems() {
19
+ return this.items.filter((item) => item.type != 'yearly_sun_shading')
20
+ }
15
21
  addOrUpdateSerializedItems(
16
22
  serializedOverlays,
17
23
  origin = { lat: null, lng: null }