@woosh/meep-engine 2.47.2 → 2.47.8

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 (126) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -0
  2. package/build/bundle-worker-terrain.js +1 -0
  3. package/build/meep.cjs +659 -553
  4. package/build/meep.min.js +1 -1
  5. package/build/meep.module.js +659 -553
  6. package/package.json +2 -2
  7. package/src/core/binary/BitSet.spec.js +3 -3
  8. package/src/core/bvh2/BinaryNode.js +12 -10
  9. package/src/core/bvh2/aabb3/AABB3.js +30 -31
  10. package/src/core/bvh2/binary/2/BinaryUint32BVH.js +1 -1
  11. package/src/core/bvh2/binary/BinaryBVH.js +1 -1
  12. package/src/core/bvh2/binary/RayLeafIntersectionVisitor.js +1 -1
  13. package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +1 -1
  14. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +2 -2
  15. package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +1 -1
  16. package/src/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +1 -1
  17. package/src/core/bvh2/bvh3/query/bvh_collect_user_data.js +10 -8
  18. package/src/core/bvh2/bvh3/query/bvh_query_leaves_generic.js +14 -22
  19. package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +13 -15
  20. package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +14 -21
  21. package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.js +16 -24
  22. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_frustum.js +23 -26
  23. package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +10 -11
  24. package/src/core/bvh2/transform/BottomUpOptimizingRebuilder.js +2 -2
  25. package/src/core/bvh2/transform/tryRotateSingleNode.js +2 -2
  26. package/src/core/bvh2/traversal/aabb3_detailed_volume_intersection_callback_based.js +1 -1
  27. package/src/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +1 -1
  28. package/src/core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js +13 -0
  29. package/src/core/color/Color.d.ts +2 -1
  30. package/src/core/color/Color.js +30 -5
  31. package/src/core/color/ColorUtils.js +7 -5
  32. package/src/core/color/parseHex.js +11 -3
  33. package/src/core/color/rgb2hex.js +1 -1
  34. package/src/core/geom/3d/SurfacePoint3.d.ts +7 -0
  35. package/src/core/geom/3d/SurfacePoint3.js +56 -1
  36. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_combine.js +2 -2
  37. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_contains_point.js +1 -1
  38. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_frustum_degree.js +2 -2
  39. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_combined_surface_area.js +2 -2
  40. package/src/core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js +1 -1
  41. package/src/core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.spec.js +8 -0
  42. package/src/core/geom/3d/aabb/{computeAABB3PlaneSide.js → aabb3_compute_plane_side.js} +1 -1
  43. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_detailed_volume_intersection.js +7 -7
  44. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_from_v3_array.js +4 -4
  45. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_from_v3_array_transformed.js +2 -2
  46. package/src/core/{bvh2/aabb3/aabb3_intersect_aabb3.js → geom/3d/aabb/aabb3_intersects_aabb3.js} +2 -2
  47. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_frustum_array.js +2 -2
  48. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_frustum_degree.js +4 -4
  49. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_line_segment.js +1 -1
  50. package/src/core/geom/3d/aabb/aabb3_intersects_ray.js +87 -0
  51. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray.spec.js +1 -1
  52. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray_branchless.js +2 -2
  53. package/src/core/{bvh2/aabb3/aabb3_intersect_ray_slab.js → geom/3d/aabb/aabb3_intersects_ray_slab.js} +35 -17
  54. package/src/core/geom/3d/aabb/aabb3_matrix4_project_by_corners.js +5 -1
  55. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_nearest_point_on_surface.js +2 -2
  56. package/src/core/geom/3d/aabb/aabb3_raycast.js +103 -0
  57. package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_signed_distance_sqr_to_point.js +1 -1
  58. package/src/core/geom/3d/aabb/computeBoundingBoxFromVertexData.js +4 -12
  59. package/src/core/geom/3d/aabb/compute_aabb_from_points.js +8 -1
  60. package/src/core/geom/3d/shape/UnitCubeShape3D.js +1 -1
  61. package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +4 -7
  62. package/src/core/model/node-graph/DataType.d.ts +4 -0
  63. package/src/core/model/node-graph/node/NodeDescription.d.ts +11 -1
  64. package/src/core/model/node-graph/node/NodeInstance.js +8 -1
  65. package/src/core/model/node-graph/node/NodeRegistry.spec.js +47 -1
  66. package/src/core/model/node-graph/node/Port.d.ts +3 -0
  67. package/src/core/model/node-graph/node/Port.js +7 -3
  68. package/src/core/model/node-graph/node/Port.spec.js +44 -0
  69. package/src/core/model/node-graph/node/PortDirection.d.ts +5 -0
  70. package/src/engine/asset/loaders/GLTFAssetLoader.js +1 -1
  71. package/src/engine/ecs/foliage/InstancedFoliage.js +1 -1
  72. package/src/engine/ecs/storage/BinaryBufferSerializer.js +13 -1
  73. package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +11 -4
  74. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +54 -0
  75. package/src/engine/ecs/systems/RenderSystem.js +1 -33
  76. package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +2 -4
  77. package/src/engine/ecs/terrain/tiles/TileBuildWorker.js +6 -1
  78. package/src/engine/graphics/GraphicsEngine.js +5 -1
  79. package/src/engine/graphics/ecs/decal/v2/Decal.js +44 -2
  80. package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +31 -0
  81. package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +16 -5
  82. package/src/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +88 -56
  83. package/src/engine/graphics/geometry/buffered/query/ClippingPlaneContainmentComputingVisitor.js +2 -2
  84. package/src/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +1 -1
  85. package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +3 -2
  86. package/src/engine/graphics/geometry/skining/computeSkinnedMeshBoundingVolumes.js +3 -2
  87. package/src/engine/graphics/micron/format/MicronGeometry.js +1 -1
  88. package/src/engine/graphics/micron/format/validate_patch_bounds.js +1 -1
  89. package/src/engine/graphics/micron/render/refinement/ActivePatchList.js +1 -1
  90. package/src/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +16 -16
  91. package/src/engine/graphics/render/forward_plus/LightManager.js +3 -0
  92. package/src/engine/graphics/render/forward_plus/LightManager.spec.js +5 -5
  93. package/src/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_APPLY_DECALS.js +4 -0
  94. package/src/engine/graphics/render/forward_plus/model/Decal.js +10 -2
  95. package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_objects.js +2 -2
  96. package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +18 -16
  97. package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +2 -0
  98. package/src/engine/graphics/render/visibility/IncrementalDeltaSet.js +26 -13
  99. package/src/engine/graphics/sh3/path_tracer/GeometryBVHBatched.js +8 -2
  100. package/src/engine/graphics/sh3/path_tracer/PathTracer.js +3 -3
  101. package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +18 -15
  102. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_max.js +1 -1
  103. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min.js +1 -1
  104. package/src/engine/graphics/three/three_computeObjectBoundingBox.js +56 -0
  105. package/src/engine/input/devices/{InputDeviceButton.d.ts → InputDeviceSwitch.d.ts} +1 -1
  106. package/src/engine/input/devices/{InputDeviceButton.js → InputDeviceSwitch.js} +1 -1
  107. package/src/engine/input/devices/KeyboardDevice.d.ts +2 -2
  108. package/src/engine/input/devices/KeyboardDevice.js +58 -40
  109. package/src/engine/input/devices/PointerDevice.js +224 -179
  110. package/src/core/bvh2/aabb3/aabb3_intersects_ray.js +0 -97
  111. package/src/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane_max.spec.js +0 -8
  112. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_frustum_array.js +0 -0
  113. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_ray.js +0 -0
  114. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_array_intersects_ray_array.js +0 -0
  115. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_box_surface_area_2.js +0 -0
  116. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_compute_half_surface_area.js +0 -0
  117. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_compute_surface_area.js +0 -0
  118. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_corner_edge_mapping.js +0 -0
  119. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_corner_edge_mapping.spec.js +0 -0
  120. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_corner_mapping.js +0 -0
  121. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_corner_mapping.spec.js +0 -0
  122. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_edge_plane_mapping.js +0 -0
  123. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_expand_array.js +0 -0
  124. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_intersects_ray_fast.js +0 -0
  125. /package/src/core/{bvh2/aabb3 → geom/3d/aabb}/aabb3_score_boxes_SAH.js +0 -0
  126. /package/src/core/{bvh2/aabb3/aabb_score_boxes_SAH_delta.js → geom/3d/aabb/aabb3_score_boxes_SAH_delta.js} +0 -0
