@woosh/meep-engine 2.34.33 → 2.34.37

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 (62) hide show
  1. package/core/assert.js +11 -0
  2. package/core/binary/BitSet.js +5 -0
  3. package/core/bvh2/BinaryNode.js +880 -848
  4. package/core/bvh2/LeafNode.js +80 -82
  5. package/core/bvh2/Node.d.ts +3 -0
  6. package/core/bvh2/Node.js +111 -114
  7. package/core/bvh2/aabb3/AABB3.js +50 -4
  8. package/core/bvh2/aabb3/AABB3.spec.js +27 -1
  9. package/core/bvh2/aabb3/AABB3Math.js +1 -1
  10. package/core/bvh2/aabb3/aabb3_from_v3_array.js +34 -0
  11. package/core/bvh2/aabb3/aabb3_from_v3_array_transformed.js +39 -0
  12. package/core/bvh2/aabb3/aabb3_intersects_frustum_degree.js +46 -0
  13. package/core/bvh2/transform/RotationOptimizer.js +2 -262
  14. package/core/bvh2/transform/tryRotateSingleNode.js +259 -0
  15. package/core/bvh2/traversal/ThreeFrustumsIntersectionBVHVisitor.js +16 -35
  16. package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +52 -0
  17. package/core/collection/list/List.js +0 -34
  18. package/core/events/signal/Signal.js +1 -1
  19. package/core/geom/3d/aabb/aabb3_matrix4_project.js +3 -4
  20. package/core/geom/3d/aabb/aabb3_matrix4_project.spec.js +13 -0
  21. package/core/geom/3d/triangle/computeTriangleRayIntersection.js +1 -2
  22. package/core/geom/Quaternion.d.ts +2 -0
  23. package/core/geom/Vector3.js +22 -11
  24. package/engine/asset/loaders/ArrayBufferLoader.js +7 -0
  25. package/engine/asset/loaders/image/ImageRGBADataLoader.js +11 -6
  26. package/engine/ecs/EntityBuilder.js +12 -5
  27. package/engine/ecs/EntityComponentDataset.js +26 -6
  28. package/engine/ecs/attachment/AttachmentSystem.js +1 -1
  29. package/engine/ecs/attachment/TransformAttachmentBinding.js +0 -1
  30. package/engine/ecs/foliage/FoliageVisibilitySetBuilder.js +1 -31
  31. package/engine/ecs/foliage/InstancedFoliage.js +85 -152
  32. package/engine/ecs/foliage/ViewState.js +190 -0
  33. package/engine/ecs/foliage/ecs/Foliage2System.js +82 -19
  34. package/engine/ecs/foliage/ecs/InstancedMeshComponent.js +30 -0
  35. package/engine/ecs/foliage/ecs/InstancedMeshLayer.js +16 -0
  36. package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +2 -2
  37. package/engine/ecs/parent/EntityNode.js +31 -49
  38. package/engine/ecs/sockets/AttachmentSockets.js +11 -1
  39. package/engine/ecs/transform-attachment/TransformAttachment.js +88 -0
  40. package/engine/ecs/transform-attachment/TransformAttachmentSystem.js +59 -0
  41. package/engine/graphics/GraphicsEngine.js +23 -2
  42. package/engine/graphics/ecs/camera/Camera.js +33 -16
  43. package/engine/graphics/ecs/camera/unprojectPoint.js +14 -0
  44. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +2 -19
  45. package/engine/graphics/ecs/mesh/updateNodeByTransformAndBBB.js +21 -21
  46. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +9 -1
  47. package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +4 -1
  48. package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +40 -8
  49. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +3 -3
  50. package/engine/graphics/ecs/water2/shader/AlexWaterShader.js +7 -1
  51. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +17 -11
  52. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +1 -34
  53. package/engine/graphics/micron/build/fill_patch_geometry_data.js +12 -0
  54. package/engine/graphics/micron/format/MicronGeometry.js +21 -0
  55. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -3
  56. package/engine/graphics/micron/prototypeVirtualGeometry.js +69 -1
  57. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +5 -1
  58. package/engine/graphics/render/layers/RenderLayer.js +22 -85
  59. package/engine/graphics/render/visibility/VisibilityComputer.js +23 -103
  60. package/engine/sound/ecs/emitter/SoundEmitterSystem.js +1 -1
  61. package/package.json +1 -1
  62. package/samples/terrain/editor.js +0 -1
