@woosh/meep-engine 2.34.47 → 2.35.0

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 (56) hide show
  1. package/core/binary/BitSet.js +10 -3
  2. package/core/bvh2/BinaryNode.js +19 -35
  3. package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +5 -5
  4. package/core/bvh2/aabb3_combined_surface_area.js +21 -0
  5. package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +24 -12
  6. package/core/cache/Cache.d.ts +2 -0
  7. package/core/cache/Cache.js +27 -23
  8. package/core/geom/3d/aabb/aabb3_estimate_projected_area2.js +1 -1
  9. package/core/geom/3d/frustum/frustum_from_projection_matrix_array.js +29 -24
  10. package/core/math/max2.js +2 -6
  11. package/core/math/min2.js +2 -6
  12. package/engine/asset/loaders/geometry/geometry/computeGeometryEquality.js +3 -2
  13. package/engine/asset/loaders/geometry/geometry/computeGeometryHash.js +9 -1
  14. package/engine/ecs/EntityComponentDataset.js +7 -2
  15. package/engine/ecs/foliage/ViewState.js +13 -3
  16. package/engine/ecs/foliage/ecs/Foliage2System.js +15 -3
  17. package/engine/ecs/parent/EntityNode.js +23 -11
  18. package/engine/ecs/transform/Transform.js +15 -13
  19. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +63 -26
  20. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +63 -3
  21. package/engine/graphics/ecs/mesh-v2/render/AbstractRenderAdapter.js +67 -0
  22. package/engine/graphics/ecs/mesh-v2/render/GenericRendererAdapter.js +48 -0
  23. package/engine/graphics/ecs/mesh-v2/render/InstancedRendererAdapter.js +110 -0
  24. package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +98 -0
  25. package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +5 -0
  26. package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +23 -5
  27. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +8 -3
  28. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +23 -85
  29. package/engine/graphics/geometry/instancing/rewriteMaterial.js +9 -45
  30. package/engine/graphics/material/optimization/BUFFER_GEOMETRY_UVS.js +10 -0
  31. package/engine/graphics/material/optimization/MaterialDescriptor.js +46 -0
  32. package/engine/graphics/material/optimization/MaterialOptimizationContext.js +470 -201
  33. package/engine/graphics/material/optimization/UvContext.js +18 -0
  34. package/engine/graphics/material/optimization/is_compliant_mesh.js +71 -0
  35. package/engine/graphics/material/optimization/prepare_atlas_texture.js +23 -0
  36. package/engine/graphics/material/optimization/prototypeMaterialOptimizer.js +127 -0
  37. package/engine/graphics/micron/convert_three_object_to_micron.js +0 -2
  38. package/engine/graphics/micron/format/MicronGeometry.js +1 -3
  39. package/engine/graphics/micron/format/MicronGeometryPatch.js +34 -24
  40. package/engine/graphics/micron/format/VirtualGeometry.js +47 -11
  41. package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +22 -0
  42. package/engine/graphics/micron/prototypeVirtualGeometry.js +10 -5
  43. package/engine/graphics/micron/render/VirtualGeometryBuilder.js +14 -55
  44. package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +1 -45
  45. package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +18 -7
  46. package/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -12
  47. package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +118 -0
  48. package/engine/graphics/micron/render/v1/MaterialContext.js +3 -2
  49. package/engine/graphics/micron/render/v1/VGThreeRenderer.js +19 -4
  50. package/engine/graphics/render/utils/ThreeBypassRenderer.js +3 -2
  51. package/engine/graphics/texture/normalized_internal_format.js +48 -0
  52. package/engine/graphics/texture/sampler/Sampler2D.js +6 -0
  53. package/engine/graphics/texture/sampler/sampler2d_copy_channel_data.js +25 -0
  54. package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -0
  55. package/engine/graphics/texture/sampler/util/drawSamplerHTML.js +14 -1
  56. package/package.json +1 -1
@@ -6,6 +6,7 @@ import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
6
6
  import { three_object_to_entity_composition } from "../three_object_to_entity_composition.js";
7
7
  import { AttachmentSystem } from "../../../../ecs/attachment/AttachmentSystem.js";
