@eturnity/eturnity_3d 6.31.0 → 6.31.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 +2 -2
- package/src/components/ThreeCanvasViewer.vue +6 -7
- package/src/config.js +1 -1
- package/src/helper/materialMixin.js +75 -0
- package/src/helper/render/background.js +2 -34
- package/src/helper/render/clear.js +2 -2
- package/src/helper/render/edge.js +42 -56
- package/src/helper/render/geometryHandler.js +50 -1
- package/src/helper/render/imageOverlay.js +126 -0
- package/src/helper/render/index.js +5 -1
- package/src/helper/render/loader.js +3 -60
- package/src/helper/render/mapProjection.js +86 -0
- package/src/helper/render/obstacle.js +2 -8
- package/src/helper/render/projectionMaterial.js +57 -0
- package/src/helper/render/roof.js +19 -8
- package/src/helper/render/texture.js +19 -0
- package/src/helper/renderMixin.js +43 -38
- package/src/store/hydrateData.js +10 -1
- package/src/store/three-d-module.js +8 -1
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eturnity/eturnity_3d",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "6.31.
|
|
4
|
+
"version": "6.31.2",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vue-cli-service serve --skip-plugins @vue/cli-plugin-eslint",
|
|
8
8
|
"build": "vue-cli-service build --skip-plugins @vue/cli-plugin-eslint"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@eturnity/eturnity_maths": "6.31.
|
|
11
|
+
"@eturnity/eturnity_maths": "6.31.1",
|
|
12
12
|
"axios": "^1.3.2",
|
|
13
13
|
"core-js": "^2.6.12",
|
|
14
14
|
"cors": "^2.8.5",
|
|
@@ -9,7 +9,7 @@ import { addVector, multiplyVector } from '@eturnity/eturnity_maths'
|
|
|
9
9
|
import { updateComputedGeometryPolygon } from '@eturnity/eturnity_maths'
|
|
10
10
|
|
|
11
11
|
import threeMixin from '../helper/threeMixin'
|
|
12
|
-
import
|
|
12
|
+
import materialMixin from '../helper/materialMixin'
|
|
13
13
|
import renderMixin from '../helper/renderMixin'
|
|
14
14
|
export default {
|
|
15
15
|
name: 'ThreeCanvas',
|
|
@@ -28,7 +28,6 @@ export default {
|
|
|
28
28
|
provider:null,
|
|
29
29
|
cameraprojection: null,
|
|
30
30
|
texture: null,
|
|
31
|
-
material: material,
|
|
32
31
|
renderer: new THREE.WebGLRenderer({
|
|
33
32
|
antialias: true,
|
|
34
33
|
preserveDrawingBuffer: true
|
|
@@ -57,21 +56,21 @@ export default {
|
|
|
57
56
|
areModuleFieldsVisible:false
|
|
58
57
|
}
|
|
59
58
|
},
|
|
60
|
-
mixins: [renderMixin,threeMixin],
|
|
59
|
+
mixins: [renderMixin,threeMixin,materialMixin],
|
|
61
60
|
async mounted() {
|
|
62
61
|
await this.hydrateData(this.geometryData)
|
|
63
62
|
this.renderer.domElement.style.width = '100%'
|
|
64
63
|
this.renderer.domElement.style.height = '100%'
|
|
65
64
|
|
|
66
65
|
this.initialiseThree(this.isInteractive)
|
|
67
|
-
this.loadProjectionMaterial()
|
|
68
66
|
this.initialiseThreeMap()
|
|
69
|
-
await this.
|
|
67
|
+
await this.loadPanelsTexture()
|
|
70
68
|
this.renderGeometry()
|
|
71
69
|
this.onWindowResize()
|
|
70
|
+
// this.updateProjectionMaterials()
|
|
72
71
|
this.animate()
|
|
73
72
|
this.$root.$on('on-roofSelected',(polygon)=>this.setCameraOrthogonalTo(polygon))
|
|
74
|
-
this.
|
|
73
|
+
this.initializeProjectionMaterial()
|
|
75
74
|
|
|
76
75
|
const polygon = this.polygons.find((p) => p.id == this.uuid)
|
|
77
76
|
this.setCamera(polygon, this.view_mode)
|
|
@@ -83,6 +82,7 @@ export default {
|
|
|
83
82
|
uuid: (state) => state.threeDModule.uuid,
|
|
84
83
|
view_mode: (state) => state.threeDModule.view_mode,
|
|
85
84
|
isInteractive: (state) => state.threeDModule.isInteractive,
|
|
85
|
+
imageOverlay: (state) => state.threeDModule.imageOverlay,
|
|
86
86
|
}),
|
|
87
87
|
...mapGetters({
|
|
88
88
|
polygons: 'getPolygons',
|
|
@@ -91,7 +91,6 @@ export default {
|
|
|
91
91
|
mapConfig: 'getMapConfig',
|
|
92
92
|
roofsBounds: 'getRoofsBounds',
|
|
93
93
|
layoutSettings: 'getLayoutSettings',
|
|
94
|
-
|
|
95
94
|
roofs: 'getRoofs',
|
|
96
95
|
obstacles: 'getObstacles',
|
|
97
96
|
moduleFields: 'getModuleFields',
|
package/src/config.js
CHANGED
|
@@ -65,7 +65,7 @@ export const maxMargin=2500
|
|
|
65
65
|
export const node3DRadius=0.05
|
|
66
66
|
export const beamColor="#ffffff"
|
|
67
67
|
export const node3DColor="white"
|
|
68
|
-
export const beamOpacity=0.
|
|
68
|
+
export const beamOpacity=0.4
|
|
69
69
|
export const node3dOpacity=0.3
|
|
70
70
|
export const dimMarginColor='#ff000020'
|
|
71
71
|
export const defaultTextureUrl=require('./assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png')
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
import {beamColor,beamOpacity,node3DColor,node3dOpacity,defaultTextureUrls} from '../config'
|
|
3
|
+
export default {
|
|
4
|
+
data(){
|
|
5
|
+
return {
|
|
6
|
+
material:{}
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
created(){
|
|
10
|
+
let wallColor=0xdddddd
|
|
11
|
+
if(this.wallColor){
|
|
12
|
+
wallColor = new THREE.Color(this.wallColor)
|
|
13
|
+
}
|
|
14
|
+
this.material.wall = new THREE.MeshLambertMaterial({
|
|
15
|
+
color: wallColor,
|
|
16
|
+
side:THREE.DoubleSide
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
this.material.obstacle = new THREE.MeshPhongMaterial({
|
|
20
|
+
color: 0xff0000,
|
|
21
|
+
side:THREE.DoubleSide,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
this.material.edge=new THREE.MeshPhongMaterial({ color: beamColor,transparent:true,opacity:beamOpacity })
|
|
25
|
+
this.material.node=new THREE.PointsMaterial( { size: 0.05, sizeAttenuation: true,color: node3DColor, opacity:node3dOpacity, transparent: true } );
|
|
26
|
+
const loader = new THREE.TextureLoader()
|
|
27
|
+
// loader.crossOrigin = 'anonymous'
|
|
28
|
+
// texture.minFilter = THREE.LinearFilter
|
|
29
|
+
this.material.panel={}
|
|
30
|
+
|
|
31
|
+
for(let k=0;k<defaultTextureUrls.length;k++){
|
|
32
|
+
let texture=loader.load(defaultTextureUrls[k], function (texture) {})
|
|
33
|
+
this.material.panel['default_'+k] = new THREE.MeshBasicMaterial({
|
|
34
|
+
map: texture,
|
|
35
|
+
side: THREE.DoubleSide,
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
this.material.roof=[this.material.wall]
|
|
39
|
+
|
|
40
|
+
this.material.flatRoof = new THREE.MeshPhongMaterial({
|
|
41
|
+
color: 0x00ff00,
|
|
42
|
+
specular: 0x009900,
|
|
43
|
+
shininess: 0,
|
|
44
|
+
flatShading: true,
|
|
45
|
+
side:THREE.DoubleSide,
|
|
46
|
+
transparent:true,
|
|
47
|
+
opacity:0.5
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
this.material.moduleField = new THREE.MeshPhongMaterial({
|
|
51
|
+
color: 0xfc9d03,
|
|
52
|
+
specular: 0x000000,
|
|
53
|
+
shininess: 0,
|
|
54
|
+
flatShading: true,
|
|
55
|
+
side:THREE.DoubleSide,
|
|
56
|
+
transparent:true,
|
|
57
|
+
opacity:0.8
|
|
58
|
+
})
|
|
59
|
+
this.material.curvedRoof = new THREE.MeshPhongMaterial({
|
|
60
|
+
color: 0xffff00,
|
|
61
|
+
specular: 0x009900,
|
|
62
|
+
shininess: 0,
|
|
63
|
+
flatShading: true,
|
|
64
|
+
side:THREE.DoubleSide,
|
|
65
|
+
transparent:true,
|
|
66
|
+
opacity:0.5
|
|
67
|
+
})
|
|
68
|
+
},
|
|
69
|
+
watch: {
|
|
70
|
+
wallColor(color) {
|
|
71
|
+
let wallColor = new THREE.Color(color)
|
|
72
|
+
this.material.wall.color.set(wallColor)
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -1,40 +1,8 @@
|
|
|
1
1
|
import * as THREE from 'three'
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
export default {
|
|
4
5
|
methods:{
|
|
5
|
-
|
|
6
|
-
// if(this.meshes.backgroundMesh){
|
|
7
|
-
// let sizeInMm={width:2000000,height:2000000}
|
|
8
|
-
// let positionInMm={x:0,y:0}
|
|
9
|
-
// if(this.layoutSettings.background_map_settings && this.layoutSettings.background_map_settings.sizeInMm){
|
|
10
|
-
// sizeInMm=this.layoutSettings.background_map_settings.sizeInMm
|
|
11
|
-
// positionInMm=this.layoutSettings.background_map_settings.positionInMm
|
|
12
|
-
// }
|
|
13
|
-
|
|
14
|
-
// this.meshes.backgroundMesh.geometry.dispose()
|
|
15
|
-
// let xMin=positionInMm.x/1000-sizeInMm.width/2000
|
|
16
|
-
// let xMax=positionInMm.x/1000+sizeInMm.width/2000
|
|
17
|
-
// let yMin=positionInMm.y/1000-sizeInMm.height/2000
|
|
18
|
-
// let yMax=positionInMm.y/1000+sizeInMm.height/2000
|
|
19
|
-
// let c1=[xMin,yMax,0.1]
|
|
20
|
-
// let c2=[xMax,yMax,0.1]
|
|
21
|
-
// let c3=[xMax,yMin,0.1]
|
|
22
|
-
// let c4=[xMin,yMin,0.1]
|
|
23
|
-
// let geometry = new THREE.BufferGeometry();
|
|
24
|
-
// const vertices = new Float32Array( [
|
|
25
|
-
// ...c1,
|
|
26
|
-
// ...c4,
|
|
27
|
-
// ...c3,
|
|
28
|
-
// ...c3,
|
|
29
|
-
// ...c2,
|
|
30
|
-
// ...c1
|
|
31
|
-
// ] );
|
|
32
|
-
// geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
|
|
33
|
-
// geometry.computeVertexNormals()
|
|
34
|
-
// this.meshes.backgroundMesh.geometry=geometry
|
|
35
|
-
// }else{
|
|
36
|
-
// this.initialiseThreeMap()
|
|
37
|
-
// }
|
|
38
|
-
},
|
|
6
|
+
|
|
39
7
|
}
|
|
40
8
|
}
|
|
@@ -12,13 +12,13 @@ export default {
|
|
|
12
12
|
//in case of map, bumpMap, normalMap, envMap ...
|
|
13
13
|
Object.keys(obj.material).forEach((prop) => {
|
|
14
14
|
if (!obj.material[prop]) return
|
|
15
|
-
if (
|
|
15
|
+
if (false &&
|
|
16
16
|
obj.material[prop] !== null &&
|
|
17
17
|
typeof obj.material[prop].dispose === 'function'
|
|
18
18
|
)
|
|
19
19
|
obj.material[prop].dispose()
|
|
20
20
|
})
|
|
21
|
-
obj.material.dispose()
|
|
21
|
+
if(obj.material.dispose) obj.material.dispose()
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
clearPanelsFromChangingRoofs(roofIds){
|
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
import * as THREE from 'three'
|
|
2
2
|
export default {
|
|
3
3
|
methods:{
|
|
4
|
+
setCylinderPosition(cylinder,edge){
|
|
5
|
+
const point_0 = new THREE.Vector3(
|
|
6
|
+
edge.outline[0].x / 1000,
|
|
7
|
+
edge.outline[0].y / 1000,
|
|
8
|
+
edge.outline[0].z / 1000
|
|
9
|
+
)
|
|
10
|
+
const point_1 = new THREE.Vector3(
|
|
11
|
+
edge.outline[1].x / 1000,
|
|
12
|
+
edge.outline[1].y / 1000,
|
|
13
|
+
edge.outline[1].z / 1000
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
const midPoint = point_0.clone().add(point_1).multiplyScalar(0.5)
|
|
17
|
+
var direction = new THREE.Vector3().subVectors(point_1, point_0)
|
|
18
|
+
let length = direction.length()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
//cylinder.rotation.set(arrow.rotation)
|
|
25
|
+
var axis = new THREE.Vector3(0, 1, 0)
|
|
26
|
+
cylinder.quaternion.setFromUnitVectors(
|
|
27
|
+
axis,
|
|
28
|
+
direction.clone().normalize()
|
|
29
|
+
)
|
|
30
|
+
//cylinder.position.set(new THREE.Vector3().addVectors( pointX, direction.multiplyScalar(0.5) ))
|
|
31
|
+
cylinder.position.copy(midPoint.clone())
|
|
32
|
+
let oldLength = cylinder.userData.cylinderLength
|
|
33
|
+
let newLength = length
|
|
34
|
+
if (!oldLength || oldLength != 0) {
|
|
35
|
+
cylinder.scale.set(1, newLength, 1)
|
|
36
|
+
cylinder.userData.cylinderLength = newLength
|
|
37
|
+
}
|
|
38
|
+
cylinder.updateMatrix()
|
|
39
|
+
return cylinder
|
|
40
|
+
},
|
|
4
41
|
renderEdges() {
|
|
5
42
|
this.clearEdgesRemovedOnes('edgeMeshes')
|
|
6
43
|
let cylinder
|
|
@@ -14,67 +51,16 @@ export default {
|
|
|
14
51
|
cylinder = this.meshes.edgeMeshes[edge.id]
|
|
15
52
|
if (cylinder) {
|
|
16
53
|
//update
|
|
17
|
-
|
|
18
|
-
edge.outline[0].x / 1000,
|
|
19
|
-
edge.outline[0].y / 1000,
|
|
20
|
-
edge.outline[0].z / 1000
|
|
21
|
-
)
|
|
22
|
-
const point_1 = new THREE.Vector3(
|
|
23
|
-
edge.outline[1].x / 1000,
|
|
24
|
-
edge.outline[1].y / 1000,
|
|
25
|
-
edge.outline[1].z / 1000
|
|
26
|
-
)
|
|
27
|
-
const midPoint = point_0.clone().add(point_1).multiplyScalar(0.5)
|
|
28
|
-
var direction = new THREE.Vector3().subVectors(point_1, point_0)
|
|
29
|
-
let length = direction.length()
|
|
30
|
-
//cylinder.rotation.set(arrow.rotation)
|
|
31
|
-
var axis = new THREE.Vector3(0, 1, 0)
|
|
32
|
-
cylinder.quaternion.setFromUnitVectors(
|
|
33
|
-
axis,
|
|
34
|
-
direction.clone().normalize()
|
|
35
|
-
)
|
|
36
|
-
//cylinder.position.set(new THREE.Vector3().addVectors( pointX, direction.multiplyScalar(0.5) ))
|
|
37
|
-
cylinder.position.copy(midPoint.clone())
|
|
38
|
-
let oldLength = cylinder.userData.cylinderLength
|
|
39
|
-
let newLength = length
|
|
40
|
-
if (oldLength != 0) {
|
|
41
|
-
let scaleRatio = newLength / oldLength
|
|
42
|
-
//let scaleVector=direction.multiplyScalar(scaleRatio-1)
|
|
43
|
-
cylinder.scale.set(1, newLength, 1)
|
|
44
|
-
cylinder.userData.cylinderLength = newLength
|
|
45
|
-
}
|
|
46
|
-
cylinder.updateMatrix()
|
|
54
|
+
this.setCylinderPosition(cylinder,edge)
|
|
47
55
|
//change cylinder length
|
|
48
56
|
} else {
|
|
49
|
-
|
|
50
|
-
edge.outline[0].x / 1000,
|
|
51
|
-
edge.outline[0].y / 1000,
|
|
52
|
-
edge.outline[0].z / 1000
|
|
53
|
-
)
|
|
54
|
-
const point_1 = new THREE.Vector3(
|
|
55
|
-
edge.outline[1].x / 1000,
|
|
56
|
-
edge.outline[1].y / 1000,
|
|
57
|
-
edge.outline[1].z / 1000
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
const midPoint = point_0.clone().add(point_1).multiplyScalar(0.5)
|
|
61
|
-
var direction = new THREE.Vector3().subVectors(point_1, point_0)
|
|
62
|
-
let length = direction.length()
|
|
57
|
+
|
|
63
58
|
const geometry = new THREE.CylinderGeometry(0.1, 0.1, 1, 6)
|
|
64
59
|
cylinder = new THREE.Mesh(geometry, material)
|
|
65
|
-
cylinder.
|
|
66
|
-
|
|
67
|
-
//cylinder.rotation.set(arrow.rotation)
|
|
68
|
-
var axis = new THREE.Vector3(0, 1, 0)
|
|
69
|
-
cylinder.quaternion.setFromUnitVectors(
|
|
70
|
-
axis,
|
|
71
|
-
direction.clone().normalize()
|
|
72
|
-
)
|
|
73
|
-
//cylinder.position.set(new THREE.Vector3().addVectors( pointX, direction.multiplyScalar(0.5) ))
|
|
74
|
-
cylinder.position.copy(midPoint.clone())
|
|
75
|
-
//cylinder.position.set(edge.outline[0].x/1000, edge.outline[0].y/1000, edge.outline[0].z/1000);
|
|
60
|
+
cylinder=this.setCylinderPosition(cylinder,edge)
|
|
61
|
+
|
|
76
62
|
cylinder.userData.edgeId = edge.id
|
|
77
|
-
|
|
63
|
+
|
|
78
64
|
this.meshes.edgeMeshes[edge.id] = cylinder
|
|
79
65
|
this.scene.add(cylinder)
|
|
80
66
|
|
|
@@ -375,6 +375,56 @@ export function getBufferModuleFieldGeometry(moduleFieldPolygon) {
|
|
|
375
375
|
return geometry
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
+
export function getBufferImageOverlayGeometry(corners){
|
|
379
|
+
corners.forEach(p=>p.z=0)
|
|
380
|
+
let normalVector = getNormalVectorFrom3Points(
|
|
381
|
+
corners[0],
|
|
382
|
+
corners[1],
|
|
383
|
+
corners[2]
|
|
384
|
+
)
|
|
385
|
+
if (normalVector.z < 0) {
|
|
386
|
+
normalVector = multiplyVector(-1, normalVector)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const geometry = new THREE.BufferGeometry()
|
|
390
|
+
//Calcul of triangles using cutear algo
|
|
391
|
+
const trianglesVertices = []
|
|
392
|
+
trianglesVertices.push(...getTriangleVerticesFromOutline(corners))
|
|
393
|
+
if(hasNaN(trianglesVertices)){return null}
|
|
394
|
+
const vertices = new Float32Array(trianglesVertices)
|
|
395
|
+
var A = corners[2]
|
|
396
|
+
var B = corners[3]
|
|
397
|
+
var C = corners[1]
|
|
398
|
+
var D = corners[0]
|
|
399
|
+
const AB = getDistanceBetweenPoints(A, B)
|
|
400
|
+
const AC = getDistanceBetweenPoints(A, C)
|
|
401
|
+
let uvs
|
|
402
|
+
if (AB < AC) {
|
|
403
|
+
uvs = new Float32Array([
|
|
404
|
+
0, 1,
|
|
405
|
+
0, 0,
|
|
406
|
+
1, 0,
|
|
407
|
+
|
|
408
|
+
0, 1,
|
|
409
|
+
1, 0,
|
|
410
|
+
1, 1
|
|
411
|
+
])
|
|
412
|
+
}else{
|
|
413
|
+
uvs = new Float32Array([
|
|
414
|
+
0, 0,
|
|
415
|
+
1, 0,
|
|
416
|
+
1, 1,
|
|
417
|
+
|
|
418
|
+
1, 0,
|
|
419
|
+
0, 1,
|
|
420
|
+
1, 1
|
|
421
|
+
])
|
|
422
|
+
}
|
|
423
|
+
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
|
|
424
|
+
geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2))
|
|
425
|
+
geometry.computeVertexNormals()
|
|
426
|
+
return geometry
|
|
427
|
+
}
|
|
378
428
|
export function getBufferPanelGeometry(panelPolygon) {
|
|
379
429
|
let panelNormalVector = getNormalVectorFrom3Points(
|
|
380
430
|
panelPolygon.outline[0],
|
|
@@ -384,7 +434,6 @@ export function getBufferPanelGeometry(panelPolygon) {
|
|
|
384
434
|
if (panelNormalVector.z < 0) {
|
|
385
435
|
panelNormalVector = multiplyVector(-1, panelNormalVector)
|
|
386
436
|
}
|
|
387
|
-
const roofPolygon = panelPolygon.roof
|
|
388
437
|
const panelHeight = parseInt(panelPolygon.height || 50)
|
|
389
438
|
//get lowest verticalProjection
|
|
390
439
|
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
import {mapGetters} from 'vuex'
|
|
3
|
+
import ProjectedMaterial from 'three-projected-material'
|
|
4
|
+
import {
|
|
5
|
+
substractVector,
|
|
6
|
+
addVector,
|
|
7
|
+
multiplyVector,
|
|
8
|
+
getDistanceBetweenPoints,
|
|
9
|
+
getAngleInDegFromCanvasVector
|
|
10
|
+
} from '@eturnity/eturnity_maths'
|
|
11
|
+
import {getBufferImageOverlayGeometry,updateBufferRoofGeometry} from './geometryHandler'
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
data(){
|
|
15
|
+
return {
|
|
16
|
+
imageOverlayProjectionCamera: new THREE.PerspectiveCamera(1, 300 / 300, 100, 1000),
|
|
17
|
+
imageOverlayTexture:null,
|
|
18
|
+
imageOverlayMaterial:null,
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
computed:{
|
|
22
|
+
...mapGetters({
|
|
23
|
+
imageOverlay: 'getImageOverlay',
|
|
24
|
+
}),
|
|
25
|
+
},
|
|
26
|
+
methods:{
|
|
27
|
+
renderImageOverlayOnBackground() {
|
|
28
|
+
if(!this.imageOverlay || !this.imageOverlayMaterial){
|
|
29
|
+
this.clearMesh(this.meshes.backgroundMesh)
|
|
30
|
+
this.meshes.backgroundMesh=null
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
let corners=this.imageOverlay.corners.map(p=>{return {...p,z:100}})
|
|
34
|
+
if(this.meshes.backgroundMesh && this.meshes.backgroundMesh.geometry){
|
|
35
|
+
let geometry=this.meshes.backgroundMesh.geometry
|
|
36
|
+
geometry=updateBufferRoofGeometry(corners,[],geometry)
|
|
37
|
+
//updateBufferRoofGeometry(corners,[],geometry)
|
|
38
|
+
this.meshes.backgroundMesh.geometry=geometry
|
|
39
|
+
|
|
40
|
+
}else{
|
|
41
|
+
let planeGeometry = getBufferImageOverlayGeometry(corners)
|
|
42
|
+
let planeMaterial = this.imageOverlayMaterial
|
|
43
|
+
|
|
44
|
+
this.meshes.backgroundMesh = new THREE.Mesh(planeGeometry, planeMaterial)
|
|
45
|
+
this.scene.add(this.meshes.backgroundMesh)
|
|
46
|
+
}
|
|
47
|
+
this.meshes.backgroundMesh.position.z=0.15
|
|
48
|
+
if(this.imageOverlayMaterial){
|
|
49
|
+
this.applyTextureOnMesh([this.imageOverlayMaterial],this.meshes.backgroundMesh)
|
|
50
|
+
}
|
|
51
|
+
this.meshes.backgroundMesh.visible=true
|
|
52
|
+
},
|
|
53
|
+
async changeImageOverlay(){
|
|
54
|
+
if(this.imageOverlayMaterial){
|
|
55
|
+
this.imageOverlayMaterial.dispose()
|
|
56
|
+
this.imageOverlayMaterial=null
|
|
57
|
+
}
|
|
58
|
+
await this.updateProjectionMaterials()
|
|
59
|
+
},
|
|
60
|
+
async getImageOverlayMaterial(){
|
|
61
|
+
if(!this.imageOverlay || !this.imageOverlay.url){
|
|
62
|
+
if(this.imageOverlayMaterial){
|
|
63
|
+
this.imageOverlayMaterial.dispose()
|
|
64
|
+
}
|
|
65
|
+
this.imageOverlayMaterial=null
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if(!this.imageOverlayMaterial || this.imageOverlay.url!= this.imageOverlayMaterial.userData.url){
|
|
70
|
+
this.imageOverlayMaterial = await this.newImageOverlayMaterial()
|
|
71
|
+
}else{
|
|
72
|
+
this.setImageOverlayCameraPosition()
|
|
73
|
+
}
|
|
74
|
+
return this.imageOverlayMaterial
|
|
75
|
+
},
|
|
76
|
+
removeImageOverlay(){
|
|
77
|
+
if(this.imageOverlayMaterial && this.imageOverlayMaterial.dispose)
|
|
78
|
+
this.imageOverlayMaterial.dispose()
|
|
79
|
+
this.imageOverlayMaterial=null
|
|
80
|
+
this.material.roof=this.material.roof.filter(material=>material.userData.type!='imageOverlayMaterial')
|
|
81
|
+
},
|
|
82
|
+
async newImageOverlayMaterial(){
|
|
83
|
+
return new Promise((resolve)=>{this.loader.load(this.imageOverlay.url,(texture)=>{
|
|
84
|
+
this.imageOverlayTexture=texture
|
|
85
|
+
this.setImageOverlayCameraPosition()
|
|
86
|
+
let imageOverlayProjectionMaterial = new ProjectedMaterial({
|
|
87
|
+
camera: this.imageOverlayProjectionCamera,
|
|
88
|
+
texture: this.imageOverlayTexture,
|
|
89
|
+
transparent: true,
|
|
90
|
+
side: THREE.DoubleSide,
|
|
91
|
+
depthWrite: false
|
|
92
|
+
})
|
|
93
|
+
imageOverlayProjectionMaterial.userData={}
|
|
94
|
+
imageOverlayProjectionMaterial.userData.type="imageOverlayMaterial"
|
|
95
|
+
imageOverlayProjectionMaterial.userData.priority=2
|
|
96
|
+
imageOverlayProjectionMaterial.userData.url=this.imageOverlay.url
|
|
97
|
+
resolve(imageOverlayProjectionMaterial)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
},
|
|
101
|
+
setImageOverlayCameraPosition(){
|
|
102
|
+
if(!this.imageOverlay || !this.imageOverlay.url) return
|
|
103
|
+
let height=getDistanceBetweenPoints(this.imageOverlay.corners[1],this.imageOverlay.corners[2])
|
|
104
|
+
let width=getDistanceBetweenPoints(this.imageOverlay.corners[0],this.imageOverlay.corners[1])
|
|
105
|
+
this.imageOverlayProjectionCamera.aspect =
|
|
106
|
+
width / height
|
|
107
|
+
let projectionAltitude = height /(2 * Math.tan((this.imageOverlayProjectionCamera.fov * Math.PI) / 360))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
//set projection camera over background_map_center
|
|
111
|
+
let imageOverlayProjectionCameraPosition={x:0,y:0,z:projectionAltitude / 1000}
|
|
112
|
+
|
|
113
|
+
let positionInMm=multiplyVector(0.5,addVector(this.imageOverlay.corners[0],this.imageOverlay.corners[2]))
|
|
114
|
+
imageOverlayProjectionCameraPosition.x=positionInMm.x/1000
|
|
115
|
+
imageOverlayProjectionCameraPosition.y=positionInMm.y/1000
|
|
116
|
+
|
|
117
|
+
this.imageOverlayProjectionCamera.position.set(imageOverlayProjectionCameraPosition.x, imageOverlayProjectionCameraPosition.y, projectionAltitude / 1000)
|
|
118
|
+
this.imageOverlayProjectionCamera.lookAt(imageOverlayProjectionCameraPosition.x, imageOverlayProjectionCameraPosition.y,0)
|
|
119
|
+
let zAngle=getAngleInDegFromCanvasVector(substractVector(this.imageOverlay.corners[3],this.imageOverlay.corners[0]))
|
|
120
|
+
this.imageOverlayProjectionCamera.rotation.set(0, 0, zAngle*Math.PI/180)
|
|
121
|
+
this.imageOverlayProjectionCamera.far = projectionAltitude * 1.5
|
|
122
|
+
this.imageOverlayProjectionCamera.near = projectionAltitude * 0.8
|
|
123
|
+
this.imageOverlayProjectionCamera.updateProjectionMatrix()
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -9,8 +9,12 @@ import moduleField from './moduleField'
|
|
|
9
9
|
import obstacle from './obstacle'
|
|
10
10
|
import panel from './panel'
|
|
11
11
|
import roof from './roof'
|
|
12
|
+
import imageOverlay from './imageOverlay'
|
|
13
|
+
import mapProjection from './mapProjection'
|
|
14
|
+
import texture from './texture'
|
|
15
|
+
import projectionMaterial from './projectionMaterial'
|
|
12
16
|
|
|
13
17
|
export default {
|
|
14
18
|
//mixins:[node,background,clear,edge,loader,margin,moduleField,obstacle,panel,roof,base]
|
|
15
|
-
mixins:[margin,node,background, base,roof,edge,obstacle,moduleField,panel,clear,loader]
|
|
19
|
+
mixins:[margin,node,background, base,roof,edge,obstacle,moduleField,panel,clear,loader,imageOverlay,texture,mapProjection,projectionMaterial]
|
|
16
20
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as THREE from 'three'
|
|
2
2
|
import ProjectedMaterial from 'three-projected-material'
|
|
3
|
+
|
|
3
4
|
export default {
|
|
4
5
|
methods:{
|
|
5
|
-
|
|
6
|
+
loadNewPanelTextures(){
|
|
6
7
|
Object.values(this.pvDataMemo).forEach((component) => {
|
|
7
8
|
const pvId = component.id
|
|
8
9
|
if (!this.material.panel[pvId]) {
|
|
@@ -19,7 +20,7 @@ export default {
|
|
|
19
20
|
}
|
|
20
21
|
})
|
|
21
22
|
},
|
|
22
|
-
async
|
|
23
|
+
async loadPanelsTexture(){
|
|
23
24
|
for(let k=0;k<this.moduleFields.length;k++){
|
|
24
25
|
let mf=this.moduleFields[k]
|
|
25
26
|
const pvId = mf.data.component_id_pv_module
|
|
@@ -37,63 +38,5 @@ export default {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
},
|
|
40
|
-
async loadProjectionMaterial() {
|
|
41
|
-
const _this=this
|
|
42
|
-
if(!this.layoutSettings.base64_image_url)
|
|
43
|
-
{
|
|
44
|
-
this.loader.load(require("../../assets/images/white_tile.png"),(texture)=>{
|
|
45
|
-
let projectionMaterial = new ProjectedMaterial({
|
|
46
|
-
camera: _this.cameraprojection,
|
|
47
|
-
texture: texture
|
|
48
|
-
})
|
|
49
|
-
this.material.roof = projectionMaterial
|
|
50
|
-
})
|
|
51
|
-
return
|
|
52
|
-
}
|
|
53
|
-
let projectedMaterialLoaded= await new Promise((resolve,reject) => {
|
|
54
|
-
this.loader.load(this.layoutSettings.base64_image_url,(texture)=>{
|
|
55
|
-
let backgroundImageZoomLvl=_this.layoutSettings.map_zoom
|
|
56
|
-
let backgroundImageCenter={
|
|
57
|
-
lat:_this.layoutSettings.layout_latitude,
|
|
58
|
-
lng:_this.layoutSettings.layout_longitude
|
|
59
|
-
}
|
|
60
|
-
if(_this.layoutSettings.background_map_settings){
|
|
61
|
-
backgroundImageZoomLvl=_this.layoutSettings.background_map_settings.zoom_lvl
|
|
62
|
-
backgroundImageCenter={
|
|
63
|
-
lat:_this.layoutSettings.background_map_settings.lat,
|
|
64
|
-
lng:_this.layoutSettings.background_map_settings.lng
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
_this.backgroundImagesizeInMm=_this.layoutSettings.background_map_settings.sizeInMm
|
|
68
|
-
if (_this.backgroundImagesizeInMm) {
|
|
69
|
-
_this.cameraprojection.aspect =
|
|
70
|
-
_this.backgroundImagesizeInMm.width / _this.backgroundImagesizeInMm.height
|
|
71
|
-
let projectionAltitude =
|
|
72
|
-
_this.backgroundImagesizeInMm.height /
|
|
73
|
-
(2 * Math.tan((_this.cameraprojection.fov * Math.PI) / 360))
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
//set projection camera over background_map_center
|
|
77
|
-
let cameraProjectionPosition={x:0,y:0,z:projectionAltitude / 1000}
|
|
78
|
-
if(_this.layoutSettings.background_map_settings && _this.layoutSettings.background_map_settings.positionInMm){
|
|
79
|
-
let positionInMm=this.layoutSettings.background_map_settings.positionInMm
|
|
80
|
-
cameraProjectionPosition.x=positionInMm.x/1000
|
|
81
|
-
cameraProjectionPosition.y=positionInMm.y/1000
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
_this.cameraprojection.position.set(cameraProjectionPosition.x, cameraProjectionPosition.y, projectionAltitude / 1000)
|
|
85
|
-
_this.cameraprojection.far = projectionAltitude * 16
|
|
86
|
-
_this.cameraprojection.updateProjectionMatrix()
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
let projectionMaterial = new ProjectedMaterial({
|
|
90
|
-
camera: _this.cameraprojection,
|
|
91
|
-
texture: texture
|
|
92
|
-
})
|
|
93
|
-
resolve(projectionMaterial)
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
this.material.roof =projectedMaterialLoaded
|
|
97
|
-
},
|
|
98
41
|
}
|
|
99
42
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
import ProjectedMaterial from 'three-projected-material'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
data(){
|
|
6
|
+
return {
|
|
7
|
+
mapProjectionTexture:null,
|
|
8
|
+
mapProjectionMaterial:null
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
methods:{
|
|
12
|
+
async changeMapProjection(){
|
|
13
|
+
if(this.mapProjectionMaterial){
|
|
14
|
+
this.mapProjectionMaterial.dispose()
|
|
15
|
+
this.mapProjectionMaterial=null
|
|
16
|
+
}
|
|
17
|
+
await this.updateProjectionMaterials()
|
|
18
|
+
},
|
|
19
|
+
async getMapProjectionMaterial(){
|
|
20
|
+
if(!this.layoutSettings.base64_image_url){
|
|
21
|
+
return null
|
|
22
|
+
}else{
|
|
23
|
+
if(!this.mapProjectionMaterial){
|
|
24
|
+
this.mapProjectionMaterial = await this.newMapProjectionMaterial()
|
|
25
|
+
}else{
|
|
26
|
+
this.setMapProjectionCameraPosition()
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return this.mapProjectionMaterial
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
async newMapProjectionMaterial() {
|
|
33
|
+
return new Promise((resolve,reject) => {
|
|
34
|
+
this.loader.load(this.layoutSettings.base64_image_url,(texture)=>{
|
|
35
|
+
this.mapProjectionTexture=texture
|
|
36
|
+
this.setMapProjectionCameraPosition()
|
|
37
|
+
let mapProjectionMaterial = new ProjectedMaterial({
|
|
38
|
+
camera: this.cameraprojection,
|
|
39
|
+
texture: texture,
|
|
40
|
+
transparent: true,
|
|
41
|
+
side: THREE.DoubleSide,
|
|
42
|
+
})
|
|
43
|
+
mapProjectionMaterial.userData={}
|
|
44
|
+
mapProjectionMaterial.userData.type="mapProjectionMaterial"
|
|
45
|
+
mapProjectionMaterial.userData.priority=1
|
|
46
|
+
mapProjectionMaterial.userData.url=this.layoutSettings.base64_image_url
|
|
47
|
+
resolve(mapProjectionMaterial)
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
},
|
|
51
|
+
setMapProjectionCameraPosition(){
|
|
52
|
+
let backgroundImageCenter={
|
|
53
|
+
lat:this.layoutSettings.layout_latitude,
|
|
54
|
+
lng:this.layoutSettings.layout_longitude
|
|
55
|
+
}
|
|
56
|
+
if(this.layoutSettings.background_map_settings){
|
|
57
|
+
backgroundImageCenter={
|
|
58
|
+
lat:this.layoutSettings.background_map_settings.lat,
|
|
59
|
+
lng:this.layoutSettings.background_map_settings.lng
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
this.backgroundImagesizeInMm=this.layoutSettings.background_map_settings.sizeInMm
|
|
63
|
+
if (this.backgroundImagesizeInMm) {
|
|
64
|
+
this.cameraprojection.aspect =
|
|
65
|
+
this.backgroundImagesizeInMm.width / this.backgroundImagesizeInMm.height
|
|
66
|
+
let projectionAltitude =
|
|
67
|
+
this.backgroundImagesizeInMm.height /
|
|
68
|
+
(2 * Math.tan((this.cameraprojection.fov * Math.PI) / 360))
|
|
69
|
+
|
|
70
|
+
//set projection camera over background_map_center
|
|
71
|
+
let cameraProjectionPosition={x:0,y:0,z:projectionAltitude / 1000}
|
|
72
|
+
if(this.layoutSettings.background_map_settings && this.layoutSettings.background_map_settings.positionInMm){
|
|
73
|
+
let positionInMm=this.layoutSettings.background_map_settings.positionInMm
|
|
74
|
+
cameraProjectionPosition.x=positionInMm.x/1000
|
|
75
|
+
cameraProjectionPosition.y=positionInMm.y/1000
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.cameraprojection.position.set(cameraProjectionPosition.x, cameraProjectionPosition.y, projectionAltitude / 1000)
|
|
79
|
+
this.cameraprojection.far = projectionAltitude * 1.5
|
|
80
|
+
this.cameraprojection.near = projectionAltitude * 0.5
|
|
81
|
+
this.cameraprojection.updateProjectionMatrix()
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
getBufferObstacleGeometry,
|
|
4
4
|
getBufferObstacleSideGeometry,
|
|
5
5
|
} from './geometryHandler'
|
|
6
|
-
import { material } from '../materials'
|
|
7
6
|
export default {
|
|
8
7
|
methods:{
|
|
9
8
|
renderObstacles() {
|
|
@@ -24,13 +23,8 @@ export default {
|
|
|
24
23
|
)
|
|
25
24
|
if (geometry && geometrySide) {
|
|
26
25
|
const mesh = new THREE.Mesh(geometry, this.material.roof)
|
|
27
|
-
const meshSide = new THREE.Mesh(geometrySide, material.wall)
|
|
28
|
-
|
|
29
|
-
if(this.material.roof && this.material.roof.project){
|
|
30
|
-
this.material.roof.project(mesh)
|
|
31
|
-
}else{
|
|
32
|
-
mesh.material=this.material.wall
|
|
33
|
-
}
|
|
26
|
+
const meshSide = new THREE.Mesh(geometrySide, this.material.wall)
|
|
27
|
+
this.applyTextureOnMesh(this.material.roof,mesh)
|
|
34
28
|
|
|
35
29
|
mesh.userData.version = obstaclePolygon.version
|
|
36
30
|
mesh.userData.type = 'obstacleMeshes'
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
methods:{
|
|
3
|
+
reorderRoofMaterials(){
|
|
4
|
+
this.material.roof.sort((a,b)=>{
|
|
5
|
+
let aPrio=a.priority || 0
|
|
6
|
+
let bPrio=b.priority || 0
|
|
7
|
+
return aPrio-bPrio
|
|
8
|
+
})
|
|
9
|
+
},
|
|
10
|
+
async updateProjectionMaterials(){
|
|
11
|
+
this.setImageOverlayCameraPosition()
|
|
12
|
+
let materialPromises=[
|
|
13
|
+
this.getMapProjectionMaterial(),
|
|
14
|
+
this.getImageOverlayMaterial()
|
|
15
|
+
]
|
|
16
|
+
let materials = await Promise.all(materialPromises)
|
|
17
|
+
this.mapProjectionMaterial = materials[0]
|
|
18
|
+
this.imageOverlayMaterial= materials[1]
|
|
19
|
+
|
|
20
|
+
let index=this.material.roof.findIndex(material=>material.userData.type=="mapProjectionMaterial")
|
|
21
|
+
if(this.mapProjectionMaterial){
|
|
22
|
+
if(index>=0){
|
|
23
|
+
this.material.roof[index]=this.mapProjectionMaterial
|
|
24
|
+
this.material.roof=[...this.material.roof]
|
|
25
|
+
}else{
|
|
26
|
+
this.material.roof=[...this.material.roof,this.mapProjectionMaterial]
|
|
27
|
+
this.reorderRoofMaterials()
|
|
28
|
+
}
|
|
29
|
+
}else if(index>=0){
|
|
30
|
+
this.material.roof[index].dispose()
|
|
31
|
+
this.material.roof.splice(index,1)
|
|
32
|
+
this.material.roof=[...this.material.roof]
|
|
33
|
+
this.reorderRoofMaterials()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
index=this.material.roof.findIndex(material=> material.userData.type=="imageOverlayMaterial")
|
|
37
|
+
if(this.imageOverlayMaterial){
|
|
38
|
+
if(index>=0){
|
|
39
|
+
this.material.roof[index]=this.imageOverlayMaterial
|
|
40
|
+
this.material.roof=[...this.material.roof]
|
|
41
|
+
}else{
|
|
42
|
+
this.material.roof=[...this.material.roof,this.imageOverlayMaterial]
|
|
43
|
+
this.reorderRoofMaterials()
|
|
44
|
+
}
|
|
45
|
+
}else if(index>=0){
|
|
46
|
+
this.material.roof[index].dispose()
|
|
47
|
+
this.material.roof.splice(index,1)
|
|
48
|
+
this.material.roof=[...this.material.roof]
|
|
49
|
+
this.reorderRoofMaterials()
|
|
50
|
+
}
|
|
51
|
+
this.renderImageOverlayOnBackground()
|
|
52
|
+
this.applyTextureOnRoofs()
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -68,6 +68,19 @@ export default {
|
|
|
68
68
|
|
|
69
69
|
return geometry
|
|
70
70
|
},
|
|
71
|
+
|
|
72
|
+
applyTextureOnRoofs(){
|
|
73
|
+
this.roofs.forEach(roof=>{
|
|
74
|
+
//roofs
|
|
75
|
+
let mesh=this.meshes.roofMeshes[roof.id]
|
|
76
|
+
this.applyTextureOnMesh(this.material.roof,mesh)
|
|
77
|
+
//obstacle on roof
|
|
78
|
+
roof.holes.filter(p=>p.layer=="obstacle").forEach(obstacle=>{
|
|
79
|
+
let meshObstacle=this.meshes.obstacleMeshes[obstacle.id + '-' + roof.id + '_top']
|
|
80
|
+
this.applyTextureOnMesh(this.material.roof,meshObstacle)
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
},
|
|
71
84
|
renderRoofs() {
|
|
72
85
|
this.clearRemovedOnes('roofMeshes')
|
|
73
86
|
this.roofs.forEach((roofPolygon) => {
|
|
@@ -82,17 +95,18 @@ export default {
|
|
|
82
95
|
mesh = this.meshes.roofMeshes[roofPolygon.id]
|
|
83
96
|
geometry = mesh.geometry
|
|
84
97
|
geometry = this.updateRoofGeometry(geometry, roofPolygon)
|
|
98
|
+
//in order to be able to render multiple material on it (background and image overlay)
|
|
99
|
+
|
|
85
100
|
mesh.geometry = geometry
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if(this.material.roof && this.material.roof.project) this.material.roof.project(mesh)
|
|
89
|
-
}
|
|
101
|
+
this.applyTextureOnMesh(this.material.roof,mesh)
|
|
102
|
+
|
|
90
103
|
mesh.frustumCulled = false
|
|
91
104
|
mesh.updateMatrix()
|
|
92
105
|
}
|
|
93
106
|
if (!this.meshes.roofMeshes[roofPolygon.id]) {
|
|
94
107
|
//create
|
|
95
108
|
geometry = this.createRoofGeometry(roofPolygon)
|
|
109
|
+
|
|
96
110
|
if (geometry) {
|
|
97
111
|
mesh = new THREE.Mesh(geometry, this.material.roof)
|
|
98
112
|
mesh.userData.version = roofPolygon.version
|
|
@@ -101,10 +115,7 @@ export default {
|
|
|
101
115
|
mesh.userData.polygonId = roofPolygon.id
|
|
102
116
|
mesh.matrixAutoUpdate = false
|
|
103
117
|
this.scene.add(mesh)
|
|
104
|
-
|
|
105
|
-
mesh.material=this.material.roof
|
|
106
|
-
if(this.material.roof.project) this.material.roof.project(mesh)
|
|
107
|
-
}
|
|
118
|
+
this.applyTextureOnMesh(this.material.roof,mesh)
|
|
108
119
|
mesh.frustumCulled = false
|
|
109
120
|
this.meshes.roofMeshes[roofPolygon.id] = mesh
|
|
110
121
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
methods:{
|
|
3
|
+
applyTextureOnMesh(materials,mesh){
|
|
4
|
+
if(materials && materials.length>0){
|
|
5
|
+
let geometry=mesh.geometry
|
|
6
|
+
geometry.clearGroups();
|
|
7
|
+
for(let k=0;k<materials.length;k++){
|
|
8
|
+
geometry.addGroup( 0, Infinity, k )
|
|
9
|
+
}
|
|
10
|
+
mesh.material=materials
|
|
11
|
+
for(let m=0;m<materials.length;m++){
|
|
12
|
+
if(materials[m].project) {
|
|
13
|
+
materials[m].project(mesh)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -36,10 +36,6 @@ export default {
|
|
|
36
36
|
roofMarginMeshes: {},
|
|
37
37
|
moduleFieldsMeshes: {}
|
|
38
38
|
}
|
|
39
|
-
if (this.wallColor) {
|
|
40
|
-
let wallColor = new THREE.Color(this.wallColor)
|
|
41
|
-
this.material.wall.color.set(wallColor)
|
|
42
|
-
}
|
|
43
39
|
},
|
|
44
40
|
|
|
45
41
|
computed: {
|
|
@@ -206,9 +202,41 @@ export default {
|
|
|
206
202
|
method: this.initialiseThreeMap,
|
|
207
203
|
arg: []
|
|
208
204
|
})
|
|
205
|
+
break
|
|
206
|
+
case 'changeMapProjection':
|
|
207
|
+
methodList.push({
|
|
208
|
+
name: 'changeMapProjection',
|
|
209
|
+
method: this.changeMapProjection,
|
|
210
|
+
arg: []
|
|
211
|
+
})
|
|
209
212
|
methodList.push({
|
|
210
|
-
name: '
|
|
211
|
-
method: this.
|
|
213
|
+
name: 'applyTextureOnRoofs',
|
|
214
|
+
method: this.applyTextureOnRoofs,
|
|
215
|
+
arg: []
|
|
216
|
+
})
|
|
217
|
+
break
|
|
218
|
+
// methodList.push({
|
|
219
|
+
// name: 'removeImageOverlay',
|
|
220
|
+
// method: this.removeImageOverlay,
|
|
221
|
+
// arg: []
|
|
222
|
+
// })
|
|
223
|
+
// methodList.push({
|
|
224
|
+
// name: 'applyTextureOnBackground',
|
|
225
|
+
// method: this.renderImageOverlayOnBackground,
|
|
226
|
+
// arg: []
|
|
227
|
+
// })
|
|
228
|
+
// methodList.push({
|
|
229
|
+
// name: 'applyTextureOnRoofs',
|
|
230
|
+
// method: this.applyTextureOnRoofs,
|
|
231
|
+
// arg: []
|
|
232
|
+
// })
|
|
233
|
+
// break
|
|
234
|
+
case 'removeImageOverlay':
|
|
235
|
+
case 'changeImageOverlay':
|
|
236
|
+
case 'updateImageOverlay':
|
|
237
|
+
methodList.push({
|
|
238
|
+
name: 'updateProjectionMaterials()',
|
|
239
|
+
method: this.updateProjectionMaterials,
|
|
212
240
|
arg: []
|
|
213
241
|
})
|
|
214
242
|
break
|
|
@@ -228,11 +256,11 @@ export default {
|
|
|
228
256
|
}
|
|
229
257
|
},
|
|
230
258
|
renderGeometry() {
|
|
231
|
-
this.renderBackground()
|
|
232
259
|
this.renderBuilding()
|
|
233
260
|
this.renderModuleFields()
|
|
234
261
|
this.renderPanels()
|
|
235
262
|
this.renderRoofsMargin()
|
|
263
|
+
this.updateProjectionMaterials()
|
|
236
264
|
},
|
|
237
265
|
renderBuilding() {
|
|
238
266
|
this.renderBase()
|
|
@@ -242,32 +270,10 @@ export default {
|
|
|
242
270
|
this.renderEdges()
|
|
243
271
|
this.renderFlatRoofs()
|
|
244
272
|
},
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
this.
|
|
248
|
-
//roofs
|
|
249
|
-
let mesh = this.meshes.roofMeshes[roof.id]
|
|
250
|
-
mesh.material = this.material.roof
|
|
251
|
-
if (this.material.roof && this.material.roof.project) {
|
|
252
|
-
this.material.roof.project(mesh)
|
|
253
|
-
}
|
|
254
|
-
//obstacle on roof
|
|
255
|
-
roof.holes
|
|
256
|
-
.filter((p) => p.layer == 'obstacle')
|
|
257
|
-
.forEach((obstacle) => {
|
|
258
|
-
let meshObstacle =
|
|
259
|
-
this.meshes.obstacleMeshes[obstacle.id + '-' + roof.id + '_top']
|
|
260
|
-
meshObstacle.material = this.material.roof
|
|
261
|
-
if (this.material.roof && this.material.roof.project)
|
|
262
|
-
this.material.roof.project(meshObstacle)
|
|
263
|
-
})
|
|
264
|
-
})
|
|
265
|
-
},
|
|
266
|
-
|
|
267
|
-
async updateProjectionMaterial() {
|
|
268
|
-
await this.loadProjectionMaterial()
|
|
273
|
+
|
|
274
|
+
async initializeProjectionMaterial(){
|
|
275
|
+
await this.updateProjectionMaterials()
|
|
269
276
|
this.applyTextureOnRoofs()
|
|
270
|
-
this.renderBackground()
|
|
271
277
|
},
|
|
272
278
|
|
|
273
279
|
getCanvasOffset() {
|
|
@@ -320,13 +326,9 @@ export default {
|
|
|
320
326
|
}
|
|
321
327
|
},
|
|
322
328
|
watch: {
|
|
323
|
-
wallColor(color) {
|
|
324
|
-
let wallColor = new THREE.Color(color)
|
|
325
|
-
this.material.wall.color.set(wallColor)
|
|
326
|
-
},
|
|
327
329
|
pvDataMemo: {
|
|
328
330
|
handler(val) {
|
|
329
|
-
this.
|
|
331
|
+
this.loadNewPanelTextures()
|
|
330
332
|
}
|
|
331
333
|
},
|
|
332
334
|
'material.panel': {
|
|
@@ -360,7 +362,10 @@ export default {
|
|
|
360
362
|
this.scene = null
|
|
361
363
|
this.camera = null
|
|
362
364
|
this.cameraprojection = null
|
|
363
|
-
this.material.forEach((m) =>
|
|
365
|
+
Object.values(this.material).forEach((m) =>{
|
|
366
|
+
if(m && m.dispose)
|
|
367
|
+
m.dispose()
|
|
368
|
+
} )
|
|
364
369
|
this.material = null
|
|
365
370
|
this.orbitControl = null
|
|
366
371
|
this.raycaster = null
|
package/src/store/hydrateData.js
CHANGED
|
@@ -15,6 +15,7 @@ export async function hydrateData({ state, commit }, data) {
|
|
|
15
15
|
let obstaclesResponse = data.obstacles
|
|
16
16
|
let moduleFieldsResponse = data.moduleFields
|
|
17
17
|
const layoutSettingResponse = data.layoutSettings
|
|
18
|
+
const imageOverlayResponse = data.imageOverlay
|
|
18
19
|
//removing empty roof,obstacle and modulefield generated by BE on variant creation
|
|
19
20
|
roofsResponse=roofsResponse.reduce((acc,cur)=>{
|
|
20
21
|
if(cur.roof_outline.length>0){acc.push(cur)}
|
|
@@ -29,9 +30,17 @@ export async function hydrateData({ state, commit }, data) {
|
|
|
29
30
|
return acc
|
|
30
31
|
},[])
|
|
31
32
|
|
|
33
|
+
if (imageOverlayResponse && imageOverlayResponse.image_overlay_url) {
|
|
34
|
+
let imageOverlay = {
|
|
35
|
+
url: imageOverlayResponse.image_overlay_url,
|
|
36
|
+
uuid: imageOverlayResponse.image_overlay_uuid,
|
|
37
|
+
corners: imageOverlayResponse.image_overlay_settings.corners
|
|
38
|
+
}
|
|
39
|
+
commit('mutate_imageOverlay', imageOverlay)
|
|
40
|
+
}
|
|
41
|
+
|
|
32
42
|
if (!!layoutSettingResponse) {
|
|
33
43
|
const layoutSetting = layoutSettingResponse
|
|
34
|
-
console.log(layoutSetting)
|
|
35
44
|
const moduleTextureVersionId=layoutSetting.module_texture_version_id || 0
|
|
36
45
|
commit('mutate_layoutSettings', layoutSetting)
|
|
37
46
|
commit('mutate_moduleTextureVersionId',moduleTextureVersionId)
|
|
@@ -19,6 +19,7 @@ const init_state = {
|
|
|
19
19
|
cancelTokenGlobal: '',
|
|
20
20
|
globalProjectProperties: [],
|
|
21
21
|
buildingLocation: null,
|
|
22
|
+
imageOverlay:null,
|
|
22
23
|
layoutSettings: {
|
|
23
24
|
base64_image_url: null,
|
|
24
25
|
layout_latitude: null,
|
|
@@ -35,6 +36,7 @@ const init_state = {
|
|
|
35
36
|
panelOpacity:1,
|
|
36
37
|
selectedMapLayer:null,
|
|
37
38
|
globalProjectProperties: [],
|
|
39
|
+
imageOverlay:null
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
const state = init_state
|
|
@@ -87,7 +89,9 @@ const getters = {
|
|
|
87
89
|
getBuildingLocation(state) {
|
|
88
90
|
return state.buildingLocation
|
|
89
91
|
},
|
|
90
|
-
|
|
92
|
+
getImageOverlay(state){
|
|
93
|
+
return state.imageOverlay
|
|
94
|
+
},
|
|
91
95
|
getLayoutSettings(state) {
|
|
92
96
|
return state.layoutSettings
|
|
93
97
|
},
|
|
@@ -116,6 +120,9 @@ const mutations = {
|
|
|
116
120
|
mutate_layoutSettings(state, value) {
|
|
117
121
|
state.layoutSettings = value
|
|
118
122
|
},
|
|
123
|
+
mutate_imageOverlay(state, value) {
|
|
124
|
+
state.imageOverlay = value
|
|
125
|
+
},
|
|
119
126
|
mutate_selectedZoom(state, value) {
|
|
120
127
|
state.selectedZoom = value
|
|
121
128
|
},
|