@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
@@ -0,0 +1,52 @@
1
+ /**
2
+ *
3
+ * @type {(BinaryNode|LeafNode)[]}
4
+ */
5
+ const stack = [];
6
+
7
+
8
+ /**
9
+ * @template T
10
+ * @param {T[]} destination
11
+ * @param {number} destinationOffset
12
+ * @param {BinaryNode<T>} root
13
+ * @param {ArrayLike<number>|number[]|Float32Array} frustum
14
+ * @returns {number} Number of results
15
+ */
16
+ export function queryBinaryNode_FrustumIntersections_Data(destination, destinationOffset, root, frustum) {
17
+ let n;
18
+ let i = 0;
19
+ let stackPointer = 1;
20
+
21
+ stack[0] = root;
22
+
23
+ while (stackPointer > 0) {
24
+ stackPointer--;
25
+
26
+ n = stack[stackPointer];
27
+
28
+ if (!n.intersectFrustum_array(frustum)) {
29
+ continue;
30
+ }
31
+
32
+ if (n.isBinaryNode) {
33
+
34
+ if (n.right !== null) {
35
+ stack[stackPointer++] = n.right;
36
+ }
37
+
38
+ if (n.left !== null) {
39
+ stack[stackPointer++] = n.left;
40
+ }
41
+
42
+ } else {
43
+
44
+ destination[destinationOffset + i] = n.object;
45
+
46
+ i++;
47
+ }
48
+
49
+ }
50
+
51
+ return i;
52
+ }
@@ -719,40 +719,6 @@ List.prototype.copy = function (other) {
719
719
  }
720
720
  };
721
721
 
722
- /**
723
- *
724
- * @param {List} other
725
- * @param {function} elementComparator
726
- * @returns {number} -1, 0 or 1
727
- */
728
- List.prototype.compare = function (other, elementComparator) {
729
- const thisLength = this.length;
730
- const otherLength = other.length;
731
-
732
- const deltaLength = thisLength - otherLength;
733
-
734
- if (deltaLength !== 0) {
735
- return deltaLength;
736
- }
737
-
738
- for (let i = 0; i < thisLength; i++) {
739
- const thisElement = this.get(i);
740
- const otherElement = other.get(i);
741
-
742
- if (thisElement === otherElement) {
743
- continue;
744
- }
745
-
746
- const elementDelta = elementComparator(thisElement, otherElement);
747
-
748
- if (elementDelta !== 0) {
749
- return elementDelta;
750
- }
751
- }
752
-
753
- return 0;
754
- };
755
-
756
722
  /**
757
723
  * NOTE: do not modify resulting array
758
724
  * @returns {T[]}
@@ -162,7 +162,7 @@ export class Signal {
162
162
  * @param {*} [context]
163
163
  */
