@woosh/meep-engine 2.33.76 → 2.34.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/core/collection/Set.js +0 -61
- package/core/collection/array/arrayIndexByEquality.js +20 -0
- package/core/collection/array/arraySetDiff.js +42 -0
- package/core/collection/array/arraySetSortingDiff.js +67 -0
- package/core/collection/array/arraySetSortingDiff.spec.js +74 -0
- package/core/collection/array/array_filter_by_multiple.js +36 -0
- package/core/collection/array/weightedRandomFromArray.js +9 -5
- package/core/collection/list/FilteredListProjection.js +1 -1
- package/core/collection/list/List.js +2 -1
- package/core/geom/3d/topology/compareEdges.js +16 -0
- package/core/geom/3d/topology/compareFaces.js +9 -0
- package/core/geom/3d/topology/compareVertices.js +9 -0
- package/core/geom/3d/topology/computeTopoMeshVertexDuplicates.js +25 -6
- package/core/geom/3d/topology/expandConnectivityByLocality.js +35 -19
- package/core/geom/Vector2.js +7 -2
- package/core/geom/Vector3.js +2 -2
- package/core/geom/v3_angle_between.js +3 -1
- package/editor/view/ecs/components/items/ItemContainerController.stories.js +1 -1
- package/engine/asset/loaders/image/ImageDecoderWorker.js +3 -2
- package/engine/asset/loaders/image/ImageRGBADataAsset.js +2 -6
- package/engine/asset/loaders/image/ImageRGBADataLoader.js +18 -2
- package/engine/asset/loaders/image/codec/NativeImageDecoder.js +2 -1
- package/engine/asset/loaders/image/png/PNG.js +3 -2
- package/engine/asset/loaders/image/png/PNGReader.js +1 -0
- package/engine/ecs/EntityComponentDataset.js +1 -1
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +38 -0
- package/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +1 -2
- package/engine/graphics/ecs/highlight/system/MeshHighlightSystem.d.ts +3 -2
- package/engine/graphics/ecs/highlight/system/RenderableHighlightSystem.d.ts +3 -1
- package/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts +8 -0
- package/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +180 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +74 -16
- package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +7 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +9 -0
- package/engine/graphics/ecs/mesh-v2/prototypeShadedGeometry.js +4 -2
- package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +41 -1
- package/engine/graphics/particles/particular/engine/parameter/ParticleParameter.js +7 -2
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +3 -2
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +7 -3
- package/engine/graphics/texture/sampler/Sampler2D.js +2 -0
- package/engine/graphics/texture/sampler/downsampleSampler2D.js +3 -1
- package/engine/graphics/texture/sampler/genericResampleSampler2D.js +67 -0
- package/engine/graphics/texture/sampler/scaleSampler2D.js +29 -35
- package/engine/graphics/texture/sampler/upsampleSampler2D.js +47 -0
- package/generation/filtering/numeric/CellFilterReadGridLayer.js +2 -2
- package/generation/filtering/numeric/math/CellFilterSaturate.js +24 -0
- package/package.json +1 -1
- package/samples/terrain/from_image.js +289 -0
- package/samples/terrain/from_image_2.js +219 -0
- package/view/elements/radial/RadialMenu.js +1 -1
- package/generation/theme/TerrainThemeApplicator.js +0 -6
package/core/collection/Set.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
import Signal from "../events/signal/Signal.js";
|
|
7
|
-
import { strictEquals } from "../function/Functions.js";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Structure with event signals for observing changes.
|
|
@@ -165,64 +164,4 @@ class Set {
|
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
|
|
168
|
-
/**
|
|
169
|
-
* @template T
|
|
170
|
-
* @param {T[]} array
|
|
171
|
-
* @param {T} element
|
|
172
|
-
* @param {function(a:T,b:T):boolean} equals
|
|
173
|
-
* @returns {number}
|
|
174
|
-
*/
|
|
175
|
-
export function arrayIndexByEquality(array, element, equals) {
|
|
176
|
-
const n = array.length;
|
|
177
|
-
|
|
178
|
-
for (let i = 0; i < n; i++) {
|
|
179
|
-
const el = array[i];
|
|
180
|
-
|
|
181
|
-
if (equals(element, el)) {
|
|
182
|
-
return i;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return -1;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* @template T
|
|
191
|
-
* @param {T[]} a
|
|
192
|
-
* @param {T[]} b
|
|
193
|
-
* @param {function(a:T,b:T):boolean} [equals]
|
|
194
|
-
* @returns {{uniqueA:T[], uniqueB:T[], common:T[]}}
|
|
195
|
-
*/
|
|
196
|
-
export function arraySetDiff(a, b, equals = strictEquals) {
|
|
197
|
-
const uniqueA = a.slice();
|
|
198
|
-
const uniqueB = b.slice();
|
|
199
|
-
|
|
200
|
-
const common = [];
|
|
201
|
-
|
|
202
|
-
let lA = uniqueA.length;
|
|
203
|
-
|
|
204
|
-
let i;
|
|
205
|
-
for (i = 0; i < lA; i++) {
|
|
206
|
-
const elA = uniqueA[i];
|
|
207
|
-
|
|
208
|
-
const j = arrayIndexByEquality(uniqueB, elA, equals);
|
|
209
|
-
|
|
210
|
-
if (j !== -1) {
|
|
211
|
-
common.push(elA);
|
|
212
|
-
|
|
213
|
-
uniqueA.splice(i, 1);
|
|
214
|
-
uniqueB.splice(j, 1);
|
|
215
|
-
|
|
216
|
-
i--;
|
|
217
|
-
lA--;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return {
|
|
222
|
-
uniqueA,
|
|
223
|
-
uniqueB,
|
|
224
|
-
common
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
|
|
228
167
|
export default Set;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
* @param {T[]} array
|
|
4
|
+
* @param {T} element
|
|
5
|
+
* @param {function(a:T,b:T):boolean} equals
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
export function arrayIndexByEquality(array, element, equals) {
|
|
9
|
+
const n = array.length;
|
|
10
|
+
|
|
11
|
+
for (let i = 0; i < n; i++) {
|
|
12
|
+
const el = array[i];
|
|
13
|
+
|
|
14
|
+
if (equals(element, el)) {
|
|
15
|
+
return i;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return -1;
|
|
20
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { strictEquals } from "../../function/Functions.js";
|
|
2
|
+
import { arrayIndexByEquality } from "./arrayIndexByEquality.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @template T
|
|
6
|
+
* @param {T[]} a
|
|
7
|
+
* @param {T[]} b
|
|
8
|
+
* @param {function(a:T,b:T):boolean} [equals]
|
|
9
|
+
* @returns {{uniqueA:T[], uniqueB:T[], common:T[]}}
|
|
10
|
+
*/
|
|
11
|
+
export function arraySetDiff(a, b, equals = strictEquals) {
|
|
12
|
+
const uniqueA = a.slice();
|
|
13
|
+
const uniqueB = b.slice();
|
|
14
|
+
|
|
15
|
+
const common = [];
|
|
16
|
+
|
|
17
|
+
let lA = uniqueA.length;
|
|
18
|
+
|
|
19
|
+
let i;
|
|
20
|
+
for (i = 0; i < lA; i++) {
|
|
21
|
+
const elA = uniqueA[i];
|
|
22
|
+
|
|
23
|
+
const j = arrayIndexByEquality(uniqueB, elA, equals);
|
|
24
|
+
|
|
25
|
+
if (j !== -1) {
|
|
26
|
+
common.push(elA);
|
|
27
|
+
|
|
28
|
+
uniqueA.splice(i, 1);
|
|
29
|
+
uniqueB.splice(j, 1);
|
|
30
|
+
|
|
31
|
+
i--;
|
|
32
|
+
lA--;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
uniqueA,
|
|
38
|
+
uniqueB,
|
|
39
|
+
common
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { assert } from "../../assert.js";
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Based on 2-way merge algorith from wiki: https://en.wikipedia.org/wiki/K-way_merge_algorithm
|
|
7
|
+
* @template T
|
|
8
|
+
* @param {T[]} a
|
|
9
|
+
* @param {T[]} b
|
|
10
|
+
* @param {function(a:T,b:T):number} [compare]
|
|
11
|
+
* @returns {{uniqueA:T[], uniqueB:T[], common:T[]}}
|
|
12
|
+
*/
|
|
13
|
+
export function arraySetSortingDiff(a, b, compare) {
|
|
14
|
+
assert.isFunction(compare, 'compare');
|
|
15
|
+
|
|
16
|
+
const uniqueA = a.slice();
|
|
17
|
+
const uniqueB = b.slice();
|
|
18
|
+
|
|
19
|
+
// sort both a and b
|
|
20
|
+
uniqueA.sort(compare);
|
|
21
|
+
uniqueB.sort(compare);
|
|
22
|
+
|
|
23
|
+
const common = [];
|
|
24
|
+
|
|
25
|
+
let lA = uniqueA.length;
|
|
26
|
+
let lB = uniqueB.length;
|
|
27
|
+
|
|
28
|
+
let i;
|
|
29
|
+
let j;
|
|
30
|
+
let cursor_j = 0;
|
|
31
|
+
|
|
32
|
+
for (i = 0; i < lA; i++) {
|
|
33
|
+
const el_a = uniqueA[i];
|
|
34
|
+
|
|
35
|
+
for (j = cursor_j; j < lB; j++) {
|
|
36
|
+
const el_b = uniqueB[j];
|
|
37
|
+
|
|
38
|
+
const diff = compare(el_a, el_b);
|
|
39
|
+
|
|
40
|
+
if (diff === 0) {
|
|
41
|
+
common.push(el_a);
|
|
42
|
+
|
|
43
|
+
uniqueA.splice(i, 1);
|
|
44
|
+
uniqueB.splice(j, 1);
|
|
45
|
+
|
|
46
|
+
i--;
|
|
47
|
+
j--;
|
|
48
|
+
|
|
49
|
+
lA--;
|
|
50
|
+
lB--;
|
|
51
|
+
|
|
52
|
+
} else if (diff > 0) {
|
|
53
|
+
cursor_j++;
|
|
54
|
+
} else {
|
|
55
|
+
// too far
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
uniqueA,
|
|
64
|
+
uniqueB,
|
|
65
|
+
common
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { arraySetSortingDiff } from "./arraySetSortingDiff.js";
|
|
2
|
+
import { compareNumbers } from "../../primitives/numbers/compareNumbers.js";
|
|
3
|
+
|
|
4
|
+
test('two empty inputs', () => {
|
|
5
|
+
expect(arraySetSortingDiff([], [], compareNumbers)).toEqual({
|
|
6
|
+
uniqueA: [],
|
|
7
|
+
uniqueB: [],
|
|
8
|
+
common: []
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('[] and [1] inputs', () => {
|
|
13
|
+
expect(arraySetSortingDiff([], [1], compareNumbers)).toEqual({
|
|
14
|
+
uniqueA: [],
|
|
15
|
+
uniqueB: [1],
|
|
16
|
+
common: []
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('[1] and [] inputs', () => {
|
|
21
|
+
expect(arraySetSortingDiff([1], [], compareNumbers)).toEqual({
|
|
22
|
+
uniqueA: [1],
|
|
23
|
+
uniqueB: [],
|
|
24
|
+
common: []
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('[1] and [1] inputs', () => {
|
|
29
|
+
expect(arraySetSortingDiff([1], [1], compareNumbers)).toEqual({
|
|
30
|
+
uniqueA: [],
|
|
31
|
+
uniqueB: [],
|
|
32
|
+
common: [1]
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('[1] and [1,2] inputs', () => {
|
|
37
|
+
expect(arraySetSortingDiff([1], [1, 2], compareNumbers)).toEqual({
|
|
38
|
+
uniqueA: [],
|
|
39
|
+
uniqueB: [2],
|
|
40
|
+
common: [1]
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('[1,2] and [1] inputs', () => {
|
|
45
|
+
expect(arraySetSortingDiff([1, 2], [1], compareNumbers)).toEqual({
|
|
46
|
+
uniqueA: [2],
|
|
47
|
+
uniqueB: [],
|
|
48
|
+
common: [1]
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('[5,4,3,2,1] and [1,2,3,4,5] inputs', () => {
|
|
53
|
+
expect(arraySetSortingDiff([5, 4, 3, 2, 1], [1, 2, 3, 4, 5], compareNumbers)).toEqual({
|
|
54
|
+
uniqueA: [],
|
|
55
|
+
uniqueB: [],
|
|
56
|
+
common: [1, 2, 3, 4, 5]
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('[5,1] and [1,2,3,4,5] inputs', () => {
|
|
61
|
+
expect(arraySetSortingDiff([5, 1], [1, 2, 3, 4, 5], compareNumbers)).toEqual({
|
|
62
|
+
uniqueA: [],
|
|
63
|
+
uniqueB: [2,3,4],
|
|
64
|
+
common: [1, 5]
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('[1,2,3,4,5] and [5,1] inputs', () => {
|
|
69
|
+
expect(arraySetSortingDiff([1, 2, 3, 4, 5], [5, 1], compareNumbers)).toEqual({
|
|
70
|
+
uniqueA: [2,3,4],
|
|
71
|
+
uniqueB: [],
|
|
72
|
+
common: [1, 5]
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
* @param {T[]} input_items
|
|
4
|
+
* @param {((T)=>boolean)[]} filters
|
|
5
|
+
* @return {T[]}
|
|
6
|
+
*/
|
|
7
|
+
export function array_filter_by_multiple(input_items, filters) {
|
|
8
|
+
|
|
9
|
+
const filter_count = filters.length;
|
|
10
|
+
|
|
11
|
+
if (filter_count === 0) {
|
|
12
|
+
// special case, no filters
|
|
13
|
+
return input_items;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const filtered = [];
|
|
17
|
+
|
|
18
|
+
const input_item_count = input_items.length;
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
main_loop:for (let i = 0; i < input_item_count; i++) {
|
|
22
|
+
const d = input_items[i];
|
|
23
|
+
for (let j = 0; j < filter_count; j++) {
|
|
24
|
+
const filter = filters[j];
|
|
25
|
+
|
|
26
|
+
if (filter(d) === false) {
|
|
27
|
+
continue main_loop;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// filters passed
|
|
32
|
+
filtered.push(d);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return filtered;
|
|
36
|
+
}
|
|
@@ -3,7 +3,11 @@ import { compareNumbers } from "../../primitives/numbers/compareNumbers.js";
|
|
|
3
3
|
import { binarySearchHighIndex } from "./binarySearchHighIndex.js";
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @type {number[]}
|
|
9
|
+
*/
|
|
10
|
+
const scratch_weights = [];
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* @template T
|
|
@@ -16,8 +20,8 @@ const weights = [];
|
|
|
16
20
|
*/
|
|
17
21
|
export function weightedRandomFromArray(array, random, weight, weightContext, length = array.length) {
|
|
18
22
|
assert.isArray(array, 'array');
|
|
19
|
-
assert.
|
|
20
|
-
assert.
|
|
23
|
+
assert.isFunction(random, 'random');
|
|
24
|
+
assert.isFunction(weight, 'weight');
|
|
21
25
|
|
|
22
26
|
if (length === 0) {
|
|
23
27
|
return undefined;
|
|
@@ -36,12 +40,12 @@ export function weightedRandomFromArray(array, random, weight, weightContext, le
|
|
|
36
40
|
weight_total += w;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
scratch_weights[i] = weight_total;
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
const target_weight = random() * weight_total;
|
|
43
47
|
|
|
44
|
-
const index = binarySearchHighIndex(
|
|
48
|
+
const index = binarySearchHighIndex(scratch_weights, target_weight, compareNumbers, 0, length - 1);
|
|
45
49
|
|
|
46
50
|
return array[index];
|
|
47
51
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { frameThrottle } from "../../../engine/graphics/FrameThrottle.js";
|
|
2
2
|
import { invokeObjectEquals } from "../../model/object/invokeObjectEquals.js";
|
|
3
|
-
import { arraySetDiff } from "../Set.js";
|
|
4
3
|
import List from "./List.js";
|
|
4
|
+
import { arraySetDiff } from "../array/arraySetDiff.js";
|
|
5
5
|
|
|
6
6
|
export class FilteredListProjection {
|
|
7
7
|
/**
|
|
@@ -6,7 +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 {
|
|
9
|
+
import { arraySetDiff } from "../array/arraySetDiff.js";
|
|
10
|
+
import { arrayIndexByEquality } from "../array/arrayIndexByEquality.js";
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { compareVertices } from "./compareVertices.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {TopoEdge} a
|
|
6
|
+
* @param {TopoEdge} b
|
|
7
|
+
* @returns {number}
|
|
8
|
+
*/
|
|
9
|
+
function compareEdges(a, b) {
|
|
10
|
+
const v0 = compareVertices(a.v0, b.v0);
|
|
11
|
+
if (v0 !== 0) {
|
|
12
|
+
return v0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return compareVertices(a.v0, b.v0);
|
|
16
|
+
}
|
|
@@ -7,7 +7,10 @@ import { mortonEncode_magicbits } from "../morton/mortonEncode_magicbits.js";
|
|
|
7
7
|
* @param {TopoVertex} b
|
|
8
8
|
*/
|
|
9
9
|
function isPositionEquivalent(a, b) {
|
|
10
|
-
return epsilonEquals(b.x, a.x, EPSILON)
|
|
10
|
+
return epsilonEquals(b.x, a.x, EPSILON)
|
|
11
|
+
&& epsilonEquals(b.y, a.y, EPSILON)
|
|
12
|
+
&& epsilonEquals(b.z, a.z, EPSILON)
|
|
13
|
+
;
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
/**
|
|
@@ -31,8 +34,9 @@ function recordDuplicate(result, a, b) {
|
|
|
31
34
|
/**
|
|
32
35
|
*
|
|
33
36
|
* @param {TopoMesh} mesh
|
|
37
|
+
* @param {AABB3} aabb
|
|
34
38
|
*/
|
|
35
|
-
export function computeTopoMeshVertexDuplicates(mesh) {
|
|
39
|
+
export function computeTopoMeshVertexDuplicates(mesh, aabb) {
|
|
36
40
|
const vertices = mesh.vertices;
|
|
37
41
|
|
|
38
42
|
const n = vertices.length;
|
|
@@ -46,11 +50,26 @@ export function computeTopoMeshVertexDuplicates(mesh) {
|
|
|
46
50
|
*/
|
|
47
51
|
const result = new Map();
|
|
48
52
|
|
|
53
|
+
let i, j;
|
|
54
|
+
|
|
55
|
+
const x0 = aabb.x0;
|
|
56
|
+
const y0 = aabb.y0;
|
|
57
|
+
const z0 = aabb.z0;
|
|
58
|
+
|
|
59
|
+
// 10 bit quantization
|
|
60
|
+
const e_x = 1023 / aabb.getExtentsX();
|
|
61
|
+
const e_y = 1023 / aabb.getExtentsY();
|
|
62
|
+
const e_z = 1023 / aabb.getExtentsZ();
|
|
63
|
+
|
|
49
64
|
//
|
|
50
|
-
for (
|
|
65
|
+
for (i = 0; i < n; i++) {
|
|
51
66
|
const vertex_a = vertices[i];
|
|
52
67
|
|
|
53
|
-
const morton = mortonEncode_magicbits(
|
|
68
|
+
const morton = mortonEncode_magicbits(
|
|
69
|
+
Math.round((vertex_a.x - x0) * e_x),
|
|
70
|
+
Math.round((vertex_a.y - y0) * e_y),
|
|
71
|
+
Math.round((vertex_a.z - z0) * e_z)
|
|
72
|
+
);
|
|
54
73
|
|
|
55
74
|
let spatial_bucket = spatial_hash[morton];
|
|
56
75
|
if (spatial_bucket === undefined) {
|
|
@@ -59,7 +78,7 @@ export function computeTopoMeshVertexDuplicates(mesh) {
|
|
|
59
78
|
} else {
|
|
60
79
|
// look at others in the bucket
|
|
61
80
|
const bucket_size = spatial_bucket.length;
|
|
62
|
-
for (
|
|
81
|
+
for (j = 0; j < bucket_size; j++) {
|
|
63
82
|
/**
|
|
64
83
|
* @type {TopoVertex}
|
|
65
84
|
*/
|
|
@@ -77,4 +96,4 @@ export function computeTopoMeshVertexDuplicates(mesh) {
|
|
|
77
96
|
}
|
|
78
97
|
|
|
79
98
|
return result;
|
|
80
|
-
}
|
|
99
|
+
}
|
|
@@ -1,35 +1,46 @@
|
|
|
1
1
|
import { array_copy } from "../../../collection/array/copyArray.js";
|
|
2
|
-
import { arraySetDiff } from "../../../collection/Set.js";
|
|
3
2
|
import { computeTopoMeshVertexDuplicates } from "./computeTopoMeshVertexDuplicates.js";
|
|
3
|
+
import { arraySetSortingDiff } from "../../../collection/array/arraySetSortingDiff.js";
|
|
4
|
+
import { compareFaces } from "./compareFaces.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
*
|
|
8
|
+
* @param {TopoEdge[]} result
|
|
7
9
|
* @param {TopoVertex[]} source_a
|
|
8
10
|
* @param {TopoVertex[]} source_b
|
|
9
|
-
* @returns {
|
|
11
|
+
* @returns {number} number of elements placed into the result array
|
|
10
12
|
*/
|
|
11
|
-
function findCommonDuplicateEdges(source_a, source_b) {
|
|
12
|
-
|
|
13
|
+
function findCommonDuplicateEdges(result, source_a, source_b) {
|
|
14
|
+
let i, j;
|
|
15
|
+
let result_count = 0;
|
|
13
16
|
|
|
14
17
|
const na = source_a.length;
|
|
15
|
-
|
|
18
|
+
|
|
19
|
+
for (i = 0; i < na; i++) {
|
|
16
20
|
const v_a = source_a[i];
|
|
17
21
|
|
|
18
22
|
const edges_a = v_a.edges;
|
|
19
23
|
|
|
20
24
|
const edge_count_a = edges_a.length;
|
|
21
|
-
for (
|
|
25
|
+
for (j = 0; j < edge_count_a; j++) {
|
|
22
26
|
const topoEdge = edges_a[j];
|
|
23
27
|
|
|
24
28
|
const other_vertex_a = topoEdge.getOtherVertex(v_a);
|
|
25
29
|
|
|
26
30
|
if (source_b.includes(other_vertex_a)) {
|
|
27
|
-
result.
|
|
31
|
+
const existing_result_place = result.indexOf(topoEdge);
|
|
32
|
+
|
|
33
|
+
if (existing_result_place > result_count || existing_result_place === -1) {
|
|
34
|
+
// not included in result set yet
|
|
35
|
+
result[result_count] = topoEdge;
|
|
36
|
+
result_count++;
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
}
|
|
29
40
|
}
|
|
30
41
|
}
|
|
31
42
|
|
|
32
|
-
return
|
|
43
|
+
return result_count;
|
|
33
44
|
}
|
|
34
45
|
|
|
35
46
|
/**
|
|
@@ -41,23 +52,30 @@ function connectEdges(a, b) {
|
|
|
41
52
|
const faces_a = a.faces;
|
|
42
53
|
const faces_b = b.faces;
|
|
43
54
|
|
|
44
|
-
const diff =
|
|
55
|
+
const diff = arraySetSortingDiff(faces_a, faces_b, compareFaces);
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
const unique_a = diff.uniqueA;
|
|
58
|
+
const unique_b = diff.uniqueB;
|
|
48
59
|
|
|
60
|
+
array_copy(unique_a, 0, faces_b, faces_b.length, unique_a.length);
|
|
61
|
+
array_copy(unique_b, 0, faces_a, faces_a.length, unique_b.length);
|
|
49
62
|
}
|
|
50
63
|
|
|
51
64
|
/**
|
|
52
|
-
*
|
|
65
|
+
* Connect together vertices that are spatially on top of one another
|
|
53
66
|
* @param {TopoMesh} mesh
|
|
67
|
+
* @param {AABB3} aabb
|
|
54
68
|
*/
|
|
55
|
-
export function expandConnectivityByLocality(mesh) {
|
|
69
|
+
export function expandConnectivityByLocality(mesh, aabb) {
|
|
70
|
+
const duplicate_edges = [];
|
|
56
71
|
|
|
57
|
-
const vertex_duplicates = computeTopoMeshVertexDuplicates(mesh);
|
|
72
|
+
const vertex_duplicates = computeTopoMeshVertexDuplicates(mesh, aabb);
|
|
58
73
|
|
|
59
74
|
// find duplicate edges from vertices
|
|
60
75
|
const edges = mesh.getEdges();
|
|
76
|
+
|
|
77
|
+
let j;
|
|
78
|
+
|
|
61
79
|
for (let topoEdge of edges) {
|
|
62
80
|
|
|
63
81
|
const duplicate_v0s = vertex_duplicates.get(topoEdge.v0);
|
|
@@ -74,12 +92,10 @@ export function expandConnectivityByLocality(mesh) {
|
|
|
74
92
|
continue;
|
|
75
93
|
}
|
|
76
94
|
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
const n = dulicate_edges.length;
|
|
95
|
+
const n = findCommonDuplicateEdges(duplicate_edges, duplicate_v0s, duplicate_v1s);
|
|
80
96
|
|
|
81
|
-
for (
|
|
82
|
-
const dulicateEdge =
|
|
97
|
+
for (j = 0; j < n; j++) {
|
|
98
|
+
const dulicateEdge = duplicate_edges[j];
|
|
83
99
|
connectEdges(topoEdge, dulicateEdge);
|
|
84
100
|
}
|
|
85
101
|
}
|
package/core/geom/Vector2.js
CHANGED
|
@@ -332,8 +332,13 @@ class Vector2 {
|
|
|
332
332
|
return { x: this.x, y: this.y };
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
-
fromJSON(
|
|
336
|
-
|
|
335
|
+
fromJSON(json) {
|
|
336
|
+
if (typeof json === "number") {
|
|
337
|
+
this.set(json, json);
|
|
338
|
+
} else {
|
|
339
|
+
const { x = 0, y = 0 } = json;
|
|
340
|
+
this.set(x, y);
|
|
341
|
+
}
|
|
337
342
|
}
|
|
338
343
|
|
|
339
344
|
/**
|
package/core/geom/Vector3.js
CHANGED
|
@@ -11,7 +11,7 @@ import { sign } from "../math/sign.js";
|
|
|
11
11
|
import { v3_dot } from "./v3_dot.js";
|
|
12
12
|
import { v3_length_sqr } from "./v3_length_sqr.js";
|
|
13
13
|
import { v3_length } from "./v3_length.js";
|
|
14
|
-
import { v3_angle_between
|
|
14
|
+
import { v3_angle_between } from "./v3_angle_between.js";
|
|
15
15
|
import { v3_lerp } from "./v3_lerp.js";
|
|
16
16
|
import { v3_slerp } from "./v3_slerp.js";
|
|
17
17
|
import { computeHashFloat } from "../math/hash/computeHashFloat.js";
|
|
@@ -448,7 +448,7 @@ class Vector3 {
|
|
|
448
448
|
* @returns {number}
|
|
449
449
|
*/
|
|
450
450
|
angleTo(other) {
|
|
451
|
-
return
|
|
451
|
+
return v3_angle_between(this.x, this.y, this.z, other.x, other.y, other.z);
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
/**
|
|
@@ -31,7 +31,7 @@ export function v3_angle_between(x0, y0, z0, x1, y1, z1) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
34
|
+
* @see https://stackoverflow.com/questions/21483999/using-atan2-to-find-angle-between-two-vectors
|
|
35
35
|
* @param {number} x0
|
|
36
36
|
* @param {number} y0
|
|
37
37
|
* @param {number} z0
|
|
@@ -41,6 +41,8 @@ export function v3_angle_between(x0, y0, z0, x1, y1, z1) {
|
|
|
41
41
|
* @returns {number}
|
|
42
42
|
*/
|
|
43
43
|
export function v3_angle_between_atan2(x0, y0, z0, x1, y1, z1) {
|
|
44
|
+
// angle = atan2(norm(cross(a,b)), dot(a,b))
|
|
45
|
+
|
|
44
46
|
const cx = y0 * z1 - z0 * y1;
|
|
45
47
|
const cy = z0 * x1 - x0 * z1;
|
|
46
48
|
const cz = x0 * y1 - y0 * x1;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { storiesOf } from "@storybook/html/dist/client/preview";
|
|
2
2
|
import { Localization } from "../../../../../core/Localization.js";
|
|
3
3
|
import { ItemContainerController } from "./ItemContainerController.js";
|
|
4
|
-
import ItemContainer from "../../../../../../model/game/ecs/component/ItemContainer.js";
|
|
4
|
+
import ItemContainer from "../../../../../../model/game/ecs/component/item_container/ItemContainer.js";
|
|
5
5
|
import Item from "../../../../../../model/game/ecs/component/Item.js";
|
|
6
6
|
import { EngineHarness } from "../../../../../engine/EngineHarness.js";
|
|
7
7
|
import { assert } from "../../../../../core/assert.js";
|
|
@@ -19,10 +19,11 @@ async function decode_png(png_bytes) {
|
|
|
19
19
|
// console.profileEnd('decode');
|
|
20
20
|
|
|
21
21
|
resolve({
|
|
22
|
-
data: uint_channels.data,
|
|
22
|
+
data: uint_channels.data.buffer,
|
|
23
23
|
width,
|
|
24
24
|
height,
|
|
25
|
-
itemSize: uint_channels.itemSize
|
|
25
|
+
itemSize: uint_channels.itemSize,
|
|
26
|
+
bitDepth: uint_channels.bitDepth
|
|
26
27
|
});
|
|
27
28
|
});
|
|
28
29
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Asset } from "../../Asset.js";
|
|
2
|
+
import { Sampler2D } from "../../../graphics/texture/sampler/Sampler2D.js";
|
|
2
3
|
|
|
3
4
|
export class ImageRGBADataAsset extends Asset {
|
|
4
5
|
/**
|
|
@@ -39,11 +40,6 @@ export class ImageRGBADataAsset extends Asset {
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
create() {
|
|
42
|
-
return
|
|
43
|
-
data: this.data,
|
|
44
|
-
width: this.width,
|
|
45
|
-
height: this.height,
|
|
46
|
-
itemSize: this.itemSize
|
|
47
|
-
};
|
|
43
|
+
return new Sampler2D(this.data, this.itemSize, this.width, this.height);
|
|
48
44
|
}
|
|
49
45
|
}
|