@@ -3,7 +3,7 @@ import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
3
3
  import Vector4 from "../../../../core/geom/Vector4.js";
4
4
  import { computeBoundingSphereFromVertexData } from "../computeBoundingSphereFromVertexData.js";
5
5
  import { Box3, Sphere as ThreeSphere, Vector3 as ThreeVector3 } from "three";
6
- import { computeBoundingBoxFromVertexData } from "../../../../core/geom/3d/aabb/computeBoundingBoxFromVertexData.js";
6
+ import { aabb3_from_v3_array } from "../../../../core/geom/3d/aabb/aabb3_from_v3_array.js";
7
7
 
8
8
  /**
9
9
  *
@@ -21,7 +21,8 @@ export function computeSkinnedMeshBoundingVolumes(mesh) {
21
21
  const aabb3 = new AABB3(0, 0, 0, 0, 0, 0);
22
22
  const sphere = new Vector4();
23
23
 
24
- computeBoundingBoxFromVertexData(vertices, aabb3);
24
+
25
+ aabb3_from_v3_array(aabb3, vertices, vertices.length);
25
26
  computeBoundingSphereFromVertexData(vertices, sphere);
26
27
 
27
28
  const min = new ThreeVector3(aabb3.x0, aabb3.y0, aabb3.z0);
@@ -2,7 +2,7 @@ import { VertexDataSpec } from "../../geometry/VertexDataSpec.js";
2
2
  import { assert } from "../../../../core/assert.js";
3
3
  import { computeTriangleRayIntersection } from "../../../../core/geom/3d/triangle/computeTriangleRayIntersection.js";
4
4
  import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
5
- import { aabb3_array_intersects_ray } from "../../../../core/bvh2/aabb3/aabb3_array_intersects_ray.js";
5
+ import { aabb3_array_intersects_ray } from "../../../../core/geom/3d/aabb/aabb3_array_intersects_ray.js";
6
6
  import { sphere_array_intersects_ray } from "../../../../core/geom/3d/sphere/sphere_array_intersects_ray.js";
7
7
  import { BitSet } from "../../../../core/binary/BitSet.js";
8
8
  import { micron_build_proxy_geometry } from "./micron_build_proxy_geometry.js";
@@ -1,5 +1,5 @@
1
1
  import { noop } from "../../../../core/function/Functions.js";
2
- import { aabb3_array_contains_point } from "../../../../core/bvh2/aabb3/aabb3_array_contains_point.js";
2
+ import { aabb3_array_contains_point } from "../../../../core/geom/3d/aabb/aabb3_array_contains_point.js";
3
3
  import { sphere_array_intersects_point } from "../../../../core/geom/3d/sphere/sphere_array_intersects_point.js";
4
4
 
5
5
  /**
@@ -4,7 +4,7 @@ import { aabb3_project_to_2d } from "../../../../../core/geom/3d/aabb/aabb3_comp
4
4
  import { BitSet } from "../../../../../core/binary/BitSet.js";
5
5
  import {
6
6
  aabb3_array_intersects_frustum_array
7
- } from "../../../../../core/bvh2/aabb3/aabb3_array_intersects_frustum_array.js";
7
+ } from "../../../../../core/geom/3d/aabb/aabb3_array_intersects_frustum_array.js";
8
8
 
9
9
  export class ActivePatchList {
10
10
  constructor() {
@@ -1,8 +1,9 @@
1
1
  import { BitSet } from "../../../../../core/binary/BitSet.js";
2
2
  import {
3
3
  aabb3_array_intersects_frustum_array
4
- } from "../../../../../core/bvh2/aabb3/aabb3_array_intersects_frustum_array.js";
4
+ } from "../../../../../core/geom/3d/aabb/aabb3_array_intersects_frustum_array.js";
5
5
  import { aabb3_estimate_projected_area2 } from "../../../../../core/geom/3d/aabb/aabb3_estimate_projected_area2.js";
6
+ import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../../../core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
6
7
 
7
8
 
8
9
  /**
@@ -12,12 +13,7 @@ import { aabb3_estimate_projected_area2 } from "../../../../../core/geom/3d/aabb
12
13
  const scratch_traversal_bitset = new BitSet();
13
14
  scratch_traversal_bitset.preventShrink();
14
15
 
15
- /**
16
- * Using a pre-allocated continuous chunk of memory gets us better cache coherence
17
- * @readonly
18
- * @type {number[]}
19
- */
20
- const scratch_traversal_stack = new Uint32Array(781250);
16
+ const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
21
17
 