164
164
  add(h, context) {
165
- assert.typeOf(h, "function", "handler");
165
+ assert.isFunction(h, "handler");
166
166
 
167
167
  // if (!ENV_PRODUCTION) {
168
168
  // if (this.handlers.length + 1 === 100) {
@@ -1,8 +1,7 @@
1
-
2
1
  /**
3
2
  * NOTE: Based on Transforming Axis-Aligned Bounding Boxes by Jim Arvo from "Graphics Gems", Academic Press, 1990
4
- * @param {number[]} result
5
- * @param {number[]} aabb
3
+ * @param {ArrayLike<number>|number[]|Float32Array} result
4
+ * @param {ArrayLike<number>|number[]|Float32Array} aabb
6
5
  * @param {number[]} matrix 4x4 matrix
7
6
  */
8
7
  export function aabb3_matrix4_project(result, aabb, matrix) {
@@ -15,7 +14,7 @@ export function aabb3_matrix4_project(result, aabb, matrix) {
15
14
  for (let i = 0; i < 3; i++) {
16
15
  for (let j = 0; j < 3; j++) {
17
16
 
18
- const m_a = i * 4 + j;
17
+ const m_a = i + j * 4;
19
18
  const m_v = matrix[m_a];
20
19
 
21
20
  const a = m_v * aabb[j];
@@ -1,4 +1,7 @@
1
1
  import { aabb3_matrix4_project } from "./aabb3_matrix4_project.js";
2
+ import { compose_matrix4_array } from "../../../../engine/graphics/util/composeMatrix4.js";
3
+ import Vector3 from "../../Vector3.js";
4
+ import Quaternion from "../../Quaternion.js";
2
5
 
3
6
  test('identity', () => {
4
7
  const r = [];
@@ -39,3 +42,13 @@ test('scale case', () => {
39
42
 
40
43
  expect(r).toEqual([-5, 4, -27, -1, 14, -9]);
41
44
  });
45
+
46
+ test('translation + scale case', () => {
47
+ const m4 = [];
48
+ compose_matrix4_array(m4, new Vector3(-1, 2, -3), Quaternion.identity, new Vector3(7, -11, 13));
49
+
50
+ const r = [];
51
+ aabb3_matrix4_project(r, [1, 2, 3, 5, 7, 9], m4);
52
+
53
+ expect(r).toEqual([6, -75, 36, 34, -20, 114]);
54
+ });
@@ -95,9 +95,8 @@ export function computeTriangleRayIntersection(
95
95
  // Line intersects triangle, check if ray does.
96
96
  const QdN = -sign * v3_dot(diff_x, diff_y, diff_z, normal_x, normal_y, normal_z);
97
97
 
98
- // t < 0, no intersection
99
98
  if (QdN < 0) {
100
-
99
+ // t < 0, no intersection
101
100
  return false;
102
101
 
103
102
  }
@@ -22,4 +22,6 @@ export default class Quaternion {
22
22
  threeSetRotationMatrix(result: Matrix4): void
23
23
 
24
24
  setFromRotationMatrix(m: Matrix4): void
25
+
26
+ decodeFromUint32(uint: number): void
25
27
  }
@@ -523,21 +523,25 @@ class Vector3 {
523
523
  /**
524
524
  *
525
525
  * @param {THREE.Matrix4} matrix4
526
- * @returns {Vector3}
527
526
  */
528
527
  applyMatrix4_three(matrix4) {
528
+ this.applyMatrix4(matrix4.elements);
529
+ }
529
530
 
531
+ /**
532
+ *
533
+ * @param {ArrayList<number>|number[]|Float32Array} m4
534
+ */
535
+ applyMatrix4(m4) {
530
536
  const x = this.x;
531
537
  const y = this.y;
532
538
  const z = this.z;
533
539
 
534
- const e = matrix4.elements;
535
-
536
- const _x = e[0] * x + e[4] * y + e[8] * z + e[12];
537
- const _y = e[1] * x + e[5] * y + e[9] * z + e[13];
538
- const _z = e[2] * x + e[6] * y + e[10] * z + e[14];
540
+ const _x = m4[0] * x + m4[4] * y + m4[8] * z + m4[12];
541
+ const _y = m4[1] * x + m4[5] * y + m4[9] * z + m4[13];
542
+ const _z = m4[2] * x + m4[6] * y + m4[10] * z + m4[14];
539
543
 
540
- return this.set(_x, _y, _z);
544
+ this.set(_x, _y, _z);
541
545
  }
542
546
 
543
547
  /**
@@ -589,11 +593,18 @@ class Vector3 {
589
593
  * @param {THREE.Matrix4} matrix4
590
594
  */
591
595
  threejs_setFromMatrixPosition(matrix4) {
592
- const e = matrix4.elements;
596
+ this.setFromMatrixPosition(matrix4.elements);
597
+ }
598
+
599
+ /**
600
+ *
601
+ * @param {ArrayLike<number>|number[]|Float32Array} matrix4 4x4 transform matrix
602
+ */
603
+ setFromMatrixPosition(matrix4) {
593
604
 
594
- const _x = e[12];
595
- const _y = e[13];
596
- const _z = e[14];
605
+ const _x = matrix4[12];
606
+ const _y = matrix4[13];
607
+ const _z = matrix4[14];
597
608
 
598
609
  this.set(_x, _y, _z);
599
610
  }
@@ -1,5 +1,6 @@
1
1
  import { Asset } from "../Asset.js";
2
2
  import { AssetLoader } from "./AssetLoader.js";
3
+ import { CrossOriginKind } from "../CORS/CrossOriginKind.js";
3
4
 
4
5
  export class ArrayBufferLoader extends AssetLoader {
5
6
  load(path, success, failure, progress) {
@@ -8,6 +9,12 @@ export class ArrayBufferLoader extends AssetLoader {
8
9
  xhr.open('GET', path, true);
9
10
  xhr.responseType = "arraybuffer";
10
11
 
12
+ const coc = this.assetManager.crossOriginConfig;
13
+
14
+ if (coc.kind === CrossOriginKind.UseCredentials) {
15
+ xhr.withCredentials = true;
16
+ }
17
+
11
18
  xhr.addEventListener('load', function () {
12
19
  if (xhr.readyState === xhr.DONE && xhr.status === 200) {
13
20
  const arrayBuffer = xhr.response;
@@ -4,11 +4,11 @@ import { GameAssetType } from "../../GameAssetType.js";
4
4
  import { convertTexture2Sampler2D } from "../../../graphics/texture/sampler/convertTexture2Sampler2D.js";
5
5
  import { ImageRGBADataAsset } from "./ImageRGBADataAsset.js";
6
6
  import { ArrayBufferLoader } from "../ArrayBufferLoader.js";
7
- import { noop } from "../../../../core/function/Functions.js";
8
7
  import { CodecWithFallback } from "./codec/CodecWithFallback.js";
9
8
  import { ThreadedImageDecoder } from "./codec/ThreadedImageDecoder.js";
10
9
  import { NativeImageDecoder } from "./codec/NativeImageDecoder.js";
11
10
 
11
+ const ASSET_TYPE_ARRAY_BUFFER = "arraybuffer";
12
12
 
13
13
  export class ImageRGBADataLoader extends AssetLoader {
14
14
  constructor() {
@@ -20,6 +20,15 @@ export class ImageRGBADataLoader extends AssetLoader {
20
20
  );
21
21
  }
22
22
 
23
+ async link(assetManager, engine) {
24
+
25
+ if (assetManager.getLoaderByType(ASSET_TYPE_ARRAY_BUFFER) === undefined) {
26
+ assetManager.registerLoader(ASSET_TYPE_ARRAY_BUFFER, new ArrayBufferLoader());
27
+ }
28
+
29
+ super.link(assetManager, engine);
30
+ }
31
+
23
32
  /**
24
33
  *
25
34
  * @param {string} path
@@ -27,11 +36,7 @@ export class ImageRGBADataLoader extends AssetLoader {
27
36
  * @private
28
37
  */
29
38
  async __decode_via_worker(path) {
30
- const loader = new ArrayBufferLoader();
31
-
32
- const asset = await new Promise((resolve, reject) => {
33
- loader.load(path, resolve, reject, noop);
34
- });
39
+ const asset = await this.assetManager.promise(path, ASSET_TYPE_ARRAY_BUFFER);
35
40
 
36
41
  /**
37
42
  * @type {ArrayBuffer}
@@ -132,7 +132,7 @@ class EntityBuilder {
132
132
  throw new Error("Can not add " + componentInstance + " to EntityBuilder");
133
133
  }
134
134
 
135
- assert.notOk(this.getComponent(componentInstance.__proto__.constructor) !== null, `Component of this type already exists`);
135
+ assert.notOk(this.getComponent(componentInstance.__proto__.constructor) !== null, 'Component of this type already exists');
136
136
 
137
137
  this.element.push(componentInstance);
138
138
 
@@ -150,12 +150,16 @@ class EntityBuilder {
150
150
  * @returns {T|null} component of specified class
151
151
  */
152
152
  getComponent(klass) {
153
- for (let i = 0; i < this.element.length; i++) {
154
- const component = this.element[i];
153
+ const elements = this.element;
154
+ const element_count = elements.length;
155
+
156
+ for (let i = 0; i < element_count; i++) {
157
+ const component = elements[i];
155
158
  if (component instanceof klass) {
156
159
  return component;
157
160
  }
158
161
  }
162
+
159
163
  return null;
160
164
  }
161
165
 
@@ -314,7 +318,10 @@ class EntityBuilder {
314
318
  assert.defined(dataset, "dataset");
315
319
  assert.notNull(dataset, "dataset");
316
320
 
317
- if (this.getFlag(EntityBuilderFlags.Built) && checkExistingComponents(this.entity, this.element, dataset)) {
321
+ if (
322
+ this.getFlag(EntityBuilderFlags.Built)
323
+ && checkExistingComponents(this.entity, this.element, dataset)
324
+ ) {
318
325
  //already built
319
326
  return this.entity;
320
327
  }
@@ -322,7 +329,7 @@ class EntityBuilder {
322
329
  const entity = this.entity = dataset.createEntity();
323
330
  this.dataset = dataset;
324
331
 
325
- let i, l;
332
+ let i;
326
333
 
327
334
  const listeners = this.deferredListeners;
328
335
  const listeners_count = listeners.length;
@@ -122,6 +122,13 @@ export class EntityComponentDataset {
122
122
  */
123
123
  this.componentTypeMap = [];
124
124
 
125
+ /**
126
+ * Fast index lookup from a component class
127
+ * @type {Map<Class, number>}
128
+ * @private
129
+ */
130
+ this.__type_to_index_map = new Map();
131
+
125
132
  /**
126
133
  * How many component types exist for this collection. This is the same as componentMap.length
127
134
  * @private
@@ -605,6 +612,13 @@ export class EntityComponentDataset {
605
612
  updateObservers(indexRemapping);
606
613
 
607
614
  this.componentTypeMap = map;
615
+
616
+ // rebuild class->index lookup
617
+ this.__type_to_index_map.clear();
618
+ for (let i = 0; i < newComponentTypeCount; i++) {
619
+ this.__type_to_index_map.set(map[i], i);
620
+ }
621
+
608
622
  this.componentTypeCount = newComponentTypeCount;
609
623
  }
610
624
 
@@ -876,7 +890,13 @@ export class EntityComponentDataset {
876
890
  * @returns {number}
877
891
  */
878
892
  computeComponentTypeIndex(klass) {
879
- return this.componentTypeMap.indexOf(klass);
893
+ const idx = this.__type_to_index_map.get(klass);
894
+
895
+ if (idx === undefined) {
896
+ return -1;
897
+ }
898
+
899
+ return idx;
880
900
  }
881
901
 
882
902
  /**
@@ -926,16 +946,16 @@ export class EntityComponentDataset {
926
946
  addComponentToEntity(entityIndex, componentInstance) {
927
947
 
928
948
  if (!ENV_PRODUCTION) {
929
- assert.notEqual(componentInstance, null, "componentInstance is null");
949
+ assert.notNull(componentInstance, "componentInstance");
930
950
 
931
- assert.notEqual(componentInstance, undefined, "componentInstance is undefined");
951
+ assert.defined(componentInstance, "componentInstance");
932
952
  }
933
953
 
934
954
  const klass = componentInstance.constructor;
935
955
 
936
- const componentTypeIndex = this.componentTypeMap.indexOf(klass);
956
+ const componentTypeIndex = this.__type_to_index_map.get(klass);
937
957
 
938
- if (componentTypeIndex === -1) {
958
+ if (typeof componentTypeIndex !== "number") {
939
959
 
940
960
 
941
961
  throw new Error(`Component class not found in this dataset for componentInstance ${stringifyComponent(componentInstance)}`);
@@ -1509,7 +1529,7 @@ export class EntityComponentDataset {
1509
1529
  sendEvent(entity, name, event) {
1510
1530
  // console.log("sendEvent", entity, name, event);
1511
1531
 
1512
- assert.typeOf(name, "string", "name");
1532
+ assert.isString(name, "name");
1513
1533
 
1514
1534
  dispatchEntityEventListeners(this.__entityEventListeners, entity, name, event);
1515
1535
 
@@ -175,7 +175,7 @@ export class AttachmentSystem extends System {
175
175
 
176
176
  const boneName = attachmentSocket.boneName;
177
177
 
178
- assert.typeOf(boneName, 'string', 'boneName');
178
+ assert.isString(boneName, 'boneName');
179
179
 
180
180
  //try to get the bone
181
181
  const mesh = ecd.getComponent(parent, Mesh);
@@ -8,7 +8,6 @@ const scratch_m4_2 = new Float32Array(16);
8
8
  export class TransformAttachmentBinding extends AttachmentBinding {
9
9
  constructor() {
10
10
  super();
11
-
12
11
  }
13
12
 
14
13
  /**
@@ -5,28 +5,13 @@ export class FoliageVisibilitySetBuilder extends BVHVisitor {
5
5
  constructor() {
6
6
  super();
7
7
 
8
- /**
9
- * Visibility filters
10
- * @type {(function(LeafNode):boolean)[]}
11
- */
12
- this.filters = [];
13
-
14
8
  /**
15
9
  *
16
10
  * @type {BitSet}
17
11
  */
18
12
  this.visibleSet = new BitSet();
19
13
  //prevent re-allocation
20
- this.visibleSet.__shrinkFactor = 0;
21
- }
22
-
23
- /**
24
- *
25
- * @param {(function(LeafNode):boolean)[]} filters
26
- */
27
- setFilters(filters) {
28
- this.filters = filters;
29
- this.filterCount = filters.length;
14
+ this.visibleSet.preventShrink();
30
15
  }
31
16
 
32
17
  initialize() {
@@ -34,21 +19,6 @@ export class FoliageVisibilitySetBuilder extends BVHVisitor {
34
19
  }
35
20
 
36
21
  visitLeaf(node) {
37
-
38
- const n = this.filterCount;
39
-
40
- const filters = this.filters;
41
-
42
- for (let i = 0; i < n; i++) {
43
- const visibilityFilter = filters[i];
44
-
45
- if (!visibilityFilter(node)) {
46
- //not visible
47
- return;
48
- }
49
-
50
- }
51
-
52
22
  const index = node.object;
53
23
 
54
24
  //TODO check screen space size to decide if element should be seen or not