@@ -14,98 +14,97 @@ function isLeaf(node) {
14
14
  return node.isLeafNode;
15
15
  }
16
16
 
17
- /**
18
- *
19
- * @param {*} object
20
- * @param {number} x0
21
- * @param {number} y0
22
- * @param {number} z0
23
- * @param {number} x1
24
- * @param {number} y1
25
- * @param {number} z1
26
- * @constructor
27
- */
28
- function LeafNode(object, x0, y0, z0, x1, y1, z1) {
29
- this.object = object;
30
- this.parentNode = null;
31
-
32
-
33
- this.x0 = x0;
34
- this.y0 = y0;
35
- this.z0 = z0;
36
- this.x1 = x1;
37
- this.y1 = y1;
38
- this.z1 = z1;
39
- }
17
+ export class LeafNode extends Node {
18
+ /**
19
+ *
20
+ * @param {*} object
21
+ * @param {number} x0
22
+ * @param {number} y0
23
+ * @param {number} z0
24
+ * @param {number} x1
25
+ * @param {number} y1
26
+ * @param {number} z1
27
+ * @constructor
28
+ */
29
+ constructor(object, x0, y0, z0, x1, y1, z1) {
30
+ super();
31
+
32
+ this.object = object;
33
+ this.parentNode = null;
34
+
35
+ this.x0 = x0;
36
+ this.y0 = y0;
37
+ this.z0 = z0;
38
+ this.x1 = x1;
39
+ this.y1 = y1;
40
+ this.z1 = z1;
41
+
42
+ /**
43
+ *
44
+ * @type {boolean}
45
+ */
46
+ this.isLeafNode = true;
47
+ /**
48
+ * Useful shortcut, to avoid having to distinguish between leaf and intermediate nodes
49
+ * @readonly
50
+ * @type {number}
51
+ */
52
+ this.leafNodeCount = 1;
53
+ }
40
54
 
41
- LeafNode.prototype = Object.create(Node.prototype);
55
+ /**
56
+ *
57
+ * @param {number} dx
58
+ * @param {number} dy
59
+ * @param {number} dz
60
+ */
61
+ move(dx, dy, dz) {
62
+ this.x0 += dx;
63
+ this.x1 += dx;
64
+ this.y0 += dy;
65
+ this.y1 += dy;
66
+ this.z0 += dz;
67
+ this.z1 += dz;
68
+ if (this.parentNode !== null) {
69
+ this.parentNode.bubbleRefit();
70
+ }
71
+ }
42
72
 
43
- /**
44
- *
45
- * @type {boolean}
46
- */
47
- LeafNode.prototype.isLeafNode = true;
73
+ /**
74
+ *
75
+ * @param {number} x0
76
+ * @param {number} y0
77
+ * @param {number} z0
78
+ * @param {number} x1
79
+ * @param {number} y1
80
+ * @param {number} z1
81
+ */
82
+ resize(x0, y0, z0, x1, y1, z1) {
83
+ this.setBounds(x0, y0, z0, x1, y1, z1);
84
+
85
+ this.bubbleRefit();
86
+ }
48
87
 
49
- /**
50
- * Useful shortcut, to avoid having to distinguish between leaf and intermediate nodes
51
- * @readonly
52
- * @type {number}
53
- */
54
- LeafNode.prototype.leafNodeCount = 1;
88
+ bubbleRefit() {
55
89
 
56
- /**
57
- *
58
- * @param {number} dx
59
- * @param {number} dy
60
- * @param {number} dz
61
- */
62
- LeafNode.prototype.move = function (dx, dy, dz) {
63
- this.x0 += dx;
64
- this.x1 += dx;
65
- this.y0 += dy;
66
- this.y1 += dy;
67
- this.z0 += dz;
68
- this.z1 += dz;
69
- if (this.parentNode !== null) {
70
- this.parentNode.bubbleRefit();
90
+ if (this.parentNode !== null) {
91
+ this.parentNode.bubbleRefit();
92
+ }
71
93
  }
72
- };
73
-
74
- /**
75
- *
76
- * @param {number} x0
77
- * @param {number} y0
78
- * @param {number} z0
79
- * @param {number} x1
80
- * @param {number} y1
81
- * @param {number} z1
82
- */
83
- LeafNode.prototype.resize = function (x0, y0, z0, x1, y1, z1) {
84
- this.setBounds(x0, y0, z0, x1, y1, z1);
85
94
 
86
- this.bubbleRefit();
87
- };
95
+ /**
96
+ *
97
+ * @return {LeafNode}
98
+ */
99
+ clone() {
100
+ const clone = new LeafNode(this.object, this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
88
101
 
89
- LeafNode.prototype.bubbleRefit = function (){
102
+ clone.parentNode = this.parentNode;
90
103
 
91
- if (this.parentNode !== null) {
92
- this.parentNode.bubbleRefit();
104
+ return clone;
93
105
  }
94
106
  }
95
107
 
96
- /**
97
- *
98
- * @return {LeafNode}
99
- */
100
- LeafNode.prototype.clone = function () {
101
- const clone = new LeafNode(this.object, this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
102
-
103
- clone.parentNode = this.parentNode;
104
-
105
- return clone;
106
- };
107
-
108
-
109
108
  /**
110
109
  *
111
110
  * @param {BinaryBuffer} buffer
@@ -130,7 +129,6 @@ function deserializeLeafNode(buffer, node, valueDeserializer) {
130
129
 
131
130
  export {
132
131
  isLeaf,
133
- LeafNode,
134
132
  serializeLeafNode,
135
133
  deserializeLeafNode
136
134
  };
@@ -3,4 +3,7 @@ import {BinaryNode} from "./BinaryNode";
3
3
 
4
4
  export class Node<T> extends AABB3 {
5
5
  public parentNode: BinaryNode<T>
6
+
7
+
8
+ readonly leafNodeCount: number
6
9
  }
package/core/bvh2/Node.js CHANGED
@@ -5,144 +5,142 @@ import computeMortonCode from "../geom/3d/morton/Morton.js";
5
5
  import { AABB3 } from "./aabb3/AABB3.js";
6
6
 
7
7
 
8
- /**
9
- * @extends {AABB3}
10
- * @constructor
11
- */
12
- function Node() {
8
+ export class Node extends AABB3 {
9
+ constructor() {
10
+ super();
11
+
12
+ /**
13
+ *
14
+ * @type {BinaryNode|null}
15
+ */
16
+ this.parentNode = null;
17
+ this._mortonCode = void 0;
18
+ }
19
+
13
20
  /**
14
- *
15
- * @type {BinaryNode|null}
21
+ * @return {boolean}
16
22
  */
17
- this.parentNode = null;
18
- this._mortonCode = void 0;
19
- }
20
-
21
- Node.prototype = Object.create(AABB3.prototype);
23
+ validateAncestorChain() {
24
+ //check containment
25
+ const parent = this.parentNode;
26
+ if (parent === null) {
27
+ //nothing to do
28
+ return true;
29
+ }
22
30
 
23
- /**
24
- * @return {boolean}
25
- */
26
- Node.prototype.validateAncestorChain = function () {
27
- //check containment
28
- const parent = this.parentNode;
29
- if (parent === null) {
30
- //nothing to do
31
- return true;
32
- }
31
+ if (!parent.containsBox(this)) {
32
+ //bounds violated
33
+ return false;
34
+ }
33
35
 
34
- if (!parent.containsBox(this)) {
35
- //bounds violated
36
- return false;
37
- }
36
+ if (parent.left === this || parent.right === this) {
37
+ //all is well
38
+ } else {
39
+ return false;
40
+ }
38
41
 
39
- if (parent.left === this || parent.right === this) {
40
- //all is well
41
- } else {
42
- return false;
42
+ return true;
43
43
  }
44
44
 
45
- return true;
46
- };
45
+ /**
46
+ *
47
+ * @returns {number}
48
+ */
49
+ computeDepth() {
50
+ let d = 0;
51
+ let node = this.parentNode;
47
52
 
48
- /**
49
- *
50
- * @returns {number}
51
- */
52
- Node.prototype.computeDepth = function () {
53
- let d = 0;
54
- let node = this.parentNode;
53
+ while (node !== null) {
54
+ node = node.parentNode;
55
55
 
56
- while (node !== null) {
57
- node = node.parentNode;
56
+ d++;
57
+ }
58
58
 
59
- d++;
59
+ return d;
60
60
  }
61
61
 
62
- return d;
63
- };
62
+ /**
63
+ *
64
+ * @returns {Node}
65
+ */
66
+ computeRoot() {
67
+ let p = this;
64
68
 
65
- /**
66
- *
67
- * @returns {Node}
68
- */
69
- Node.prototype.computeRoot = function () {
70
- let p = this;
69
+ while (p.parentNode !== null) {
70
+ p = p.parentNode;
71
+ }
71
72
 
72
- while (p.parentNode !== null) {
73
- p = p.parentNode;
73
+ return p;
74
74
  }
75
75
 
76
- return p;
77
- };
78
-
79
- Node.prototype.getMortonCode = function () {
80
- if (this._mortonCode === void 0) {
81
- const hx = (this.x1 + this.x0) / 2;
82
- const hy = (this.y1 + this.y0) / 2;
83
- const hz = (this.z1 + this.z0) / 2;
84
- const mortonCode = computeMortonCode(hx, hy, hz);
85
- this._mortonCode = mortonCode;
86
- return mortonCode;
87
- } else {
88
- return this._mortonCode;
76
+ getMortonCode() {
77
+ if (this._mortonCode === void 0) {
78
+ const hx = (this.x1 + this.x0) / 2;
79
+ const hy = (this.y1 + this.y0) / 2;
80
+ const hz = (this.z1 + this.z0) / 2;
81
+ const mortonCode = computeMortonCode(hx, hy, hz);
82
+ this._mortonCode = mortonCode;
83
+ return mortonCode;
84
+ } else {
85
+ return this._mortonCode;
86
+ }
89
87
  }
90
- };
91
88
 
92
- /**
93
- * Expands current node and all ancestors until root to accommodate for given box, terminate if node is already
94
- * large enough
95
- * @param {AABB3} box
96
- */
97
- Node.prototype.bubbleExpandToFit = function (box) {
98
- let node = this;
99
- while (node.expandToFit(box)) {
100
- node = node.parentNode;
101
- if (node === null) {
102
- break;
89
+ /**
90
+ * Expands current node and all ancestors until root to accommodate for given box, terminate if node is already
91
+ * large enough
92
+ * @param {AABB3} box
93
+ */
94
+ bubbleExpandToFit(box) {
95
+ let node = this;
96
+ while (node.expandToFit(box)) {
97
+ node = node.parentNode;
98
+ if (node === null) {
99
+ break;
100
+ }
103
101
  }
104
102
  }
105
- };
106
103
 
107
- /**
108
- * @deprecated
109
- */
110
- Node.prototype.remove = function () {
111
- console.error("This method is deprecated, use 'disconnect' instead.");
112
- this.disconnect();
113
- };
104
+ /**
105
+ * @deprecated
106
+ */
107
+ remove() {
108
+ console.error("This method is deprecated, use 'disconnect' instead.");
109
+ this.disconnect();
110
+ }
114
111
 
115
- /**
116
- * Detaches this node from its parent
117
- */
118
- Node.prototype.disconnect = function () {
119
- const node = this.parentNode;
112
+ /**
113
+ * Detaches this node from its parent
114
+ */
115
+ disconnect() {
116
+ const node = this.parentNode;
120
117
 
121
- if (node === null) {
122
- //no parent already
123
- // console.warn(`Node has no parent, nothing to disconnect from`);
124
- return;
125
- }
118
+ if (node === null) {
119
+ //no parent already
120
+ // console.warn(`Node has no parent, nothing to disconnect from`);
121
+ return;
122
+ }
126
123
 
127
- if (this === node.left) {
128
- node.left = null;
129
- this.parentNode = null;
130
- } else if (this === node.right) {
131
- node.right = null;
132
- this.parentNode = null;
133
- } else {
134
- throw new Error("impostor child");
135
- }
124
+ if (this === node.left) {
125
+ node.left = null;
126
+ this.parentNode = null;
127
+ } else if (this === node.right) {
128
+ node.right = null;
129
+ this.parentNode = null;
130
+ } else {
131
+ throw new Error("impostor child");
132
+ }
136
133
 
137
- node.updateLeafNodeCount();
138
- };
134
+ node.updateLeafNodeCount();
135
+ }
139
136
 
140
- /**
141
- * traverses all siblings up to the root
142
- */
143
- Node.prototype.traverseSiblingsUp = function () {
144
- throw new Error('Not Implemented');
145
- };
137
+ /**
138
+ * traverses all siblings up to the root
139
+ */
140
+ traverseSiblingsUp() {
141
+ throw new Error('Not Implemented');
142
+ }
143
+ }
146
144
 
147
145
  function buildPathForNode(n) {
148
146
 
@@ -185,7 +183,7 @@ function strinfityPath(path) {
185
183
  * @param {int} len maximum number of path elements
186
184
  * @returns {string}
187
185
  */
188
- function buildShortStringPath(n, len) {
186
+ export function buildShortStringPath(n, len) {
189
187
  const longPath = buildPathForNode(n);
190
188
 
191
189
  if (longPath.length > len) {
@@ -195,4 +193,3 @@ function buildShortStringPath(n, len) {
195
193
  }
196
194
  }
197
195
 
198
- export { Node, buildShortStringPath };
@@ -6,9 +6,10 @@
6
6
  import { aabb3_computeDistanceAbovePlane } from "../../geom/3d/aabb/aabb3_computeDistanceAbovePlane.js";
7
7
  import { computeAABB3PlaneSide } from "../../geom/3d/aabb/computeAABB3PlaneSide.js";
8
8
  import computeMortonCode from "../../geom/3d/morton/Morton.js";
9
- import { _boxSurfaceArea2, intersectRay, intersectSegment } from "./AABB3Math.js";
9
+ import { boxSurfaceArea, intersectRay, intersectSegment } from "./AABB3Math.js";
10
10
  import { aabb3_build_corners } from "../../geom/3d/aabb/aabb3_build_corners.js";
11
11
  import { assert } from "../../assert.js";
12
+ import { aabb3_intersects_frustum_degree } from "./aabb3_intersects_frustum_degree.js";
12
13
 
13
14
 
14
15
  /**
@@ -81,7 +82,7 @@ AABB3.prototype.computeMortonCode = function () {
81
82
  * @returns {number}
82
83
  */
83
84
  AABB3.prototype.computeSurfaceArea = function () {
84
- return _boxSurfaceArea2(this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
85
+ return boxSurfaceArea(this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
85
86
  };
86
87
 
87
88
  /**
@@ -296,7 +297,8 @@ AABB3.prototype.costForInclusion = function (other) {
296
297
  };
297
298
 
298
299
  /**
299
- *
300
+ * Surface area delta when including a given AABB
301
+ * 0 means that including a given AABB would not cause any change to total surface area
300
302
  * @param {number} x0
301
303
  * @param {number} y0
302
304
  * @param {number} z0
@@ -834,7 +836,7 @@ AABB3.prototype.intersectFrustumDegree = function (frustum) {
834
836
 
835
837
  let i = 0;
836
838
  let result = 2;
837
- for (i = 0; i < 6; i++) {
839
+ for (; i < 6; i++) {
838
840
 
839
841
  const plane = planes[i];
840
842
 
@@ -848,6 +850,16 @@ AABB3.prototype.intersectFrustumDegree = function (frustum) {
848
850
  }
849
851
  return result;
850
852
  };
853
+ /**
854
+ *
855
+ * @param {number[]} frustum
856
+ * @returns {number}
857
+ */
858
+ AABB3.prototype.intersectFrustumDegree_array = function (frustum) {
859
+ return aabb3_intersects_frustum_degree(
860
+ this.x0, this.y0, this.z0, this.x1, this.y1, this.z1, frustum
861
+ );
862
+ };
851
863
 
852
864
  /**
853
865
  *
@@ -866,6 +878,40 @@ AABB3.prototype.intersectFrustum = function intersectFrustum(frustum) {
866
878
  return true;
867
879
  };
868
880
 
881
+ /**
882
+ *
883
+ * @param {ArrayLike<number>|number[]|Float32Array}frustum
884
+ * @returns {boolean}
885
+ */
886
+ AABB3.prototype.intersectFrustum_array = function intersectFrustum(frustum) {
887
+ const x0 = this.x0;
888
+ const y0 = this.y0;
889
+ const z0 = this.z0;
890
+ const x1 = this.x1;
891
+ const y1 = this.y1;
892
+ const z1 = this.z1;
893
+
894
+ for (let i = 0; i < 24; i += 4) {
895
+
896
+ const p_nx = frustum[i];
897
+ const p_ny = frustum[i + 1];
898
+ const p_nz = frustum[i + 2];
899
+ const p_c = frustum[i + 3];
900
+
901
+ if (aabb3_computeDistanceAbovePlane(
902
+ p_nx, p_ny, p_nz, p_c,
903
+ x0, y0, z0,
904
+ x1, y1, z1
905
+ ) < 0) {
906
+ // below plane, i.e. outside of the frustum
907
+ return false;
908
+ }
909
+
910
+ }
911
+ return true;
912
+ };
913
+
914
+
869
915
  /**
870
916
  *
871
917
  * @param {number} v
@@ -1,5 +1,11 @@
1
1
  import { BinaryBuffer } from "../../binary/BinaryBuffer.js";
2
- import { AABB3, deserializeAABB3, deserializeAABB3Quantized16Uint, serializeAABB3, serializeAABB3Quantized16Uint } from "./AABB3.js";
2
+ import {
3
+ AABB3,
4
+ deserializeAABB3,
5
+ deserializeAABB3Quantized16Uint,
6
+ serializeAABB3,
7
+ serializeAABB3Quantized16Uint
8
+ } from "./AABB3.js";
3
9
 
4
10
 
5
11
  function compareBounds(expected, actual, numDigits = 10) {
@@ -182,3 +188,23 @@ test('isBelowPlane negative space and orthogonal planes', () => {
182
188
  expect(a._isBelowPlane(0, 0, -1, -4)).toBeTruthy();
183
189
  });
184
190
 
191
+ test('readFrom/writeTo Array consistency', () => {
192
+ const s = new AABB3(
193
+ 1, 2, 3, 4, 5, 6
194
+ );
195
+
196
+ const a = [];
197
+
198
+ s.writeToArray(a, 0);
199
+
200
+ expect(a).toEqual([1, 2, 3, 4, 5, 6]);
201
+
202
+ s.readFromArray(a, 0);
203
+
204
+ expect(s.x0).toEqual(1);
205
+ expect(s.y0).toEqual(2);
206
+ expect(s.z0).toEqual(3);
207
+ expect(s.x1).toEqual(4);
208
+ expect(s.y1).toEqual(5);
209
+ expect(s.z1).toEqual(6);
210
+ });
@@ -540,7 +540,7 @@ function boxSurfaceArea(x0, y0, z0, x1, y1, z1) {
540
540
  const dx = x1 - x0;
541
541
  const dy = y1 - y0;
542
542
  const dz = z1 - z0;
543
- return (dx * dy + dy * dz + dz * dx) * 2; //2 of each side
543
+ return (dy * (dx + dz) + dz * dx) * 2; //2 of each side
544
544
  }
545
545
 
546
546
  /**
@@ -0,0 +1,34 @@
1
+ import { min2 } from "../../math/min2.js";
2
+ import { max2 } from "../../math/max2.js";
3
+
4
+ /**
5
+ *
6
+ * @param {AABB3} result
7
+ * @param {number[]|ArrayLike<number>} input
8
+ * @param {number} input_length
9
+ */
10
+ export function aabb3_from_v3_array(result, input, input_length) {
11
+ let x0 = Infinity;
12
+ let y0 = Infinity;
13
+ let z0 = Infinity;
14
+
15
+ let x1 = -Infinity;
16
+ let y1 = -Infinity;
17
+ let z1 = -Infinity;
18
+
19
+ for (let i = 0; i < input_length; i += 3) {
20
+ const x = input[i];
21
+ const y = input[i + 1];
22
+ const z = input[i + 2];
23
+
24
+ x0 = min2(x, x0);
25
+ y0 = min2(y, y0);
26
+ z0 = min2(z, z0);
27
+
28
+ x1 = max2(x, x1);
29
+ y1 = max2(y, y1);
30
+ z1 = max2(z, z1);
31
+ }
32
+
33
+ result.setBounds(x0, y0, z0, x1, y1, z1);
34
+ }
@@ -0,0 +1,39 @@
1
+ import { min2 } from "../../math/min2.js";
2
+ import { max2 } from "../../math/max2.js";
3
+
4
+ /**
5
+ *
6
+ * @param {AABB3} result
7
+ * @param {number[]|ArrayLike<number>} input
8
+ * @param {number} input_length
9
+ * @param {ArrayLike<number>|number[]|Float32Array} e 4x4 transformation matrix
10
+ */
11
+ export function aabb3_from_v3_array_transformed(result, input, input_length, e) {
12
+ let x0 = Infinity;
13
+ let y0 = Infinity;
14
+ let z0 = Infinity;
15
+
16
+ let x1 = -Infinity;
17
+ let y1 = -Infinity;
18
+ let z1 = -Infinity;
19
+
20
+ for (let i = 0; i < input_length; i += 3) {
21
+ const x = input[i];
22
+ const y = input[i + 1];
23
+ const z = input[i + 2];
24
+
25
+ const _x = e[0] * x + e[4] * y + e[8] * z + e[12];
26
+ const _y = e[1] * x + e[5] * y + e[9] * z + e[13];
27
+ const _z = e[2] * x + e[6] * y + e[10] * z + e[14];
28
+
29
+ x0 = min2(_x, x0);
30
+ y0 = min2(_y, y0);
31
+ z0 = min2(_z, z0);
32
+
33
+ x1 = max2(_x, x1);
34
+ y1 = max2(_y, y1);
35
+ z1 = max2(_z, z1);
36
+ }
37
+
38
+ result.setBounds(x0, y0, z0, x1, y1, z1);
39
+ }