22
18
  /**
23
19
  *
@@ -41,16 +37,20 @@ export function get_geometry_patch_cut(
41
37
 
42
38
  const geometry_id = geometry.id;
43
39
 
44
- const destination_patch_address = destination.patch_count;
45
- let output_patch_cursor = destination_patch_address;
40
+ let output_patch_cursor = destination.patch_count;
46
41
 
47
42
  let i;
48
- let stack_cursor = 1;
49
43
 
50
44
  // initialize stack
51
- const stack = scratch_traversal_stack;
52
45
  const root = geometry.root;
53
- stack[0] = root.id;
46
+
47
+ /**
48
+ *
49
+ * @type {number}
50
+ */
51
+ const stack_top = stack.pointer++;
52
+
53
+ stack[stack_top] = root.id;
54
54
 
55
55
  const included_set = scratch_traversal_bitset;
56
56
  included_set.reset();
@@ -60,10 +60,10 @@ export function get_geometry_patch_cut(
60
60
  const patches = geometry.patches;
61
61
  const destination_patches = destination.patches;
62
62
 
63
- while (stack_cursor > 0) {
64
- stack_cursor--;
63
+ while (stack.pointer > stack_top) {
64
+ stack.pointer--;
65
65
 
66
- const patch_id = stack[stack_cursor];
66
+ const patch_id = stack[stack.pointer];
67
67
  const patch = patches[patch_id];
68
68
 
69
69
  /*
@@ -101,7 +101,7 @@ export function get_geometry_patch_cut(
101
101
  continue;
102
102
  }
103
103
 
104
- stack[stack_cursor++] = child_id;
104
+ stack[stack.pointer++] = child_id;
105
105
  }
106
106
 
107
107
  continue;
@@ -1133,14 +1133,17 @@ export class LightManager {
1133
1133
  assert.isNumber(x, 'x');
1134
1134
  assert.isNonNegativeInteger(x, 'x');
1135
1135
  assert.isFiniteNumber(x, 'x');
1136
+ assert.greaterThan(x,0,'x must be > 0');
1136
1137
 
1137
1138
  assert.isNumber(y, 'y');
1138
1139
  assert.isNonNegativeInteger(y, 'y');
1139
1140
  assert.isFiniteNumber(y, 'y');
1141
+ assert.greaterThan(y,0,'y must be > 0');
1140
1142
 
1141
1143
  assert.isNumber(z, 'z');
1142
1144
  assert.isNonNegativeInteger(z, 'z');
1143
1145
  assert.isFiniteNumber(z, 'z');
1146
+ assert.greaterThan(z,0,'z must be > 0');
1144
1147
 
1145
1148
  const r = this.__tiles_resolution;
1146
1149
 
@@ -20,7 +20,7 @@ test('correct cluster content (empty)', () => {
20
20
 
21
21
  const tex = lm.getTextureClusters();
22
22
 
23
- expect(Array.from(tex.image.data)).toEqual([0, 0, 0]);
23
+ expect(Array.from(tex.image.data)).toEqual([0, 0, 0, 0]);
24
24
  });
25
25
 
26
26
  test('correct cluster content (single small light)', () => {
@@ -35,7 +35,7 @@ test('correct cluster content (single small light)', () => {
35
35
 
36
36
  const camera = new PerspectiveCamera(45, 1, 1, 10);
37
37
  camera.lookAt(0, 0, 5);
38
-
38
+
39
39
  camera.updateProjectionMatrix();
40
40
  camera.updateMatrix();
41
41
  camera.updateMatrixWorld(true);
@@ -46,7 +46,7 @@ test('correct cluster content (single small light)', () => {
46
46
 
47
47
  const tex = lm.getTextureClusters();
48
48
 
49
- expect(Array.from(tex.image.data)).toEqual([0, 1, 0]);
49
+ expect(Array.from(tex.image.data)).toEqual([0, 1, 0, 0]);
50
50
  });
51
51
 
52
52
  test('correct cluster content (single huge light)', () => {
@@ -68,7 +68,7 @@ test('correct cluster content (single huge light)', () => {
68
68
 
69
69
  const tex = lm.getTextureClusters();
70
70
 
71
- expect(Array.from(tex.image.data)).toEqual([0, 1, 0]);
71
+ expect(Array.from(tex.image.data)).toEqual([0, 1, 0, 0]);
72
72
  });
73
73
 
74
74
  test('correct cluster content (single huge light overlapping)', () => {
@@ -90,5 +90,5 @@ test('correct cluster content (single huge light overlapping)', () => {
90
90
 
91
91
  const tex = lm.getTextureClusters();
92
92
 
93
- expect(Array.from(tex.image.data)).toEqual([0, 1, 0]);
93
+ expect(Array.from(tex.image.data)).toEqual([0, 1, 0, 0]);
94
94
  });
@@ -54,6 +54,10 @@ export const FP_SHADER_CHUNK_APPLY_DECALS = `
54
54
 
55
55
  vec4 decal_color = texture2D(fp_t_decal_atlas,decal_uv, -0.2);
56
56
 
57
+ vec4 decal_color_tint = texelFetch(fp_t_light_data, address_to_data_texture_coordinates(light_address+5u), 0);
58
+
59
+ decal_color*= decal_color_tint;
60
+
57
61
  // compute decal alpha
58
62
  float decal_alpha = decal_color.a * decal_surface_angle_fade;
59
63
 
@@ -19,6 +19,11 @@ export class Decal extends AbstractLight {
19
19
  this.transform_inverse = new Float32Array(16);
20
20
  this.uv = new Float32Array(4);
21
21
 
22
+ this.color = new Float32Array(4);
23
+ // initialize color to full white
24
+ this.color.fill(1);
25
+
26
+
22
27
  /**
23
28
  *
24
29
  * @type {Sampler2D}
@@ -98,8 +103,11 @@ export class Decal extends AbstractLight {
98
103
  array_copy(this.uv, 0, destination, address + 16, 4);
99
104
 
100
105
  // required for sorting
101
- destination[address + 20] = this.draw_priority;
102
- destination[address + 21] = this.id;
106
+ // destination[address + 20] = this.draw_priority;
107
+ // destination[address + 21] = this.id;
108
+
109
+ // color
110
+ array_copy(this.color, 0, destination, address + 20, 4);
103
111
 
104
112
  return 24;
105
113
  }
@@ -1,5 +1,5 @@
1
1
  import {
2
- aabb3_computeDistanceAbovePlane_max
2
+ aabb3_compute_distance_above_plane_max
3
3
  } from "../../../../../core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js";
4
4
  import { point_light_inside_volume } from "./point_light_inside_volume.js";
5
5
  import { spot_light_inside_volume } from "./spot_light_inside_volume.js";
@@ -52,7 +52,7 @@ export function query_bvh_frustum_from_objects(
52
52
  const plane_normal_z = planes[plane_address + 2];
53
53
  const plane_constant = planes[plane_address + 3];
54
54
 
55
- const distanceAbovePlane = aabb3_computeDistanceAbovePlane_max(
55
+ const distanceAbovePlane = aabb3_compute_distance_above_plane_max(
56
56
  plane_normal_x, plane_normal_y, plane_normal_z, plane_constant,
57
57
  n.x0, n.y0, n.z0,
58
58
  n.x1, n.y1, n.z1
@@ -1,14 +1,11 @@
1
1
  import {
2
- aabb3_computeDistanceAbovePlane_max
2
+ aabb3_compute_distance_above_plane_max
3
3
  } from "../../../../../core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js";
4
4
  import { point_light_inside_volume } from "./point_light_inside_volume.js";
5
5
  import { BVH_BINARY_NODE_SIZE, BVH_LEAF_NODE_SIZE } from "../../../../../core/bvh2/binary/2/BinaryUint32BVH.js";
6
+ import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../../../core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
6
7
 
7
- /**
8
- *
9
- * @type {number[]}
10
- */
11
- const stack = [];
8
+ const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
12
9
 
13
10
  /**
14
11
  *
@@ -33,7 +30,7 @@ function frustum_check(data_view, address, planes) {
33
30
  const plane_normal_z = planes[plane_address + 2];
34
31
  const plane_constant = planes[plane_address + 3];
35
32
 
36
- const distanceAbovePlane = aabb3_computeDistanceAbovePlane_max(
33
+ const distanceAbovePlane = aabb3_compute_distance_above_plane_max(
37
34
  plane_normal_x, plane_normal_y, plane_normal_z, plane_constant,
38
35
  n_x0, n_y0, n_z0,
39
36
  n_x1, n_y1, n_z1
@@ -70,8 +67,6 @@ export function query_bvh_frustum_from_texture(
70
67
  source_data,
71
68
  planes, points
72
69
  ) {
73
-
74
- let stackPointer = 1;
75
70
  let result = 0;
76
71
 
77
72
  const binary_node_count = root.getBinaryNodeCount();
@@ -81,19 +76,26 @@ export function query_bvh_frustum_from_texture(
81
76
  return 0;
82
77
  }
83
78
 
79
+ /**
80
+ *
81
+ * @type {number}
82
+ */
83
+ const stack_top = stack.pointer++;
84
+
84
85
  /**
85
86
  * After performing empirical tests, stack-based depth-first traversal turns out faster than using a queue
86
87
  * @type {number}
87
88
  */
88
- stack[0] = 0;
89
+ stack[stack_top] = 0;
89
90
 
90
91
  const last_valid_index = binary_node_count + root.getLeafNodeCount();
91
92
  const data_view = root.getDataView();
92
93
 
93
- while (stackPointer-- > 0) {
94
+ do {
95
+ stack.pointer--;
94
96
 
95
97
  // query_bvh_frustum_from_objects.iteration_count++;
96
- const node_index = stack[stackPointer];
98
+ const node_index = stack[stack.pointer];
97
99
 
98
100
  if (node_index < binary_node_count) {
99
101
  // is intermediate node
@@ -108,11 +110,11 @@ export function query_bvh_frustum_from_texture(
108
110
 
109
111
  // left node ends up on top of the stack, which aligns with the desired access sequence
110
112
  if (right_index < last_valid_index) {
111
- stack[stackPointer++] = right_index;
113
+ stack[stack.pointer++] = right_index;
112
114
  // micro-optimization, since we know that right node is valid and left appears before that, left is valid too
113
- stack[stackPointer++] = left_index;
115
+ stack[stack.pointer++] = left_index;
114
116
  } else if (left_index < last_valid_index) {
115
- stack[stackPointer++] = left_index;
117
+ stack[stack.pointer++] = left_index;
116
118
  }
117
119
 
118
120
 
@@ -160,7 +162,7 @@ export function query_bvh_frustum_from_texture(
160
162
  result++;
161
163
  }
162
164
 
163
- }
165
+ }while (stack.pointer > stack_top)
164
166
 
165
167
  return result;
166
168
  }
@@ -35,6 +35,8 @@ function add_instance(group, matrix, color) {
35
35
  Math.round(color[2] * 255),
36
36
  Math.round(color[3] * 255)
37
37
  );
38
+
39
+ group.requestAttributeUpdate();
38
40
  }
39
41
 
40
42
  /**
@@ -229,18 +229,31 @@ export class IncrementalDeltaSet {
229
229
  finalizeUpdate() {
230
230
  assert.equal(this.state, IncrementalDeltaSetState.Building, `Expected BUILDING state, instead got '${this.state}'`);
231
231
 
232
- this.size = this.__elements_cursor;
232
+ const array_main_count = this.__elements_cursor;
233
+ const array_previous_count = this.__swap_elements_count;
234
+
235
+ this.size = array_main_count;
233
236
 
234
237
  // sort newly populated elements array
235
- array_shrink_to_size(this.__elements, this.size);
236
- this.__elements.sort(this.__compare);
238
+ const array_main = this.__elements;
239
+ const array_previous = this.__swap_elements;
240
+
241
+ const compare = this.__compare;
242
+
243
+ const onAdded = this.onAdded;
244
+ const onRemoved = this.onRemoved;
245
+
246
+ array_shrink_to_size(array_main, array_main_count);
247
+ array_main.sort(compare);
248
+
237
249
 
238
250
  let i0 = 0, i1 = 0;
239
- while (i0 < this.size && i1 < this.__swap_elements_count) {
240
- const el_0 = this.__elements[i0];
241
- const el_1 = this.__swap_elements[i1];
242
251
 
243
- const diff = this.__compare(el_0, el_1);
252
+ while (i0 < array_main_count && i1 < array_previous_count) {
253
+ const el_0 = array_main[i0];
254
+ const el_1 = array_previous[i1];
255
+
256
+ const diff = compare(el_0, el_1);
244
257
 
245
258
  if (diff === 0) {
246
259
  i0++;
@@ -249,20 +262,20 @@ export class IncrementalDeltaSet {
249
262
  } else if (diff < 0) {
250
263
  i0++;
251
264
  // addition
252
- this.onAdded.send1(el_0);
265
+ onAdded.send1(el_0);
253
266
  } else {
254
267
  i1++;
255
268
  // removal
256
- this.onRemoved.send1(el_1);
269
+ onRemoved.send1(el_1);
257
270
  }
258
271
  }
259
272
 
260
273
  // process remainders
261
- for (; i0 < this.size; i0++) {
262
- this.onAdded.send1(this.__elements[i0]);
274
+ for (; i0 < array_main_count; i0++) {
275
+ onAdded.send1(array_main[i0]);
263
276
  }
264
- for (; i1 < this.__swap_elements_count; i1++) {
265
- this.onRemoved.send1(this.__swap_elements[i1]);
277
+ for (; i1 < array_previous_count; i1++) {
278
+ onRemoved.send1(array_previous[i1]);
266
279
  }
267
280
 
268
281
  this.state = IncrementalDeltaSetState.Ready;
@@ -2,7 +2,9 @@ import {
2
2
  ExplicitBinaryBoundingVolumeHierarchy
3
3
  } from "../../../../core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js";
4
4
  import { bvh_query_leaves_ray } from "../../../../core/bvh2/bvh3/query/bvh_query_leaves_ray.js";
5
- import { aabb3_signed_distance_sqr_to_point } from "../../../../core/bvh2/aabb3/aabb3_signed_distance_sqr_to_point.js";
5
+ import {
6
+ aabb3_signed_distance_sqr_to_point
7
+ } from "../../../../core/geom/3d/aabb/aabb3_signed_distance_sqr_to_point.js";
6
8
  import {
7
9
  computeTriangleRayIntersectionBarycentric
8
10
  } from "../../../../core/geom/3d/triangle/computeTriangleRayIntersection.js";
@@ -197,7 +199,11 @@ export class GeometryBVHBatched {
197
199
 
198
200
  bvh.node_get_aabb(node_id, temp_aabb3);
199
201
 
200
- const distance = aabb3_signed_distance_sqr_to_point(temp_aabb3[0], temp_aabb3[1], temp_aabb3[2], temp_aabb3[3], temp_aabb3[4], temp_aabb3[5], ray[0], ray[1], ray[2]);
202
+ const distance = aabb3_signed_distance_sqr_to_point(
203
+ temp_aabb3[0], temp_aabb3[1], temp_aabb3[2],
204
+ temp_aabb3[3], temp_aabb3[4], temp_aabb3[5],
205
+ ray[0], ray[1], ray[2]
206
+ );
201
207
 
202
208
  if (distance > best_t * best_t) {
203
209
  // whole AABB is too far
@@ -92,8 +92,8 @@ export class PathTracer {
92
92
  this.geo_cache = new Map();
93
93
 
94
94
  /**
95
- *
96
- * @type {Map<THREE.Texture, Sampler2D>}
95
+ * Maps {@link Texture.id} to relevant sampler
96
+ * @type {Map<number, Sampler2D>}
97
97
  */
98
98
  this.textures = new Map();
99
99
 
@@ -171,7 +171,7 @@ export class PathTracer {
171
171
 
172
172
  /**
173
173
  *
174
- * @param {THREE.Light} light
174
+ * @param {AbstractLight} light
175
175
  */
176
176
  addLight(light) {
177
177
  this.__lights.push(light);
@@ -397,8 +397,8 @@ function* render(target, pt, camera, progress = { current: 0, total: 0 }) {
397
397
  camera.matrixWorldInverse.copy(camera.matrixWorld);
398
398
  camera.matrixWorldInverse.invert();
399
399
 
400
- const out = [];
401
- const out2 = [];
400
+ const pixel_color = [];
401
+ const pixel_accummulation = [];
402
402
  const ray = [];
403
403
 
404
404
  const ray_origin = new Vector3();
@@ -414,7 +414,7 @@ function* render(target, pt, camera, progress = { current: 0, total: 0 }) {
414
414
  const pixel_scale_x = 1 / (width - 1);
415
415
  const pixel_scale_y = 1 / (height - 1);
416
416
 
417
- const pixel_sample_count = 500;
417
+ const pixel_sample_count = 4;
418
418
 
419
419
  progress.total = width * height;
420
420
 
@@ -446,9 +446,13 @@ function* render(target, pt, camera, progress = { current: 0, total: 0 }) {
446
446
  const u = x * pixel_scale_x;
447
447
  const _x = u * 2 - 1;
448
448
 
449
- out2[0] = 0;
450
- out2[1] = 0;
451
- out2[2] = 0;
449
+ pixel_accummulation[0] = 0;
450
+ pixel_accummulation[1] = 0;
451
+ pixel_accummulation[2] = 0;
452
+
453
+ const pixel_address = ((max_y - y) * width + x) * 4;
454
+
455
+ target.data[pixel_address + 3] = 255;
452
456
 
453
457
  for (let i = 0; i < pixel_sample_count; i++) {
454
458
 
@@ -464,22 +468,20 @@ function* render(target, pt, camera, progress = { current: 0, total: 0 }) {
464
468
  ray_direction.x, ray_direction.y, ray_direction.z
465
469
  );
466
470
 
467
- pt.path_trace(out, ray, Infinity, 4, random);
471
+ pt.path_trace(pixel_color, ray, Infinity, 4, random);
468
472
 
469
- out2[0] += out[0];
470
- out2[1] += out[1];
471
- out2[2] += out[2];
473
+ pixel_accummulation[0] += pixel_color[0];
474
+ pixel_accummulation[1] += pixel_color[1];
475
+ pixel_accummulation[2] += pixel_color[2];
472
476
 
473
477
 
474
478
  sample_count++;
475
479
  }
476
480
 
477
- const pixel_address = ((max_y - y) * width + x) * 4;
481
+ target.data[pixel_address] = float2uint8(pixel_accummulation[0] / pixel_sample_count);
482
+ target.data[pixel_address + 1] = float2uint8(pixel_accummulation[1] / pixel_sample_count);
483
+ target.data[pixel_address + 2] = float2uint8(pixel_accummulation[2] / pixel_sample_count);
478
484
 
479
- target.data[pixel_address] = float2uint8(out2[0] / pixel_sample_count);
480
- target.data[pixel_address + 1] = float2uint8(out2[1] / pixel_sample_count);
481
- target.data[pixel_address + 2] = float2uint8(out2[2] / pixel_sample_count);
482
- target.data[pixel_address + 3] = 255;
483
485
 
484
486
  progress.current++;
485
487
 
@@ -515,6 +517,7 @@ async function start_renderer(camera) {
515
517
  camera.aspect = vCanvas.size.x / vCanvas.size.y;
516
518
 
517
519
  // const path = 'data/models/LowPolyTownshipSet/Small_house/Small_house.gltf';
520
+ const path = 'data/models/pica_pica/pica_pica.gltf';
518
521
  // const path = 'data/models/road_bike/road_bike.gltf'; //large CAD-type model
519
522
 
520
523
  // await prepare_scene_lucy(pt, camera);
@@ -35,7 +35,7 @@ export function sampler2d_channel_compute_max(sampler, channel=0){
35
35
 
36
36
  }
37
37
 
38
- const width = this.width;
38
+ const width = sampler.width;
39
39
 
40
40
  const itemIndex = (bestIndex / itemSize) | 0;
41
41
 
@@ -35,7 +35,7 @@ export function sampler2d_channel_compute_min(sampler, channel=0){
35
35
 
36
36
  }
37
37
 
38
- const width = this.width;
38
+ const width = sampler.width;
39
39
 
40
40
  const itemIndex = (bestIndex / itemSize) | 0;
41
41
 
@@ -0,0 +1,56 @@
1
+ import { Box3 } from "three";
2
+
3
+ /**
4
+ *
5
+ * @param {Object3D} object
6
+ * @param {AABB3} result
7
+ */
8
+ export function three_computeObjectBoundingBox(object, result) {
9
+ const _sX = object.scale.x;
10
+ const _sY = object.scale.y;
11
+ const _sZ = object.scale.z;
12
+
13
+ object.scale.set(1, 1, 1);
14
+
15
+ const box3 = new Box3();
16
+
17
+ box3.expandByObject(object);
18
+
19
+ object.scale.set(_sX, _sY, _sZ);
20
+
21
+ const min = box3.min;
22
+ const max = box3.max;
23
+
24
+ let x0 = min.x;
25
+ let y0 = min.y;
26
+ let z0 = min.z;
27
+ let x1 = max.x;
28
+ let y1 = max.y;
29
+ let z1 = max.z;
30
+
31
+ // validate and fix missing bounds
32
+ if (x1 < x0) {
33
+ // no bounds
34
+ x0 = 0;
35
+ x1 = 0;
36
+ }
37
+
38
+ if (y1 < y0) {
39
+ // no bounds
40
+ y0 = 0;
41
+ y1 = 0;
42
+ }
43
+
44
+ if (z1 < z0) {
45
+ // no bounds
46
+ z0 = 0;
47
+ z1 = 0;
48
+ }
49
+
50
+
51
+ result.setBounds(
52
+ x0, y0, z0,
53
+ x1, y1, z1
54
+ );
55
+
56
+ }
@@ -1,6 +1,6 @@
1
1
  import Signal from "../../../core/events/signal/Signal";
2
2
 
3
- export class InputDeviceButton{
3
+ export class InputDeviceSwitch {
4
4
  readonly up: Signal
5
5
  readonly down: Signal
6
6
  readonly is_down: boolean
@@ -3,7 +3,7 @@ import Signal from "../../../core/events/signal/Signal.js";
3
3
  /**
4
4
  * Representation of an input device key
5
5
  */
6
- export class InputDeviceButton {
6
+ export class InputDeviceSwitch {
7
7
  /**
8
8
  * Button press
9
9
  * @type {Signal}
@@ -1,4 +1,4 @@
1
- import {InputDeviceButton} from "./InputDeviceButton";
1
+ import {InputDeviceSwitch} from "./InputDeviceSwitch";
2
2
  import Signal from "../../../core/events/signal/Signal";
3
3
 
4
4
  export default class KeyboardDevice {
@@ -6,7 +6,7 @@ export default class KeyboardDevice {
6
6
 
7
7
  readonly on: {up:Signal,down:Signal}
8
8
 
9
- readonly keys:{[key:string]:InputDeviceButton}
9
+ readonly keys:{[key:string]:InputDeviceSwitch}
10
10
 
11
11
  start():void
12
12