@woosh/meep-engine 2.49.2 → 2.49.4
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/package.json +1 -1
- package/src/core/bvh2/binary/IndexedBinaryBVH.spec.js +20 -0
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.d.ts +4 -0
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.spec.js +30 -0
- package/src/core/bvh2/bvh3/ebvh_build_for_geometry_incremental.js +6 -1
- package/src/core/bvh2/bvh3/query/bvh_collect_user_data.js +5 -1
- package/src/core/cache/Cache.d.ts +2 -0
- package/src/core/cache/Cache.js +1 -1
- package/src/core/cache/Cache.spec.js +19 -0
- package/src/core/cache/LoadingCache.d.ts +18 -0
- package/src/core/cache/LoadingCache.js +115 -0
- package/src/core/codegen/LineBuilder.js +8 -1
- package/src/core/codegen/LineBuilder.spec.js +34 -0
- package/src/core/collection/array/arrayQuickSort.js +11 -2
- package/src/core/collection/array/array_contains_duplicates.js +6 -1
- package/src/core/collection/array/typed/is_typed_array_equals.js +13 -4
- package/src/core/collection/array/typed/is_typed_array_equals.spec.js +71 -0
- package/src/core/collection/table/RowFirstTable.js +1 -1
- package/src/core/collection/table/RowFirstTable.spec.js +36 -0
- package/src/core/collection/table/RowFirstTableSpec.js +3 -0
- package/src/core/color/hsv2rgb.js +8 -3
- package/src/core/color/hsv2rgb.spec.js +43 -0
- package/src/core/geom/3d/aabb/aabb3_array_intersects_ray_array.js +2 -1
- package/src/core/geom/3d/compute_triangle_normal.js +1 -51
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +2 -2
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.spec.js +27 -0
- package/src/core/geom/3d/triangle/computeTriangleRayIntersection.spec.js +25 -0
- package/src/core/geom/3d/v3_compute_triangle_normal.js +51 -0
- package/src/core/geom/3d/v3_compute_triangle_normal.spec.js +27 -0
- package/src/core/geom/packing/miniball/Miniball.spec.js +11 -0
- package/src/core/graph/SquareMatrix.js +1 -9
- package/src/core/graph/graph_k_means_cluster.spec.js +23 -0
- package/src/core/{land → lang}/reactive/compileReactiveExpression.spec.js +2 -2
- package/src/core/model/reactive/trigger/ReactiveTrigger.js +1 -1
- package/src/engine/ecs/dynamic_actions/actions/definition/SendRequestActionDescription.js +1 -1
- package/src/engine/ecs/dynamic_actions/actions/definition/WhiteToBlackboardActionDescription.js +1 -1
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.js +1 -1
- package/src/engine/ecs/fow/FogOfWarRevealer.js +0 -27
- package/src/engine/ecs/fow/serialization/FogOfWarRevealerSerializationAdapter.js +29 -0
- package/src/engine/ecs/transform/TransformSerializationAdapter.spec.js +28 -0
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.spec.js +5 -0
- package/src/engine/options/Option.js +36 -14
- package/src/engine/options/Option.spec.js +69 -0
- package/src/engine/reference/v2/Reference.d.ts +2 -0
- package/src/engine/reference/v2/Reference.js +3 -0
- package/src/engine/reference/v2/Reference.spec.js +44 -0
- package/src/core/bvh2/bvh3/BVHNodeProxy.js +0 -53
- package/src/core/graph/GraphElement.js +0 -6
- package/src/core/graph/Node.js +0 -12
- package/src/generation/GridGeneratorConfigurator.js +0 -0
- /package/src/core/{land → lang}/reactive/AbstractCachingParser.js +0 -0
- /package/src/core/{land → lang}/reactive/ReactiveOperatorType.js +0 -0
- /package/src/core/{land → lang}/reactive/compileReactiveExpression.js +0 -0
- /package/src/core/{land → lang}/reactive/nearley/Reactive.ne +0 -0
- /package/src/core/{land → lang}/reactive/pegjs/Reactive.peg +0 -0
- /package/src/core/{land → lang}/reactive/pegjs/ReactivePegCompiler.js +0 -0
- /package/src/core/{land → lang}/reactive/pegjs/ReactivePegParser.js +0 -0
- /package/src/core/{land → lang}/reactive/pegjs/parser.js +0 -0
- /package/src/core/{land → lang}/reactive/validateReactiveExpression.js +0 -0
- /package/src/generation/rules/{CellMatcherContainsTag.spec.js → CellMatcherLayerBitMaskTest.spec.js} +0 -0
package/package.json
CHANGED
|
@@ -5,3 +5,23 @@ test("constructor does not throw", () => {
|
|
|
5
5
|
});
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
test("build a tree with a single leaf", () => {
|
|
9
|
+
const bvh = new IndexedBinaryBVH();
|
|
10
|
+
|
|
11
|
+
bvh.initialize(1);
|
|
12
|
+
bvh.writeLeaf(0, -1, -3, -7, 11, 13, 17);
|
|
13
|
+
|
|
14
|
+
bvh.unsortedBuiltIntermediate();
|
|
15
|
+
|
|
16
|
+
expect(bvh.leafNodeCount).toBe(1);
|
|
17
|
+
expect(bvh.binaryNodeCount).toBe(0);
|
|
18
|
+
|
|
19
|
+
expect(bvh.x0).toBe(-1);
|
|
20
|
+
expect(bvh.y0).toBe(-3);
|
|
21
|
+
expect(bvh.z0).toBe(-7);
|
|
22
|
+
|
|
23
|
+
expect(bvh.x1).toBe(11);
|
|
24
|
+
expect(bvh.y1).toBe(13);
|
|
25
|
+
expect(bvh.z1).toBe(17);
|
|
26
|
+
|
|
27
|
+
});
|
|
@@ -13,6 +13,8 @@ export class ExplicitBinaryBoundingVolumeHierarchy {
|
|
|
13
13
|
|
|
14
14
|
collect_nodes_all(destination: ArrayLike<number>, destination_offset: number): void
|
|
15
15
|
|
|
16
|
+
node_set_aabb_primitive(node_id: number, x0: number, y0: number, z0: number, x1: number, y1: number, z1: number): void
|
|
17
|
+
|
|
16
18
|
node_set_aabb(node: number, aabb: ArrayLike<number>): void
|
|
17
19
|
|
|
18
20
|
node_get_aabb(node: number, aabb: ArrayLike<number>): void
|
|
@@ -37,6 +39,8 @@ export class ExplicitBinaryBoundingVolumeHierarchy {
|
|
|
37
39
|
|
|
38
40
|
node_get_height(node: number): number
|
|
39
41
|
|
|
42
|
+
swap_nodes(node_a_id: number, node_b_id: number): boolean
|
|
43
|
+
|
|
40
44
|
release_all(): void
|
|
41
45
|
|
|
42
46
|
trim(): void
|
|
@@ -218,3 +218,33 @@ test("node property setters/getters", () => {
|
|
|
218
218
|
|
|
219
219
|
expect(actual_aabb).toEqual(Array.from(expected_aabb));
|
|
220
220
|
});
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
test("node_set_aabb_primitive", () => {
|
|
224
|
+
const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
225
|
+
|
|
226
|
+
const node = bvh.allocate_node();
|
|
227
|
+
|
|
228
|
+
bvh.node_set_aabb_primitive(node, -1, -3, -5, 7, 11, 13);
|
|
229
|
+
|
|
230
|
+
const aabb = [];
|
|
231
|
+
|
|
232
|
+
bvh.node_get_aabb(node, aabb);
|
|
233
|
+
|
|
234
|
+
expect(aabb).toEqual([-1, -3, -5, 7, 11, 13]);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test("swap two detached nodes", () => {
|
|
238
|
+
const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
|
|
239
|
+
|
|
240
|
+
const a = bvh.allocate_node();
|
|
241
|
+
const b = bvh.allocate_node();
|
|
242
|
+
|
|
243
|
+
bvh.node_set_user_data(a, 7);
|
|
244
|
+
bvh.node_set_user_data(b, 11);
|
|
245
|
+
|
|
246
|
+
bvh.swap_nodes(a, b);
|
|
247
|
+
|
|
248
|
+
expect(bvh.node_get_user_data(a)).toBe(11);
|
|
249
|
+
expect(bvh.node_get_user_data(b)).toBe(7);
|
|
250
|
+
});
|
|
@@ -8,7 +8,12 @@ import { compute_triangle_group_aabb3 } from "../../../engine/graphics/sh3/path_
|
|
|
8
8
|
* @param {number[]|Float32Array} positions_array
|
|
9
9
|
* @param {number} [batch_size] can batch triangles in groups of up-to this many triangles per BVH leaf
|
|
10
10
|
*/
|
|
11
|
-
export function ebvh_build_for_geometry_incremental(
|
|
11
|
+
export function ebvh_build_for_geometry_incremental(
|
|
12
|
+
bvh,
|
|
13
|
+
index_array, positions_array,
|
|
14
|
+
batch_size = 1
|
|
15
|
+
) {
|
|
16
|
+
|
|
12
17
|
bvh.release_all();
|
|
13
18
|
const triangle_count = index_array.length / 3;
|
|
14
19
|
|
|
@@ -11,8 +11,12 @@ const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
|
11
11
|
* @param {number} destination_offset
|
|
12
12
|
* @param {ExplicitBinaryBoundingVolumeHierarchy} bvh
|
|
13
13
|
* @param {number} node
|
|
14
|
+
* @returns {number} number of collected elements
|
|
14
15
|
*/
|
|
15
|
-
export function bvh_collect_user_data(
|
|
16
|
+
export function bvh_collect_user_data(
|
|
17
|
+
destination, destination_offset,
|
|
18
|
+
bvh, node
|
|
19
|
+
) {
|
|
16
20
|
|
|
17
21
|
if (node === NULL_NODE) {
|
|
18
22
|
return 0;
|
package/src/core/cache/Cache.js
CHANGED
|
@@ -18,7 +18,7 @@ export class Cache {
|
|
|
18
18
|
* @param {function(value:Value):number} [valueWeigher= value=>1]
|
|
19
19
|
* @param {function(Key):number} [keyHashFunction]
|
|
20
20
|
* @param {function(Key, Key):boolean} [keyEqualityFunction]
|
|
21
|
-
* @param {number} capacity initial capacity for the cache, helps prevent early resizing
|
|
21
|
+
* @param {number} [capacity] initial capacity for the cache, helps prevent early resizing
|
|
22
22
|
* @constructor
|
|
23
23
|
*/
|
|
24
24
|
constructor({
|
|
@@ -18,6 +18,19 @@ test("elements beyond capacity are evicted", () => {
|
|
|
18
18
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
+
test("trying to insert an element into the cache that's larger than the cache capacity should result in the item not being inserted", () => {
|
|
22
|
+
const cache = new Cache({
|
|
23
|
+
maxWeight: 1,
|
|
24
|
+
keyWeigher(key) {
|
|
25
|
+
return key;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
cache.put(2, "hello");
|
|
30
|
+
|
|
31
|
+
expect(cache.contains(2)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
|
|
21
34
|
test("removeListener is called when element is evicted", () => {
|
|
22
35
|
|
|
23
36
|
const removeListener = jest.fn();
|
|
@@ -140,3 +153,9 @@ test("clear with a single entry", () => {
|
|
|
140
153
|
expect(cache.contains("x")).toBe(false);
|
|
141
154
|
|
|
142
155
|
});
|
|
156
|
+
|
|
157
|
+
test("calling 'evictOne' on empty cache should return false", () => {
|
|
158
|
+
const cache = new Cache();
|
|
159
|
+
|
|
160
|
+
expect(cache.evictOne()).toBe(false);
|
|
161
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class LoadingCache<K,V>{
|
|
2
|
+
constructor(options:{
|
|
3
|
+
maxWeight?: number,
|
|
4
|
+
keyWeigher?: (key: K) => number,
|
|
5
|
+
valueWeigher?: (value: V) => number,
|
|
6
|
+
keyHashFunction?: (key: K) => number,
|
|
7
|
+
keyEqualityFunction?: (a: K, b: K) => boolean,
|
|
8
|
+
capacity?: number,
|
|
9
|
+
timeToLive?:number,
|
|
10
|
+
load:(key:K)=> Promise<V>
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
invalidate(key:K):void
|
|
14
|
+
|
|
15
|
+
clear():void
|
|
16
|
+
|
|
17
|
+
get(key:K):Promise<V>
|
|
18
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { Cache } from "./Cache.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @template {V}
|
|
7
|
+
*/
|
|
8
|
+
class Record {
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param {V} value
|
|
12
|
+
* @param {number} time
|
|
13
|
+
*/
|
|
14
|
+
constructor(value, time) {
|
|
15
|
+
this.value = value;
|
|
16
|
+
this.time = time;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const DEFAULT_TIME_TO_LIVE = 10;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @template K,V
|
|
24
|
+
*/
|
|
25
|
+
export class LoadingCache {
|
|
26
|
+
/**
|
|
27
|
+
* @type {Cache<K,Record<Promise<V>>>}
|
|
28
|
+
*/
|
|
29
|
+
#internal
|
|
30
|
+
/**
|
|
31
|
+
* In seconds
|
|
32
|
+
* @type {number}
|
|
33
|
+
*/
|
|
34
|
+
#timeToLive = DEFAULT_TIME_TO_LIVE;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @type {function(key:K):Promise<V>}
|
|
38
|
+
*/
|
|
39
|
+
#load
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @see {@link Cache} for more details on what each parameter means
|
|
43
|
+
* @param maxWeight
|
|
44
|
+
* @param keyWeigher
|
|
45
|
+
* @param valueWeigher
|
|
46
|
+
* @param keyHashFunction
|
|
47
|
+
* @param keyEqualityFunction
|
|
48
|
+
* @param capacity
|
|
49
|
+
* @param {number} [timeToLive] in seconds
|
|
50
|
+
* @param load
|
|
51
|
+
*/
|
|
52
|
+
constructor({
|
|
53
|
+
maxWeight,
|
|
54
|
+
keyWeigher,
|
|
55
|
+
valueWeigher,
|
|
56
|
+
keyHashFunction,
|
|
57
|
+
keyEqualityFunction,
|
|
58
|
+
capacity,
|
|
59
|
+
timeToLive = DEFAULT_TIME_TO_LIVE,
|
|
60
|
+
load
|
|
61
|
+
}) {
|
|
62
|
+
|
|
63
|
+
this.#internal = new Cache({
|
|
64
|
+
maxWeight,
|
|
65
|
+
keyWeigher,
|
|
66
|
+
valueWeigher,
|
|
67
|
+
keyHashFunction,
|
|
68
|
+
keyEqualityFunction,
|
|
69
|
+
capacity,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
this.#timeToLive = timeToLive;
|
|
73
|
+
this.#load = load;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @param {K} key
|
|
79
|
+
*/
|
|
80
|
+
invalidate(key) {
|
|
81
|
+
this.#internal.remove(key);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
*/
|
|
87
|
+
clear() {
|
|
88
|
+
this.#internal.clear();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
*
|
|
93
|
+
* @param {K} key
|
|
94
|
+
* @return {Promise<V>}
|
|
95
|
+
*/
|
|
96
|
+
async get(key) {
|
|
97
|
+
const currentTime = performance.now() * 1e-3;
|
|
98
|
+
|
|
99
|
+
let record = this.#internal.get(key);
|
|
100
|
+
|
|
101
|
+
if (record === null || (record.time + this.#timeToLive) < currentTime) {
|
|
102
|
+
|
|
103
|
+
// missing or stale record
|
|
104
|
+
const promise = this.#load(key);
|
|
105
|
+
|
|
106
|
+
record = new Record(promise, currentTime);
|
|
107
|
+
|
|
108
|
+
this.#internal.put(key, record);
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
return record.value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -39,6 +39,14 @@ class LineBuilder {
|
|
|
39
39
|
*/
|
|
40
40
|
indentSpaces = DEFAULT_INDENT_SPACES;
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Number of lines
|
|
44
|
+
* @return {number}
|
|
45
|
+
*/
|
|
46
|
+
get count() {
|
|
47
|
+
return this.lines.length;
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
/**
|
|
43
51
|
*
|
|
44
52
|
* @return {boolean}
|
|
@@ -115,7 +123,6 @@ class LineBuilder {
|
|
|
115
123
|
clear() {
|
|
116
124
|
this.lines = [];
|
|
117
125
|
this.indentation = 0;
|
|
118
|
-
this.indentSpaces = DEFAULT_INDENT_SPACES;
|
|
119
126
|
}
|
|
120
127
|
|
|
121
128
|
/**
|
|
@@ -5,3 +5,37 @@ test("Empty builder should produce empty string", () => {
|
|
|
5
5
|
|
|
6
6
|
expect(b.build()).toEqual("");
|
|
7
7
|
});
|
|
8
|
+
|
|
9
|
+
test("build simple indented fragment", () => {
|
|
10
|
+
const b = new LineBuilder();
|
|
11
|
+
|
|
12
|
+
b.indentSpaces = 1;
|
|
13
|
+
|
|
14
|
+
b.add('a');
|
|
15
|
+
b.indent();
|
|
16
|
+
b.add('b');
|
|
17
|
+
b.dedent();
|
|
18
|
+
b.add('c');
|
|
19
|
+
|
|
20
|
+
expect(b.build()).toEqual('a\n b\nc');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("adding another line builder copies lines correctly", () => {
|
|
24
|
+
const a = new LineBuilder();
|
|
25
|
+
|
|
26
|
+
const b = new LineBuilder();
|
|
27
|
+
|
|
28
|
+
b.add('a');
|
|
29
|
+
|
|
30
|
+
a.addLines(b);
|
|
31
|
+
|
|
32
|
+
expect(a.build()).toEqual('a');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("fromText parses correct number of lines", () => {
|
|
36
|
+
|
|
37
|
+
const builder = LineBuilder.fromText('a\nb');
|
|
38
|
+
|
|
39
|
+
expect(builder.count).toBe(2);
|
|
40
|
+
|
|
41
|
+
});
|
|
@@ -12,7 +12,12 @@ const stack = [];
|
|
|
12
12
|
* @param {function(T[],number, number):*} [swap_operator]
|
|
13
13
|
* @param {*} [swap_context]
|
|
14
14
|
*/
|
|
15
|
-
export function arrayQuickSort(
|
|
15
|
+
export function arrayQuickSort(
|
|
16
|
+
data,
|
|
17
|
+
score_function, score_function_context,
|
|
18
|
+
start, end,
|
|
19
|
+
swap_operator = arraySwapElements, swap_context = undefined
|
|
20
|
+
) {
|
|
16
21
|
if (start >= end) {
|
|
17
22
|
// section of 0 size, nothing to sort
|
|
18
23
|
return;
|
|
@@ -79,7 +84,11 @@ export function arrayQuickSort(data, score_function, score_function_context, sta
|
|
|
79
84
|
* @param {number} start
|
|
80
85
|
* @param {number} end
|
|
81
86
|
*/
|
|
82
|
-
export function array_quick_sort_by_comparator(
|
|
87
|
+
export function array_quick_sort_by_comparator(
|
|
88
|
+
data,
|
|
89
|
+
compare_function, compare_function_context,
|
|
90
|
+
start, end
|
|
91
|
+
) {
|
|
83
92
|
if (start >= end) {
|
|
84
93
|
// section of 0 size, nothing to sort
|
|
85
94
|
return;
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
* @param {number} [end_index] last index to be included in the search
|
|
6
6
|
* @return {boolean}
|
|
7
7
|
*/
|
|
8
|
-
export function array_contains_duplicates(
|
|
8
|
+
export function array_contains_duplicates(
|
|
9
|
+
source,
|
|
10
|
+
start_index = 0,
|
|
11
|
+
end_index = source.length - 1
|
|
12
|
+
) {
|
|
13
|
+
|
|
9
14
|
for (let k = start_index; k <= end_index; k++) {
|
|
10
15
|
|
|
11
16
|
const element = source[k];
|
|
@@ -3,11 +3,16 @@ import { isArrayEqualStrict } from "../isArrayEqualStrict.js";
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
*
|
|
6
|
-
* @param {Uint8Array} a
|
|
7
|
-
* @param {Uint8Array} b
|
|
6
|
+
* @param {Uint8Array|Uint32Array} a
|
|
7
|
+
* @param {Uint8Array|Uint32Array} b
|
|
8
8
|
* @returns {boolean}
|
|
9
9
|
*/
|
|
10
10
|
export function is_typed_array_equals(a, b) {
|
|
11
|
+
if (a === b) {
|
|
12
|
+
// quick shortcut
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
const a_length = a.length;
|
|
12
17
|
const b_length = b.length;
|
|
13
18
|
|
|
@@ -26,13 +31,15 @@ export function is_typed_array_equals(a, b) {
|
|
|
26
31
|
return false;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
const
|
|
34
|
+
const a_constructor = a.constructor;
|
|
35
|
+
const b_constructor = b.constructor;
|
|
30
36
|
|
|
31
|
-
if (
|
|
37
|
+
if (a_constructor !== b_constructor) {
|
|
32
38
|
// incompatible constructors
|
|
33
39
|
return false;
|
|
34
40
|
}
|
|
35
41
|
|
|
42
|
+
|
|
36
43
|
const a_buffer = a.buffer;
|
|
37
44
|
const b_buffer = b.buffer;
|
|
38
45
|
|
|
@@ -45,6 +52,8 @@ export function is_typed_array_equals(a, b) {
|
|
|
45
52
|
let a_proxy = a;
|
|
46
53
|
let b_proxy = b;
|
|
47
54
|
|
|
55
|
+
const bytes_per_element = a_constructor.BYTES_PER_ELEMENT;
|
|
56
|
+
|
|
48
57
|
if (bytes_per_element < 4 && byte_length % 4 === 0) {
|
|
49
58
|
// 4 byte alignment, can use uint32
|
|
50
59
|
a_proxy = new Uint32Array(a_buffer, a.byteOffset, byte_length / 4);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { is_typed_array_equals } from "./is_typed_array_equals.js";
|
|
2
|
+
|
|
3
|
+
test("small uint32 arrays", () => {
|
|
4
|
+
expect(is_typed_array_equals(
|
|
5
|
+
new Uint32Array(0),
|
|
6
|
+
new Uint32Array(0)
|
|
7
|
+
)).toBe(true);
|
|
8
|
+
|
|
9
|
+
expect(is_typed_array_equals(
|
|
10
|
+
new Uint32Array([1, 3, 5]),
|
|
11
|
+
new Uint32Array([1, 3, 5])
|
|
12
|
+
)).toBe(true);
|
|
13
|
+
|
|
14
|
+
expect(is_typed_array_equals(
|
|
15
|
+
new Uint32Array([7, 3]),
|
|
16
|
+
new Uint32Array([1, 3])
|
|
17
|
+
)).toBe(false);
|
|
18
|
+
|
|
19
|
+
expect(is_typed_array_equals(
|
|
20
|
+
new Uint32Array([1, 3]),
|
|
21
|
+
new Uint32Array([7, 3])
|
|
22
|
+
)).toBe(false);
|
|
23
|
+
|
|
24
|
+
expect(is_typed_array_equals(
|
|
25
|
+
new Uint32Array([1, 7]),
|
|
26
|
+
new Uint32Array([1, 3])
|
|
27
|
+
)).toBe(false);
|
|
28
|
+
|
|
29
|
+
expect(is_typed_array_equals(
|
|
30
|
+
new Uint32Array([1, 3]),
|
|
31
|
+
new Uint32Array([1, 7])
|
|
32
|
+
)).toBe(false);
|
|
33
|
+
|
|
34
|
+
expect(is_typed_array_equals(
|
|
35
|
+
new Uint32Array([1, 3]),
|
|
36
|
+
new Uint32Array([1, 3, 7])
|
|
37
|
+
)).toBe(false);
|
|
38
|
+
|
|
39
|
+
expect(is_typed_array_equals(
|
|
40
|
+
new Uint32Array([1, 3, 7]),
|
|
41
|
+
new Uint32Array([1, 3])
|
|
42
|
+
)).toBe(false);
|
|
43
|
+
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("large uin32 array", () => {
|
|
47
|
+
expect(is_typed_array_equals(
|
|
48
|
+
new Uint32Array(1024),
|
|
49
|
+
new Uint32Array(1024),
|
|
50
|
+
)).toBe(true);
|
|
51
|
+
|
|
52
|
+
expect(is_typed_array_equals(
|
|
53
|
+
new Uint32Array(1024),
|
|
54
|
+
new Uint32Array(1023),
|
|
55
|
+
)).toBe(false);
|
|
56
|
+
|
|
57
|
+
expect(is_typed_array_equals(
|
|
58
|
+
new Uint32Array(1023),
|
|
59
|
+
new Uint32Array(1024),
|
|
60
|
+
)).toBe(false);
|
|
61
|
+
|
|
62
|
+
const a = new Uint32Array(1024);
|
|
63
|
+
const b = new Uint32Array(1024);
|
|
64
|
+
|
|
65
|
+
a[127] = 1;
|
|
66
|
+
|
|
67
|
+
expect(is_typed_array_equals(
|
|
68
|
+
a,
|
|
69
|
+
b,
|
|
70
|
+
)).toBe(false);
|
|
71
|
+
});
|
|
@@ -285,3 +285,39 @@ test('reverse_rows empty', () => {
|
|
|
285
285
|
|
|
286
286
|
expect(a.length).toBe(0);
|
|
287
287
|
});
|
|
288
|
+
|
|
289
|
+
test("hash on an empty ", () => {
|
|
290
|
+
const table = new RowFirstTable(new RowFirstTableSpec([BinaryDataType.Uint8]));
|
|
291
|
+
|
|
292
|
+
expect(() => table.hash()).not.toThrow();
|
|
293
|
+
expect(table.hash()).toEqual(table.hash());
|
|
294
|
+
expect(typeof table.hash() === "number").toBe(true);
|
|
295
|
+
expect(Number.isInteger(table.hash())).toBe(true);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("equals method", () => {
|
|
299
|
+
const a = new RowFirstTable(new RowFirstTableSpec([BinaryDataType.Uint8]));
|
|
300
|
+
const b = new RowFirstTable(new RowFirstTableSpec([BinaryDataType.Uint8]));
|
|
301
|
+
|
|
302
|
+
expect(a.equals(b)).toBe(true);
|
|
303
|
+
|
|
304
|
+
a.addRow([1]);
|
|
305
|
+
|
|
306
|
+
expect(a.equals(b)).toBe(false);
|
|
307
|
+
expect(b.equals(a)).toBe(false);
|
|
308
|
+
|
|
309
|
+
b.addRow([3]);
|
|
310
|
+
|
|
311
|
+
expect(a.equals(b)).toBe(false);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
test("toRowArray", () => {
|
|
315
|
+
const a = new RowFirstTable(new RowFirstTableSpec([BinaryDataType.Uint8, BinaryDataType.Float64]));
|
|
316
|
+
a.addRow([3, 7.11]);
|
|
317
|
+
a.addRow([5, 13.17]);
|
|
318
|
+
|
|
319
|
+
expect(a.toRowArray()).toEqual([
|
|
320
|
+
[3, 7.11],
|
|
321
|
+
[5, 13.17],
|
|
322
|
+
]);
|
|
323
|
+
});
|
|
@@ -9,6 +9,7 @@ import { computeStringHash } from "../../primitives/strings/computeStringHash.js
|
|
|
9
9
|
import { isArrayEqualStrict } from "../array/isArrayEqualStrict.js";
|
|
10
10
|
import { BinaryDataType } from "../../binary/type/BinaryDataType.js";
|
|
11
11
|
import { DataTypeByteSizes } from "../../binary/type/DataTypeByteSizes.js";
|
|
12
|
+
import { assert } from "../../assert.js";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* @readonly
|
|
@@ -158,6 +159,8 @@ function genCellReader(type, offset, endianType = EndianType.BigEndian) {
|
|
|
158
159
|
* @constructor
|
|
159
160
|
*/
|
|
160
161
|
export function RowFirstTableSpec(types, endianType = EndianType.BigEndian) {
|
|
162
|
+
assert.isArray(types, 'types');
|
|
163
|
+
|
|
161
164
|
const numTypes = types.length;
|
|
162
165
|
|
|
163
166
|
/**
|
|
@@ -10,22 +10,27 @@ import { float2uint8 } from "../binary/float2uint8.js";
|
|
|
10
10
|
*/
|
|
11
11
|
export function hsv2rgb(h, s, v) {
|
|
12
12
|
|
|
13
|
-
let _h = h
|
|
13
|
+
let _h = h;
|
|
14
14
|
|
|
15
15
|
if (_h < 0) {
|
|
16
|
-
_h =
|
|
16
|
+
_h = _h + Math.ceil(Math.abs(_h));
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
_h = _h % 1;
|
|
20
|
+
|
|
19
21
|
const _s = clamp01(s);
|
|
20
22
|
const _v = clamp01(v);
|
|
21
23
|
|
|
22
24
|
let r, g, b, i, f, p, q, t;
|
|
23
25
|
|
|
24
|
-
i = Math.floor(
|
|
26
|
+
i = Math.floor(_h * 6);
|
|
27
|
+
|
|
25
28
|
f = _h * 6 - i;
|
|
29
|
+
|
|
26
30
|
p = _v * (1 - _s);
|
|
27
31
|
q = _v * (1 - f * _s);
|
|
28
32
|
t = _v * (1 - (1 - f) * _s);
|
|
33
|
+
|
|
29
34
|
switch (i % 6) {
|
|
30
35
|
case 0:
|
|
31
36
|
r = _v, g = t, b = p;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { hsv2rgb } from "./hsv2rgb.js";
|
|
2
|
+
|
|
3
|
+
function validate_element(number) {
|
|
4
|
+
expect(typeof number).toBe('number');
|
|
5
|
+
expect(Number.isNaN(number)).toBe(false);
|
|
6
|
+
|
|
7
|
+
expect(number).toBeLessThanOrEqual(255);
|
|
8
|
+
expect(number).toBeGreaterThanOrEqual(0);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function validate_rgb(rgb) {
|
|
12
|
+
expect(rgb).not.toBeUndefined();
|
|
13
|
+
expect(rgb).not.toBeNull();
|
|
14
|
+
expect(typeof rgb).toBe('object');
|
|
15
|
+
|
|
16
|
+
validate_element(rgb.r);
|
|
17
|
+
validate_element(rgb.g);
|
|
18
|
+
validate_element(rgb.b);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
test("sanity test", () => {
|
|
22
|
+
|
|
23
|
+
validate_rgb(hsv2rgb(0, 0, 0));
|
|
24
|
+
validate_rgb(hsv2rgb(0, 0, 1));
|
|
25
|
+
validate_rgb(hsv2rgb(0, 1, 0));
|
|
26
|
+
validate_rgb(hsv2rgb(0, 1, 1));
|
|
27
|
+
validate_rgb(hsv2rgb(1, 0, 0));
|
|
28
|
+
validate_rgb(hsv2rgb(1, 0, 1));
|
|
29
|
+
validate_rgb(hsv2rgb(1, 1, 0));
|
|
30
|
+
validate_rgb(hsv2rgb(1, 1, 1));
|
|
31
|
+
|
|
32
|
+
validate_rgb(hsv2rgb(0.5, 0.5, 0.5));
|
|
33
|
+
|
|
34
|
+
validate_rgb(hsv2rgb(0.1, 0.5, 0.5));
|
|
35
|
+
validate_rgb(hsv2rgb(0.2, 0.5, 0.5));
|
|
36
|
+
validate_rgb(hsv2rgb(0.3, 0.5, 0.5));
|
|
37
|
+
validate_rgb(hsv2rgb(0.4, 0.5, 0.5));
|
|
38
|
+
validate_rgb(hsv2rgb(0.6, 0.5, 0.5));
|
|
39
|
+
validate_rgb(hsv2rgb(0.7, 0.5, 0.5));
|
|
40
|
+
validate_rgb(hsv2rgb(0.8, 0.5, 0.5));
|
|
41
|
+
validate_rgb(hsv2rgb(0.9, 0.5, 0.5));
|
|
42
|
+
|
|
43
|
+
});
|
|
@@ -7,7 +7,8 @@ import { aabb3_intersects_ray } from "./aabb3_intersects_ray.js";
|
|
|
7
7
|
* @returns {boolean}
|
|
8
8
|
*/
|
|
9
9
|
export function aabb3_array_intersects_ray_array(aabb, ray) {
|
|
10
|
-
return aabb3_intersects_ray(
|
|
10
|
+
return aabb3_intersects_ray(
|
|
11
|
+
aabb[0], aabb[1], aabb[2], aabb[3], aabb[4], aabb[5],
|
|
11
12
|
ray[0], ray[1], ray[2],
|
|
12
13
|
ray[3], ray[4], ray[5]
|
|
13
14
|
);
|