@woosh/meep-engine 2.34.34 → 2.34.35

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.
@@ -541,11 +541,12 @@ BinaryNode.prototype.bubbleRefit = function () {
541
541
  n = n.parentNode;
542
542
 
543
543
  if (n === null) {
544
+ // hit the root
544
545
  return;
545
546
  }
546
547
 
547
- //check if this node violates bounds of the parent
548
548
 
549
+ //check if this node violates bounds of the parent
549
550
  let flag = false;
550
551
 
551
552
  if (_x0 < n.x0) {
@@ -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
  }
@@ -1,8 +1,7 @@
1
- import { boxSurfaceArea2 as computeArea, scoreBoxesSAH as computeAreaFor2 } from "../aabb3/AABB3Math.js";
2
1
  import { BinaryNode } from "../BinaryNode.js";
3
2
  import { isLeaf } from "../LeafNode.js";
4
- import { surfaceAreaHeuristic as sah } from "../sah/surfaceAreaHeuristic.js";
5
3
  import { StacklessTraverser } from "../StacklessTraverser.js";
4
+ import { tryRotateSingleNode } from "./tryRotateSingleNode.js";
6
5
 
7
6
 
8
7
  /**
@@ -73,266 +72,12 @@ function getLeafCount(node, leafCounts) {
73
72
  return result;
74
73
  }
75
74
 
76
- /**
77
- *
78
- * @param {Node} node
79
- * @param {BinaryNode} parent
80
- */
81
- function setParent(node, parent) {
82
- node.parentNode = parent;
83
- }
84
-
85
- /**
86
- * Based on paper "Fast, Effective BVH Updates for Animated Scenes" Kopta et. al. (url: http://www.cs.utah.edu/~thiago/papers/rotations.pdf)
87
- * @param {BinaryNode} node
88
- * @param {Map.<NodeDescription,int>} leafCounts
89
- * @returns {int} value from 0 to 6, 0 means no rotation has taken place
90
- */
91
- function tryRotateSingleNode(node, leafCounts) {
92
-
93
-
94
- const left = node.left;
95
- const right = node.right;
96
-
97
- if (left === null || right === null) {
98
- return 0;
99
- }
100
-
101
- let bestRotation = 0;
102
-
103
-
104
- const nodeArea = computeArea(node);
105
- const leftArea = computeArea(left);
106
- const rightArea = computeArea(right);
107
-
108
- const leftLeaves = left.leafNodeCount;
109
- const rightLeaves = right.leafNodeCount;
110
-
111
-
112
- let bestCost = sah(
113
- nodeArea,
114
- leftArea,
115
- rightArea,
116
- leftLeaves,
117
- rightLeaves
118
- );
119
-
120
- let candidateCost;
121
-
122
- let leftLeftArea,
123
- leftRightArea,
124
- rightLeftArea,
125
- rightRightArea;
126
-
127
- let leftLeft,
128
- leftRight,
129
- rightLeft,
130
- rightRight;
131
-
132
- let leftLeftLeaves,
133
- leftRightLeaves,
134
- rightLeftLeaves,
135
- rightRightLeaves;
136
-
137
- let considerLeft = !isLeaf(left);
138
-
139
- if (considerLeft) {
140
- leftLeft = left.left;
141
- leftRight = left.right;
142
-
143
- considerLeft = (leftLeft !== null && leftRight !== null);
144
- if (considerLeft) {
145
-
146
- leftLeftArea = computeArea(leftLeft);
147
- leftRightArea = computeArea(leftRight);
148
-
149
- leftLeftLeaves = leftLeft.leafNodeCount;
150
- leftRightLeaves = leftRight.leafNodeCount;
151
-
152
- // (1) N N //
153
- // / \ / \ //
154
- // L R -----> L LL //
155
- // / \ / \ //
156
- // LL LR R LR //
157
- candidateCost = sah(nodeArea, computeAreaFor2(right, leftRight), leftLeftArea, rightLeaves + leftRightLeaves, leftLeftLeaves);
158
-
159
- if (candidateCost < bestCost) {
160
- bestRotation = 1;
161
- bestCost = candidateCost;
162
- }
163
-
164
- // (2) N N //
165
- // / \ / \ //
166
- // L R -----> L LR //
167
- // / \ / \ //
168
- // LL LR LL R //
169
- candidateCost = sah(nodeArea, computeAreaFor2(leftLeft, right), leftRightArea, leftLeftLeaves + rightLeaves, leftRightLeaves);
170
-
171
-
172
- if (candidateCost < bestCost) {
173
- bestRotation = 2;
174
- bestCost = candidateCost;
175
- }
176
- }
177
- }
178
- if (!isLeaf(right)) {
179
- rightLeft = right.left;
180
- rightRight = right.right;
181
- if (rightLeft !== null && rightRight !== null) {
182
-
183
- rightLeftArea = computeArea(rightLeft);
184
- rightRightArea = computeArea(rightRight);
185
-
186
- rightLeftLeaves = rightLeft.leafNodeCount;
187
- rightRightLeaves = rightRight.leafNodeCount;
188
-
189
- // (3) N N //
190
- // / \ / \ //
191
- // L R -----> RL R //
192
- // / \ / \ //
193
- // RL RR L RR //
194
- candidateCost = sah(nodeArea, rightLeftArea, computeAreaFor2(left, rightRight), rightLeftLeaves, leftLeaves + rightRightLeaves);
195
-
196
- if (candidateCost < bestCost) {
197
- bestRotation = 3;
198
- bestCost = candidateCost;
199
- }
200
-
201
- // (4) N N //
202
- // / \ / \ //
203
- // L R -----> RR R //
204
- // / \ / \ //
205
- // RL RR RL L //
206
- candidateCost = sah(nodeArea, rightRightArea, computeAreaFor2(rightLeft, left), rightRightLeaves, rightLeftLeaves + leftLeaves);
207
-
208
-
209
- if (candidateCost < bestCost) {
210
- bestRotation = 4;
211
- bestCost = candidateCost;
212
- }
213
-
214
- if (considerLeft) {
215
- //both child nodes are not leaf
216
-
217
- // (5) N N //
218
- // / \ / \ //
219
- // L R -----> L R //
220
- // / \ / \ / \ / \ //
221
- // LL LR RL RR LL RL LR RR //
222
- candidateCost = sah(
223
- nodeArea,
224
- computeAreaFor2(leftLeft, rightLeft),
225
- computeAreaFor2(leftRight, rightRight),
226
- leftLeftLeaves + rightLeftLeaves,
227
- leftRightLeaves + rightRightLeaves
228
- );
229
-
230
-
231
- if (candidateCost < bestCost) {
232
- bestRotation = 5;
233
- bestCost = candidateCost;
234
- }
235
-
236
- // (6) N N //
237
- // / \ / \ //
238
- // L R -----> L R //
239
- // / \ / \ / \ / \ //
240
- // LL LR RL RR LL RR RL LR //
241
- candidateCost = sah(
242
- nodeArea,
243
- computeAreaFor2(leftLeft, rightRight),
244
- computeAreaFor2(rightLeft, leftRight),
245
- leftLeftLeaves + rightRightLeaves,
246
- rightLeftLeaves + leftRightLeaves
247
- );
248
-
249
- if (candidateCost < bestCost) {
250
- bestRotation = 6;
251
- }
252
- }
253
- }
254
- }
255
-
256
- switch (bestRotation) {
257
- case 0:
258
- //no rotation
259
- break;
260
- case 1:
261
- node.right = leftLeft;
262
- setParent(leftLeft, node);
263
- left.left = right;
264
- setParent(right, left);
265
-
266
- left.refit();
267
- //update leaf count
268
- node.left.updateLeafNodeCount();
269
- break;
270
- case 2:
271
- node.right = leftRight;
272
- setParent(leftRight, node);
273
- left.right = right;
274
- setParent(right, left);
275
-
276
- left.refit();
277
- //update leaf count
278
- node.left.updateLeafNodeCount();
279
- break;
280
- case 3:
281
- node.left = rightLeft;
282
- setParent(rightLeft, node);
283
- right.left = left;
284
- setParent(left, right);
285
-
286
- right.refit();
287
- //update leaf count
288
- node.right.updateLeafNodeCount();
289
- break;
290
- case 4:
291
- node.left = rightRight;
292
- setParent(rightRight, node);
293
- right.right = left;
294
- setParent(left, right);
295
-
296
- right.refit();
297
- //update leaf count
298
- node.right.updateLeafNodeCount();
299
- break;
300
- case 5:
301
- left.right = rightLeft;
302
- setParent(rightLeft, left);
303
- right.left = leftRight;
304
- setParent(leftRight, right);
305
-
306
- left.refit();
307
- right.refit();
308
-
309
- //update leaf count
310
- node.left.updateLeafNodeCount();
311
- node.right.updateLeafNodeCount();
312
- break;
313
- case 6:
314
- left.right = rightRight;
315
- setParent(rightRight, left);
316
- right.right = leftRight;
317
- setParent(leftRight, right);
318
-
319
- left.refit();
320
- right.refit();
321
- //update leaf count
322
- node.left.updateLeafNodeCount();
323
- node.right.updateLeafNodeCount();
324
- break;
325
- }
326
-
327
- return bestRotation;
328
- }
329
-
330
75
  /**
331
76
  *
332
77
  * @param {BinaryNode} root
333
78
  * @param {int} maxIterations
334
79
  */
335
- function optimize(root, maxIterations = 1000) {
80
+ export function optimize(root, maxIterations = 1000) {
336
81
  const traverser = new StacklessTraverser();
337
82
 
338
83
  traverser.init(root);
@@ -376,8 +121,3 @@ function optimize(root, maxIterations = 1000) {
376
121
 
377
122
  return changeCounter;
378
123
  }
379
-
380
- export {
381
- optimize,
382
- tryRotateSingleNode
383
- };
@@ -0,0 +1,259 @@
1
+ import { boxSurfaceArea2 as computeArea, scoreBoxesSAH as computeAreaFor2 } from "../aabb3/AABB3Math.js";
2
+ import { surfaceAreaHeuristic as sah } from "../sah/surfaceAreaHeuristic.js";
3
+ import { isLeaf } from "../LeafNode.js";
4
+
5
+ /**
6
+ *
7
+ * @param {Node} node
8
+ * @param {BinaryNode} parent
9
+ */
10
+ function setParent(node, parent) {
11
+ node.parentNode = parent;
12
+ }
13
+
14
+ /**
15
+ * Based on paper "Fast, Effective BVH Updates for Animated Scenes" Kopta et. al. (url: http://www.cs.utah.edu/~thiago/papers/rotations.pdf)
16
+ * @param {BinaryNode} node
17
+ * @returns {int} value from 0 to 6, 0 means no rotation has taken place
18
+ */
19
+ export function tryRotateSingleNode(node) {
20
+
21
+ const left = node.left;
22
+ const right = node.right;
23
+
24
+ if (left === null || right === null) {
25
+ return 0;
26
+ }
27
+
28
+ /*
29
+ First we compute best rotation to apply, enumerated by 0-6
30
+ */
31
+
32
+ let bestRotation = 0;
33
+
34
+
35
+ const nodeArea = computeArea(node);
36
+ const leftArea = computeArea(left);
37
+ const rightArea = computeArea(right);
38
+
39
+ const leftLeaves = left.leafNodeCount;
40
+ const rightLeaves = right.leafNodeCount;
41
+
42
+
43
+ let bestCost = sah(
44
+ nodeArea,
45
+ leftArea,
46
+ rightArea,
47
+ leftLeaves,
48
+ rightLeaves
49
+ );
50
+
51
+ let candidateCost;
52
+
53
+ let leftLeftArea,
54
+ leftRightArea,
55
+ rightLeftArea,
56
+ rightRightArea;
57
+
58
+ let leftLeft,
59
+ leftRight,
60
+ rightLeft,
61
+ rightRight;
62
+
63
+ let leftLeftLeaves,
64
+ leftRightLeaves,
65
+ rightLeftLeaves,
66
+ rightRightLeaves;
67
+
68
+ let considerLeft = !isLeaf(left);
69
+
70
+ if (considerLeft) {
71
+ leftLeft = left.left;
72
+ leftRight = left.right;
73
+
74
+ considerLeft = (leftLeft !== null && leftRight !== null);
75
+ if (considerLeft) {
76
+
77
+ leftLeftArea = computeArea(leftLeft);
78
+ leftRightArea = computeArea(leftRight);
79
+
80
+ leftLeftLeaves = leftLeft.leafNodeCount;
81
+ leftRightLeaves = leftRight.leafNodeCount;
82
+
83
+ // (1) N N //
84
+ // / \ / \ //
85
+ // L R -----> L LL //
86
+ // / \ / \ //
87
+ // LL LR R LR //
88
+ candidateCost = sah(nodeArea, computeAreaFor2(right, leftRight), leftLeftArea, rightLeaves + leftRightLeaves, leftLeftLeaves);
89
+
90
+ if (candidateCost < bestCost) {
91
+ bestRotation = 1;
92
+ bestCost = candidateCost;
93
+ }
94
+
95
+ // (2) N N //
96
+ // / \ / \ //
97
+ // L R -----> L LR //
98
+ // / \ / \ //
99
+ // LL LR LL R //
100
+ candidateCost = sah(nodeArea, computeAreaFor2(leftLeft, right), leftRightArea, leftLeftLeaves + rightLeaves, leftRightLeaves);
101
+
102
+
103
+ if (candidateCost < bestCost) {
104
+ bestRotation = 2;
105
+ bestCost = candidateCost;
106
+ }
107
+ }
108
+ }
109
+ if (!isLeaf(right)) {
110
+ rightLeft = right.left;
111
+ rightRight = right.right;
112
+ if (rightLeft !== null && rightRight !== null) {
113
+
114
+ rightLeftArea = computeArea(rightLeft);
115
+ rightRightArea = computeArea(rightRight);
116
+
117
+ rightLeftLeaves = rightLeft.leafNodeCount;
118
+ rightRightLeaves = rightRight.leafNodeCount;
119
+
120
+ // (3) N N //
121
+ // / \ / \ //
122
+ // L R -----> RL R //
123
+ // / \ / \ //
124
+ // RL RR L RR //
125
+ candidateCost = sah(nodeArea, rightLeftArea, computeAreaFor2(left, rightRight), rightLeftLeaves, leftLeaves + rightRightLeaves);
126
+
127
+ if (candidateCost < bestCost) {
128
+ bestRotation = 3;
129
+ bestCost = candidateCost;
130
+ }
131
+
132
+ // (4) N N //
133
+ // / \ / \ //
134
+ // L R -----> RR R //
135
+ // / \ / \ //
136
+ // RL RR RL L //
137
+ candidateCost = sah(nodeArea, rightRightArea, computeAreaFor2(rightLeft, left), rightRightLeaves, rightLeftLeaves + leftLeaves);
138
+
139
+
140
+ if (candidateCost < bestCost) {
141
+ bestRotation = 4;
142
+ bestCost = candidateCost;
143
+ }
144
+
145
+ if (considerLeft) {
146
+ //both child nodes are not leaf
147
+
148
+ // (5) N N //
149
+ // / \ / \ //
150
+ // L R -----> L R //
151
+ // / \ / \ / \ / \ //
152
+ // LL LR RL RR LL RL LR RR //
153
+ candidateCost = sah(
154
+ nodeArea,
155
+ computeAreaFor2(leftLeft, rightLeft),
156
+ computeAreaFor2(leftRight, rightRight),
157
+ leftLeftLeaves + rightLeftLeaves,
158
+ leftRightLeaves + rightRightLeaves
159
+ );
160
+
161
+
162
+ if (candidateCost < bestCost) {
163
+ bestRotation = 5;
164
+ bestCost = candidateCost;
165
+ }
166
+
167
+ // (6) N N //
168
+ // / \ / \ //
169
+ // L R -----> L R //
170
+ // / \ / \ / \ / \ //
171
+ // LL LR RL RR LL RR RL LR //
172
+ candidateCost = sah(
173
+ nodeArea,
174
+ computeAreaFor2(leftLeft, rightRight),
175
+ computeAreaFor2(rightLeft, leftRight),
176
+ leftLeftLeaves + rightRightLeaves,
177
+ rightLeftLeaves + leftRightLeaves
178
+ );
179
+
180
+ if (candidateCost < bestCost) {
181
+ bestRotation = 6;
182
+ }
183
+ }
184
+ }
185
+ }
186
+
187
+ switch (bestRotation) {
188
+ case 0:
189
+ //no rotation
190
+ break;
191
+ case 1:
192
+ node.right = leftLeft;
193
+ setParent(leftLeft, node);
194
+ left.left = right;
195
+ setParent(right, left);
196
+
197
+ left.refit();
198
+ //update leaf count
199
+ node.left.updateLeafNodeCount();
200
+ break;
201
+ case 2:
202
+ node.right = leftRight;
203
+ setParent(leftRight, node);
204
+ left.right = right;
205
+ setParent(right, left);
206
+
207
+ left.refit();
208
+ //update leaf count
209
+ node.left.updateLeafNodeCount();
210
+ break;
211
+ case 3:
212
+ node.left = rightLeft;
213
+ setParent(rightLeft, node);
214
+ right.left = left;
215
+ setParent(left, right);
216
+
217
+ right.refit();
218
+ //update leaf count
219
+ node.right.updateLeafNodeCount();
220
+ break;
221
+ case 4:
222
+ node.left = rightRight;
223
+ setParent(rightRight, node);
224
+ right.right = left;
225
+ setParent(left, right);
226
+
227
+ right.refit();
228
+ //update leaf count
229
+ node.right.updateLeafNodeCount();
230
+ break;
231
+ case 5:
232
+ left.right = rightLeft;
233
+ setParent(rightLeft, left);
234
+ right.left = leftRight;
235
+ setParent(leftRight, right);
236
+
237
+ left.refit();
238
+ right.refit();
239
+
240
+ //update leaf count
241
+ node.left.updateLeafNodeCount();
242
+ node.right.updateLeafNodeCount();
243
+ break;
244
+ case 6:
245
+ left.right = rightRight;
246
+ setParent(rightRight, left);
247
+ right.right = leftRight;
248
+ setParent(leftRight, right);
249
+
250
+ left.refit();
251
+ right.refit();
252
+ //update leaf count
253
+ node.left.updateLeafNodeCount();
254
+ node.right.updateLeafNodeCount();
255
+ break;
256
+ }
257
+
258
+ return bestRotation;
259
+ }
@@ -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,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);
@@ -18,7 +18,17 @@ export class AttachmentSockets {
18
18
  * @returns {AttachmentSocket|undefined}
19
19
  */
20
20
  get(id) {
21
- return this.elements.find(s => s.id === id);
21
+ const elements = this.elements;
22
+ const n = elements.length;
23
+
24
+ for (let i = 0; i < n; i++) {
25
+ const socket = elements.get(i);
26
+
27
+ if (socket.id === id) {
28
+ return socket;
29
+ }
30
+ }
31
+
22
32
  }
23
33
 
24
34
  /**
@@ -46,9 +46,15 @@ async function main(engine) {
46
46
 
47
47
  const three_object = asset.create();
48
48
 
49
+ console.time('composition conversion');
49
50
  const composition = three_object_to_entity_composition(three_object);
51
+ console.timeEnd('composition conversion');
50
52
 
53
+ console.time('composition build');
54
+ // console.profile('composition build');
51
55
  composition.build(ecd);
56
+ // console.profileEnd('composition build');
57
+ console.timeEnd('composition build');
52
58
  }
53
59
 
54
60
  init(eh);
@@ -14,11 +14,11 @@ import { BinaryNode } from "../../../../core/bvh2/BinaryNode.js";
14
14
  import SoundListener from "../SoundListener.js";
15
15
  import { IncrementalDeltaSet } from "../../../graphics/render/visibility/IncrementalDeltaSet.js";
16
16
  import { queryBinaryNode_SphereIntersections_Data } from "../../../../core/bvh2/traversal/queryBinaryNode_SphereIntersections.js";
17
- import { tryRotateSingleNode } from "../../../../core/bvh2/transform/RotationOptimizer.js";
18
17
  import { SoundEmitterComponentContext } from "./SoundEmitterComponentContext.js";
19
18
  import { SoundEmitterFlags } from "./SoundEmitterFlags.js";
20
19
  import { SoundEmitterChannel } from "./SoundEmitterChannel.js";
21
20
  import { invokeObjectCompare } from "../../../../core/model/object/invokeObjectCompare.js";
21
+ import { tryRotateSingleNode } from "../../../../core/bvh2/transform/tryRotateSingleNode.js";
22
22
 
23
23
  /**
24
24
  * @readonly
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "productName": "Meep",
6
6
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.34.34",
8
+ "version": "2.34.35",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",