@woosh/meep-engine 2.33.2 → 2.33.6

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 (98) hide show
  1. package/core/bvh2/aabb3/AABB3.js +18 -0
  2. package/core/bvh2/aabb3/aabb3_intersects_frustum.js +38 -0
  3. package/core/collection/RingBuffer.js +40 -10
  4. package/core/collection/array/copyArray.js +2 -2
  5. package/core/collection/array/typed/typed_array_copy.js +2 -2
  6. package/core/collection/table/RowFirstTableSpec.js +8 -0
  7. package/core/geom/3d/aabb/aabb3_compute_projected_area.js +16 -14
  8. package/core/geom/3d/aabb/aabb3_estimate_projected_area2.js +59 -0
  9. package/core/geom/3d/aabb/aabb3_matrix4_project.js +33 -0
  10. package/core/geom/3d/aabb/aabb3_matrix4_project.spec.js +41 -0
  11. package/core/geom/3d/plane/plane3_lerp.js +2 -2
  12. package/core/geom/3d/topology/TopoTriangle.js +2 -2
  13. package/core/geom/AABB2.d.ts +2 -0
  14. package/core/geom/Matrix4.js +4 -4
  15. package/core/geom/Vector3.js +5 -5
  16. package/core/model/reactive/model/terminal/ReactiveReference.js +7 -1
  17. package/core/process/undo/ActionProcessor.d.ts +2 -0
  18. package/core/process/undo/ActionProcessor.js +59 -1
  19. package/core/process/undo/ActionProcessor.spec.js +59 -0
  20. package/core/process/undo/Mark.js +2 -1
  21. package/engine/asset/loaders/GLTFAssetLoader.js +3 -3
  22. package/engine/asset/loaders/material/TextureAttachmensByMaterialType.js +11 -1
  23. package/engine/asset/loaders/material/TextureAttachment.js +12 -1
  24. package/engine/asset/loaders/material/bitmap2sampler_gl.js +19 -0
  25. package/engine/asset/loaders/material/computeImageBitmapEquality.js +7 -19
  26. package/engine/asset/loaders/material/computeTextureEquality.js +1 -1
  27. package/engine/asset/loaders/material/computeTextureHash.js +16 -14
  28. package/engine/asset/loaders/material/traverseMaterialTextures.js +2 -2
  29. package/engine/ecs/animation/OneBoneSurfaceAlignmentSolver.js +2 -2
  30. package/engine/ecs/animation/TwoBoneInverseKinematicsSolver.js +4 -4
  31. package/engine/graphics/GraphicsEngine.d.ts +2 -2
  32. package/engine/graphics/GraphicsEngine.js +20 -62
  33. package/engine/graphics/filter/FlipArrayInPlace.js +25 -0
  34. package/engine/graphics/filter/FlipArrayViaCanvas.js +13 -0
  35. package/engine/graphics/filter/ImageFilter.js +20 -51
  36. package/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +2 -2
  37. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +25 -16
  38. package/engine/graphics/material/SplatMaterial.js +4 -97
  39. package/engine/graphics/material/optimization/MaterialOptimizationContext.js +598 -0
  40. package/engine/graphics/micron/build/PatchRepresentation.js +4 -43
  41. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +4 -75
  42. package/engine/graphics/micron/build/compute_buffer_geometry_byte_size.js +16 -0
  43. package/engine/graphics/micron/build/fill_patch_geometry_data.js +2 -0
  44. package/engine/graphics/micron/format/MicronGeometryBufferAttributeSpec.js +1 -1
  45. package/engine/graphics/micron/format/MicronGeometryPatch.js +17 -5
  46. package/engine/graphics/micron/format/MicronVertexDataSpec.js +25 -3
  47. package/engine/graphics/micron/prototypeVirtualGeometry.js +19 -12
  48. package/engine/graphics/micron/render/VirtualGeometryBuilder.js +34 -27
  49. package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +2 -4
  50. package/engine/graphics/micron/render/instanced/PatchDataTextures.js +1 -0
  51. package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +1 -29
  52. package/engine/graphics/micron/render/refinement/ActivePatchList.js +43 -159
  53. package/engine/graphics/micron/render/refinement/ActivePatchRecord.js +4 -2
  54. package/engine/graphics/micron/render/refinement/RefinementSpec.js +98 -0
  55. package/engine/graphics/micron/render/refinement/array_normalize_plane.js +25 -0
  56. package/engine/graphics/micron/render/refinement/array_setFromProjectionMatrix.js +60 -0
  57. package/engine/graphics/micron/render/refinement/is_patch_facing_back.js +43 -0
  58. package/engine/graphics/micron/render/refinement/is_patch_visible.js +37 -0
  59. package/engine/graphics/micron/render/v1/MaterialVertexSpec.js +21 -0
  60. package/engine/graphics/micron/render/v1/VGThreeRenderer.js +12 -9
  61. package/engine/graphics/micron/util/unit_hemioct.spec.js +2 -2
  62. package/engine/graphics/render/buffer/buffers/ColorAndDepthFrameBuffer.js +5 -3
  63. package/engine/graphics/render/buffer/buffers/NormalFrameBuffer.js +12 -2
  64. package/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +8 -10
  65. package/engine/graphics/render/forward_plus/LightManager.js +5 -7
  66. package/engine/graphics/render/forward_plus/data/NumericType.js +9 -0
  67. package/engine/graphics/render/forward_plus/{TextureBackedMemoryRegion.js → data/TextureBackedMemoryRegion.js} +11 -190
  68. package/engine/graphics/render/forward_plus/data/channelCountToThreIntegerTextureType.js +16 -0
  69. package/engine/graphics/render/forward_plus/data/computeDataType.js +36 -0
  70. package/engine/graphics/render/forward_plus/data/computeThreeTextureFormat.js +18 -0
  71. package/engine/graphics/render/forward_plus/data/computeThreeTextureInternalFormatFromDataType.js +63 -0
  72. package/engine/graphics/render/forward_plus/data/computeThreeTextureTypeFromDataType.js +41 -0
  73. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  74. package/engine/graphics/render/forward_plus/prototypeLightManager.js +1 -1
  75. package/engine/graphics/render/utils/ThreeBypassRenderer.js +1 -3
  76. package/engine/graphics/render/visibility/hiz/buffer/HierarchicalZBuffer.js +198 -0
  77. package/engine/graphics/render/visibility/hiz/buffer/ReductionShader.js +51 -0
  78. package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +179 -0
  79. package/engine/graphics/render/visibility/hiz/prototypeHiZ.js +435 -0
  80. package/engine/graphics/render/visibility/hiz/query/BatchOcclusionQuery.js +174 -0
  81. package/engine/graphics/render/visibility/hiz/query/QueryShader.js +173 -0
  82. package/engine/graphics/shadows/ShadowMapRenderer.js +12 -2
  83. package/engine/graphics/texture/atlas/TextureAtlas.js +1 -1
  84. package/engine/graphics/texture/cubemap/buildCubeURLs.js +13 -0
  85. package/engine/graphics/texture/cubemap/load_environment_map.d.ts +8 -0
  86. package/engine/graphics/texture/cubemap/load_environment_map.js +163 -0
  87. package/engine/graphics/texture/sampler/Sampler2D.js +18 -62
  88. package/engine/graphics/texture/sampler/convertTexture2Sampler2D.js +8 -4
  89. package/engine/graphics/texture/sampler/debug/paintSamplerOnHTML.js +3 -2
  90. package/engine/graphics/texture/sampler/differenceSampler.js +31 -0
  91. package/engine/graphics/texture/sampler/typedArrayConstructorByInstance.js +25 -0
  92. package/engine/graphics/texture/sampler/util/drawSamplerHTML.js +3 -2
  93. package/engine/graphics/texture/virtual/v2/ShaderUsage.js +6 -5
  94. package/engine/graphics/texture/virtual/v2/prototype.js +16 -6
  95. package/package.json +1 -1
  96. package/view/elements/progress/segmented/SegmentedResourceBarView.js +50 -15
  97. package/view/minimap/gl/MinimapMarkersGL.js +2 -2
  98. package/engine/graphics/micron/render/RefinementSpec.js +0 -110