8
8
  import { TransformAttachmentSystem } from "../../../../ecs/transform-attachment/TransformAttachmentSystem.js";
9
+ import { Camera } from "../../camera/Camera.js";
9
10
 
10
11
  const eh = new EngineHarness();
11
12
 
@@ -70,6 +71,10 @@ async function main(engine) {
70
71
  enableTerrain: false
71
72
  });
72
73
 
74
+ const camera = engine.entityManager.dataset.getAnyComponent(Camera);
75
+ camera.component.autoClip = false;
76
+ camera.component.object.far = 300;
77
+
73
78
  // a small delay to let background tasks finish, so we can get better performance reading later on
74
79
  timeout(20);
75
80
 
@@ -3,7 +3,7 @@ import { ShadedGeometrySystem } from "../ShadedGeometrySystem.js";
3
3
  import EntityBuilder from "../../../../ecs/EntityBuilder.js";
4
4
  import { Transform } from "../../../../ecs/transform/Transform.js";
5
5
  import { ShadedGeometry } from "../ShadedGeometry.js";
6
- import { BoxBufferGeometry, MeshBasicMaterial } from "three";
6
+ import { BoxBufferGeometry, MeshStandardMaterial } from "three";
7
7
  import { randomFloatBetween } from "../../../../../core/math/random/randomFloatBetween.js";
8
8
  import { seededRandom } from "../../../../../core/math/random/seededRandom.js";
9
9
  import ViewportPosition from "../../../../ecs/gui/position/ViewportPosition.js";
@@ -13,9 +13,15 @@ import { downloadAsFile } from "../../../../../core/binary/ByteArrayTools.js";
13
13
  import { convert_bvh_to_dot_format_string } from "../../../../../core/bvh2/visual/convert_bvh_to_dot_format_string.js";
14
14
  import ViewportPositionSystem from "../../../../ecs/gui/position/ViewportPositionSystem.js";
15
15
  import GUIElementSystem from "../../../../ecs/gui/GUIElementSystem.js";
16
+ import Vector3 from "../../../../../core/geom/Vector3.js";
17
+ import Quaternion from "../../../../../core/geom/Quaternion.js";
18
+ import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
16
19
 
17
20
  const eh = new EngineHarness();
18
21
 
