@woosh/meep-engine 2.33.74 → 2.34.1

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.
Files changed (52) hide show
  1. package/core/collection/Set.js +0 -61
  2. package/core/collection/array/arrayIndexByEquality.js +20 -0
  3. package/core/collection/array/arraySetDiff.js +42 -0
  4. package/core/collection/array/arraySetSortingDiff.js +67 -0
  5. package/core/collection/array/arraySetSortingDiff.spec.js +74 -0
  6. package/core/collection/array/array_filter_by_multiple.js +36 -0
  7. package/core/collection/array/weightedRandomFromArray.js +9 -5
  8. package/core/collection/list/FilteredListProjection.js +1 -1
  9. package/core/collection/list/List.js +2 -1
  10. package/core/geom/3d/topology/compareEdges.js +16 -0
  11. package/core/geom/3d/topology/compareFaces.js +9 -0
  12. package/core/geom/3d/topology/compareVertices.js +9 -0
  13. package/core/geom/3d/topology/computeTopoMeshVertexDuplicates.js +25 -6
  14. package/core/geom/3d/topology/expandConnectivityByLocality.js +35 -19
  15. package/core/geom/Vector2.js +7 -2
  16. package/core/geom/Vector3.js +2 -2
  17. package/core/geom/v3_angle_between.js +3 -1
  18. package/editor/view/ecs/components/items/ItemContainerController.stories.js +1 -1
  19. package/engine/asset/loaders/image/ImageDecoderWorker.js +3 -2
  20. package/engine/asset/loaders/image/ImageRGBADataAsset.js +2 -6
  21. package/engine/asset/loaders/image/ImageRGBADataLoader.js +18 -2
  22. package/engine/asset/loaders/image/codec/NativeImageDecoder.js +2 -1
  23. package/engine/asset/loaders/image/png/PNG.js +3 -2
  24. package/engine/asset/loaders/image/png/PNGReader.js +1 -0
  25. package/engine/ecs/EntityComponentDataset.js +1 -1
  26. package/engine/ecs/terrain/ecs/splat/SplatMapping.js +39 -26
  27. package/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +3 -4
  28. package/engine/graphics/ecs/highlight/system/MeshHighlightSystem.d.ts +3 -2
  29. package/engine/graphics/ecs/highlight/system/RenderableHighlightSystem.d.ts +3 -1
  30. package/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts +8 -0
  31. package/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +180 -0
  32. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +74 -16
  33. package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +7 -0
  34. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +9 -0
  35. package/engine/graphics/ecs/mesh-v2/prototypeShadedGeometry.js +4 -2
  36. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +41 -1
  37. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +10 -1
  38. package/engine/graphics/particles/particular/engine/parameter/ParticleParameter.js +7 -2
  39. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +3 -2
  40. package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +7 -3
  41. package/engine/graphics/texture/sampler/Sampler2D.js +2 -0
  42. package/engine/graphics/texture/sampler/downsampleSampler2D.js +3 -1
  43. package/engine/graphics/texture/sampler/genericResampleSampler2D.js +67 -0
  44. package/engine/graphics/texture/sampler/scaleSampler2D.js +29 -35
  45. package/engine/graphics/texture/sampler/upsampleSampler2D.js +47 -0
  46. package/generation/filtering/numeric/CellFilterReadGridLayer.js +2 -2
  47. package/generation/filtering/numeric/math/CellFilterSaturate.js +24 -0
  48. package/package.json +1 -1
  49. package/samples/terrain/from_image.js +289 -0
  50. package/samples/terrain/from_image_2.js +219 -0
  51. package/view/elements/radial/RadialMenu.js +1 -1
  52. package/generation/theme/TerrainThemeApplicator.js +0 -6
@@ -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
- const weights = [];
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.typeOf(random, 'function', 'random');
20
- assert.typeOf(weight, 'function', 'weight');
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
- weights[i] = weight_total;
43
+ scratch_weights[i] = weight_total;
40
44
  }
41
45
 
42
46
  const target_weight = random() * weight_total;
43
47
 
44
- const index = binarySearchHighIndex(weights, target_weight, compareNumbers, 0, length - 1);
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 { arrayIndexByEquality, arraySetDiff } from "../Set.js";
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
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ * @param {TopoTriangle} a
4
+ * @param {TopoTriangle} b
5
+ * @returns {number}
6
+ */
7
+ export function compareFaces(a, b) {
8
+ return a.index - b.index;
9
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ * @param {TopoVertex} a
4
+ * @param {TopoVertex} b
5
+ * @returns {number}
6
+ */
7
+ export function compareVertices(a, b) {
8
+ return a.index - b.index;
9
+ }
@@ -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) && epsilonEquals(b.y, a.y, EPSILON) && epsilonEquals(b.z, a.z, 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 (let i = 0; i < n; i++) {
65
+ for (i = 0; i < n; i++) {
51
66
  const vertex_a = vertices[i];
52
67
 
53
- const morton = mortonEncode_magicbits(vertex_a.x*1000, vertex_a.y*1000, vertex_a.z*1000);
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 (let j = 0; j < bucket_size; j++) {
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 {TopoEdge[]}
11
+ * @returns {number} number of elements placed into the result array
10
12
  */
11
- function findCommonDuplicateEdges(source_a, source_b) {
12
- const result = [];
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
- for (let i = 0; i < na; i++) {
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 (let j = 0; j < edge_count_a; j++) {
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.push(topoEdge);
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 result;
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 = arraySetDiff(faces_a, faces_b);
55
+ const diff = arraySetSortingDiff(faces_a, faces_b, compareFaces);
45
56
 
46
- array_copy(diff.uniqueA, 0, faces_b, faces_b.length, diff.uniqueA.length);
47
- array_copy(diff.uniqueB, 0, faces_a, faces_a.length, diff.uniqueB.length);
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 dulicate_edges = findCommonDuplicateEdges(duplicate_v0s, duplicate_v1s);
78
-
79
- const n = dulicate_edges.length;
95
+ const n = findCommonDuplicateEdges(duplicate_edges, duplicate_v0s, duplicate_v1s);
80
96
 
81
- for (let j = 0; j < n; j++) {
82
- const dulicateEdge = dulicate_edges[j];
97
+ for (j = 0; j < n; j++) {
98
+ const dulicateEdge = duplicate_edges[j];
83
99
  connectEdges(topoEdge, dulicateEdge);
84
100
  }
85
101
  }
@@ -332,8 +332,13 @@ class Vector2 {
332
332
  return { x: this.x, y: this.y };
333
333
  }
334
334
 
335
- fromJSON({ x = 0, y = 0 }) {
336
- this.set(x, y);
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
  /**
@@ -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, v3_angle_between_atan2 } from "./v3_angle_between.js";
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 v3_angle_between_atan2(this.x, this.y, this.z, other.x, other.y, other.z);
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
  }