@eturnity/eturnity_3d 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.babelrc +3 -0
  2. package/.env +0 -0
  3. package/.eslintrc +18 -0
  4. package/.eslintrc.json +18 -0
  5. package/.prettierrc +7 -0
  6. package/Dockerfile +17 -0
  7. package/README.md +18 -0
  8. package/bitbucket-pipelines.yml +681 -0
  9. package/dist/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  10. package/dist/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  11. package/dist/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  12. package/dist/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  13. package/dist/assets/images/panels/uv.png +0 -0
  14. package/dist/assets/panels/longiSolarLR4_60HPH_350M.png +0 -0
  15. package/dist/assets/panels/longiSolarLR4_60HPH_370M.png +0 -0
  16. package/dist/assets/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  17. package/dist/assets/panels/uv.png +0 -0
  18. package/dist/assets/theme.js +43 -0
  19. package/dist/assets/vue.svg +1 -0
  20. package/dist/css/main.1f8fe45d.css +1 -0
  21. package/dist/img/longiSolarLR4_60HPH_350M.85a84b2e.png +0 -0
  22. package/dist/img/longiSolarLR4_60HPH_370M.bf6b1f4e.png +0 -0
  23. package/dist/img/reneSola_Virtus_2_JC320S_24_Bbw.8b1892e0.png +0 -0
  24. package/dist/index.html +26 -0
  25. package/dist/main.js +60230 -0
  26. package/dist/main.js.map +1 -0
  27. package/dist/vite.svg +1 -0
  28. package/docker_conf/nginx/nginx.conf +16 -0
  29. package/index.html +26 -0
  30. package/package.json +71 -0
  31. package/postcss.config.js +1 -0
  32. package/preview.html +55 -0
  33. package/public/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  34. package/public/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  35. package/public/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  36. package/public/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  37. package/public/assets/images/panels/uv.png +0 -0
  38. package/public/assets/panels/longiSolarLR4_60HPH_350M.png +0 -0
  39. package/public/assets/panels/longiSolarLR4_60HPH_370M.png +0 -0
  40. package/public/assets/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  41. package/public/assets/panels/uv.png +0 -0
  42. package/public/assets/theme.js +43 -0
  43. package/public/assets/vue.svg +1 -0
  44. package/public/vite.svg +1 -0
  45. package/server.js +17 -0
  46. package/src/App.vue +28 -0
  47. package/src/assets/images/panels/longiSolarLR4_60HPH_350M.png +0 -0
  48. package/src/assets/images/panels/longiSolarLR4_60HPH_370M.png +0 -0
  49. package/src/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw copy.png +0 -0
  50. package/src/assets/images/panels/reneSola_Virtus_2_JC320S_24_Bbw.png +0 -0
  51. package/src/assets/images/panels/uv.png +0 -0
  52. package/src/assets/images/white_tile.png +0 -0
  53. package/src/assets/theme.js +43 -0
  54. package/src/components/ThreeCanvasViewer.vue +247 -0
  55. package/src/config.js +104 -0
  56. package/src/functions.js +2 -0
  57. package/src/helper/DFS.js +80 -0
  58. package/src/helper/MapView.js +253 -0
  59. package/src/helper/UpdateRoofModuleFieldRelations.js +119 -0
  60. package/src/helper/UpdateRoofObstacleRelations.js +86 -0
  61. package/src/helper/clearThreeObjects.js +21 -0
  62. package/src/helper/customProvider.js +57 -0
  63. package/src/helper/geometryHandler.js +606 -0
  64. package/src/helper/graphCreation.js +43 -0
  65. package/src/helper/materials.js +55 -0
  66. package/src/helper/projectedMaterial.js +502 -0
  67. package/src/helper/renderMixin.js +1132 -0
  68. package/src/helper/threeMixin.js +171 -0
  69. package/src/main.js +28 -0
  70. package/src/store/AddMargin.js +107 -0
  71. package/src/store/hydrateData.js +209 -0
  72. package/src/store/nodesEdgesCreation.js +216 -0
  73. package/src/store/store.js +10 -0
  74. package/src/store/three-d-module.js +142 -0
  75. package/src/style.css +96 -0
  76. package/src/utils/layers.js +265 -0
  77. package/src/utils/leaflet-config.service.js +67 -0
  78. package/vue.config.js +46 -0