22
+ const DRAW_METHOD_PLAIN = 0;
23
+ const DRAW_METHOD_INSTANCED = 1;
24
+
19
25
  /**
20
26
  *
21
27
  * @param {Engine} engine
@@ -26,12 +32,18 @@ async function main(engine) {
26
32
 
27
33
  await em.addSystem(new ShadedGeometrySystem(engine));
28
34
 
29
- EngineHarness.buildBasics({ engine })
35
+ EngineHarness.buildBasics({
36
+ engine,
37
+ yaw: -0.8,
38
+ pitch: 1,
39
+ distance: 46,
40
+ focus: new Vector3(10, 0, 10)
41
+ });
30
42
 
31
43
 
32
44
  const ecd = em.dataset;
33
45
 
34
- const material = new MeshBasicMaterial({
46
+ const material = new MeshStandardMaterial({
35
47
  color: 0xFFFFFF
36
48
  });
37
49
 
@@ -45,6 +57,11 @@ async function main(engine) {
45
57
 
46
58
  for (let i = 0; i < 100000; i++) {
47
59
 
60
+ const sg = ShadedGeometry.from(geometry, material);
61
+
62
+ sg.draw_method = DRAW_METHOD_INSTANCED;
63
+ sg.clearFlag(ShadedGeometryFlags.CastShadow | ShadedGeometryFlags.ReceiveShadow);
64
+
48
65
  new EntityBuilder()
49
66
  .add(Transform.fromJSON({
50
67
  position: {
@@ -52,9 +69,10 @@ async function main(engine) {
52
69
  y: randomFloatBetween(random, 0, 10),
53
70
  z: randomFloatBetween(random, -50, 50)
54
71
  },
55
- scale: 0.01
72
+ rotation: Quaternion.random(random),
73
+ scale: 0.05
56
74
  }))
57
- .add(ShadedGeometry.from(geometry, material))
75
+ .add(sg)
58
76
  .build(ecd);
59
77
  }
60
78
 
@@ -12,24 +12,29 @@ export function three_object_to_entity_composition(root) {
12
12
 
13
13
  node.transform.fromMatrix4(root.matrix.elements);
14
14
 
15
- node.entity.add(new Transform());
15
+ const entity = node.entity;
16
+
17
+ entity.add(new Transform());
16
18
 
17
19
  if (root.isMesh) {
18
20
  if (root.isSkinnedMesh) {
19
21
  throw new Error(`Skinned meshes are not supported`);
20
22
  }
21
23
 
22
- node.entity.add(ShadedGeometry.from(root.geometry, root.material));
24
+ const sg = ShadedGeometry.from(root.geometry, root.material);
25
+ sg.draw_method = 1;
26
+
27
+ entity.add(sg);
23
28
  }
24
29
 
25
30
  const children = root.children;
26
31
  const child_count = children.length;
32
+
27
33
  for (let i = 0; i < child_count; i++) {
28
34
  const child = children[i];
29
35
 
30
36
  const child_node = three_object_to_entity_composition(child);
31
37
 
32
-
33
38
  node.addChild(child_node);
34
39
  }
35
40
 
@@ -3,7 +3,8 @@ import {
3
3
  InstancedBufferAttribute,
4
4
  InstancedBufferGeometry,
5
5
  MeshDepthMaterial,
6
- RGBADepthPacking
6
+ RGBADepthPacking,
7
+ StreamDrawUsage
7
8
  } from 'three';
8
9
  import ThreeFactory from "../../three/ThreeFactory.js";
9
10
  import { StaticMaterialCache } from "../../../asset/loaders/material/StaticMaterialCache.js";
@@ -66,21 +67,7 @@ export class InstancedMeshGroup {
66
67
  * @type {InstancedBufferAttribute}
67
68
  * @private
68
69
  */
69
- this.__attributePosition = null;
70
-
71
- /**
72
- *
73
- * @type {InstancedBufferAttribute}
74
- * @private
75
- */
76
- this.__attributeRotation = null;
77
-
78
- /**
79
- *
80
- * @type {InstancedBufferAttribute}
81
- * @private
82
- */
83
- this.__attributeScale = null;
70
+ this.__attributeTransform = null;
84
71
 
85
72
  /**
86
73
  *
@@ -203,39 +190,16 @@ export class InstancedMeshGroup {
203
190
  /**
204
191
  *
205
192
  * @param {number} index
206
- * @param {number} x
207
- * @param {number} y
208
- * @param {number} z
193
+ * @param {number[]|ArrayLike<number>|Float32Array} transform 4x4 transform matrix of the instance
209
194
  */
