@woosh/meep-engine 2.62.0 → 2.64.0
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 +1061 -1058
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +1061 -1058
- package/package.json +1 -1
- package/src/core/binary/EncodingBinaryBuffer.js +7 -43
- package/src/core/binary/EncodingBinaryBuffer.spec.js +16 -0
- package/src/core/binary/UINT16_MAX.js +5 -0
- package/src/core/bvh2/bvh3/EBBVHLeafProxy.js +4 -2
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +5 -5
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +8 -10
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +7 -7
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsSphere.js +37 -0
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +12 -4
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.spec.js +29 -0
- package/src/core/cache/LoadingCache.js +4 -1
- package/src/core/collection/list/List.js +9 -3
- package/src/core/collection/map/BiMap.js +49 -0
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +11 -4
- package/src/core/geom/Vector2.js +6 -4
- package/src/engine/ecs/components/Tag.d.ts +2 -0
- package/src/engine/ecs/components/Tag.js +19 -28
- package/src/engine/ecs/components/Tag.spec.js +47 -0
- package/src/engine/ecs/fow/FogOfWar.js +4 -0
- package/src/engine/ecs/fow/FogOfWarEditor.js +3 -0
- package/src/engine/ecs/terrain/TerrainPreview.js +45 -44
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrain.js +22 -4
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +17 -12
- package/src/engine/graphics/ecs/mesh/Mesh.d.ts +0 -4
- package/src/engine/graphics/ecs/mesh/Mesh.js +0 -11
- package/src/engine/graphics/ecs/mesh/MeshSystem.js +57 -67
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +49 -86
- package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +41 -72
- package/src/engine/graphics/particles/particular/engine/emitter/write_particle_patch_uv.js +28 -0
- package/src/engine/grid/ORTHOGONAL_NEIGHBOURHOOD_MASK.js +11 -0
- package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +17 -17
- package/src/core/binary/stringToByteArray.js +0 -24
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.js +0 -81
- package/src/engine/ecs/foliage/Foliage.js +0 -151
- package/src/engine/ecs/foliage/FoliageLoader.js +0 -39
- package/src/engine/ecs/foliage/FoliageVisibilitySetBuilder.js +0 -27
- package/src/engine/ecs/foliage/ImpostorFoliage.js +0 -106
- package/src/engine/ecs/foliage/InstancedFoliage.js +0 -395
- package/src/engine/ecs/foliage/ViewState.js +0 -181
- package/src/engine/ecs/foliage/ecs/Foliage2System.js +0 -333
- package/src/engine/ecs/foliage/ecs/InstancedMeshComponent.js +0 -70
- package/src/engine/ecs/foliage/ecs/InstancedMeshLayer.js +0 -138
- package/src/engine/ecs/foliage/ecs/InstancedMeshSerializationAdapter.js +0 -28
- package/src/engine/ecs/foliage/ecs/convertInstancedMeshComponents2Entities.js +0 -64
- package/src/engine/ecs/foliage/ecs/optimizeIndividualMeshesEntitiesToInstances.js +0 -233
- package/src/engine/save/storage/GooglePlayStorage.js +0 -47
- package/src/engine/save/storage/JsonStringCodec.js +0 -24
- package/src/engine/save/storage/LocalStorage.js +0 -148
- package/src/engine/save/storage/MsgPackCodec.js +0 -22
- /package/src/engine/sound/ecs/emitter/{SoundEmitter.spec.js → SoundEmitterSerializationAdapter.spec.js} +0 -0
package/package.json
CHANGED
|
@@ -1,58 +1,22 @@
|
|
|
1
|
+
import { BiMap } from "../collection/map/BiMap.js";
|
|
1
2
|
import { BinaryBuffer } from "./BinaryBuffer.js";
|
|
2
3
|
|
|
3
|
-
class
|
|
4
|
-
constructor() {
|
|
5
|
-
this.forward = new Map();
|
|
6
|
-
this.backward = new Map();
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* @param {*} value
|
|
12
|
-
* @param {number} address
|
|
13
|
-
*/
|
|
14
|
-
add(value, address) {
|
|
15
|
-
this.forward.set(address, value);
|
|
16
|
-
this.backward.set(value, address);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
* @param {*} value
|
|
22
|
-
* @returns {number|undefined}
|
|
23
|
-
*/
|
|
24
|
-
getAddress(value) {
|
|
25
|
-
return this.backward.get(value);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
*
|
|
30
|
-
* @param {number} address
|
|
31
|
-
* @returns {*}
|
|
32
|
-
*/
|
|
33
|
-
getValue(address) {
|
|
34
|
-
return this.forward.get(address);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
4
|
+
export class EncodingBinaryBuffer extends BinaryBuffer {
|
|
37
5
|
|
|
6
|
+
__dictionary = new BiMap();
|
|
38
7
|
|
|
39
|
-
export class EncodingBinaryBuffer extends BinaryBuffer {
|
|
40
|
-
constructor() {
|
|
41
|
-
super();
|
|
42
|
-
this.__dictionary = new Dictionary();
|
|
43
|
-
}
|
|
44
8
|
|
|
45
9
|
writeUTF8String(value) {
|
|
46
|
-
const address = this.__dictionary.
|
|
10
|
+
const address = this.__dictionary.getKeyByValue(value);
|
|
47
11
|
|
|
48
12
|
if (address === undefined) {
|
|
49
13
|
this.writeUint8(0); //mark as complete value
|
|
50
14
|
|
|
51
|
-
const
|
|
15
|
+
const current_address = this.position;
|
|
52
16
|
|
|
53
17
|
super.writeUTF8String(value);
|
|
54
18
|
|
|
55
|
-
this.__dictionary.add(value,
|
|
19
|
+
this.__dictionary.add(value, current_address);
|
|
56
20
|
} else {
|
|
57
21
|
//write as reference
|
|
58
22
|
this.writeUint32LE(1 | (address << 1));
|
|
@@ -72,7 +36,7 @@ export class EncodingBinaryBuffer extends BinaryBuffer {
|
|
|
72
36
|
|
|
73
37
|
const address = header >> 1;
|
|
74
38
|
|
|
75
|
-
let value = this.__dictionary.
|
|
39
|
+
let value = this.__dictionary.getValueByKey(address);
|
|
76
40
|
|
|
77
41
|
if (value === undefined) {
|
|
78
42
|
//remember position
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EncodingBinaryBuffer } from "./EncodingBinaryBuffer.js";
|
|
2
|
+
|
|
3
|
+
test("read/write strings", () => {
|
|
4
|
+
|
|
5
|
+
const buffer = new EncodingBinaryBuffer();
|
|
6
|
+
|
|
7
|
+
buffer.writeUTF8String("hello world");
|
|
8
|
+
buffer.writeUTF8String("cat");
|
|
9
|
+
buffer.writeUTF8String("hello world");
|
|
10
|
+
|
|
11
|
+
buffer.position = 0;
|
|
12
|
+
|
|
13
|
+
expect(buffer.readUTF8String()).toEqual("hello world");
|
|
14
|
+
expect(buffer.readUTF8String()).toEqual("cat");
|
|
15
|
+
expect(buffer.readUTF8String()).toEqual("hello world");
|
|
16
|
+
});
|
|
@@ -50,8 +50,10 @@ export class EBBVHLeafProxy {
|
|
|
50
50
|
unlink() {
|
|
51
51
|
assert.equal(this.is_linked, true, 'not linked');
|
|
52
52
|
|
|
53
|
-
this.#
|
|
54
|
-
|
|
53
|
+
const node_id = this.#node_id;
|
|
54
|
+
|
|
55
|
+
this.#tree.remove_leaf(node_id);
|
|
56
|
+
this.#tree.release_node(node_id);
|
|
55
57
|
|
|
56
58
|
this.#node_id = -1;
|
|
57
59
|
this.#tree = null;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { aabb3_compute_surface_area } from "../../geom/3d/aabb/aabb3_compute_surface_area.js";
|
|
2
|
-
import { min2 } from "../../math/min2.js";
|
|
3
|
-
import { max2 } from "../../math/max2.js";
|
|
4
1
|
import { assert } from "../../assert.js";
|
|
5
|
-
import { typed_array_copy } from "../../collection/array/typed/typed_array_copy.js";
|
|
6
2
|
import { array_copy } from "../../collection/array/array_copy.js";
|
|
3
|
+
import { typed_array_copy } from "../../collection/array/typed/typed_array_copy.js";
|
|
4
|
+
import { aabb3_compute_surface_area } from "../../geom/3d/aabb/aabb3_compute_surface_area.js";
|
|
5
|
+
import { max2 } from "../../math/max2.js";
|
|
6
|
+
import { min2 } from "../../math/min2.js";
|
|
7
7
|
|
|
8
8
|
export const COLUMN_PARENT = 6;
|
|
9
9
|
export const COLUMN_CHILD_1 = 7;
|
|
@@ -373,7 +373,7 @@ export class ExplicitBinaryBoundingVolumeHierarchy {
|
|
|
373
373
|
/**
|
|
374
374
|
*
|
|
375
375
|
* @param {number} id
|
|
376
|
-
* @param {number[]} result
|
|
376
|
+
* @param {number[]|Float32Array} result
|
|
377
377
|
*/
|
|
378
378
|
node_get_aabb(id, result) {
|
|
379
379
|
assert.isNonNegativeInteger(id, 'id');
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import { BVHQuery } from "./BVHQuery.js";
|
|
2
1
|
import { aabb3_array_intersects_frustum_array } from "../../../geom/3d/aabb/aabb3_array_intersects_frustum_array.js";
|
|
2
|
+
import { BVHQuery } from "./BVHQuery.js";
|
|
3
3
|
|
|
4
4
|
const scratch_aabb = [];
|
|
5
5
|
|
|
6
6
|
export class BVHQueryIntersectsFrustum extends BVHQuery {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.frustum = [];
|
|
15
|
-
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Collection of 6 planes: normal_x, normal_y, normal_z, offset
|
|
10
|
+
* @type {number[]}
|
|
11
|
+
*/
|
|
12
|
+
frustum = [];
|
|
13
|
+
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
*
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { BVHQuery } from "./BVHQuery.js";
|
|
2
1
|
import { aabb3_array_intersects_ray_array } from "../../../geom/3d/aabb/aabb3_array_intersects_ray_array.js";
|
|
2
|
+
import { BVHQuery } from "./BVHQuery.js";
|
|
3
3
|
|
|
4
4
|
const scratch_aabb = [];
|
|
5
5
|
|
|
6
6
|
export class BVHQueryIntersectsRay extends BVHQuery {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @type {number[]}
|
|
10
|
+
*/
|
|
11
|
+
ray = [];
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
*
|
|
15
15
|
* @param {number[]|ArrayLike<number>} ray
|
|
16
16
|
* @returns {BVHQueryIntersectsRay}
|
|
17
17
|
*/
|
|
18
|
-
static from(ray){
|
|
18
|
+
static from(ray) {
|
|
19
19
|
const r = new BVHQueryIntersectsRay();
|
|
20
20
|
|
|
21
21
|
r.ray = ray;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { aabb3_array_intersects_sphere_array } from "../../../geom/3d/aabb/aabb3_array_intersects_sphere_array.js";
|
|
2
|
+
import { BVHQuery } from "./BVHQuery.js";
|
|
3
|
+
|
|
4
|
+
const scratch_aabb = [];
|
|
5
|
+
|
|
6
|
+
export class BVHQueryIntersectsSphere extends BVHQuery {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @type {number[]}
|
|
11
|
+
*/
|
|
12
|
+
sphere = [];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param {number[]|ArrayLike<number>} sphere
|
|
17
|
+
* @returns {BVHQueryIntersectsRay}
|
|
18
|
+
*/
|
|
19
|
+
static from(sphere) {
|
|
20
|
+
const r = new BVHQueryIntersectsSphere();
|
|
21
|
+
|
|
22
|
+
r.sphere = sphere;
|
|
23
|
+
|
|
24
|
+
return r;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
evaluate(node, tree) {
|
|
28
|
+
|
|
29
|
+
tree.node_get_aabb(node, scratch_aabb);
|
|
30
|
+
|
|
31
|
+
// test node against the ray
|
|
32
|
+
return aabb3_array_intersects_sphere_array(
|
|
33
|
+
scratch_aabb,
|
|
34
|
+
this.sphere
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assert } from "../../../assert.js";
|
|
2
2
|
import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
|
|
3
|
+
import { NULL_NODE } from "../ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
3
4
|
|
|
4
5
|
const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
5
6
|
|
|
@@ -15,9 +16,15 @@ const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
|
15
16
|
*/
|
|
16
17
|
export function bvh_query_user_data_generic(
|
|
17
18
|
result, result_offset,
|
|
18
|
-
bvh,root, query
|
|
19
|
+
bvh, root, query
|
|
19
20
|
) {
|
|
20
21
|
|
|
22
|
+
assert.isArrayLike(result, 'result');
|
|
23
|
+
assert.isNonNegativeInteger(result_offset, 'result_offset');
|
|
24
|
+
assert.defined(bvh, 'bvh');
|
|
25
|
+
assert.isNonNegativeInteger(root, 'root');
|
|
26
|
+
assert.defined(query, 'query');
|
|
27
|
+
|
|
21
28
|
if (root === NULL_NODE) {
|
|
22
29
|
return 0;
|
|
23
30
|
}
|
|
@@ -44,13 +51,14 @@ export function bvh_query_user_data_generic(
|
|
|
44
51
|
// test node against the query
|
|
45
52
|
const pass = query.evaluate(node, bvh);
|
|
46
53
|
|
|
47
|
-
if (
|
|
54
|
+
if (pass === false) {
|
|
48
55
|
continue;
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
const node_is_leaf = bvh.node_is_leaf(node);
|
|
52
59
|
|
|
53
|
-
if (
|
|
60
|
+
if (node_is_leaf === false) {
|
|
61
|
+
// binary-node
|
|
54
62
|
|
|
55
63
|
// read in-order
|
|
56
64
|
const child1 = bvh.node_get_child1(node);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ExplicitBinaryBoundingVolumeHierarchy } from "../ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
2
|
+
import { bvh_query_user_data_generic } from "./bvh_query_user_data_generic.js";
|
|
3
|
+
import { BVHQueryAny } from "./BVHQueryAny.js";
|
|
4
|
+
|
|
5
|
+
test("all-accepting query", () => {
|
|
6
|
+
const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
7
|
+
|
|
8
|
+
const leaf_a = bvh.allocate_node();
|
|
9
|
+
const leaf_b = bvh.allocate_node();
|
|
10
|
+
|
|
11
|
+
bvh.node_set_user_data(leaf_a, 7);
|
|
12
|
+
bvh.node_set_user_data(leaf_b, 13);
|
|
13
|
+
|
|
14
|
+
bvh.insert_leaf(leaf_a);
|
|
15
|
+
bvh.insert_leaf(leaf_b);
|
|
16
|
+
|
|
17
|
+
const result = [];
|
|
18
|
+
|
|
19
|
+
const count = bvh_query_user_data_generic(
|
|
20
|
+
result, 1,
|
|
21
|
+
bvh, bvh.root,
|
|
22
|
+
BVHQueryAny.INSTANCE
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
expect(count).toBe(2);
|
|
26
|
+
expect(result).toContain(7);
|
|
27
|
+
expect(result).toContain(13);
|
|
28
|
+
|
|
29
|
+
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
//
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { assert } from "../assert.js";
|
|
4
4
|
import { current_time_in_seconds } from "../time/current_time_in_seconds.js";
|
|
5
|
+
import { Cache } from "./Cache.js";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @template R
|
|
@@ -79,6 +80,8 @@ export class LoadingCache {
|
|
|
79
80
|
retryFailed = true
|
|
80
81
|
}) {
|
|
81
82
|
|
|
83
|
+
assert.isFunction(load, 'load');
|
|
84
|
+
|
|
82
85
|
this.#internal = new Cache({
|
|
83
86
|
maxWeight,
|
|
84
87
|
keyWeigher,
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
import { assert } from "../../assert.js";
|
|
7
7
|
import Signal from "../../events/signal/Signal.js";
|
|
8
8
|
import { invokeObjectEquals } from "../../model/object/invokeObjectEquals.js";
|
|
9
|
-
import { arraySetDiff } from "../array/arraySetDiff.js";
|
|
10
9
|
import { arrayIndexByEquality } from "../array/arrayIndexByEquality.js";
|
|
10
|
+
import { arraySetDiff } from "../array/arraySetDiff.js";
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -51,9 +51,12 @@ class List {
|
|
|
51
51
|
/**
|
|
52
52
|
* Retrieve element at a given position in the list
|
|
53
53
|
* @param {number} index
|
|
54
|
-
* @returns {T}
|
|
54
|
+
* @returns {T|undefined}
|
|
55
55
|
*/
|
|
56
56
|
get(index) {
|
|
57
|
+
assert.isNumber(index, 'index');
|
|
58
|
+
assert.isNonNegativeInteger(index, 'index');
|
|
59
|
+
|
|
57
60
|
return this.data[index];
|
|
58
61
|
}
|
|
59
62
|
|
|
@@ -63,6 +66,9 @@ class List {
|
|
|
63
66
|
* @param {T} value
|
|
64
67
|
*/
|
|
65
68
|
set(index, value) {
|
|
69
|
+
assert.isNumber(index, 'index');
|
|
70
|
+
assert.isNonNegativeInteger(index, 'index');
|
|
71
|
+
|
|
66
72
|
const oldValue = this.data[index];
|
|
67
73
|
|
|
68
74
|
if (oldValue !== undefined) {
|
|
@@ -183,7 +189,7 @@ class List {
|
|
|
183
189
|
/**
|
|
184
190
|
* Replace the data, replacements is performed surgically, meaning that diff is computed and add/remove operations are performed on the set
|
|
185
191
|
* This method is tailored to work well with visualisation as only elements that's missing from the new set is removed, and only elements that are new to are added
|
|
186
|
-
* Conversely, relevant events are dispatched that
|
|
192
|
+
* Conversely, relevant events are dispatched that can observe. This results in fewer changes required to the visualisation
|
|
187
193
|
* @param {T[]} newOutput
|
|
188
194
|
*/
|
|
189
195
|
patch(newOutput) {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bi-directional map
|
|
3
|
+
* @template K,V
|
|
4
|
+
*/
|
|
5
|
+
export class BiMap {
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @type {Map<K, V>}
|
|
10
|
+
*/
|
|
11
|
+
forward = new Map();
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @type {Map<V, K>}
|
|
15
|
+
*/
|
|
16
|
+
backward = new Map();
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {K} key
|
|
22
|
+
* @param {V} value
|
|
23
|
+
*/
|
|
24
|
+
add(key, value) {
|
|
25
|
+
this.forward.set(value, key);
|
|
26
|
+
this.backward.set(key, value);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param {V} value
|
|
32
|
+
* @returns {K|undefined}
|
|
33
|
+
*/
|
|
34
|
+
getKeyByValue(value) {
|
|
35
|
+
return this.backward.get(value);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @param {K} address
|
|
41
|
+
* @returns {V|undefined}
|
|
42
|
+
*/
|
|
43
|
+
getValueByKey(address) {
|
|
44
|
+
return this.forward.get(address);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
BiMap.prototype.get = BiMap.prototype.getValueByKey;
|
|
49
|
+
BiMap.prototype.set = BiMap.prototype.add;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { min2 } from "../../../math/min2.js";
|
|
2
|
-
import { max2 } from "../../../math/max2.js";
|
|
3
1
|
import { assert } from "../../../assert.js";
|
|
2
|
+
import { max2 } from "../../../math/max2.js";
|
|
3
|
+
import { min2 } from "../../../math/min2.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
7
|
-
* @param {AABB3} result
|
|
7
|
+
* @param {ArrayLike<number>|number[]|Float32Array|AABB3} result
|
|
8
8
|
* @param {number[]|ArrayLike<number>|Float32Array} input
|
|
9
9
|
* @param {number} input_length length of the input array
|
|
10
10
|
*/
|
|
@@ -33,5 +33,12 @@ export function aabb3_from_v3_array(result, input, input_length) {
|
|
|
33
33
|
z1 = max2(z, z1);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
// read out
|
|
37
|
+
result[0] = x0;
|
|
38
|
+
result[1] = y0;
|
|
39
|
+
result[2] = z0;
|
|
40
|
+
|
|
41
|
+
result[3] = x1;
|
|
42
|
+
result[4] = y1;
|
|
43
|
+
result[5] = z1;
|
|
37
44
|
}
|
package/src/core/geom/Vector2.js
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
import { assert } from "../assert.js";
|
|
7
7
|
import Signal from "../events/signal/Signal.js";
|
|
8
8
|
import { clamp } from "../math/clamp.js";
|
|
9
|
+
import { EPSILON } from "../math/EPSILON.js";
|
|
10
|
+
import { epsilonEquals } from "../math/epsilonEquals.js";
|
|
9
11
|
import { lerp } from "../math/lerp.js";
|
|
10
12
|
import { max2 } from "../math/max2.js";
|
|
11
13
|
import { min2 } from "../math/min2.js";
|
|
12
|
-
import {
|
|
13
|
-
import { epsilonEquals } from "../math/epsilonEquals.js";
|
|
14
|
+
import { computeHashFloat } from "../primitives/numbers/computeHashFloat.js";
|
|
14
15
|
|
|
15
16
|
class Vector2 {
|
|
16
17
|
/**
|
|
@@ -542,8 +543,8 @@ class Vector2 {
|
|
|
542
543
|
* @returns {number}
|
|
543
544
|
*/
|
|
544
545
|
hash() {
|
|
545
|
-
const x =
|
|
546
|
-
const y =
|
|
546
|
+
const x = computeHashFloat(this.x);
|
|
547
|
+
const y = computeHashFloat(this.y);
|
|
547
548
|
|
|
548
549
|
let hash = ((x << 5) - x) + y;
|
|
549
550
|
|
|
@@ -680,6 +681,7 @@ Vector2.one = Object.freeze(new Vector2(1, 1));
|
|
|
680
681
|
* @type {boolean}
|
|
681
682
|
*/
|
|
682
683
|
Vector2.prototype.isVector2 = true;
|
|
684
|
+
|
|
683
685
|
/**
|
|
684
686
|
*
|
|
685
687
|
* @param {number} x0
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
import { computeStringHash } from "../../../core/primitives/strings/computeStringHash.js";
|
|
7
6
|
import { assert } from "../../../core/assert.js";
|
|
7
|
+
import { isArrayEqualStrict } from "../../../core/collection/array/isArrayEqualStrict.js";
|
|
8
|
+
import { computeStringHash } from "../../../core/primitives/strings/computeStringHash.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Stores textual tags, useful for marking entities
|
|
@@ -12,7 +13,7 @@ import { assert } from "../../../core/assert.js";
|
|
|
12
13
|
export class Tag {
|
|
13
14
|
/**
|
|
14
15
|
* @private
|
|
15
|
-
* @type {
|
|
16
|
+
* @type {string[]}
|
|
16
17
|
*/
|
|
17
18
|
values = [];
|
|
18
19
|
|
|
@@ -194,41 +195,31 @@ export class Tag {
|
|
|
194
195
|
* @return {boolean}
|
|
195
196
|
*/
|
|
196
197
|
equals(other) {
|
|
197
|
-
|
|
198
|
-
const s0 = this.values;
|
|
199
|
-
|
|
200
|
-
const s1 = other.values;
|
|
201
|
-
|
|
202
|
-
const n0 = s0.length;
|
|
203
|
-
const n1 = s1.length;
|
|
204
|
-
|
|
205
|
-
if (n0 !== n1) {
|
|
206
|
-
//wrong length
|
|
207
|
-
return false;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
for (let i = 0; i < n0; i++) {
|
|
211
|
-
const v0 = s0[i];
|
|
212
|
-
const v1 = s1[i];
|
|
213
|
-
|
|
214
|
-
if (v0 !== v1) {
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return true;
|
|
198
|
+
return isArrayEqualStrict(this.values, other.values);
|
|
220
199
|
}
|
|
221
200
|
|
|
222
201
|
toJSON() {
|
|
223
202
|
return this.values;
|
|
224
203
|
}
|
|
225
204
|
|
|
205
|
+
/**
|
|
206
|
+
*
|
|
207
|
+
* @param {string[]|string} json
|
|
208
|
+
*/
|
|
226
209
|
fromJSON(json) {
|
|
210
|
+
|
|
211
|
+
this.clear();
|
|
212
|
+
|
|
227
213
|
if (typeof json === "string") {
|
|
228
|
-
this.clear();
|
|
229
214
|
this.add(json);
|
|
230
|
-
} else
|
|
231
|
-
|
|
215
|
+
} else {
|
|
216
|
+
assert.isArray(json, 'json');
|
|
217
|
+
|
|
218
|
+
const n = json.length;
|
|
219
|
+
|
|
220
|
+
for (let i = 0; i < n; i++) {
|
|
221
|
+
this.add(json[i]);
|
|
222
|
+
}
|
|
232
223
|
}
|
|
233
224
|
}
|
|
234
225
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import Tag from "./Tag.js";
|
|
2
|
+
|
|
3
|
+
test("constructor", () => {
|
|
4
|
+
new Tag();
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
test("containsOneOf", () => {
|
|
8
|
+
|
|
9
|
+
const tag = Tag.fromJSON(['a', 'b']);
|
|
10
|
+
|
|
11
|
+
expect(tag.containsOneOf([])).toBe(false);
|
|
12
|
+
expect(tag.containsOneOf(['c'])).toBe(false);
|
|
13
|
+
expect(tag.containsOneOf(['a'])).toBe(true);
|
|
14
|
+
expect(tag.containsOneOf(['b'])).toBe(true);
|
|
15
|
+
expect(tag.containsOneOf(['a', 'b'])).toBe(true);
|
|
16
|
+
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("hash", () => {
|
|
20
|
+
|
|
21
|
+
const tag = Tag.fromJSON(['a', 'b']);
|
|
22
|
+
|
|
23
|
+
const hash = tag.hash();
|
|
24
|
+
|
|
25
|
+
expect(tag.hash()).toEqual(hash);
|
|
26
|
+
|
|
27
|
+
expect(typeof hash).toBe("number");
|
|
28
|
+
expect(Number.isInteger(hash)).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("equals", () => {
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
const a = Tag.fromJSON(['a', 'b']);
|
|
35
|
+
const b = Tag.fromJSON([]);
|
|
36
|
+
const c = Tag.fromJSON(['a']);
|
|
37
|
+
const d = Tag.fromJSON(['b']);
|
|
38
|
+
const e = Tag.fromJSON(['a', 'b']);
|
|
39
|
+
const f = Tag.fromJSON(['a', 'c']);
|
|
40
|
+
|
|
41
|
+
expect(a.equals(b)).toBe(false);
|
|
42
|
+
expect(a.equals(c)).toBe(false);
|
|
43
|
+
expect(a.equals(d)).toBe(false);
|
|
44
|
+
expect(a.equals(e)).toBe(true);
|
|
45
|
+
expect(a.equals(f)).toBe(false);
|
|
46
|
+
|
|
47
|
+
});
|