@eturnity/eturnity_3d 8.4.3-EPDM-12535.1 → 8.4.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 +2 -2
- package/src/Overlay/ImageOverlay.js +135 -7
- package/src/Overlay/Overlay.js +14 -118
- package/src/Overlay/OverlayFactory.js +0 -3
- package/src/Overlay/OverlayLayer.js +0 -6
- package/src/Overlay/ThreeDModelOverlay.js +119 -11
- package/src/helper/render/imageOverlay.js +9 -23
- package/src/helper/render/overlay.js +5 -60
- package/src/helper/render/projectionMaterial.js +0 -2
- package/src/helper/render/roof.js +1 -0
- package/src/helper/renderMixin.js +0 -10
- package/src/Overlay/YearlySunShadingOverlay.js +0 -362
- package/src/helper/render/shadingMaterial/ShadingImageGenerator.js +0 -245
- package/src/helper/render/shadingMaterial/grids.js +0 -543
- package/src/helper/render/shadingMaterial/gridsOld.js +0 -527
- package/src/helper/render/shadingMaterial/helper.js +0 -109
- package/src/helper/render/shadingMaterial/yearlySunShaderMaterial.js +0 -338
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eturnity/eturnity_3d",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "8.4.3
|
|
4
|
+
"version": "8.4.3",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
7
|
"src"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"prettier": "prettier --write \"**/*.{js,vue}\""
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@eturnity/eturnity_maths": "8.4.2
|
|
18
|
+
"@eturnity/eturnity_maths": "8.4.2",
|
|
19
19
|
"@originjs/vite-plugin-commonjs": "1.0.3",
|
|
20
20
|
"core-js": "3.30.2",
|
|
21
21
|
"cors": "2.8.5",
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
normalize2DVector,
|
|
10
10
|
vectorLength2D,
|
|
11
11
|
} from '@eturnity/eturnity_maths'
|
|
12
|
+
let Paper
|
|
12
13
|
export default class ImageOverlay extends Overlay {
|
|
13
14
|
constructor(overlay, emit) {
|
|
14
15
|
super(overlay, emit)
|
|
@@ -41,6 +42,15 @@ export default class ImageOverlay extends Overlay {
|
|
|
41
42
|
this.isReadyCallback = []
|
|
42
43
|
})
|
|
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
|
+
}
|
|
44
54
|
async initialiseImage(url) {
|
|
45
55
|
const img = new Image()
|
|
46
56
|
img.crossOrigin = 'Anonymous'
|
|
@@ -110,7 +120,7 @@ export default class ImageOverlay extends Overlay {
|
|
|
110
120
|
this.emit('overlay-scale-updated', { id: this.id })
|
|
111
121
|
}
|
|
112
122
|
renderOnPaperJS(paperJSComponent) {
|
|
113
|
-
|
|
123
|
+
Paper = paperJSComponent.paperScope
|
|
114
124
|
if (!this.isReady || !this.isActive || !this.corners) {
|
|
115
125
|
return
|
|
116
126
|
}
|
|
@@ -130,9 +140,15 @@ export default class ImageOverlay extends Overlay {
|
|
|
130
140
|
paperJSComponent.clearPath(group.children[0])
|
|
131
141
|
group.insertChild(0, imageOverlayPath)
|
|
132
142
|
}
|
|
143
|
+
handles = this.renderImageOverlayHandles(
|
|
144
|
+
corners,
|
|
145
|
+
isRotationHandleVisible,
|
|
146
|
+
group.children[1]
|
|
147
|
+
)
|
|
133
148
|
this.applyRasterToCorners(imageOverlayPath, corners)
|
|
149
|
+
group.visible = true
|
|
134
150
|
} else {
|
|
135
|
-
group = new
|
|
151
|
+
group = new Paper.Group()
|
|
136
152
|
imageOverlayPath = this.loadImageOverlay(this.url, corners)
|
|
137
153
|
|
|
138
154
|
handles = this.renderImageOverlayHandles(corners, isRotationHandleVisible)
|
|
@@ -144,23 +160,21 @@ export default class ImageOverlay extends Overlay {
|
|
|
144
160
|
group.type = 'imageOverlays'
|
|
145
161
|
group.pathId = this.id
|
|
146
162
|
group.overlayId = this.id
|
|
163
|
+
group.visible = true
|
|
147
164
|
paperJSComponent.paths.imageOverlays[this.id] = group
|
|
148
165
|
}
|
|
149
|
-
group.visible = true
|
|
150
166
|
imageOverlayPath.opacity = this.opacity
|
|
151
167
|
handles.visible = isRotationHandleVisible
|
|
152
168
|
}
|
|
153
169
|
loadImageOverlay(url, corners) {
|
|
154
170
|
let rasterImageOverlay = this.img
|
|
155
|
-
? new
|
|
156
|
-
: new
|
|
171
|
+
? new Paper.Raster(this.img)
|
|
172
|
+
: new Paper.Raster({
|
|
157
173
|
source: url,
|
|
158
174
|
crossOrigin: 'Anonymous',
|
|
159
175
|
})
|
|
160
|
-
rasterImageOverlay.visible = false
|
|
161
176
|
rasterImageOverlay.onLoad = () => {
|
|
162
177
|
this.applyRasterToCorners(rasterImageOverlay, corners)
|
|
163
|
-
rasterImageOverlay.visible = true
|
|
164
178
|
}
|
|
165
179
|
rasterImageOverlay.data.angle = 0
|
|
166
180
|
rasterImageOverlay.data.type = 'imageOverlayRaster'
|
|
@@ -168,6 +182,120 @@ export default class ImageOverlay extends Overlay {
|
|
|
168
182
|
rasterImageOverlay.data.url = url
|
|
169
183
|
return rasterImageOverlay
|
|
170
184
|
}
|
|
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
|
+
}
|
|
171
299
|
renderOnThreeJS(threeJSComponent) {}
|
|
172
300
|
serializeSettings() {
|
|
173
301
|
return {
|
package/src/Overlay/Overlay.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid'
|
|
2
2
|
import Item from '../Item/Item'
|
|
3
|
-
import { layerColors } from '../config'
|
|
4
3
|
import {
|
|
5
4
|
multiplyVector,
|
|
6
5
|
addVector,
|
|
@@ -8,7 +7,6 @@ import {
|
|
|
8
7
|
substractVector,
|
|
9
8
|
getDistanceBetweenPoints,
|
|
10
9
|
getAngleInDegFromCanvasVector,
|
|
11
|
-
vectorLength2D,
|
|
12
10
|
} from '@eturnity/eturnity_maths'
|
|
13
11
|
import {
|
|
14
12
|
updateBufferRoofGeometry,
|
|
@@ -16,7 +14,6 @@ import {
|
|
|
16
14
|
} from '../helper/render/geometryHandler'
|
|
17
15
|
import * as THREE from 'three'
|
|
18
16
|
import ProjectedMaterial from '../helper/projectedMaterial'
|
|
19
|
-
|
|
20
17
|
export default class Overlay extends Item {
|
|
21
18
|
constructor(overlay, emit) {
|
|
22
19
|
super(emit)
|
|
@@ -24,7 +21,6 @@ export default class Overlay extends Item {
|
|
|
24
21
|
? overlay.layouting_overlay_uuid.toString()
|
|
25
22
|
: uuidv4()
|
|
26
23
|
this.actionsAvailable.push('setOpacity')
|
|
27
|
-
this.hasToBeSavedInBE = true
|
|
28
24
|
this.isActive = overlay.is_active
|
|
29
25
|
this.isReady = false
|
|
30
26
|
this.resources = overlay.resources
|
|
@@ -58,16 +54,6 @@ export default class Overlay extends Item {
|
|
|
58
54
|
this.overlayProjectionCamera.up.set(0, 1, 0)
|
|
59
55
|
this.isSelected = false
|
|
60
56
|
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
|
-
})
|
|
71
57
|
}
|
|
72
58
|
getCenter() {
|
|
73
59
|
let center = multiplyVector(
|
|
@@ -147,67 +133,17 @@ export default class Overlay extends Item {
|
|
|
147
133
|
this.corners = newCorners
|
|
148
134
|
this.emit('item-updated', this)
|
|
149
135
|
}
|
|
150
|
-
loadImageOverlay(url, corners) {
|
|
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, corners)
|
|
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
|
-
}
|
|
196
136
|
async getProjectionMaterial() {
|
|
197
|
-
if (!this.isReady || !this.
|
|
137
|
+
if (!this.isReady || !this.corners) {
|
|
198
138
|
return null
|
|
199
139
|
}
|
|
200
140
|
const url = this.imageUrl
|
|
201
141
|
return new Promise((resolve) => {
|
|
202
|
-
if (
|
|
203
|
-
this.imageOverlayProjectionMaterial &&
|
|
204
|
-
this.version == this.imageOverlayProjectionMaterial.userData.version
|
|
205
|
-
) {
|
|
142
|
+
if (this.imageOverlayProjectionMaterial) {
|
|
206
143
|
const cameraChanged = this.setImageOverlayCameraPosition()
|
|
207
144
|
if (cameraChanged) {
|
|
208
145
|
this.imageOverlayProjectionMaterial.userData.version++
|
|
209
146
|
}
|
|
210
|
-
this.imageOverlayProjectionMaterial.userData.version = this.version
|
|
211
147
|
this.imageOverlayProjectionMaterial.opacity = this.opacity
|
|
212
148
|
resolve(this.imageOverlayProjectionMaterial)
|
|
213
149
|
return
|
|
@@ -228,15 +164,14 @@ export default class Overlay extends Item {
|
|
|
228
164
|
|
|
229
165
|
imageOverlayProjectionMaterial.userData = {}
|
|
230
166
|
imageOverlayProjectionMaterial.userData.type = 'overlayMaterial'
|
|
231
|
-
imageOverlayProjectionMaterial.userData.overlayType = this.type
|
|
232
167
|
imageOverlayProjectionMaterial.userData.version = 0
|
|
233
|
-
imageOverlayProjectionMaterial.priority =
|
|
234
|
-
this.projectionMaterialPriority
|
|
168
|
+
imageOverlayProjectionMaterial.priority = 30
|
|
235
169
|
imageOverlayProjectionMaterial.userData.url = url
|
|
236
170
|
imageOverlayProjectionMaterial.opacity = this.opacity
|
|
237
171
|
this.imageOverlayProjectionMaterial = imageOverlayProjectionMaterial
|
|
238
172
|
resolve(imageOverlayProjectionMaterial)
|
|
239
173
|
}
|
|
174
|
+
|
|
240
175
|
if (this.img) {
|
|
241
176
|
callback(new THREE.Texture(this.img))
|
|
242
177
|
} else {
|
|
@@ -263,7 +198,7 @@ export default class Overlay extends Item {
|
|
|
263
198
|
setImageOverlayCameraPosition() {
|
|
264
199
|
let cameraChanged = false
|
|
265
200
|
const boxCenter = multiplyVector(
|
|
266
|
-
0.
|
|
201
|
+
0.5,
|
|
267
202
|
addVector(this.corners[0], this.corners[2])
|
|
268
203
|
)
|
|
269
204
|
boxCenter.z = 0
|
|
@@ -294,63 +229,21 @@ export default class Overlay extends Item {
|
|
|
294
229
|
this.overlayProjectionCamera.rotation.set(0, 0, (zAngle * Math.PI) / 180)
|
|
295
230
|
const CAMERA_HEIGHT_OFFSET = 50
|
|
296
231
|
if (
|
|
297
|
-
this.overlayProjectionCamera.position.x != boxCenter.x ||
|
|
298
|
-
this.overlayProjectionCamera.position.y != boxCenter.y ||
|
|
232
|
+
this.overlayProjectionCamera.position.x != boxCenter.x / 1000 ||
|
|
233
|
+
this.overlayProjectionCamera.position.y != boxCenter.y / 1000 ||
|
|
299
234
|
this.overlayProjectionCamera.position.z !=
|
|
300
|
-
boxCenter.z + CAMERA_HEIGHT_OFFSET
|
|
235
|
+
boxCenter.z / 1000 + CAMERA_HEIGHT_OFFSET
|
|
301
236
|
) {
|
|
302
237
|
cameraChanged = true
|
|
303
238
|
}
|
|
304
239
|
this.overlayProjectionCamera.position.set(
|
|
305
|
-
boxCenter.x,
|
|
306
|
-
boxCenter.y,
|
|
307
|
-
boxCenter.z + CAMERA_HEIGHT_OFFSET
|
|
240
|
+
boxCenter.x / 1000,
|
|
241
|
+
boxCenter.y / 1000,
|
|
242
|
+
boxCenter.z / 1000 + CAMERA_HEIGHT_OFFSET
|
|
308
243
|
)
|
|
309
244
|
this.overlayProjectionCamera.updateProjectionMatrix()
|
|
310
245
|
return cameraChanged
|
|
311
246
|
}
|
|
312
|
-
renderImageOverlayHandles(corners, rotateHandleVisible, group = null) {
|
|
313
|
-
let circleHandle
|
|
314
|
-
let hasPaths = !!group
|
|
315
|
-
let handles = group || new this.Paper.Group()
|
|
316
|
-
//rotation handle
|
|
317
|
-
let center = multiplyVector(0.5, addVector(corners[0], corners[2]))
|
|
318
|
-
|
|
319
|
-
let radius = vectorLength2D(substractVector(center, corners[0])) - 10
|
|
320
|
-
if (!hasPaths) {
|
|
321
|
-
circleHandle = new this.Paper.Path.Circle(center, radius)
|
|
322
|
-
circleHandle.fillColor = layerColors.imageOverlayHandle.fillColor
|
|
323
|
-
circleHandle.strokeWidth = layerColors.imageOverlayHandle.strokeWidth
|
|
324
|
-
circleHandle.strokeColor = layerColors.imageOverlayHandle.strokeColor
|
|
325
|
-
circleHandle.data.type = 'imageOverlayRotateHandle'
|
|
326
|
-
circleHandle.data.overlayId = this.id
|
|
327
|
-
circleHandle.radius = radius
|
|
328
|
-
handles.addChild(circleHandle)
|
|
329
|
-
} else {
|
|
330
|
-
circleHandle = handles.children[0]
|
|
331
|
-
let ratio = radius / circleHandle.radius
|
|
332
|
-
circleHandle.transform(new this.Paper.Matrix(ratio, 0, 0, ratio, 0, 0))
|
|
333
|
-
circleHandle.position = center
|
|
334
|
-
circleHandle.radius = radius
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
circleHandle.visible = rotateHandleVisible
|
|
338
|
-
return handles
|
|
339
|
-
}
|
|
340
|
-
createCanvas() {
|
|
341
|
-
const canvas = document.createElement('canvas')
|
|
342
|
-
canvas.width = this.canvasWidth
|
|
343
|
-
canvas.height = this.canvasHeight
|
|
344
|
-
canvas.style.position = 'fixed'
|
|
345
|
-
canvas.style.top = '100px'
|
|
346
|
-
canvas.style.left = '50px'
|
|
347
|
-
canvas.style.zIndex = 0
|
|
348
|
-
// Add the canvas to the document body
|
|
349
|
-
document.body.appendChild(canvas)
|
|
350
|
-
return canvas
|
|
351
|
-
}
|
|
352
|
-
renderOnPaperJS(paperJSComponent) {}
|
|
353
|
-
renderOnThreeJS(threeJSComponent) {}
|
|
354
247
|
serialize() {
|
|
355
248
|
const serializedOverlay = {
|
|
356
249
|
layouting_overlay_uuid: this.id,
|
|
@@ -366,6 +259,9 @@ export default class Overlay extends Item {
|
|
|
366
259
|
}
|
|
367
260
|
return serializedOverlay
|
|
368
261
|
}
|
|
262
|
+
|
|
263
|
+
renderOnPaperJS(paperJSComponent) {}
|
|
264
|
+
renderOnThreeJS(threeJSComponent) {}
|
|
369
265
|
serializeSettings() {
|
|
370
266
|
return {}
|
|
371
267
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Overlay from './Overlay'
|
|
2
2
|
import GLBOverlay from './GLBOverlay'
|
|
3
3
|
import ImageOverlay from './ImageOverlay'
|
|
4
|
-
import YearlySunShadingOverlay from './YearlySunShadingOverlay'
|
|
5
4
|
|
|
6
5
|
const OverlayFactory = {
|
|
7
6
|
createOverlay(serializedOverlay, emit, origin = { lat: null, lng: null }) {
|
|
@@ -10,8 +9,6 @@ const OverlayFactory = {
|
|
|
10
9
|
overlayInstance = new GLBOverlay(serializedOverlay, emit, origin)
|
|
11
10
|
} else if (serializedOverlay.type == 'image_overlay') {
|
|
12
11
|
overlayInstance = new ImageOverlay(serializedOverlay, emit)
|
|
13
|
-
} else if (serializedOverlay.type == 'yearly_sun_shading') {
|
|
14
|
-
overlayInstance = new YearlySunShadingOverlay(serializedOverlay, emit)
|
|
15
12
|
} else {
|
|
16
13
|
overlayInstance = new Overlay(serializedOverlay, emit)
|
|
17
14
|
}
|
|
@@ -12,12 +12,6 @@ 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
|
-
}
|
|
21
15
|
addOrUpdateSerializedItems(
|
|
22
16
|
serializedOverlays,
|
|
23
17
|
origin = { lat: null, lng: null }
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import Overlay from './Overlay'
|
|
2
2
|
import * as THREE from 'three'
|
|
3
|
+
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
|
|
4
|
+
import { layerColors } from '../config'
|
|
3
5
|
import {
|
|
6
|
+
getDistanceBetweenPoints,
|
|
4
7
|
addVector,
|
|
5
8
|
multiplyVector,
|
|
9
|
+
substractVector,
|
|
10
|
+
getAngleInDegFromCanvasVector,
|
|
11
|
+
normalize2DVector,
|
|
6
12
|
isInsidePolygon,
|
|
7
13
|
calculateBestFittingPlanePolygon,
|
|
8
14
|
verticalProjectionOnPlane,
|
|
15
|
+
vectorLength2D,
|
|
16
|
+
deltaLatLngToDistance,
|
|
9
17
|
rotateTransformation,
|
|
10
18
|
getStandardDeviation,
|
|
11
19
|
} from '@eturnity/eturnity_maths'
|
|
20
|
+
let Paper
|
|
12
21
|
export default class ThreeDModelOverlay extends Overlay {
|
|
13
22
|
constructor(overlay, emit, origin, loader) {
|
|
14
23
|
super(overlay, emit)
|
|
@@ -35,6 +44,15 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
35
44
|
this.geoLocalisation = this.settings.geoLocalisation
|
|
36
45
|
}
|
|
37
46
|
loadFile() {}
|
|
47
|
+
onLoad() {
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
if (this.isReady) {
|
|
50
|
+
resolve(this)
|
|
51
|
+
} else {
|
|
52
|
+
this.isReadyCallback.push(resolve)
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
}
|
|
38
56
|
set3DObjectMaterialOpacity(obj) {
|
|
39
57
|
obj.children.forEach((child) => {
|
|
40
58
|
this.set3DObjectMaterialOpacity(child, this.opacity)
|
|
@@ -47,6 +65,7 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
47
65
|
if (this.overlayMesh && this.overlayMesh.children.length == 0) {
|
|
48
66
|
this.overlayMesh = await this.loadFile()
|
|
49
67
|
}
|
|
68
|
+
|
|
50
69
|
if (!this.isReady) {
|
|
51
70
|
let waitingBall = threeJSComponent.meshes.overlayMeshes[this.id]
|
|
52
71
|
if (!waitingBall) {
|
|
@@ -107,10 +126,9 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
107
126
|
this.overlayMesh = overlayMesh
|
|
108
127
|
this.overlayMesh.frustumCulled = false
|
|
109
128
|
this.set3DObjectMaterialOpacity(this.overlayMesh)
|
|
110
|
-
return overlayMesh
|
|
111
129
|
}
|
|
112
130
|
renderOnPaperJS(paperJSComponent) {
|
|
113
|
-
|
|
131
|
+
Paper = paperJSComponent.paperScope
|
|
114
132
|
if (!this.isActive) {
|
|
115
133
|
return
|
|
116
134
|
}
|
|
@@ -121,7 +139,7 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
121
139
|
if (!paperJSComponent.loadingSpinner) {
|
|
122
140
|
return
|
|
123
141
|
}
|
|
124
|
-
group = new
|
|
142
|
+
group = new Paper.Group()
|
|
125
143
|
|
|
126
144
|
group.addChild(this.renderImagePlaceHolder(paperJSComponent))
|
|
127
145
|
group.itemType = 'placeholderOverlays'
|
|
@@ -132,7 +150,7 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
132
150
|
this.placeholderPath = group
|
|
133
151
|
|
|
134
152
|
paperJSComponent.paperLayer['loadingSpinners'].activate()
|
|
135
|
-
|
|
153
|
+
Paper.view.onFrame = (event) => this.animatePlaceholder(event)
|
|
136
154
|
}
|
|
137
155
|
paperJSComponent.paths.imageOverlays[this.id] = group
|
|
138
156
|
this.hasPlaceholderPath = true
|
|
@@ -169,7 +187,7 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
169
187
|
group.opacity = this.opacity
|
|
170
188
|
group.transparent = this.opacity != 1
|
|
171
189
|
} else {
|
|
172
|
-
group = new
|
|
190
|
+
group = new Paper.Group()
|
|
173
191
|
imageOverlayPath = this.loadImageOverlay(this.imageUrl, corners)
|
|
174
192
|
this.applyRasterToCorners(imageOverlayPath, corners)
|
|
175
193
|
handles = this.renderImageOverlayHandles(corners, isRotationHandleVisible)
|
|
@@ -191,15 +209,15 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
191
209
|
renderImagePlaceHolder(paperJSComponent) {
|
|
192
210
|
const toCanvasRef = paperJSComponent.canvasContext.toCanvasRef
|
|
193
211
|
|
|
194
|
-
const group = new
|
|
195
|
-
const circle = new
|
|
212
|
+
const group = new Paper.Group()
|
|
213
|
+
const circle = new Paper.Path.Circle({
|
|
196
214
|
center: toCanvasRef({ x: 0, y: 0 }),
|
|
197
215
|
radius: 50,
|
|
198
216
|
fillColor: '#ffffff80',
|
|
199
217
|
})
|
|
200
218
|
circle.radius = 70
|
|
201
219
|
circle.itemData = 'circle'
|
|
202
|
-
const fillRectangle = new
|
|
220
|
+
const fillRectangle = new Paper.Path()
|
|
203
221
|
fillRectangle.fillColor = '#ffffff80'
|
|
204
222
|
fillRectangle.itemType = 'placeholder'
|
|
205
223
|
fillRectangle.itemData = this
|
|
@@ -229,16 +247,92 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
229
247
|
circle.scale(scale)
|
|
230
248
|
circle.radius = newRadius
|
|
231
249
|
}
|
|
250
|
+
loadImageOverlay(url, corners) {
|
|
251
|
+
let rasterImageOverlay = new Paper.Raster({
|
|
252
|
+
source: url,
|
|
253
|
+
crossOrigin: 'Anonymous',
|
|
254
|
+
})
|
|
255
|
+
rasterImageOverlay.visible = false
|
|
256
|
+
rasterImageOverlay.onLoad = () => {
|
|
257
|
+
this.applyRasterToCorners(rasterImageOverlay, corners)
|
|
258
|
+
}
|
|
259
|
+
rasterImageOverlay.data.angle = 0
|
|
260
|
+
rasterImageOverlay.data.type = 'imageOverlayRaster'
|
|
261
|
+
rasterImageOverlay.data.overlayId = this.id
|
|
262
|
+
rasterImageOverlay.data.url = url
|
|
263
|
+
return rasterImageOverlay
|
|
264
|
+
}
|
|
265
|
+
applyRasterToCorners(texture, corners = this.corners) {
|
|
266
|
+
//remove angle of texture
|
|
267
|
+
let textureAngle = texture.angle || 0
|
|
268
|
+
texture.rotate(-textureAngle)
|
|
269
|
+
|
|
270
|
+
//make texture the same size to fit corners
|
|
271
|
+
const textureWidth = texture.bounds.width
|
|
272
|
+
const textureHeight = texture.bounds.height
|
|
273
|
+
const frameWidth = getDistanceBetweenPoints(corners[1], corners[0])
|
|
274
|
+
const frameHeight = getDistanceBetweenPoints(corners[3], corners[0])
|
|
275
|
+
const center = multiplyVector(0.5, addVector(corners[0], corners[2]))
|
|
276
|
+
if (texture.bounds.width) {
|
|
277
|
+
var a = frameWidth / textureWidth
|
|
278
|
+
var b = 0
|
|
279
|
+
var c = 0
|
|
280
|
+
var d = frameHeight / textureHeight
|
|
281
|
+
texture.transform(new Paper.Matrix(a, b, c, d, 0, 0))
|
|
282
|
+
//translate to fit top left corner
|
|
283
|
+
var tx = center.x - texture.bounds.center.x
|
|
284
|
+
var ty = center.y - texture.bounds.center.y
|
|
285
|
+
texture.transform(new Paper.Matrix(1, 0, 0, 1, tx, ty))
|
|
286
|
+
//rotate
|
|
287
|
+
let angle = getAngleInDegFromCanvasVector(
|
|
288
|
+
substractVector(corners[0], corners[3])
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
texture.angle = angle
|
|
292
|
+
texture.rotate(angle)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
renderImageOverlayHandles(corners, rotateHandleVisible, group = null) {
|
|
296
|
+
let circleHandle
|
|
297
|
+
let hasPaths = !!group
|
|
298
|
+
let handles = group || new Paper.Group()
|
|
299
|
+
let u = normalize2DVector(substractVector(corners[1], corners[0]))
|
|
300
|
+
let v = normalize2DVector(substractVector(corners[0], corners[3]))
|
|
301
|
+
|
|
302
|
+
//rotation handle
|
|
303
|
+
let center = multiplyVector(0.5, addVector(corners[0], corners[2]))
|
|
304
|
+
|
|
305
|
+
let radius = vectorLength2D(substractVector(center, corners[0])) - 10
|
|
306
|
+
if (!hasPaths) {
|
|
307
|
+
circleHandle = new Paper.Path.Circle(center, radius)
|
|
308
|
+
circleHandle.fillColor = layerColors.imageOverlayHandle.fillColor
|
|
309
|
+
circleHandle.strokeWidth = layerColors.imageOverlayHandle.strokeWidth
|
|
310
|
+
circleHandle.strokeColor = layerColors.imageOverlayHandle.strokeColor
|
|
311
|
+
circleHandle.data.type = 'imageOverlayRotateHandle'
|
|
312
|
+
circleHandle.data.overlayId = this.id
|
|
313
|
+
circleHandle.radius = radius
|
|
314
|
+
handles.addChild(circleHandle)
|
|
315
|
+
} else {
|
|
316
|
+
circleHandle = handles.children[0]
|
|
317
|
+
let ratio = radius / circleHandle.radius
|
|
318
|
+
circleHandle.transform(new Paper.Matrix(ratio, 0, 0, ratio, 0, 0))
|
|
319
|
+
circleHandle.position = center
|
|
320
|
+
circleHandle.radius = radius
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
circleHandle.visible = rotateHandleVisible
|
|
324
|
+
return handles
|
|
325
|
+
}
|
|
232
326
|
initialiseCornersAndProjectionCamera() {
|
|
233
327
|
const box = new THREE.Box3().setFromObject(this.overlayMesh)
|
|
234
328
|
const boxSize = box.getSize(new THREE.Vector3())
|
|
235
|
-
const boxCenter = box.getCenter(new THREE.Vector3())
|
|
236
329
|
this.boxSize = boxSize
|
|
237
|
-
|
|
330
|
+
const boxCenter = box.getCenter(new THREE.Vector3())
|
|
238
331
|
const left = -boxSize.x / 2
|
|
239
332
|
const right = +boxSize.x / 2
|
|
240
333
|
const top = +boxSize.y / 2
|
|
241
334
|
const bottom = -boxSize.y / 2
|
|
335
|
+
this.boxCenter = boxCenter
|
|
242
336
|
const initialCorners = [
|
|
243
337
|
{
|
|
244
338
|
x: 1000 * (boxCenter.x + left),
|
|
@@ -280,7 +374,9 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
280
374
|
1000 // far
|
|
281
375
|
)
|
|
282
376
|
}
|
|
283
|
-
checkGeoLocDataAndOffset() {
|
|
377
|
+
checkGeoLocDataAndOffset() {
|
|
378
|
+
return
|
|
379
|
+
}
|
|
284
380
|
async initialiseModel() {
|
|
285
381
|
this.overlayMesh = await this.loadFile()
|
|
286
382
|
if (!this.geoLocalisation) {
|
|
@@ -430,6 +526,18 @@ export default class ThreeDModelOverlay extends Overlay {
|
|
|
430
526
|
})
|
|
431
527
|
return newOutlines
|
|
432
528
|
}
|
|
529
|
+
createCanvas() {
|
|
530
|
+
const canvas = document.createElement('canvas')
|
|
531
|
+
canvas.width = this.canvasWidth
|
|
532
|
+
canvas.height = this.canvasHeight
|
|
533
|
+
canvas.style.position = 'fixed'
|
|
534
|
+
canvas.style.top = '100px'
|
|
535
|
+
canvas.style.left = '50px'
|
|
536
|
+
canvas.style.zIndex = 0
|
|
537
|
+
// Add the canvas to the document body
|
|
538
|
+
document.body.appendChild(canvas)
|
|
539
|
+
return canvas
|
|
540
|
+
}
|
|
433
541
|
serializeSettings() {
|
|
434
542
|
return {
|
|
435
543
|
version: this.version,
|