210
- setPositionAt(index, x, y, z) {
211
- this.__attributePosition.setXYZ(index, x, y, z);
212
- this.__attributePosition.needsUpdate = true;
195
+ setTransformAt(index, transform) {
196
+ this.__attributeTransform.array.set(transform, index * 16);
213
197
  }
214
198
 
215
- /**
216
- *
217
- * @param {number} index
218
- * @param {number} x
219
- * @param {number} y
220
- * @param {number} z
221
- * @param {number} w
222
- */
223
- setRotationAt(index, x, y, z, w) {
224
- this.__attributeRotation.setXYZW(index, x, y, z, w);
225
- this.__attributeRotation.needsUpdate = true;
199
+ requestAttributeUpdate() {
200
+ this.__attributeTransform.needsUpdate = true;
226
201
  }
227
202
 
228
- /**
229
- *
230
- * @param {number} index
231
- * @param {number} x
232
- * @param {number} y
233
- * @param {number} z
234
- */
235
- setScaleAt(index, x, y, z) {
236
- this.__attributeScale.setXYZ(index, x, y, z);
237
- this.__attributeScale.needsUpdate = true;
238
- }
239
203
 
240
204
  /**
241
205
  * Swap position in attribute arrays of two elements
@@ -327,25 +291,13 @@ export class InstancedMeshGroup {
327
291
  delete references[index];
328
292
  } else {
329
293
  //not at the end, move the very last reference to this place, effectively shrinking the set
330
- const index3 = index * 3;
331
- const start3 = lastIndex * 3;
332
- const end3 = start3 + 3;
333
294
 
334
- const index4 = index * 4;
335
- const start4 = lastIndex * 4;
336
- const end4 = start4 + 4;
337
295
 
338
- const a_position = this.__attributePosition;
339
- const a_rotation = this.__attributeRotation;
340
- const a_scale = this.__attributeScale;
296
+ const a_transform = this.__attributeTransform;
341
297
 
342
- a_position.array.copyWithin(index3, start3, end3);
343
- a_rotation.array.copyWithin(index4, start4, end4);
344
- a_scale.array.copyWithin(index3, start3, end3);
298
+ a_transform.array.copyWithin(index * 16, lastIndex * 16, lastIndex * 16 + 16);
299
+ a_transform.needsUpdate = true;
345
300
 
346
- a_position.needsUpdate = true;
347
- a_rotation.needsUpdate = true;
348
- a_scale.needsUpdate = true;
349
301
 
350
302
  //update moved reference index
351
303
  const movedReference = references[lastIndex];
@@ -391,39 +343,25 @@ export class InstancedMeshGroup {
391
343
  }
392
344
 
393
345
  //build instanced attributes
394
- const newPositionArray = new Float32Array(this.capacity * 3);
395
- const newRotationArray = new Float32Array(this.capacity * 4);
396
- const newScaleArray = new Float32Array(this.capacity * 3);
397
-
398
- if (this.__attributePosition !== null) {
399
- //copy old data
400
- const oldPositionArray = this.__attributePosition.array;
401
- typed_array_copy(oldPositionArray, newPositionArray);
402
- }
403
- if (this.__attributeRotation !== null) {
404
- //copy old data
405
- const oldRotationArray = this.__attributeRotation.array;
406
- typed_array_copy(oldRotationArray, newRotationArray);
407
- }
408
- if (this.__attributeScale !== null) {
409
- const oldScaleArray = this.__attributeScale.array;
410
- typed_array_copy(oldScaleArray, newScaleArray);
346
+ const newTransformArray = new Float32Array(this.capacity * 16);
347
+
348
+ if (this.__attributeTransform !== null) {
349
+ const oldTransformArray = this.__attributeTransform.array;
350
+ typed_array_copy(oldTransformArray, newTransformArray);
411
351
 
412
- if (newScaleArray.length > oldScaleArray.length) {
413
- //fill the rest of the array with scale factor of 1 as a default
414
- newScaleArray.fill(1, oldScaleArray.length);
352
+ if (newTransformArray.length > oldTransformArray.length) {
353
+ //fill the rest of the array with 0s
354
+ // TODO consider writing identity matrix instead
355
+ newTransformArray.fill(0, oldTransformArray.length);
415
356
  }
416
357
  }
417
358
 
418
359
  //rewrite old attributes
419
- this.__attributePosition = new InstancedBufferAttribute(newPositionArray, 3);
420
- this.__attributeRotation = new InstancedBufferAttribute(newRotationArray, 4);
421
- this.__attributeScale = new InstancedBufferAttribute(newScaleArray, 3);
360
+ this.__attributeTransform = new InstancedBufferAttribute(newTransformArray, 16);
361
+ this.__attributeTransform.setUsage(StreamDrawUsage);
422
362
 
423
363
  //add attributes to newly created geometry
424
- geometry.setAttribute("instancePosition", this.__attributePosition);
425
- geometry.setAttribute("instanceRotation", this.__attributeRotation);
426
- geometry.setAttribute("instanceScale", this.__attributeScale);
364
+ geometry.setAttribute("instanceMatrix", this.__attributeTransform);
427
365
 
428
366
 
429
367
  this.mesh.geometry = geometry;
@@ -1,55 +1,19 @@
1
1
  const SHADER_PREAMBLE = `
2
- attribute vec3 instancePosition;
3
- attribute vec4 instanceRotation;
4
- attribute vec3 instanceScale;
5
-
6
- vec3 instanceTransform( in vec3 position, vec3 T, vec4 R, vec3 S ){
7
- vec3 result = position;
8
-
9
- //applies the scale
10
- result *= S;
11
- //computes the rotation where R is a (vec4) quaternion
12
- result += 2.0 * cross( R.xyz, cross( R.xyz, result ) + R.w * result );
13
- //translates the transformed 'blueprint'
14
- result += T;
15
-
16
- return result;
17
- }
18
-
19
- mat4 getInstanceMatrix(){
20
- vec4 q = instanceRotation;
21
- vec3 s = instanceScale;
22
- vec3 v = instancePosition;
23
-
24
- vec3 q2 = q.xyz + q.xyz;
25
- vec3 a = q.xxx * q2.xyz;
26
- vec3 b = q.yyz * q2.yzz;
27
- vec3 c = q.www * q2.xyz;
28
-
29
- vec3 r0 = vec3( 1.0 - (b.x + b.z) , a.y + c.z , a.z - c.y ) * s.xxx;
30
- vec3 r1 = vec3( a.y - c.z , 1.0 - (a.x + b.z) , b.y + c.x ) * s.yyy;
31
- vec3 r2 = vec3( a.z + c.y , b.y - c.x , 1.0 - (a.x + b.x) ) * s.zzz;
32
-
33
- return mat4(
34
- r0 , 0.0,
35
- r1 , 0.0,
36
- r2 , 0.0,
37
- v , 1.0
38
- );
39
- }\n`;
2
+ attribute mat4 instanceMatrix;
3
+ \n`;
40
4
 
41
5
  export function rewriteMaterial(shader) {
42
6
  const originalVertexShader = shader.vertexShader;
43
7
 
44
8
  const newVertexShader = SHADER_PREAMBLE
45
9
  + originalVertexShader
46
- .replace(
47
- '#include <uv_vertex>',
48
- `
49
- mat4 instanceMatrix = getInstanceMatrix();
50
- #include <uv_vertex>
51
- `
52
- )
10
+ // .replace(
11
+ // '#include <uv_vertex>',
12
+ // `
13
+ // mat4 instanceMatrix = getInstanceMatrix();
14
+ // #include <uv_vertex>
15
+ // `
16
+ // )
53
17
  .replace(
54
18
  '#include <begin_vertex>',
55
19
  `
@@ -0,0 +1,10 @@
1
+ export const BUFFER_GEOMETRY_UVS = [
2
+ {
3
+ name: 'uv',
4
+ index: 0,
5
+ },
6
+ {
7
+ name: 'uv2',
8
+ index: 1
9
+ }
10
+ ];
@@ -0,0 +1,46 @@
1
+ import { traverseMaterialTextures } from "../../../asset/loaders/material/traverseMaterialTextures.js";
2
+ import { UvContext } from "./UvContext.js";
3
+ import { max2 } from "../../../../core/math/max2.js";
4
+
5
+ export class MaterialDescriptor {
6
+ constructor() {
7
+
8
+ /**
9
+ *
10
+ * @type {THREE.Material|null}
11
+ */
12
+ this.source_material = null;
13
+
14
+ /**
15
+ *
16
+ * @type {UvContext[]}
17
+ */
18
+ this.uvs = [];
19
+ }
20
+
21
+ build_uvs() {
22
+
23
+ traverseMaterialTextures(this.source_material, (t, attachment) => {
24
+ const uv_index = attachment.uv_index;
25
+
26
+ let uv_context = this.uvs[uv_index];
27
+
28
+ if (uv_context === undefined) {
29
+ uv_context = new UvContext();
30
+ uv_context.resolution.set(1, 1);
31
+
32
+ this.uvs[uv_index] = uv_context;
33
+ }
34
+
35
+ const image = t.image;
36
+
37
+ if (image !== undefined && image.width !== undefined) {
38
+ uv_context.resolution.x = max2(uv_context.resolution.x, image.width);
39
+ uv_context.resolution.y = max2(uv_context.resolution.y, image.height);
40
+ }
41
+
42
+ });
43
+
44
+ }
45
+
46
+ }