@woosh/meep-engine 2.39.36 → 2.39.39

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 (85) hide show
  1. package/LICENSE +13 -0
  2. package/core/assert.js +14 -5
  3. package/core/binary/Base64.js +58 -31
  4. package/core/binary/Base64.spec.js +14 -0
  5. package/core/bvh2/aabb3/AABB3.js +2 -2
  6. package/core/bvh2/aabb3/aabb3_detailed_volume_intersection.js +3 -2
  7. package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +2 -2
  8. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +7 -0
  9. package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +149 -6
  10. package/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.spec.js +41 -0
  11. package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +2 -2
  12. package/core/bvh2/traversal/__process_point_if_within_planes.js +2 -2
  13. package/core/bvh2/traversal/aabb3_detailed_volume_intersection_callback_based.js +3 -0
  14. package/core/collection/array/computeHashArray.d.ts +1 -0
  15. package/core/color/Color.js +7 -3
  16. package/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane_max.spec.js +8 -0
  17. package/core/geom/3d/aabb/{aabb3_computeDistanceAbovePlane.js → aabb3_compute_distance_above_plane_max.js} +3 -2
  18. package/core/geom/3d/aabb/computeAABB3PlaneSide.js +3 -3
  19. package/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +3 -2
  20. package/core/geom/3d/plane/is_point_within_planes.js +2 -2
  21. package/core/geom/3d/plane/plane3_projectPoint.js +2 -2
  22. package/core/geom/3d/plane/plane3_projectPoint.spec.js +54 -0
  23. package/core/geom/Plane.js +0 -19
  24. package/core/geom/Quaternion.js +52 -38
  25. package/core/geom/v3_distance_above_plane.js +20 -0
  26. package/core/geom/v3_distance_above_plane.spec.js +40 -0
  27. package/core/math/statistics/halton_sequence.js +26 -0
  28. package/core/model/ModuleRegistry.js +1 -1
  29. package/core/model/reactive/model/terminal/ReactiveReference.js +1 -1
  30. package/core/model/reactive/trigger/ReactiveTrigger.js +14 -4
  31. package/editor/ecs/component/editors/ImagePathEditor.js +83 -0
  32. package/engine/asset/loaders/ArrayBufferLoader.js +76 -16
  33. package/engine/ecs/EntityComponentDataset.js +18 -28
  34. package/engine/ecs/terrain/ecs/splat/SplatMapping.js +27 -4
  35. package/engine/graphics/GraphicsEngine.d.ts +2 -2
  36. package/engine/graphics/GraphicsEngine.js +11 -15
  37. package/engine/graphics/composit/LayerCompositer.js +1 -0
  38. package/engine/graphics/ecs/camera/Camera.js +2 -2
  39. package/engine/graphics/ecs/camera/CameraSystem.js +6 -0
  40. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +1 -1
  41. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +14 -6
  42. package/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +2 -1
  43. package/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js +17 -2
  44. package/engine/graphics/ecs/mesh-v2/aggregate/prototypeSGMesh.js +17 -20
  45. package/engine/graphics/filter/FlipArrayInPlace.js +11 -6
  46. package/engine/graphics/geometry/clipping/ClippedGeometry.js +4 -4
  47. package/engine/graphics/micron/prototypeVirtualGeometry.js +3 -1
  48. package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +2 -0
  49. package/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +95 -0
  50. package/engine/graphics/render/buffer/simple-fx/taa/prototypeTAA.js +61 -0
  51. package/engine/graphics/render/forward_plus/LightManager.js +4 -4
  52. package/engine/graphics/render/forward_plus/plugin/ForwardPlusRenderingPlugin.js +6 -7
  53. package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +6 -2
  54. package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_objects.js +4 -2
  55. package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +4 -2
  56. package/engine/graphics/render/frame_graph/GraphNode.js +22 -0
  57. package/engine/graphics/render/frame_graph/RenderGraph.js +405 -0
  58. package/engine/graphics/render/frame_graph/RenderGraphBuilder.js +77 -0
  59. package/engine/graphics/render/frame_graph/RenderPass.js +30 -12
  60. package/engine/graphics/render/frame_graph/RenderPassNode.js +103 -0
  61. package/engine/graphics/render/frame_graph/RenderPassResources.js +54 -4
  62. package/engine/graphics/render/frame_graph/ResourceEntry.js +77 -0
  63. package/engine/graphics/render/frame_graph/ResourceNode.js +23 -0
  64. package/engine/graphics/render/frame_graph/TextureDescriptor.js +38 -4
  65. package/engine/graphics/render/frame_graph/sample/deferred/GBufferDrawPass.js +11 -5
  66. package/engine/graphics/render/frame_graph/sample/deferred/LightingPass.js +24 -0
  67. package/engine/graphics/render/frame_graph/sample/deferred/run.js +31 -0
  68. package/engine/graphics/render/frame_graph/sample/meep-v1/ColorDepthPass.js +38 -0
  69. package/engine/graphics/render/frame_graph/sample/meep-v1/OutlinePass.js +9 -0
  70. package/engine/graphics/render/frame_graph/sample/meep-v1/SSAOPass.js +5 -0
  71. package/engine/graphics/render/frame_graph/sample/meep-v1/render.js +7 -0
  72. package/engine/graphics/render/frame_graph/webgl/WebGLRenderContext.js +5 -0
  73. package/engine/graphics/render/layers/RenderLayerUtils.js +5 -3
  74. package/engine/graphics/render/view/CameraView.js +38 -0
  75. package/engine/graphics/texture/sampler/Sampler2D.js +22 -2
  76. package/engine/knowledge/database/DATABASE_SERIALIZATION_IGNORE_PROPERTY.js +1 -0
  77. package/engine/knowledge/database/StaticKnowledgeDataTable.js +5 -4
  78. package/package.json +1 -1
  79. package/view/elements/button/ButtonView.js +12 -1
  80. package/core/geom/Plane.spec.js +0 -12
  81. package/engine/graphics/render/frame_graph/FrameGraphBuilder.js +0 -36
  82. package/engine/graphics/render/frame_graph/Resource.js +0 -21
  83. package/engine/graphics/render/frame_graph/ResourceReference.js +0 -14
  84. package/engine/graphics/render/frame_graph/UsageModeType.js +0 -5
  85. package/engine/graphics/render/frame_graph/sample/deferred/PresentPass.js +0 -17
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Please note that this package comes without a license.
2
+ No permission is granted for any kind of usage.
3
+ All rights are reserved by the author.
4
+
5
+ For illustration purposes, this means that unless you have obtained a license, all of the following terms apply:
6
+ * You are NOT permitted to make copies of this package
7
+ * You are NOT permitted to re-distribute this package
8
+ * You are NOT permitted to extend the code from this package
9
+ * You are NOT permitted to make use of this package for any purpose, commercial or otherwise
10
+
11
+ If you would like to use this package in any context, please contact me via email so we can arrange a license:
12
+
13
+ travnick [at] gmail [d0t] com
package/core/assert.js CHANGED
@@ -280,18 +280,27 @@ assert.isFunction = function (value, name = 'value') {
280
280
  * @param {number|*} value
281
281
  * @param {string} [name]
282
282
  */
283
- assert.isNonNegativeInteger = function (value, name = 'value') {
283
+ assert.isInteger = function (value, name = 'value') {
284
284
  assert.isNumber(value, name);
285
285
 
286
- if (value < 0) {
287
- throw new Error(`${name} must be >= 0, instead was ${value}`);
288
- }
289
-
290
286
  if (!Number.isInteger(value)) {
291
287
  throw new Error(`${name} must be an integer, instead was ${value}`);
292
288
  }
293
289
  }
294
290
 
291
+ /**
292
+ *
293
+ * @param {number|*} value
294
+ * @param {string} [name]
295
+ */
296
+ assert.isNonNegativeInteger = function (value, name = 'value') {
297
+ assert.isInteger(value, name);
298
+
299
+ if (value < 0) {
300
+ throw new Error(`${name} must be >= 0, instead was ${value}`);
301
+ }
302
+ }
303
+
295
304
  /**
296
305
  * @template T
297
306
  * @param {T[]} value
@@ -3,13 +3,21 @@
3
3
  * @author Jameson Little
4
4
  */
5
5
 
6
- var lookup = [];
7
- var revLookup = [];
8
- var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
6
+ /**
7
+ *
8
+ * @type {string[]}
9
+ */
10
+ const lookup = [];
11
+ /**
12
+ *
13
+ * @type {number[]}
14
+ */
15
+ const revLookup = [];
16
+ const Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array;
9
17
 
10
- var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
18
+ const code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
11
19
 
12
- for (var i = 0, len = code.length; i < len; ++i) {
20
+ for (let i = 0, len = code.length; i < len; ++i) {
13
21
  lookup[i] = code[i];
14
22
  revLookup[code.charCodeAt(i)] = i;
15
23
  }
@@ -19,6 +27,11 @@ for (var i = 0, len = code.length; i < len; ++i) {
19
27
  revLookup['-'.charCodeAt(0)] = 62;
20
28
  revLookup['_'.charCodeAt(0)] = 63;
21
29
 
30
+ /**
31
+ *
32
+ * @param {string} b64
33
+ * @return {number[]}
34
+ */
22
35
  function getLens(b64) {
23
36
  var len = b64.length;
24
37
 
@@ -41,12 +54,6 @@ function getLens(b64) {
41
54
  }
42
55
 
43
56
  // base64 is 4/3 + up to two characters of the original data
44
- function byteLength(b64) {
45
- var lens = getLens(b64);
46
- var validLen = lens[0];
47
- var placeHoldersLen = lens[1];
48
- return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen;
49
- }
50
57
 
51
58
  function _byteLength(b64, validLen, placeHoldersLen) {
52
59
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen;
@@ -99,37 +106,57 @@ function toByteArray(b64) {
99
106
  }
100
107
 
101
108
  function tripletToBase64(num) {
102
- return lookup[num >> 18 & 0x3F] +
103
- lookup[num >> 12 & 0x3F] +
104
- lookup[num >> 6 & 0x3F] +
105
- lookup[num & 0x3F];
109
+ return lookup[num >> 18 & 0x3F]
110
+ + lookup[num >> 12 & 0x3F]
111
+ + lookup[num >> 6 & 0x3F]
112
+ + lookup[num & 0x3F]
113
+ ;
106
114
  }
107
115
 
116
+ /**
117
+ *
118
+ * @param {Uint8Array} uint8
119
+ * @param {number} start
120
+ * @param {number} end
121
+ * @return {string}
122
+ */
108
123
  function encodeChunk(uint8, start, end) {
109
- var tmp;
110
- var output = [];
111
- for (var i = start; i < end; i += 3) {
112
- tmp =
113
- ((uint8[i] << 16) & 0xFF0000) +
114
- ((uint8[i + 1] << 8) & 0xFF00) +
115
- (uint8[i + 2] & 0xFF);
124
+ const output = [];
125
+
126
+ for (let i = start; i < end; i += 3) {
127
+
128
+ const tmp = ((uint8[i] << 16) & 0xFF0000)
129
+ + ((uint8[i + 1] << 8) & 0xFF00)
130
+ + (uint8[i + 2] & 0xFF);
131
+
116
132
  output.push(tripletToBase64(tmp));
117
133
  }
134
+
118
135
  return output.join('');
119
136
  }
120
137
 
138
+ /**
139
+ *
140
+ * @param {Uint8Array} uint8
141
+ * @return {string}
142
+ */
121
143
  function fromByteArray(uint8) {
122
- var tmp;
123
- var len = uint8.length;
124
- var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
125
- var parts = [];
126
- var maxChunkLength = 16383; // must be multiple of 3
144
+ let tmp;
145
+
146
+ const len = uint8.length;
147
+ const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
148
+ const parts = [];
149
+ const maxChunkLength = 16383; // must be multiple of 3
127
150
 
128
151
  // go through the array every three bytes, we'll deal with trailing stuff later
129
- for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
130
- parts.push(encodeChunk(
131
- uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
132
- ));
152
+ const len2 = len - extraBytes;
153
+
154
+ for (let i = 0; i < len2; i += maxChunkLength) {
155
+ const end = (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength);
156
+
157
+ const chunk = encodeChunk(uint8, i, end);
158
+
159
+ parts.push(chunk);
133
160
  }
134
161
 
135
162
  // pad the end with zeros, but make sure to not forget the extra bytes
@@ -0,0 +1,14 @@
1
+ import { Base64 } from "./Base64.js";
2
+
3
+ test("to/from consistency", () => {
4
+ const source = new Uint8Array(256);
5
+ for (let i = 0; i < source.length; i++) {
6
+ source[i] = i;
7
+ }
8
+
9
+ const encoded = Base64.encode(source.buffer);
10
+
11
+ const decoded = Base64.decode(encoded);
12
+
13
+ expect(Array.from(new Uint8Array(decoded))).toEqual(Array.from(source));
14
+ });
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
 
6
- import { aabb3_computeDistanceAbovePlane } from "../../geom/3d/aabb/aabb3_computeDistanceAbovePlane.js";
6
+ import { aabb3_computeDistanceAbovePlane_max } from "../../geom/3d/aabb/aabb3_compute_distance_above_plane_max.js";
7
7
  import { computeAABB3PlaneSide } from "../../geom/3d/aabb/computeAABB3PlaneSide.js";
8
8
  import computeMortonCode from "../../geom/3d/morton/Morton.js";
9
9
  import { aabb3_build_corners } from "../../geom/3d/aabb/aabb3_build_corners.js";
@@ -795,7 +795,7 @@ export class AABB3 {
795
795
  * @returns {number}
796
796
  */
797
797
  computeDistanceAbovePlane(normal_x, normal_y, normal_z, offset) {
798
- return aabb3_computeDistanceAbovePlane(
798
+ return aabb3_computeDistanceAbovePlane_max(
799
799
  normal_x, normal_y, normal_z, offset,
800
800
  this.x0, this.y0, this.z0,
801
801
  this.x1, this.y1, this.z1
@@ -1,11 +1,12 @@
1
1
  import { aabb3_build_corners } from "../../geom/3d/aabb/aabb3_build_corners.js";
2
2
  import { aabb_build_frustum } from "../../geom/3d/aabb/aabb3_build_frustum.js";
3
- import { computePointDistanceToPlane, plane3_computeLineSegmentIntersection } from "../../geom/Plane.js";
3
+ import { plane3_computeLineSegmentIntersection } from "../../geom/Plane.js";
4
4
  import { aabb3_corner_edge_mapping } from "./aabb3_corner_edge_mapping.js";
5
5
  import { aabb3_edge_corner_mapping } from "./aabb3_edge_corner_mapping.js";
6
6
  import { plane_computeConvex3PlaneIntersection } from "../../geom/3d/plane/plane_computeConvex3PlaneIntersection.js";
7
7
  import { EPSILON } from "../../math/MathUtils.js";
8
8
  import { is_point_within_planes } from "../../geom/3d/plane/is_point_within_planes.js";
9
+ import { v3_distance_above_plane } from "../../geom/v3_distance_above_plane.js";
9
10
 
10
11
  /**
11
12
  * Common piece of continuous memory for better cache coherence
@@ -120,7 +121,7 @@ export function aabb3_detailed_volume_intersection(
120
121
  const nz = planes[plane_address + 2];
121
122
  const c = planes[plane_address + 3];
122
123
 
123
- const distance_to_plane = computePointDistanceToPlane(
124
+ const distance_to_plane = v3_distance_above_plane(
124
125
  x, y, z,
125
126
  nx, ny, nz, c
126
127
  );
@@ -1,4 +1,4 @@
1
- import { aabb3_computeDistanceAbovePlane } from "../../geom/3d/aabb/aabb3_computeDistanceAbovePlane.js";
1
+ import { aabb3_computeDistanceAbovePlane_max } from "../../geom/3d/aabb/aabb3_compute_distance_above_plane_max.js";
2
2
 
3
3
  /**
4
4
  *
@@ -19,7 +19,7 @@ export function aabb3_intersects_frustum_array(x0, y0, z0, x1, y1, z1, frustum)
19
19
  const plane_z = frustum[i + 2];
20
20
  const plane_w = frustum[i + 3];
21
21
 
22
- const plane_distance = aabb3_computeDistanceAbovePlane(
22
+ const plane_distance = aabb3_computeDistanceAbovePlane_max(
23
23
  plane_x, plane_y, plane_z, plane_w,
24
24
  x0, y0, z0,
25
25
  x1, y1, z1
@@ -299,6 +299,13 @@ export class ExplicitBinaryBoundingVolumeHierarchy {
299
299
  node_set_aabb(id, aabb) {
300
300
  assert.isNonNegativeInteger(id, 'id');
301
301
 
302
+ assert.notNaN(aabb[0], 'aabb[0] x0');
303
+ assert.notNaN(aabb[1], 'aabb[1] y0');
304
+ assert.notNaN(aabb[2], 'aabb[2] z0');
305
+ assert.notNaN(aabb[3], 'aabb[3] x1');
306
+ assert.notNaN(aabb[4], 'aabb[4] y1');
307
+ assert.notNaN(aabb[5], 'aabb[5] z1');
308
+
302
309
  const address = ELEMENT_WORD_COUNT * id;
303
310
  const float32 = this.__data_float32;
304
311
 
@@ -1,13 +1,156 @@
1
1
  //
2
2
 
3
3
 
4
+ import { array_copy } from "../../../collection/array/copyArray.js";
5
+ import { NULL_NODE } from "../ExplicitBinaryBoundingVolumeHierarchy.js";
6
+ import { aabb3_array_intersects_frustum_degree } from "../../aabb3/aabb3_array_intersects_frustum_degree.js";
7
+ import { bvh_collect_user_data } from "../bvh_collect_user_data.js";
8
+ import { v3_distance_above_plane } from "../../../geom/v3_distance_above_plane.js";
9
+
10
+ const traversal_stack = [];
11
+
12
+ const scratch_aabb = [];
13
+
4
14
  /**
5
- *
6
- * @param result
7
- * @param result_offset
8
- * @param bvh
9
- * @param frustum
15
+ *
16
+ * @param {number[]} result
17
+ * @param {number} result_offset
18
+ * @param {number} constrained_planes_mask if bit is set to 1, that plane is not allowed to move
19
+ * @param {ExplicitBinaryBoundingVolumeHierarchy} bvh
20
+ * @param {number[]|ArrayLike<number>|Float32Array} frustum
10
21
  */
11
- export function compute_tight_near_far_clipping_planes(result, result_offset, bvh, frustum) {
22
+ export function compute_tight_near_far_clipping_planes(result, result_offset, constrained_planes_mask, bvh, frustum) {
23
+ // initialize result
24
+ array_copy(frustum, 0, result, result_offset, 24);
25
+
26
+ const root = bvh.root;
27
+
28
+ if (root === NULL_NODE) {
29
+ return 0;
30
+ }
31
+
32
+ /**
33
+ *
34
+ * @type {number}
35
+ */
36
+ let traversal_cursor = 1;
37
+
38
+ traversal_stack[0] = root;
39
+
40
+ let result_cursor = result_offset;
41
+
42
+ // 0 is the nearest point along the normal and 1 is the furthest
43
+ let x0,
44
+ y0,
45
+ z0,
46
+ x1,
47
+ y1,
48
+ z1;
49
+
50
+ node_loop: while (traversal_cursor > 0) {
51
+ traversal_cursor--;
52
+
53
+ /**
54
+ *
55
+ * @type {number}
56
+ */
57
+ const node = traversal_stack[traversal_cursor];
58
+
59
+ // test node against the ray
60
+ bvh.node_get_aabb(node, scratch_aabb);
61
+
62
+ const _x0 = scratch_aabb[0];
63
+ const _y0 = scratch_aabb[1];
64
+ const _z0 = scratch_aabb[2];
65
+ const _x1 = scratch_aabb[3];
66
+ const _y1 = scratch_aabb[4];
67
+ const _z1 = scratch_aabb[5];
68
+
69
+ for (let i = 0; i < 6; i++) {
70
+ const plane_address = i * 4;
71
+
72
+ //read out plane
73
+ const plane_normal_x = frustum[plane_address];
74
+ const plane_normal_y = frustum[plane_address + 1];
75
+ const plane_normal_z = frustum[plane_address + 2];
76
+ const plane_offset = frustum[plane_address + 3];
77
+
78
+
79
+ // construct nearest and farthest corners along the plane normal
80
+ if (plane_normal_x > 0) {
81
+ x0 = _x0;
82
+ x1 = _x1;
83
+ } else {
84
+ x0 = _x1;
85
+ x1 = _x0;
86
+ }
87
+
88
+ if (plane_normal_y > 0) {
89
+ y0 = _y0;
90
+ y1 = _y1;
91
+ } else {
92
+ y0 = _y1;
93
+ y1 = _y0;
94
+ }
95
+
96
+ if (plane_normal_z > 0) {
97
+ z0 = _z0;
98
+ z1 = _z1;
99
+ } else {
100
+ z0 = _z1;
101
+ z1 = _z0;
102
+ }
103
+
104
+ const distance_above_plane = v3_distance_above_plane(
105
+ x1, y1, z1,
106
+ plane_normal_x, plane_normal_y, plane_normal_z, plane_offset
107
+ );
108
+
109
+ if (distance_above_plane < 0) {
110
+ // below plane, reject this branch
111
+ continue node_loop;
112
+ }
113
+
114
+ if ((constrained_planes_mask & (1 << i)) !== 0) {
115
+ // plane is constrained, we're done here
116
+ continue;
117
+ }
118
+
119
+ //
120
+
121
+ }
122
+
123
+ const intersection = aabb3_array_intersects_frustum_degree(scratch_aabb, frustum);
124
+
125
+ if (intersection === 0) {
126
+ // fully outside
127
+ continue;
128
+ }
129
+
130
+ const node_is_leaf = bvh.node_is_leaf(node);
131
+
132
+ if (!node_is_leaf) {
133
+
134
+ if (intersection === 2) {
135
+ // fully inside, fast collection path
136
+ result_cursor += bvh_collect_user_data(result, result_cursor, bvh, node);
137
+ } else {
138
+ // partially inside
139
+ // read in-order
140
+ const child1 = bvh.node_get_child1(node);
141
+ const child2 = bvh.node_get_child2(node);
142
+
143
+ // write to stack in reverse order, so that fist child ends up being visited first
144
+ traversal_stack[traversal_cursor++] = child1;
145
+ traversal_stack[traversal_cursor++] = child2;
146
+ }
147
+
148
+ } else {
149
+ // leaf node
150
+
151
+ }
152
+ }
153
+
154
+ // drop stack frame
12
155
 
13
156
  }
@@ -0,0 +1,41 @@
1
+ import { ExplicitBinaryBoundingVolumeHierarchy } from "../ExplicitBinaryBoundingVolumeHierarchy.js";
2
+ import { compute_tight_near_far_clipping_planes } from "./compute_tight_near_far_clipping_planes.js";
3
+
4
+
5
+ function orthographic_frustum(left, right, up, down, near, far) {
6
+ return new Float32Array([
7
+ 1, 0, 0, right,
8
+ -1, 0, 0, -left,
9
+ 0, 1, 0, down,
10
+ 0, -1, 0, -up,
11
+ 0, 0, 1, far,
12
+ 0, 0, -1, -near
13
+ ]);
14
+ }
15
+
16
+ test('Empty', () => {
17
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
18
+
19
+ const res = [];
20
+
21
+ const frustum = new Float32Array(24);
22
+
23
+ compute_tight_near_far_clipping_planes(res, 0, 0b000011, bvh, frustum);
24
+ });
25
+
26
+ test('Axis-aligned, orthographic tight fit around a single small node', () => {
27
+ const frustum = orthographic_frustum(-1, 1, -1, 1, -1, 1);
28
+
29
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
30
+
31
+ const leaf = bvh.allocate_node();
32
+ bvh.node_set_aabb(leaf, [-0.1, -0.1, -0.1, 0.1, 0.1, 0.1]);
33
+ bvh.insert_leaf(leaf);
34
+
35
+ const res = [];
36
+
37
+ compute_tight_near_far_clipping_planes(res, 0, 0b000011, bvh, frustum);
38
+
39
+ expect(res[4 * 4 + 3]).toBeCloseTo(0.1);
40
+ expect(res[4 * 5 + 3]).toBeCloseTo(0.1);
41
+ });
@@ -1,9 +1,9 @@
1
- import { computePointDistanceToPlane } from "../../geom/Plane.js";
2
1
  import { BVHVisitor } from "./BVHVisitor.js";
3
2
  import { read_frustum_planes_to_array } from "../../geom/3d/frustum/read_frustum_planes_to_array.js";
4
3
  import {
5
4
  aabb3_detailed_volume_intersection_callback_based
6
5
  } from "./aabb3_detailed_volume_intersection_callback_based.js";
6
+ import { v3_distance_above_plane } from "../../geom/v3_distance_above_plane.js";
7
7
 
8
8
  export class ThreeClippingPlaneComputingBVHVisitor extends BVHVisitor {
9
9
  constructor() {
@@ -113,7 +113,7 @@ export class ThreeClippingPlaneComputingBVHVisitor extends BVHVisitor {
113
113
 
114
114
  const n = this.__nearPlaneNormal;
115
115
 
116
- return computePointDistanceToPlane(x, y, z, n.x, n.y, n.z, this.__nearPlaneConstant);
116
+ return v3_distance_above_plane(x, y, z, n.x, n.y, n.z, this.__nearPlaneConstant);
117
117
  }
118
118
 
119
119
  /**
@@ -1,5 +1,5 @@
1
- import { computePointDistanceToPlane } from "../../geom/Plane.js";
2
1
  import { EPSILON } from "../../math/MathUtils.js";
2
+ import { v3_distance_above_plane } from "../../geom/v3_distance_above_plane.js";
3
3
 
4
4
  /**
5
5
  *
@@ -39,7 +39,7 @@ export function __process_point_if_within_planes(
39
39
  const nz = planes[plane_address + 2];
40
40
  const c = planes[plane_address + 3];
41
41
 
42
- const distance_to_plane = computePointDistanceToPlane(x, y, z, nx, ny, nz, c);
42
+ const distance_to_plane = v3_distance_above_plane(x, y, z, nx, ny, nz, c);
43
43
 
44
44
  if (distance_to_plane < -EPSILON) {
45
45
  // point is outside of one of the planes
@@ -43,10 +43,13 @@ export function aabb3_detailed_volume_intersection_callback_based(
43
43
  );
44
44
 
45
45
  for (let i = 0; i < point_count; i++) {
46
+
46
47
  const address = i * 3;
48
+
47
49
  const x = scratch_points_data[address];
48
50
  const y = scratch_points_data[address + 1];
49
51
  const z = scratch_points_data[address + 2];
52
+
50
53
  callback.call(thisArg,
51
54
  x,
52
55
  y,
@@ -0,0 +1 @@
1
+ export function computeHashArray<T>(array: T[], hash: (T) => number): number
@@ -301,12 +301,15 @@ export class Color {
301
301
  * @param {number} v 0..1
302
302
  */
303
303
  setHSV(h, s, v) {
304
- let _h = h % 1;
304
+ let _h = h;
305
305
 
306
306
  if (_h < 0) {
307
- _h = h + 1;
307
+ // move into positive range
308
+ _h = _h + Math.ceil(Math.abs(_h));
308
309
  }
309
310
 
311
+ _h = _h % 1
312
+
310
313
  const _s = clamp01(s);
311
314
  const _v = clamp01(v);
312
315
 
@@ -409,7 +412,8 @@ export class Color {
409
412
  * @param {Color} other
410
413
  */
411
414
  copy(other) {
412
- this.setRGB(this.r, this.g, this.b);
415
+ this.a = other.a;
416
+ this.setRGB(other.r, other.g, other.b);
413
417
  }
414
418
 
415
419
  /**
@@ -0,0 +1,8 @@
1
+ import { aabb3_computeDistanceAbovePlane_max } from "./aabb3_compute_distance_above_plane_max.js";
2
+
3
+ test('cube above orthographic plane',()=>{
4
+ expect(aabb3_computeDistanceAbovePlane_max(
5
+ 0,1,0,-1,
6
+ -1,3,-1,1,5,1
7
+ )).toBe(4);
8
+ });
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * Distance of the farthest point along the plane normal from the plane. If the result is >= 0, at least a portion of AABB pokes above the plane
2
3
  * @param {number} plane_normal_x
3
4
  * @param {number} plane_normal_y
4
5
  * @param {number} plane_normal_z
@@ -11,13 +12,13 @@
11
12
  * @param {number} _z1
12
13
  * @returns {number}
13
14
  */
14
- export function aabb3_computeDistanceAbovePlane(
15
+ export function aabb3_computeDistanceAbovePlane_max(
15
16
  plane_normal_x, plane_normal_y, plane_normal_z, plane_constant,
16
17
  _x0, _y0, _z0,
17
18
  _x1, _y1, _z1
18
19
  ) {
19
20
 
20
- // pick a corner point furthest along the plane normal
21
+ // pick a corner point nearest along the plane normal
21
22
  const px = plane_normal_x > 0 ? _x1 : _x0;
22
23
  const py = plane_normal_y > 0 ? _y1 : _y0;
23
24
  const pz = plane_normal_z > 0 ? _z1 : _z0;
@@ -1,4 +1,4 @@
1
- import { computePointDistanceToPlane } from "../../Plane.js";
1
+ import { v3_distance_above_plane } from "../../v3_distance_above_plane.js";
2
2
 
3
3
  /**
4
4
  * 2,0,or -2; 2: above, -2 : below, 0 : intersects plane
@@ -62,7 +62,7 @@ export function computeAABB3PlaneSide(
62
62
 
63
63
  // check the nearest corner
64
64
 
65
- if (computePointDistanceToPlane(x0, y0, z0, plane_normal_x, plane_normal_y, plane_normal_z, plane_constant) >= 0) {
65
+ if (v3_distance_above_plane(x0, y0, z0, plane_normal_x, plane_normal_y, plane_normal_z, plane_constant) >= 0) {
66
66
  // above the plane
67
67
  result += 1;
68
68
  } else {
@@ -71,7 +71,7 @@ export function computeAABB3PlaneSide(
71
71
 
72
72
  // check the farthest corner
73
73
 
74
- if (computePointDistanceToPlane(x1, y1, z1, plane_normal_x, plane_normal_y, plane_normal_z, plane_constant) >= 0) {
74
+ if (v3_distance_above_plane(x1, y1, z1, plane_normal_x, plane_normal_y, plane_normal_z, plane_constant) >= 0) {
75
75
  // above the plane
76
76
  result += 1;
77
77
  } else {
@@ -1,8 +1,9 @@
1
- import { computePlanePlaneIntersection, computePointDistanceToPlane } from "../../Plane.js";
1
+ import { computePlanePlaneIntersection } from "../../Plane.js";
2
2
  import Vector3 from "../../Vector3.js";
3
3
  import { plane3_projectPoint } from "../plane/plane3_projectPoint.js";
4
4
  import { plane_three_computeConvex3PlaneIntersection } from "../plane/plane_computeConvex3PlaneIntersection.js";
5
5
  import { ray_computeNearestPointToPoint } from "../ray/ray_computeNearestPointToPoint.js";
6
+ import { v3_distance_above_plane } from "../../v3_distance_above_plane.js";
6
7
 
7
8
  /**
8
9
  *
@@ -42,7 +43,7 @@ export function frustum3_computeNearestPointToPoint(result, planes, target_x, ta
42
43
 
43
44
  const plane_normal = plane.normal;
44
45
 
45
- const distance = computePointDistanceToPlane(
46
+ const distance = v3_distance_above_plane(
46
47
  target_x, target_y, target_z,
47
48
  plane_normal.x, plane_normal.y, plane_normal.z, plane.constant
48
49
  );
@@ -1,5 +1,5 @@
1
- import { computePointDistanceToPlane } from "../../Plane.js";
2
1
  import { EPSILON } from "../../../math/MathUtils.js";
2
+ import { v3_distance_above_plane } from "../../v3_distance_above_plane.js";
3
3
 
4
4
  /**
5
5
  *
@@ -34,7 +34,7 @@ export function is_point_within_planes(
34
34
  const nz = planes[plane_address + 2];
35
35
  const c = planes[plane_address + 3];
36
36
 
37
- const distance_to_plane = computePointDistanceToPlane(x, y, z, nx, ny, nz, c);
37
+ const distance_to_plane = v3_distance_above_plane(x, y, z, nx, ny, nz, c);
38
38
 
39
39
  if (distance_to_plane < -EPSILON) {
40
40
  // point is outside of one of the planes
@@ -1,4 +1,4 @@
1
- import { computePointDistanceToPlane } from "../../Plane.js";
1
+ import { v3_distance_above_plane } from "../../v3_distance_above_plane.js";
2
2
 
3
3
  /**
4
4
  *
@@ -12,7 +12,7 @@ import { computePointDistanceToPlane } from "../../Plane.js";
12
12
  * @param {number} plane_offset
13
13
  */
14
14
  export function plane3_projectPoint(result, point_x, point_y, point_z, normal_x, normal_y, normal_z, plane_offset) {
15
- const distance = computePointDistanceToPlane(point_x, point_y, point_z, normal_x, normal_y, normal_z, plane_offset);
15
+ const distance = v3_distance_above_plane(point_x, point_y, point_z, normal_x, normal_y, normal_z, plane_offset);
16
16
 
17
17
  const negative_distance = -distance;
18
18