@@ -0,0 +1,598 @@
1
+ import { traverseThreeObject } from "../../ecs/highlight/renderer/traverseThreeObject.js";
2
+ import { TextureAttachmentsByMaterialType } from "../../../asset/loaders/material/TextureAttachmensByMaterialType.js";
3
+ import { HashMap } from "../../../../core/collection/HashMap.js";
4
+ import Vector2 from "../../../../core/geom/Vector2.js";
5
+ import { traverseMaterialTextures } from "../../../asset/loaders/material/traverseMaterialTextures.js";
6
+ import { max2 } from "../../../../core/math/max2.js";
7
+ import AABB2 from "../../../../core/geom/AABB2.js";
8
+ import { MaxRectanglesPacker } from "../../../../core/geom/packing/MaxRectangles.js";
9
+ import { Sampler2D } from "../../texture/sampler/Sampler2D.js";
10
+ import { array_push_if_unique } from "../../../../core/collection/array/array_push_if_unique.js";
11
+ import { computeMaterialHash } from "../../../asset/loaders/material/computeMaterialHash.js";
12
+ import { computeMaterialEquality } from "../../../asset/loaders/material/computeMaterialEquality.js";
13
+ import { collectIteratorValueToArray } from "../../../../core/collection/IteratorUtils.js";
14
+ import {
15
+ ClampToEdgeWrapping,
16
+ DataTexture,
17
+ LinearEncoding,
18
+ LinearFilter,
19
+ LinearMipmapLinearFilter,
20
+ Matrix3,
21
+ sRGBEncoding,
22
+ UnsignedByteType
23
+ } from "three";
24
+ import { convertTexture2Sampler2D } from "../../texture/sampler/convertTexture2Sampler2D.js";
25
+
26
+ const ATLAS_PATCH_BORDER = 4;
27
+
28
+ const BUFFER_GEOMETRY_UVS = [
29
+ {
30
+ name: 'uv',
31
+ index: 0,
32
+ },
33
+ {
34
+ name: 'uv2',
35
+ index: 1
36
+ }
37
+ ];
38
+
39
+ class TextureReference {
40
+ constructor() {
41
+ /**
42
+ *
43
+ * @type {TextureAttachment|null}
44
+ */
45
+ this.attachment = null;
46
+ /**
47
+ *
48
+ * @type {THREE.Material|null}
49
+ */
50
+ this.material = null;
51
+ /**
52
+ *
53
+ * @type {THREE.Texture|null}
54
+ */
55
+ this.source_texture = null;
56
+ }
57
+ }
58
+
59
+ /**
60
+ *
61
+ * @param {THREE.Mesh} mesh
62
+ * @returns {boolean}
63
+ */
64
+ function is_compliant_mesh(mesh) {
65
+ const material = mesh.material;
66
+
67
+ const attachments = TextureAttachmentsByMaterialType[material.type];
68
+
69
+ const uv_scales = [1, 1, 1, 1];
70
+
71
+ for (let i = 0; i < attachments.length; i++) {
72
+ const attachment = attachments[i];
73
+
74
+ const texture = attachment.read(material);
75
+ if (texture === undefined || texture === null) {
76
+ continue;
77
+ }
78
+
79
+ const uv_index = attachment.uv_index;
80
+
81
+ uv_scales[uv_index * 2] = max2(uv_scales[uv_index * 2], texture.repeat.x)
82
+ uv_scales[uv_index * 2 + 1] = max2(uv_scales[uv_index * 2 + 1], texture.repeat.y)
83
+ }
84
+
85
+ const geometry = mesh.geometry;
86
+
87
+ for (let i = 0; i < BUFFER_GEOMETRY_UVS.length; i++) {
88
+ const uv_metadata = BUFFER_GEOMETRY_UVS[i];
89
+
90
+ /**
91
+ *
92
+ * @type {THREE.BufferAttribute }
93
+ */
94
+ const attribute = geometry.attributes[uv_metadata.name];
95
+
96
+ if (attribute === undefined) {
97
+ continue;
98
+ }
99
+
100
+ const attribute_data = attribute.array;
101
+ const n = attribute_data.length;
102
+
103
+ const uv_index = uv_metadata.index;
104
+ const uv_index_2 = uv_index * 2;
105
+
106
+ for (let j = 0; j < n; j += 2) {
107
+ const x = attribute_data[j];
108
+ const y = attribute_data[j + 1];
109
+
110
+ const scaled_u = x * uv_scales[uv_index_2];
111
+ const scaled_v = y * uv_scales[uv_index_2 + 1];
112
+
113
+ if (scaled_u > 1 || scaled_u < 0 || scaled_v > 1 || scaled_v < 0) {
114
+ // repeating/negative UV value
115
+ return false;
116
+ }
117
+
118
+ }
119
+
120
+ }
121
+
122
+ return true;
123
+ }
124
+
125
+ class UvContext {
126
+ constructor() {
127
+
128
+ this.resolution = new Vector2(1, 1);
129
+
130
+ /**
131
+ *
132
+ * @type {AABB2}
133
+ */
134
+ this.atlas_patch = new AABB2();
135
+ }
136
+ }
137
+
138
+ /**
139
+ *
140
+ * @param {Texture} texture
141
+ * @param {string} attachment_name
142
+ */
143
+ function prepare_atlas_texture(texture, attachment_name) {
144
+
145
+ switch (attachment_name) {
146
+ case 'diffuse':
147
+ texture.encoding = sRGBEncoding;
148
+ break;
149
+ default:
150
+ texture.encoding = LinearEncoding;
151
+ }
152
+
153
+ texture.minFilter = LinearMipmapLinearFilter;
154
+ texture.magFilter = LinearFilter;
155
+
156
+ texture.generateMipmaps = true;
157
+ }
158
+
159
+
160
+ class MaterialDescriptor {
161
+ constructor() {
162
+
163
+ /**
164
+ *
165
+ * @type {THREE.Material|null}
166
+ */
167
+ this.source_material = null;
168
+
169
+ /**
170
+ *
171
+ * @type {UvContext[]}
172
+ */
173
+ this.uvs = [];
174
+ }
175
+
176
+ build_uvs() {
177
+
178
+ traverseMaterialTextures(this.source_material, (t, attachment) => {
179
+ const uv_index = attachment.uv_index;
180
+
181
+ let uv_context = this.uvs[uv_index];
182
+
183
+ if (uv_context === undefined) {
184
+ uv_context = new UvContext();
185
+ uv_context.resolution.set(1, 1);
186
+
187
+ this.uvs[uv_index] = uv_context;
188
+ }
189
+
190
+ const image = t.image;
191
+
192
+ if (image !== undefined && image.width !== undefined) {
193
+ uv_context.resolution.x = max2(uv_context.resolution.x, image.width);
194
+ uv_context.resolution.y = max2(uv_context.resolution.y, image.height);
195
+ }
196
+
197
+ });
198
+
199
+ }
200
+
201
+ }
202
+
203
+ export class MaterialOptimizationContext {
204
+ constructor() {
205
+ /**
206
+ *
207
+ * @type {THREE.Texture[]}
208
+ */
209
+ this.textures = [];
210
+
211
+ /**
212
+ *
213
+ * @type {THREE.Mesh[]}
214
+ */
215
+ this.meshes = [];
216
+
217
+
218
+ /**
219
+ *
220
+ * @type {Map<string,Sampler2D>}
221
+ */
222
+ this.atlases = new Map();
223
+
224
+ /**
225
+ *
226
+ * @type {Vector2[]}
227
+ */
228
+ this.atlas_size = [];
229
+ }
230
+
231
+ /**
232
+ *
233
+ * @param {MaterialDescriptor[]} materials
234
+ */
235
+ pack_atlas(materials) {
236
+ const uv_indices = [];
237
+ // figure out UV sets
238
+ materials.forEach(m => {
239
+ for (let i = 0; i < m.uvs.length; i++) {
240
+ if (m.uvs[i] !== undefined) {
241
+ array_push_if_unique(uv_indices, i);
242
+ }
243
+ }
244
+ });
245
+
246
+ for (let i = 0; i < uv_indices.length; i++) {
247
+ const uv_index = uv_indices[i];
248
+
249
+ const packer = new MaxRectanglesPacker(1, 1);
250
+
251
+ let pow_x = 0;
252
+ let pow_y = 0;
253
+
254
+ const uv_relevant_materials = materials.filter(d => d.uvs[uv_index] !== undefined);
255
+
256
+ const rectangles = uv_relevant_materials.map(d => {
257
+ const uv_context = d.uvs[uv_index];
258
+
259
+ const resolution = uv_context.resolution;
260
+
261
+ return new AABB2(0, 0, resolution.x + ATLAS_PATCH_BORDER * 2, resolution.y + ATLAS_PATCH_BORDER * 2);
262
+
263
+ });
264
+
265
+ let cycle_index = 0;
266
+
267
+ while (!packer.addMany(rectangles)) {
268
+ cycle_index++;
269
+
270
+ if (cycle_index % 2 !== 0) {
271
+ pow_x++;
272
+ } else {
273
+ pow_y++;
274
+ }
275
+
276
+ const size_x = Math.pow(2, pow_x);
277
+ const size_y = Math.pow(2, pow_y);
278
+
279
+ const max_texture_size = MaterialOptimizationContext.MAX_TEXTURE_SIZE;
280
+
281
+ if (size_x > max_texture_size || size_y > max_texture_size) {
282
+ throw new Error(`Maximum texture size exceeded '${max_texture_size}'`);
283
+ }
284
+
285
+ packer.resize(size_x, size_y);
286
+ }
287
+
288
+ this.atlas_size[uv_index] = packer.size.clone();
289
+
290
+ // all packed, write back bounds
291
+ rectangles.forEach((r, i) => {
292
+ const materialDescriptor = uv_relevant_materials[i];
293
+
294
+ const p = materialDescriptor.uvs[uv_index].atlas_patch;
295
+
296
+ p.set(r.x0 + ATLAS_PATCH_BORDER, r.y0 + ATLAS_PATCH_BORDER, r.x1 - ATLAS_PATCH_BORDER, r.y1 - ATLAS_PATCH_BORDER);
297
+ });
298
+ }
299
+ }
300
+
301
+ /**
302
+ *
303
+ * @param {MaterialDescriptor[]} materials
304
+ */
305
+ build_atlas_samplers(materials) {
306
+
307
+ this.atlases.clear();
308
+
309
+ const names = [];
310
+ const uv_indices = [];
311
+
312
+ for (let i = 0; i < materials.length; i++) {
313
+ const material = materials[i];
314
+
315
+ const source_material = material.source_material;
316
+ const materialType = source_material.type;
317
+
318
+ /**
319
+ *
320
+ * @type {TextureAttachment[]}
321
+ */
322
+ const attachments = TextureAttachmentsByMaterialType[materialType];
323
+
324
+ for (let i = 0; i < attachments.length; i++) {
325
+ const attachment = attachments[i];
326
+
327
+ if (array_push_if_unique(names, attachment.name)) {
328
+ // added
329
+ uv_indices[names.length - 1] = attachment.uv_index;
330
+ }
331
+
332
+ }
333
+ }
334
+
335
+ for (let i = 0; i < names.length; i++) {
336
+ const name = names[i];
337
+ const uv_index = uv_indices[i];
338
+
339
+ const size = this.atlas_size[uv_index];
340
+
341
+ this.atlases.set(name, Sampler2D.uint8(4, size.x, size.y));
342
+ }
343
+ }
344
+
345
+ /**
346
+ *
347
+ * @param {MaterialDescriptor} material
348
+ */
349
+ write_material_to_atlas(material) {
350
+ //patch textures
351
+ const source_material = material.source_material;
352
+ const materialType = source_material.type;
353
+
354
+ /**
355
+ *
356
+ * @type {TextureAttachment[]}
357
+ */
358
+ const attachments = TextureAttachmentsByMaterialType[materialType];
359
+
360
+ for (let i = 0; i < attachments.length; i++) {
361
+ const attachment = attachments[i];
362
+
363
+ const uv_context = material.uvs[attachment.uv_index];
364
+
365
+ if (uv_context === undefined) {
366
+ // material does not participate in this UV set
367
+ continue;
368
+ }
369
+
370
+ let source_sampler;
371
+
372
+ const texture = attachment.read(source_material);
373
+
374
+ const texture_width = uv_context.resolution.x;
375
+ const texture_height = uv_context.resolution.y;
376
+ if (texture !== undefined && texture !== null) {
377
+ // source_sampler = Sampler2D.uint8(5, texture_width, texture_height);
378
+ //
379
+ // source_sampler.fill(0, 0, texture_width, texture_height, [255, 255, 255, 255]);
380
+
381
+ source_sampler = convertTexture2Sampler2D(texture, texture_width, texture_height, false);
382
+ } else {
383
+ // TODO proper defaults when a texture is missing
384
+ source_sampler = Sampler2D.uint8(4, texture_width, texture_height);
385
+ }
386
+
387
+ const atlas = this.atlases.get(attachment.name);
388
+
389
+ const patch = uv_context.atlas_patch;
390
+
391
+ atlas.copy_sameItemSize(
392
+ source_sampler,
393
+ 0, 0,
394
+ patch.x0, patch.y0, patch.getWidth(), patch.getHeight()
395
+ );
396
+ }
397
+ }
398
+
399
+ /**
400
+ *
401
+ * @param {THREE.Mesh} mesh
402
+ */
403
+ addMesh(mesh) {
404
+ const material = mesh.material;
405
+
406
+ if (material.isMeshStandardMaterial) {
407
+ this.meshes.push(mesh);
408
+ } else {
409
+ throw new Error(`Unsupported material type '${material.type}'`);
410
+ }
411
+ }
412
+
413
+ /**
414
+ *
415
+ * @param {THREE.Object} o
416
+ */
417
+ addObject(o) {
418
+ traverseThreeObject(o, (o) => {
419
+ if (o.isMesh) {
420
+ this.addMesh(o);
421
+ }
422
+ });
423
+ }
424
+
425
+ /**
426
+ * Update materials and geometries
427
+ */
428
+ update() {
429
+ // collect unique materials and their geometries
430
+
431
+ /**
432
+ *
433
+ * @type {Map<MaterialDescriptor, THREE.BufferGeometry[]>}
434
+ */
435
+ const material_to_geometry_map = new Map();
436
+
437
+ /**
438
+ *
439
+ * @type {Map<MaterialDescriptor, THREE.Mesh[]>}
440
+ */
441
+ const material_to_mesh_map = new Map();
442
+
443
+ const unique_materials = new HashMap({
444
+ keyHashFunction: computeMaterialHash,
445
+ keyEqualityFunction: computeMaterialEquality
446
+ });
447
+
448
+ const input_meshes = this.meshes;
449
+ const input_mesh_count = input_meshes.length;
450
+
451
+ for (let i = 0; i < input_mesh_count; i++) {
452
+ const mesh = input_meshes[i];
453
+
454
+ if (!is_compliant_mesh(mesh)) {
455
+ continue;
456
+ }
457
+
458
+ const material = mesh.material;
459
+
460
+ let material_descriptor = unique_materials.get(material);
461
+
462
+ if (material_descriptor === undefined) {
463
+ material_descriptor = new MaterialDescriptor();
464
+ material_descriptor.source_material = material;
465
+
466
+ material_descriptor.build_uvs();
467
+
468
+ unique_materials.set(material, material_descriptor);
469
+
470
+ material_to_geometry_map.set(material_descriptor, []);
471
+ material_to_mesh_map.set(material_descriptor, []);
472
+
473
+ }
474
+
475
+ const geometries = material_to_geometry_map.get(material_descriptor);
476
+
477
+ array_push_if_unique(geometries, mesh.geometry);
478
+
479
+ const mesh_bucket = material_to_mesh_map.get(material_descriptor);
480
+ mesh_bucket.push(mesh);
481
+ }
482
+
483
+ // collect materials
484
+ /**
485
+ *
486
+ * @type {MaterialDescriptor[]}
487
+ */
488
+ const unique_material_array = [];
489
+ collectIteratorValueToArray(unique_material_array, unique_materials.values());
490
+
491
+ if (unique_material_array.length <= 4) {
492
+ // no point in atlasing
493
+ return;
494
+ }
495
+
496
+ this.pack_atlas(unique_material_array);
497
+
498
+ this.build_atlas_samplers(unique_material_array);
499
+
500
+ const textures = new Map();
501
+ //build new textures
502
+ for (const [name, sampler] of this.atlases) {
503
+ const texture = new DataTexture();
504
+
505
+ texture.image = {
506
+ data: sampler.data,
507
+ width: sampler.width,
508
+ height: sampler.height
509
+ };
510
+
511
+ texture.wrapS = ClampToEdgeWrapping;
512
+ texture.wrapT = ClampToEdgeWrapping;
513
+ texture.type = UnsignedByteType;
514
+ texture.anisotropy = 4;
515
+
516
+ prepare_atlas_texture(texture, name);
517
+
518
+ textures.set(name, texture);
519
+ }
520
+
521
+ for (let i = 0; i < unique_material_array.length; i++) {
522
+ const mat = unique_material_array[i];
523
+
524
+ this.write_material_to_atlas(mat);
525
+
526
+ // get all associated geometries
527
+ const geometries = material_to_geometry_map.get(mat);
528
+
529
+ for (let j = 0; j < geometries.length; j++) {
530
+ const bufferGeometry = geometries[j];
531
+
532
+ for (let k = 0; k < BUFFER_GEOMETRY_UVS.length; k++) {
533
+ const uv_metadata = BUFFER_GEOMETRY_UVS[k];
534
+
535
+ // update UVs
536
+ const uv_attribute = bufferGeometry.attributes[uv_metadata.name];
537
+
538
+ if (uv_attribute === undefined) {
539
+ // no UVs, nothing to update
540
+ continue;
541
+ }
542
+
543
+
544
+ const uv_index = uv_metadata.index;
545
+ const uv_context = mat.uvs[uv_index];
546
+
547
+ if (uv_context === undefined) {
548
+ // no UV context present
549
+ // TODO need to force context to exist in this case or remove the attribute
550
+ continue;
551
+ }
552
+
553
+ const atlas_size = this.atlas_size[uv_index];
554
+
555
+ const atlas_width = atlas_size.x;
556
+ const atlas_height = atlas_size.y;
557
+
558
+ const patch = uv_context.atlas_patch;
559
+
560
+ const matrix3 = new Matrix3();
561
+ matrix3.setUvTransform(
562
+ patch.x0 / atlas_width,
563
+ patch.y0 / atlas_height,
564
+ patch.getWidth() / atlas_width,
565
+ patch.getHeight() / atlas_height,
566
+ 0,
567
+ 0, 0
568
+ );
569
+
570
+ uv_attribute.applyMatrix3(matrix3);
571
+
572
+ uv_attribute.needsUpdate = true;
573
+ }
574
+ }
575
+
576
+ // build material
577
+ const new_material = mat.source_material.clone();
578
+
579
+ traverseMaterialTextures(new_material, (old_texture, attachment) => {
580
+ attachment.write(new_material, textures.get(attachment.name));
581
+ });
582
+
583
+ // set new material to all associated meshes
584
+ const meshes = material_to_mesh_map.get(mat);
585
+ for (let j = 0; j < meshes.length; j++) {
586
+ const mesh = meshes[j];
587
+ mesh.material = new_material;
588
+ }
589
+ }
590
+
591
+ }
592
+ }
593
+
594
+ /**
595
+ *
596
+ * @type {number}
597
+ */
598
+ MaterialOptimizationContext.MAX_TEXTURE_SIZE = 4096;
@@ -397,9 +397,11 @@ export class PatchRepresentation {
397
397
  result.polygon_count = topology.getFaces().size;
398
398
 
399
399
  // copy bounding_box
400
- result.bounding_box.copy(this.bounding_box);
400
+ this.bounding_box.writeToArray(result.bounding_box, 0);
401
401
 
402
- result.group_bounding_box.copy(this.group_aabb);
402
+ this.group_aabb.writeToArray(result.group_bounding_box, 0);
403
+
404
+ this.group_aabb.getCorners(result.group_bounding_box_corners);
403
405
 
404
406
  vec4.copy(result.group_bounding_sphere, this.group_bounding_sphere);
405
407
 
@@ -414,45 +416,4 @@ export class PatchRepresentation {
414
416
  // optimize index buffer for better caching
415
417
  meshopt_optimizeVertexCache(result.face_indices, result.face_indices, result.face_indices.length, result.vertex_count);
416
418
  }
417
-
418
- /**
419
- *
420
- * @param {THREE.BufferGeometry} source_geometry
421
- * @param {MicronVertexDataSpec} vertex_data_spec
422
- * @returns {MicronGeometryPatch}
423
- */
424
- buildGeometryPatch(source_geometry, vertex_data_spec) {
425
-
426
- const result = new MicronGeometryPatch();
427
-
428
- this.buildMicronGeometryPatch(result, source_geometry, vertex_data_spec);
429
-
430
- // patch children
431
- result.children = [];
432
-
433
- const rep_children = this.children;
434
- const child_count = rep_children.length;
435
-
436
- for (let i = 0; i < child_count; i++) {
437
- const child = rep_children[i];
438
-
439
- const child_patch = child.buildGeometryPatch(source_geometry, vertex_data_spec);
440
-
441
- child_patch.parent = result;
442
-
443
- result.children[i] = child_patch;
444
- }
445
-
446
- // write dependencies
447
- result.dependencies = [];
448
-
449
- const rep_dependencies = this.dependencies;
450
- const dependency_count = rep_dependencies.length;
451
- for (let i = 0; i < dependency_count; i++) {
452
- const rep_dep = rep_dependencies[i];
453
- result.dependencies.push(rep_dep.id);
454
- }
455
-
456
- return result;
457
- }
458
419
  }