@@ -0,0 +1,502 @@
1
+ import * as THREE from 'three'
2
+ import { monkeyPatch, addLoadListener } from './three-utils'
3
+
4
+ export default class ProjectedMaterial extends THREE.MeshPhysicalMaterial {
5
+ // internal values... they are exposed via getters
6
+ #camera
7
+ #cover
8
+ #textureScale
9
+
10
+ get camera() {
11
+ return this.#camera
12
+ }
13
+ set camera(camera) {
14
+ if (!camera || !camera.isCamera) {
15
+ throw new Error('Invalid camera set to the ProjectedMaterial')
16
+ }
17
+
18
+ this.#camera = camera
19
+
20
+ this.#saveDimensions()
21
+ }
22
+
23
+ get texture() {
24
+ return this.uniforms.projectedTexture.value
25
+ }
26
+ set texture(texture) {
27
+ if (!texture?.isTexture) {
28
+ throw new Error('Invalid texture set to the ProjectedMaterial')
29
+ }
30
+
31
+ this.uniforms.projectedTexture.value = texture
32
+ this.uniforms.isTextureLoaded.value = Boolean(texture.image)
33
+
34
+ if (!this.uniforms.isTextureLoaded.value) {
35
+ addLoadListener(texture, () => {
36
+ this.uniforms.isTextureLoaded.value = true
37
+
38
+ this.#saveDimensions()
39
+ })
40
+ } else {
41
+ this.#saveDimensions()
42
+ }
43
+ }
44
+
45
+ get textureScale() {
46
+ return this.#textureScale
47
+ }
48
+ set textureScale(textureScale) {
49
+ this.#textureScale = textureScale
50
+ this.#saveDimensions()
51
+ }
52
+
53
+ get textureOffset() {
54
+ return this.uniforms.textureOffset.value
55
+ }
56
+ set textureOffset(textureOffset) {
57
+ this.uniforms.textureOffset.value = textureOffset
58
+ }
59
+
60
+ get cover() {
61
+ return this.#cover
62
+ }
63
+ set cover(cover) {
64
+ this.#cover = cover
65
+ this.#saveDimensions()
66
+ }
67
+
68
+ constructor({
69
+ camera = new THREE.PerspectiveCamera(),
70
+ texture = new THREE.Texture(),
71
+ textureScale = 1,
72
+ textureOffset = new THREE.Vector2(),
73
+ cover = false,
74
+ ...options
75
+ } = {}) {
76
+ if (!texture.isTexture) {
77
+ throw new Error('Invalid texture passed to the ProjectedMaterial')
78
+ }
79
+
80
+ if (!camera.isCamera) {
81
+ throw new Error('Invalid camera passed to the ProjectedMaterial')
82
+ }
83
+
84
+ super(options)
85
+
86
+ Object.defineProperty(this, 'isProjectedMaterial', { value: true })
87
+
88
+ // save the private variables
89
+ this.#camera = camera
90
+ this.#cover = cover
91
+ this.#textureScale = textureScale
92
+
93
+ // scale to keep the image proportions and apply textureScale
94
+ const [widthScaled, heightScaled] = computeScaledDimensions(
95
+ texture,
96
+ camera,
97
+ textureScale,
98
+ cover
99
+ )
100
+
101
+ this.uniforms = {
102
+ projectedTexture: { value: texture },
103
+ // this avoids rendering black if the texture
104
+ // hasn't loaded yet
105
+ isTextureLoaded: { value: Boolean(texture.image) },
106
+ // don't show the texture if we haven't called project()
107
+ isTextureProjected: { value: false },
108
+ // if we have multiple materials we want to show the
109
+ // background only of the first material
110
+ backgroundOpacity: { value: 1 },
111
+ // these will be set on project()
112
+ viewMatrixCamera: { value: new THREE.Matrix4() },
113
+ projectionMatrixCamera: { value: new THREE.Matrix4() },
114
+ projPosition: { value: new THREE.Vector3() },
115
+ projDirection: { value: new THREE.Vector3(0, 0, -1) },
116
+ // we will set this later when we will have positioned the object
117
+ savedModelMatrix: { value: new THREE.Matrix4() },
118
+ widthScaled: { value: widthScaled },
119
+ heightScaled: { value: heightScaled },
120
+ textureOffset: { value: textureOffset },
121
+ }
122
+
123
+ this.onBeforeCompile = (shader) => {
124
+ // expose also the material's uniforms
125
+ Object.assign(this.uniforms, shader.uniforms)
126
+ shader.uniforms = this.uniforms
127
+
128
+ if (this.camera.isOrthographicCamera) {
129
+ shader.defines.ORTHOGRAPHIC = ''
130
+ }
131
+
132
+ shader.vertexShader = monkeyPatch(shader.vertexShader, {
133
+ header: /* glsl */ `
134
+ uniform mat4 viewMatrixCamera;
135
+ uniform mat4 projectionMatrixCamera;
136
+
137
+ #ifdef USE_INSTANCING
138
+ attribute vec4 savedModelMatrix0;
139
+ attribute vec4 savedModelMatrix1;
140
+ attribute vec4 savedModelMatrix2;
141
+ attribute vec4 savedModelMatrix3;
142
+ #else
143
+ uniform mat4 savedModelMatrix;
144
+ #endif
145
+
146
+ varying vec3 vSavedNormal;
147
+ varying vec4 vTexCoords;
148
+ #ifndef ORTHOGRAPHIC
149
+ varying vec4 vWorldPosition;
150
+ #endif
151
+ `,
152
+ main: /* glsl */ `
153
+ #ifdef USE_INSTANCING
154
+ mat4 savedModelMatrix = mat4(
155
+ savedModelMatrix0,
156
+ savedModelMatrix1,
157
+ savedModelMatrix2,
158
+ savedModelMatrix3
159
+ );
160
+ #endif
161
+
162
+ vSavedNormal = mat3(savedModelMatrix) * normal;
163
+ vTexCoords = projectionMatrixCamera * viewMatrixCamera * savedModelMatrix * vec4(position, 1.0);
164
+ #ifndef ORTHOGRAPHIC
165
+ vWorldPosition = savedModelMatrix * vec4(position, 1.0);
166
+ #endif
167
+ `,
168
+ })
169
+
170
+ shader.fragmentShader = monkeyPatch(shader.fragmentShader, {
171
+ header: /* glsl */ `
172
+ uniform sampler2D projectedTexture;
173
+ uniform bool isTextureLoaded;
174
+ uniform bool isTextureProjected;
175
+ uniform float backgroundOpacity;
176
+ uniform vec3 projPosition;
177
+ uniform vec3 projDirection;
178
+ uniform float widthScaled;
179
+ uniform float heightScaled;
180
+ uniform vec2 textureOffset;
181
+
182
+ varying vec3 vSavedNormal;
183
+ varying vec4 vTexCoords;
184
+ #ifndef ORTHOGRAPHIC
185
+ varying vec4 vWorldPosition;
186
+ #endif
187
+
188
+ float mapRange(float value, float min1, float max1, float min2, float max2) {
189
+ return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
190
+ }
191
+ `,
192
+ 'vec4 diffuseColor = vec4( diffuse, opacity );': /* glsl */ `
193
+ // clamp the w to make sure we don't project behind
194
+ float w = max(vTexCoords.w, 0.0);
195
+
196
+ vec2 uv = (vTexCoords.xy / w) * 0.5 + 0.5;
197
+
198
+ uv += textureOffset;
199
+
200
+ // apply the corrected width and height
201
+ uv.x = mapRange(uv.x, 0.0, 1.0, 0.5 - widthScaled / 2.0, 0.5 + widthScaled / 2.0);
202
+ uv.y = mapRange(uv.y, 0.0, 1.0, 0.5 - heightScaled / 2.0, 0.5 + heightScaled / 2.0);
203
+
204
+ // this makes sure we don't sample out of the texture
205
+ bool isInTexture = (max(uv.x, uv.y) <= 1.0 && min(uv.x, uv.y) >= 0.0);
206
+
207
+ // this makes sure we don't render also the back of the object
208
+ #ifdef ORTHOGRAPHIC
209
+ vec3 projectorDirection = projDirection;
210
+ #else
211
+ vec3 projectorDirection = normalize(projPosition - vWorldPosition.xyz);
212
+ #endif
213
+ float dotProduct = dot(vSavedNormal, projectorDirection);
214
+ bool isFacingProjector = dotProduct > 0.0000001;
215
+
216
+
217
+ vec4 diffuseColor = vec4(diffuse, opacity * backgroundOpacity);
218
+
219
+ if (isFacingProjector && isInTexture && isTextureLoaded && isTextureProjected) {
220
+ vec4 textureColor = texture2D(projectedTexture, uv);
221
+
222
+ // apply the material opacity
223
+ textureColor.a *= opacity;
224
+
225
+ // https://learnopengl.com/Advanced-OpenGL/Blending
226
+ diffuseColor = textureColor * textureColor.a + diffuseColor * (1.0 - textureColor.a);
227
+ }
228
+ `,
229
+ })
230
+ }
231
+
232
+ // Listen on resize if the camera used for the projection
233
+ // is the same used to render.
234
+ // We do this on window resize because there is no way to
235
+ // listen for the resize of the renderer
236
+ window.addEventListener('resize', this.#saveCameraProjectionMatrix)
237
+
238
+ // If the image texture passed hasn't loaded yet,
239
+ // wait for it to load and compute the correct proportions.
240
+ // This avoids rendering black while the texture is loading
241
+ addLoadListener(texture, () => {
242
+ this.uniforms.isTextureLoaded.value = true
243
+
244
+ this.#saveDimensions()
245
+ })
246
+ }
247
+
248
+ #saveCameraProjectionMatrix = () => {
249
+ this.uniforms.projectionMatrixCamera.value.copy(this.camera.projectionMatrix)
250
+
251
+ this.#saveDimensions()
252
+ }
253
+
254
+ #saveDimensions() {
255
+ const [widthScaled, heightScaled] = computeScaledDimensions(
256
+ this.texture,
257
+ this.camera,
258
+ this.textureScale,
259
+ this.cover
260
+ )
261
+
262
+ this.uniforms.widthScaled.value = widthScaled
263
+ this.uniforms.heightScaled.value = heightScaled
264
+ }
265
+
266
+ #saveCameraMatrices() {
267
+ // make sure the camera matrices are updated
268
+ this.camera.updateProjectionMatrix()
269
+ this.camera.updateMatrixWorld()
270
+ this.camera.updateWorldMatrix()
271
+
272
+ // update the uniforms from the camera so they're
273
+ // fixed in the camera's position at the projection time
274
+ const viewMatrixCamera = this.camera.matrixWorldInverse
275
+ const projectionMatrixCamera = this.camera.projectionMatrix
276
+ const modelMatrixCamera = this.camera.matrixWorld
277
+
278
+ this.uniforms.viewMatrixCamera.value.copy(viewMatrixCamera)
279
+ this.uniforms.projectionMatrixCamera.value.copy(projectionMatrixCamera)
280
+ this.uniforms.projPosition.value.copy(this.camera.position)
281
+ this.uniforms.projDirection.value.set(0, 0, 1).applyMatrix4(modelMatrixCamera)
282
+
283
+ // tell the shader we've projected
284
+ this.uniforms.isTextureProjected.value = true
285
+ }
286
+
287
+ project(mesh) {
288
+ if (
289
+ !(Array.isArray(mesh.material)
290
+ ? mesh.material.every((m) => m.isProjectedMaterial)
291
+ : mesh.material.isProjectedMaterial)
292
+ ) {
293
+ throw new Error(`The mesh material must be a ProjectedMaterial`)
294
+ }
295
+
296
+ if (
297
+ !(Array.isArray(mesh.material)
298
+ ? mesh.material.some((m) => m === this)
299
+ : mesh.material === this)
300
+ ) {
301
+ throw new Error(
302
+ `The provided mesh doesn't have the same material as where project() has been called from`
303
+ )
304
+ }
305
+
306
+ // make sure the matrix is updated
307
+ mesh.updateWorldMatrix(true, false)
308
+
309
+ // we save the object model matrix so it's projected relative
310
+ // to that position, like a snapshot
311
+ this.uniforms.savedModelMatrix.value.copy(mesh.matrixWorld)
312
+
313
+ // if the material is not the first, output just the texture
314
+ if (Array.isArray(mesh.material)) {
315
+ const materialIndex = mesh.material.indexOf(this)
316
+ if (!mesh.material[materialIndex].transparent) {
317
+ throw new Error(
318
+ `You have to pass "transparent: true" to the ProjectedMaterial if you're working with multiple materials.`
319
+ )
320
+ }
321
+ if (materialIndex > 0) {
322
+ this.uniforms.backgroundOpacity.value = 0
323
+ }
324
+ }
325
+
326
+ // persist also the current camera position and matrices
327
+ this.#saveCameraMatrices()
328
+ }
329
+
330
+ projectInstanceAt(index, instancedMesh, matrixWorld, { forceCameraSave = false } = {}) {
331
+ if (!instancedMesh.isInstancedMesh) {
332
+ throw new Error(`The provided mesh is not an InstancedMesh`)
333
+ }
334
+
335
+ if (
336
+ !(Array.isArray(instancedMesh.material)
337
+ ? instancedMesh.material.every((m) => m.isProjectedMaterial)
338
+ : instancedMesh.material.isProjectedMaterial)
339
+ ) {
340
+ throw new Error(`The InstancedMesh material must be a ProjectedMaterial`)
341
+ }
342
+
343
+ if (
344
+ !(Array.isArray(instancedMesh.material)
345
+ ? instancedMesh.material.some((m) => m === this)
346
+ : instancedMesh.material === this)
347
+ ) {
348
+ throw new Error(
349
+ `The provided InstancedMeshhave't i samenclude thas e material where project() has been called from`
350
+ )
351
+ }
352
+
353
+ if (
354
+ !instancedMesh.geometry.attributes[`savedModelMatrix0`] ||
355
+ !instancedMesh.geometry.attributes[`savedModelMatrix1`] ||
356
+ !instancedMesh.geometry.attributes[`savedModelMatrix2`] ||
357
+ !instancedMesh.geometry.attributes[`savedModelMatrix3`]
358
+ ) {
359
+ throw new Error(
360
+ `No allocated data found on the geometry, please call 'allocateProjectionData(geometry, instancesCount)'`
361
+ )
362
+ }
363
+
364
+ instancedMesh.geometry.attributes[`savedModelMatrix0`].setXYZW(
365
+ index,
366
+ matrixWorld.elements[0],
367
+ matrixWorld.elements[1],
368
+ matrixWorld.elements[2],
369
+ matrixWorld.elements[3]
370
+ )
371
+ instancedMesh.geometry.attributes[`savedModelMatrix1`].setXYZW(
372
+ index,
373
+ matrixWorld.elements[4],
374
+ matrixWorld.elements[5],
375
+ matrixWorld.elements[6],
376
+ matrixWorld.elements[7]
377
+ )
378
+ instancedMesh.geometry.attributes[`savedModelMatrix2`].setXYZW(
379
+ index,
380
+ matrixWorld.elements[8],
381
+ matrixWorld.elements[9],
382
+ matrixWorld.elements[10],
383
+ matrixWorld.elements[11]
384
+ )
385
+ instancedMesh.geometry.attributes[`savedModelMatrix3`].setXYZW(
386
+ index,
387
+ matrixWorld.elements[12],
388
+ matrixWorld.elements[13],
389
+ matrixWorld.elements[14],
390
+ matrixWorld.elements[15]
391
+ )
392
+
393
+ // if the material is not the first, output just the texture
394
+ if (Array.isArray(instancedMesh.material)) {
395
+ const materialIndex = instancedMesh.material.indexOf(this)
396
+ if (!instancedMesh.material[materialIndex].transparent) {
397
+ throw new Error(
398
+ `You have to pass "transparent: true" to the ProjectedMaterial if you're working with multiple materials.`
399
+ )
400
+ }
401
+ if (materialIndex > 0) {
402
+ this.uniforms.backgroundOpacity.value = 0
403
+ }
404
+ }
405
+
406
+ // persist the current camera position and matrices
407
+ // only if it's the first instance since most surely
408
+ // in all other instances the camera won't change
409
+ if (index === 0 || forceCameraSave) {
410
+ this.#saveCameraMatrices()
411
+ }
412
+ }
413
+
414
+ copy(source) {
415
+ super.copy(source)
416
+
417
+ this.camera = source.camera
418
+ this.texture = source.texture
419
+ this.textureScale = source.textureScale
420
+ this.textureOffset = source.textureOffset
421
+ this.cover = source.cover
422
+
423
+ return this
424
+ }
425
+
426
+ dispose() {
427
+ super.dispose()
428
+ window.removeEventListener('resize', this.#saveCameraProjectionMatrix)
429
+ }
430
+ }
431
+
432
+ // get camera ratio from different types of cameras
433
+ function getCameraRatio(camera) {
434
+ switch (camera.type) {
435
+ case 'PerspectiveCamera': {
436
+ return camera.aspect
437
+ }
438
+ case 'OrthographicCamera': {
439
+ const width = Math.abs(camera.right - camera.left)
440
+ const height = Math.abs(camera.top - camera.bottom)
441
+ return width / height
442
+ }
443
+ default: {
444
+ throw new Error(`${camera.type} is currently not supported in ProjectedMaterial`)
445
+ }
446
+ }
447
+ }
448
+
449
+ // scale to keep the image proportions and apply textureScale
450
+ function computeScaledDimensions(texture, camera, textureScale, cover) {
451
+ // return some default values if the image hasn't loaded yet
452
+ if (!texture.image) {
453
+ return [1, 1]
454
+ }
455
+
456
+ // return if it's a video and if the video hasn't loaded yet
457
+ if (texture.image.videoWidth === 0 && texture.image.videoHeight === 0) {
458
+ return [1, 1]
459
+ }
460
+
461
+ const sourceWidth =
462
+ texture.image.naturalWidth || texture.image.videoWidth || texture.image.clientWidth
463
+ const sourceHeight =
464
+ texture.image.naturalHeight || texture.image.videoHeight || texture.image.clientHeight
465
+
466
+ const ratio = sourceWidth / sourceHeight
467
+ const ratioCamera = getCameraRatio(camera)
468
+ const widthCamera = 1
469
+ const heightCamera = widthCamera * (1 / ratioCamera)
470
+ let widthScaled
471
+ let heightScaled
472
+ if (cover ? ratio > ratioCamera : ratio < ratioCamera) {
473
+ const width = heightCamera * ratio
474
+ widthScaled = 1 / ((width / widthCamera) * textureScale)
475
+ heightScaled = 1 / textureScale
476
+ } else {
477
+ const height = widthCamera * (1 / ratio)
478
+ heightScaled = 1 / ((height / heightCamera) * textureScale)
479
+ widthScaled = 1 / textureScale
480
+ }
481
+
482
+ return [widthScaled, heightScaled]
483
+ }
484
+
485
+ export function allocateProjectionData(geometry, instancesCount) {
486
+ geometry.setAttribute(
487
+ `savedModelMatrix0`,
488
+ new THREE.InstancedBufferAttribute(new Float32Array(instancesCount * 4), 4)
489
+ )
490
+ geometry.setAttribute(
491
+ `savedModelMatrix1`,
492
+ new THREE.InstancedBufferAttribute(new Float32Array(instancesCount * 4), 4)
493
+ )
494
+ geometry.setAttribute(
495
+ `savedModelMatrix2`,
496
+ new THREE.InstancedBufferAttribute(new Float32Array(instancesCount * 4), 4)
497
+ )
498
+ geometry.setAttribute(
499
+ `savedModelMatrix3`,
500
+ new THREE.InstancedBufferAttribute(new Float32Array(instancesCount * 4), 4)
501
+ )
502
+ }