@woosh/meep-engine 2.75.0 → 2.75.2
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.
- package/build/meep.cjs +21 -18
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +21 -18
- package/package.json +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.spec.js +75 -0
- package/src/core/events/signal/SignalBinding.js +18 -16
- package/src/core/model/ObservedBoolean.js +1 -1
- package/src/engine/intelligence/behavior/SelectorBehavior.js +4 -3
- package/src/engine/intelligence/behavior/SelectorBehavior.spec.js +18 -0
package/build/meep.module.js
CHANGED
|
@@ -69794,30 +69794,37 @@ class ImageRGBADataLoader extends AssetLoader {
|
|
|
69794
69794
|
}
|
|
69795
69795
|
|
|
69796
69796
|
/**
|
|
69797
|
-
*
|
|
69798
|
-
* @copyright Alex Goldring 2018
|
|
69797
|
+
* Utility class for managing connection between listeners to signals
|
|
69799
69798
|
*/
|
|
69799
|
+
class SignalBinding {
|
|
69800
|
+
/**
|
|
69801
|
+
* State flag
|
|
69802
|
+
* @type {boolean}
|
|
69803
|
+
*/
|
|
69804
|
+
#linked = false;
|
|
69800
69805
|
|
|
69806
|
+
get linked() {
|
|
69807
|
+
return this.#linked;
|
|
69808
|
+
}
|
|
69801
69809
|
|
|
69802
|
-
class SignalBinding {
|
|
69803
69810
|
/**
|
|
69804
69811
|
*
|
|
69805
69812
|
* @param {Signal} signal
|
|
69806
69813
|
* @param {function} handler
|
|
69807
|
-
* @param {*} [context]
|
|
69814
|
+
* @param {*} [context] will be passed as thisArg to the handler
|
|
69808
69815
|
* @constructor
|
|
69809
69816
|
*/
|
|
69810
69817
|
constructor(signal, handler, context) {
|
|
69811
69818
|
if (typeof handler !== "function") {
|
|
69812
|
-
throw new TypeError(`handler must be a function, instead was ${handler}`);
|
|
69819
|
+
throw new TypeError(`handler must be a function, instead was '${typeof handler}'`);
|
|
69813
69820
|
}
|
|
69814
69821
|
|
|
69815
69822
|
if (typeof signal !== "object") {
|
|
69816
|
-
throw new TypeError(`signal must be of an object, instead was ${signal}`)
|
|
69823
|
+
throw new TypeError(`signal must be of an object, instead was '${typeof signal}'`)
|
|
69817
69824
|
}
|
|
69818
69825
|
|
|
69819
69826
|
if (typeof signal.add !== "function") {
|
|
69820
|
-
throw new TypeError(`signal.add must be a function, instead was ${signal.add}`);
|
|
69827
|
+
throw new TypeError(`signal.add must be a function, instead was '${typeof signal.add}'`);
|
|
69821
69828
|
}
|
|
69822
69829
|
|
|
69823
69830
|
/**
|
|
@@ -69838,11 +69845,6 @@ class SignalBinding {
|
|
|
69838
69845
|
*/
|
|
69839
69846
|
this.context = context;
|
|
69840
69847
|
|
|
69841
|
-
/**
|
|
69842
|
-
* State flag
|
|
69843
|
-
* @type {boolean}
|
|
69844
|
-
*/
|
|
69845
|
-
this.linked = false;
|
|
69846
69848
|
}
|
|
69847
69849
|
|
|
69848
69850
|
/**
|
|
@@ -69850,11 +69852,11 @@ class SignalBinding {
|
|
|
69850
69852
|
* Idempotent
|
|
69851
69853
|
*/
|
|
69852
69854
|
link() {
|
|
69853
|
-
if (this
|
|
69855
|
+
if (this.#linked) {
|
|
69854
69856
|
return;
|
|
69855
69857
|
}
|
|
69856
69858
|
|
|
69857
|
-
this
|
|
69859
|
+
this.#linked = true;
|
|
69858
69860
|
this.signal.add(this.handler, this.context);
|
|
69859
69861
|
}
|
|
69860
69862
|
|
|
@@ -69863,11 +69865,11 @@ class SignalBinding {
|
|
|
69863
69865
|
* Idempotent
|
|
69864
69866
|
*/
|
|
69865
69867
|
unlink() {
|
|
69866
|
-
if (!this
|
|
69868
|
+
if (!this.#linked) {
|
|
69867
69869
|
return;
|
|
69868
69870
|
}
|
|
69869
69871
|
|
|
69870
|
-
this
|
|
69872
|
+
this.#linked = false;
|
|
69871
69873
|
this.signal.remove(this.handler, this.context);
|
|
69872
69874
|
}
|
|
69873
69875
|
}
|
|
@@ -70347,7 +70349,7 @@ class ObservedBoolean extends Boolean {
|
|
|
70347
70349
|
|
|
70348
70350
|
/**
|
|
70349
70351
|
*
|
|
70350
|
-
* @param {function} f
|
|
70352
|
+
* @param {function(boolean)} f
|
|
70351
70353
|
*/
|
|
70352
70354
|
process(f) {
|
|
70353
70355
|
f(this.__value);
|
|
@@ -117811,6 +117813,7 @@ class SelectorBehavior extends CompositeBehavior {
|
|
|
117811
117813
|
}
|
|
117812
117814
|
|
|
117813
117815
|
initialize(context) {
|
|
117816
|
+
|
|
117814
117817
|
const children = this.__children;
|
|
117815
117818
|
|
|
117816
117819
|
if (children.length > 0) {
|
|
@@ -117818,7 +117821,7 @@ class SelectorBehavior extends CompositeBehavior {
|
|
|
117818
117821
|
this.__currentBehaviourIndex = 0;
|
|
117819
117822
|
this.__currentBehaviour = children[0];
|
|
117820
117823
|
|
|
117821
|
-
this.__currentBehaviour.initialize(
|
|
117824
|
+
this.__currentBehaviour.initialize(context);
|
|
117822
117825
|
|
|
117823
117826
|
} else {
|
|
117824
117827
|
// no children
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { aabb3_unsigned_distance_sqr_to_point } from "../../../geom/3d/aabb/aabb3_unsigned_distance_sqr_to_point.js";
|
|
1
2
|
import { randomFloatBetween } from "../../../math/random/randomFloatBetween.js";
|
|
2
3
|
import { seededRandom } from "../../../math/random/seededRandom.js";
|
|
3
4
|
import { BVH } from "../BVH.js";
|
|
@@ -131,4 +132,78 @@ test.skip("performance, 1M random boxes, 10k queries", () => {
|
|
|
131
132
|
const duration = (t1 - t0);
|
|
132
133
|
|
|
133
134
|
console.log(`${duration / SAMPLE_POINT_COUNT}ms/query`);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test.skip('naive search, 1m random boxes, 10k queries', () => {
|
|
138
|
+
|
|
139
|
+
const random = seededRandom(1);
|
|
140
|
+
|
|
141
|
+
const OBJECT_COUNT = 1000000;
|
|
142
|
+
|
|
143
|
+
const boxes = new Float32Array(OBJECT_COUNT * 6);
|
|
144
|
+
|
|
145
|
+
const min_bound = -1000;
|
|
146
|
+
const max_bound = 1000;
|
|
147
|
+
|
|
148
|
+
const extents = 25;
|
|
149
|
+
|
|
150
|
+
for (let i = 0; i < OBJECT_COUNT; i++) {
|
|
151
|
+
const address = i * 6;
|
|
152
|
+
|
|
153
|
+
const x = randomFloatBetween(random, min_bound, max_bound);
|
|
154
|
+
const y = randomFloatBetween(random, min_bound, max_bound);
|
|
155
|
+
const z = randomFloatBetween(random, min_bound, max_bound);
|
|
156
|
+
|
|
157
|
+
boxes[address] = x - extents;
|
|
158
|
+
boxes[address + 1] = y - extents;
|
|
159
|
+
boxes[address + 2] = z - extents;
|
|
160
|
+
|
|
161
|
+
boxes[address + 3] = x + extents;
|
|
162
|
+
boxes[address + 4] = y + extents;
|
|
163
|
+
boxes[address + 5] = z + extents;
|
|
164
|
+
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function naive_query(boxes, count, x, y, z) {
|
|
168
|
+
let best_distance_sqr = Infinity;
|
|
169
|
+
let best_index = 0;
|
|
170
|
+
|
|
171
|
+
const limit = count * 6;
|
|
172
|
+
|
|
173
|
+
for (let i = 0; i < limit; i += 6) {
|
|
174
|
+
const distance_sqr = aabb3_unsigned_distance_sqr_to_point(
|
|
175
|
+
boxes[i], boxes[i + 1], boxes[i + 2],
|
|
176
|
+
boxes[i + 3], boxes[i + 4], boxes[i + 5],
|
|
177
|
+
|
|
178
|
+
x, y, z
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
if (distance_sqr < best_distance_sqr) {
|
|
182
|
+
best_index = i;
|
|
183
|
+
best_distance_sqr = distance_sqr;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return best_index;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const SAMPLE_POINT_COUNT = 10000;
|
|
191
|
+
|
|
192
|
+
const t0 = performance.now();
|
|
193
|
+
|
|
194
|
+
for (let i = 0; i < SAMPLE_POINT_COUNT; i++) {
|
|
195
|
+
|
|
196
|
+
const x = randomFloatBetween(random, min_bound, max_bound);
|
|
197
|
+
const y = randomFloatBetween(random, min_bound, max_bound);
|
|
198
|
+
const z = randomFloatBetween(random, min_bound, max_bound);
|
|
199
|
+
|
|
200
|
+
naive_query(boxes, OBJECT_COUNT, x, y, z);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const t1 = performance.now();
|
|
204
|
+
|
|
205
|
+
const duration = (t1 - t0);
|
|
206
|
+
|
|
207
|
+
console.log(`${duration / SAMPLE_POINT_COUNT}ms/query`);
|
|
208
|
+
|
|
134
209
|
});
|
|
@@ -1,28 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @copyright Alex Goldring 2018
|
|
2
|
+
* Utility class for managing connection between listeners to signals
|
|
4
3
|
*/
|
|
4
|
+
export class SignalBinding {
|
|
5
|
+
/**
|
|
6
|
+
* State flag
|
|
7
|
+
* @type {boolean}
|
|
8
|
+
*/
|
|
9
|
+
#linked = false;
|
|
5
10
|
|
|
11
|
+
get linked() {
|
|
12
|
+
return this.#linked;
|
|
13
|
+
}
|
|
6
14
|
|
|
7
|
-
export class SignalBinding {
|
|
8
15
|
/**
|
|
9
16
|
*
|
|
10
17
|
* @param {Signal} signal
|
|
11
18
|
* @param {function} handler
|
|
12
|
-
* @param {*} [context]
|
|
19
|
+
* @param {*} [context] will be passed as thisArg to the handler
|
|
13
20
|
* @constructor
|
|
14
21
|
*/
|
|
15
22
|
constructor(signal, handler, context) {
|
|
16
23
|
if (typeof handler !== "function") {
|
|
17
|
-
throw new TypeError(`handler must be a function, instead was ${handler}`);
|
|
24
|
+
throw new TypeError(`handler must be a function, instead was '${typeof handler}'`);
|
|
18
25
|
}
|
|
19
26
|
|
|
20
27
|
if (typeof signal !== "object") {
|
|
21
|
-
throw new TypeError(`signal must be of an object, instead was ${signal}`)
|
|
28
|
+
throw new TypeError(`signal must be of an object, instead was '${typeof signal}'`)
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
if (typeof signal.add !== "function") {
|
|
25
|
-
throw new TypeError(`signal.add must be a function, instead was ${signal.add}`);
|
|
32
|
+
throw new TypeError(`signal.add must be a function, instead was '${typeof signal.add}'`);
|
|
26
33
|
}
|
|
27
34
|
|
|
28
35
|
/**
|
|
@@ -43,11 +50,6 @@ export class SignalBinding {
|
|
|
43
50
|
*/
|
|
44
51
|
this.context = context;
|
|
45
52
|
|
|
46
|
-
/**
|
|
47
|
-
* State flag
|
|
48
|
-
* @type {boolean}
|
|
49
|
-
*/
|
|
50
|
-
this.linked = false;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
/**
|
|
@@ -55,11 +57,11 @@ export class SignalBinding {
|
|
|
55
57
|
* Idempotent
|
|
56
58
|
*/
|
|
57
59
|
link() {
|
|
58
|
-
if (this
|
|
60
|
+
if (this.#linked) {
|
|
59
61
|
return;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
this
|
|
64
|
+
this.#linked = true;
|
|
63
65
|
this.signal.add(this.handler, this.context);
|
|
64
66
|
}
|
|
65
67
|
|
|
@@ -68,11 +70,11 @@ export class SignalBinding {
|
|
|
68
70
|
* Idempotent
|
|
69
71
|
*/
|
|
70
72
|
unlink() {
|
|
71
|
-
if (!this
|
|
73
|
+
if (!this.#linked) {
|
|
72
74
|
return;
|
|
73
75
|
}
|
|
74
76
|
|
|
75
|
-
this
|
|
77
|
+
this.#linked = false;
|
|
76
78
|
this.signal.remove(this.handler, this.context);
|
|
77
79
|
}
|
|
78
80
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CompositeBehavior } from "./composite/CompositeBehavior.js";
|
|
2
|
-
import { BehaviorStatus } from "./BehaviorStatus.js";
|
|
3
1
|
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import { BehaviorStatus } from "./BehaviorStatus.js";
|
|
3
|
+
import { CompositeBehavior } from "./composite/CompositeBehavior.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Will try every child behaviour in order until one succeeds or if all fail - the selector behavior will fail too
|
|
@@ -83,6 +83,7 @@ export class SelectorBehavior extends CompositeBehavior {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
initialize(context) {
|
|
86
|
+
|
|
86
87
|
const children = this.__children;
|
|
87
88
|
|
|
88
89
|
if (children.length > 0) {
|
|
@@ -90,7 +91,7 @@ export class SelectorBehavior extends CompositeBehavior {
|
|
|
90
91
|
this.__currentBehaviourIndex = 0;
|
|
91
92
|
this.__currentBehaviour = children[0];
|
|
92
93
|
|
|
93
|
-
this.__currentBehaviour.initialize(
|
|
94
|
+
this.__currentBehaviour.initialize(context);
|
|
94
95
|
|
|
95
96
|
} else {
|
|
96
97
|
// no children
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Behavior } from "./Behavior.js";
|
|
2
|
+
import { SelectorBehavior } from "./SelectorBehavior.js";
|
|
3
|
+
|
|
4
|
+
test("correctly passes context to children during initialization", () => {
|
|
5
|
+
|
|
6
|
+
const child = new Behavior();
|
|
7
|
+
|
|
8
|
+
const selector = SelectorBehavior.from([
|
|
9
|
+
child
|
|
10
|
+
]);
|
|
11
|
+
|
|
12
|
+
const ctx = { a: 7 };
|
|
13
|
+
|
|
14
|
+
selector.initialize(ctx)
|
|
15
|
+
|
|
16
|
+
expect(child.context).toEqual(ctx);
|
|
17
|
+
|
|
18
|
+
});
|