@woosh/meep-engine 2.169.2 → 2.169.3

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 (37) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/mat4/m4_decompose.d.ts +5 -9
  3. package/src/core/geom/3d/mat4/m4_decompose.d.ts.map +1 -1
  4. package/src/core/geom/3d/mat4/m4_decompose.js +40 -60
  5. package/src/core/geom/3d/mat4/m4_decompose_array.d.ts +28 -0
  6. package/src/core/geom/3d/mat4/m4_decompose_array.d.ts.map +1 -0
  7. package/src/core/geom/3d/mat4/m4_decompose_array.js +157 -0
  8. package/src/core/primitives/strings/string_jaro_distance.d.ts +2 -2
  9. package/src/core/primitives/strings/string_jaro_distance.js +4 -4
  10. package/src/engine/Engine.d.ts.map +1 -1
  11. package/src/engine/Engine.js +0 -2
  12. package/src/engine/asset/loaders/SoundAssetLoader.d.ts.map +1 -1
  13. package/src/engine/asset/loaders/SoundAssetLoader.js +12 -1
  14. package/src/engine/ecs/gui/GUIElementSystem.d.ts +9 -0
  15. package/src/engine/ecs/gui/GUIElementSystem.d.ts.map +1 -1
  16. package/src/engine/ecs/gui/GUIElementSystem.js +23 -3
  17. package/src/engine/ecs/gui/position/ViewportPositionSystem.d.ts.map +1 -1
  18. package/src/engine/ecs/gui/position/ViewportPositionSystem.js +4 -2
  19. package/src/engine/ecs/transform/Transform64.d.ts +306 -0
  20. package/src/engine/ecs/transform/Transform64.d.ts.map +1 -0
  21. package/src/engine/ecs/transform/Transform64.js +591 -0
  22. package/src/engine/graphics/ecs/mesh/SkeletonUtils.d.ts +3 -3
  23. package/src/engine/graphics/ecs/mesh/SkeletonUtils.js +4 -4
  24. package/src/engine/graphics/ecs/mesh-v2/DeferredBoundsQueue.d.ts +48 -0
  25. package/src/engine/graphics/ecs/mesh-v2/DeferredBoundsQueue.d.ts.map +1 -0
  26. package/src/engine/graphics/ecs/mesh-v2/DeferredBoundsQueue.js +88 -0
  27. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +28 -0
  28. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +79 -0
  30. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +21 -3
  31. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts +13 -1
  32. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts.map +1 -1
  33. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +47 -10
  34. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  35. package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +3 -3
  36. package/src/view/minimap/gl/MinimapMarkersGL.d.ts.map +1 -1
  37. package/src/view/minimap/gl/MinimapMarkersGL.js +3 -1
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Pure JavaScript game engine. Fully featured and production ready.",
7
7
  "type": "module",
8
8
  "author": "Alexander Goldring",
9
- "version": "2.169.2",
9
+ "version": "2.169.3",
10
10
  "main": "build/meep.module.js",
11
11
  "module": "build/meep.module.js",
12
12
  "exports": {
@@ -1,17 +1,13 @@
1
1
  /**
2
2
  * Decompose a 4x4 transform into position, rotation and scale.
3
3
  *
4
- * The three column magnitudes are computed the same way {@link m4_extract_scale} computes them, but this
5
- * is deliberately NOT delegated: `m4_extract_scale` reports the raw column lengths, whereas this folds a
6
- * reflection (negative upper-left determinant) into one scale axis so the extracted rotation is proper.
7
- * The two therefore return different scale values for a mirrored matrix and are not interchangeable —
8
- * only the three `v3_length` calls coincide, and this function needs the raw `m11..m33` components again
9
- * for the determinant and the rotation extraction.
4
+ * The three outputs are written through their setters, so `Vector3`/`Quaternion` change signals fire.
5
+ * Use {@link m4_decompose_array} instead when the destinations are flat arrays.
10
6
  *
11
- * @param {number[]} mat4
7
+ * @param {number[]|Float32Array|Float64Array|mat4} mat4
12
8
  * @param {Vector3|{set(x:number,y:number,z:number)}} position
13
- * @param {Quaternion} rotation
9
+ * @param {Quaternion|{set(x:number,y:number,z:number,w:number)}} rotation
14
10
  * @param {Vector3|{set(x:number,y:number,z:number)}} scale
15
11
  */
16
- export function m4_decompose(mat4: number[], position: any, rotation: Quaternion, scale: any): void;
12
+ export function m4_decompose(mat4: any, position: any, rotation: any, scale: any): void;
17
13
  //# sourceMappingURL=m4_decompose.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"m4_decompose.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/mat4/m4_decompose.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,mCALW,MAAM,EAAE,yDAuElB"}
1
+ {"version":3,"file":"m4_decompose.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/mat4/m4_decompose.js"],"names":[],"mappings":"AAOA;;;;;;;;;;GAUG;AACH,wFA6CC"}
@@ -1,84 +1,64 @@
1
- import { v3_length } from "../../vec3/v3_length.js";
1
+ import { m4_decompose_array } from "./m4_decompose_array.js";
2
+
3
+ /**
4
+ * @type {Float64Array}
5
+ */
6
+ const scratch = new Float64Array(10);
2
7
 
3
8
  /**
4
9
  * Decompose a 4x4 transform into position, rotation and scale.
5
10
  *
6
- * The three column magnitudes are computed the same way {@link m4_extract_scale} computes them, but this
7
- * is deliberately NOT delegated: `m4_extract_scale` reports the raw column lengths, whereas this folds a
8
- * reflection (negative upper-left determinant) into one scale axis so the extracted rotation is proper.
9
- * The two therefore return different scale values for a mirrored matrix and are not interchangeable —
10
- * only the three `v3_length` calls coincide, and this function needs the raw `m11..m33` components again
11
- * for the determinant and the rotation extraction.
11
+ * The three outputs are written through their setters, so `Vector3`/`Quaternion` change signals fire.
12
+ * Use {@link m4_decompose_array} instead when the destinations are flat arrays.
12
13
  *
13
- * @param {number[]} mat4
14
+ * @param {number[]|Float32Array|Float64Array|mat4} mat4
14
15
  * @param {Vector3|{set(x:number,y:number,z:number)}} position
15
- * @param {Quaternion} rotation
16
+ * @param {Quaternion|{set(x:number,y:number,z:number,w:number)}} rotation
16
17
  * @param {Vector3|{set(x:number,y:number,z:number)}} scale
17
18
  */
18
19
  export function m4_decompose(mat4, position, rotation, scale) {
19
- const m11 = mat4[0];
20
- const m12 = mat4[1];
21
- const m13 = mat4[2];
22
-
23
- const scale_x = v3_length(m11, m12, m13);
24
-
25
- const m21 = mat4[4];
26
- const m22 = mat4[5];
27
- const m23 = mat4[6];
28
-
29
- const scale_y = v3_length(m21, m22, m23);
30
20
 
31
- const m31 = mat4[8];
32
- const m32 = mat4[9];
33
- const m33 = mat4[10];
34
-
35
- const scale_z = v3_length(m31, m32, m33);
36
-
37
- // If the upper-left 3x3 has a negative determinant the matrix encodes a reflection; fold that sign into
38
- // one scale axis (matching three.js, which negates scale.x) so the extracted rotation is a proper rotation
39
- // rather than a mirror (which __setFromRotationMatrix would decode incorrectly).
40
- const det =
41
- m11 * (m22 * m33 - m23 * m32)
42
- - m12 * (m21 * m33 - m23 * m31)
43
- + m13 * (m21 * m32 - m22 * m31);
44
-
45
- const signed_scale_x = det < 0 ? -scale_x : scale_x;
46
-
47
- // extract rotation matrix
48
- // take care of potential division by 0 when scale is 0. Result is inexact, but we get don't break the system at least
49
- const is1 = signed_scale_x !== 0 ? 1 / signed_scale_x : 1e7;
50
- const is2 = scale_y !== 0 ? 1 / scale_y : 1e7;
51
- const is3 = scale_z !== 0 ? 1 / scale_z : 1e7;
52
-
53
- const sm11 = m11 * is1;
54
- const sm12 = m12 * is1;
55
- const sm13 = m13 * is1;
21
+ // the scratch is what lets this share the decomposition math with `m4_decompose_array`
22
+ // instead of carrying a second copy of it, laid out as [translation:3, rotation:4, scale:3]
23
+ m4_decompose_array(
24
+ mat4,
25
+ scratch, 0,
26
+ scratch, 3,
27
+ scratch, 7
28
+ );
56
29
 
57
- const sm21 = m21 * is2;
58
- const sm22 = m22 * is2;
59
- const sm23 = m23 * is2;
30
+ // Drain the scratch before writing anything out. The setters below dispatch change signals, and a
31
+ // handler is free to call this function again - that would overwrite the module-static scratch
32
+ // part-way through, and the rest of this call would read the re-entrant call's numbers.
33
+ const position_x = scratch[0];
34
+ const position_y = scratch[1];
35
+ const position_z = scratch[2];
60
36
 
61
- const sm31 = m31 * is3;
62
- const sm32 = m32 * is3;
63
- const sm33 = m33 * is3;
37
+ const rotation_x = scratch[3];
38
+ const rotation_y = scratch[4];
39
+ const rotation_z = scratch[5];
40
+ const rotation_w = scratch[6];
64
41
 
65
- // write out results
42
+ const scale_x = scratch[7];
43
+ const scale_y = scratch[8];
44
+ const scale_z = scratch[9];
66
45
 
67
46
  position.set(
68
- mat4[12],
69
- mat4[13],
70
- mat4[14]
47
+ position_x,
48
+ position_y,
49
+ position_z
71
50
  );
72
51
 
73
52
  scale.set(
74
- signed_scale_x,
53
+ scale_x,
75
54
  scale_y,
76
55
  scale_z
77
56
  );
78
57
 
79
- rotation.__setFromRotationMatrix(
80
- sm11, sm21, sm31,
81
- sm12, sm22, sm32,
82
- sm13, sm23, sm33
58
+ rotation.set(
59
+ rotation_x,
60
+ rotation_y,
61
+ rotation_z,
62
+ rotation_w
83
63
  );
84
64
  }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Decompose a 4x4 transform into a translation, a rotation quaternion and a (non-uniform) scale,
3
+ * written into flat arrays at explicit offsets.
4
+ *
5
+ * Array-argument companion to {@link m4_decompose}, which takes `Vector3`/`Quaternion` objects instead.
6
+ * Use this one when the destinations are already flat arrays, such as {@link Transform64} which packs
7
+ * all four of these in a single buffer.
8
+ *
9
+ * The three destinations may all be the same array, as long as the ranges do not overlap, and they may
10
+ * overlap `m4` itself - every component of `m4` is read before the first write.
11
+ *
12
+ * A reflection (negative upper-left determinant) is folded into one scale axis, so that the extracted
13
+ * rotation is always proper. Note that this makes the scale reported here differ from
14
+ * {@link m4_extract_scale}, which reports raw column lengths; the two are not interchangeable.
15
+ *
16
+ * @param {number[]|Float32Array|Float64Array|mat4} m4 source 4x4 matrix
17
+ * @param {number[]|Float32Array|Float64Array} translation receives 3 numbers (x, y, z)
18
+ * @param {number} translation_offset offset into `translation`
19
+ * @param {number[]|Float32Array|Float64Array} rotation receives 4 numbers (x, y, z, w)
20
+ * @param {number} rotation_offset offset into `rotation`
21
+ * @param {number[]|Float32Array|Float64Array} scale receives 3 numbers (x, y, z)
22
+ * @param {number} scale_offset offset into `scale`
23
+ *
24
+ * @author Alex Goldring
25
+ * @copyright Company Named Limited (c) 2026
26
+ */
27
+ export function m4_decompose_array(m4: number[] | Float32Array | Float64Array | mat4, translation: number[] | Float32Array | Float64Array, translation_offset: number, rotation: number[] | Float32Array | Float64Array, rotation_offset: number, scale: number[] | Float32Array | Float64Array, scale_offset: number): void;
28
+ //# sourceMappingURL=m4_decompose_array.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"m4_decompose_array.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/mat4/m4_decompose_array.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,uCAXW,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,OAAK,eACvC,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,sBAClC,MAAM,YACN,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,mBAClC,MAAM,SACN,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,gBAClC,MAAM,QAqIhB"}
@@ -0,0 +1,157 @@
1
+ import { v3_length } from "../../vec3/v3_length.js";
2
+
3
+ /**
4
+ * Decompose a 4x4 transform into a translation, a rotation quaternion and a (non-uniform) scale,
5
+ * written into flat arrays at explicit offsets.
6
+ *
7
+ * Array-argument companion to {@link m4_decompose}, which takes `Vector3`/`Quaternion` objects instead.
8
+ * Use this one when the destinations are already flat arrays, such as {@link Transform64} which packs
9
+ * all four of these in a single buffer.
10
+ *
11
+ * The three destinations may all be the same array, as long as the ranges do not overlap, and they may
12
+ * overlap `m4` itself - every component of `m4` is read before the first write.
13
+ *
14
+ * A reflection (negative upper-left determinant) is folded into one scale axis, so that the extracted
15
+ * rotation is always proper. Note that this makes the scale reported here differ from
16
+ * {@link m4_extract_scale}, which reports raw column lengths; the two are not interchangeable.
17
+ *
18
+ * @param {number[]|Float32Array|Float64Array|mat4} m4 source 4x4 matrix
19
+ * @param {number[]|Float32Array|Float64Array} translation receives 3 numbers (x, y, z)
20
+ * @param {number} translation_offset offset into `translation`
21
+ * @param {number[]|Float32Array|Float64Array} rotation receives 4 numbers (x, y, z, w)
22
+ * @param {number} rotation_offset offset into `rotation`
23
+ * @param {number[]|Float32Array|Float64Array} scale receives 3 numbers (x, y, z)
24
+ * @param {number} scale_offset offset into `scale`
25
+ *
26
+ * @author Alex Goldring
27
+ * @copyright Company Named Limited (c) 2026
28
+ */
29
+ export function m4_decompose_array(
30
+ m4,
31
+ translation, translation_offset,
32
+ rotation, rotation_offset,
33
+ scale, scale_offset
34
+ ) {
35
+ const m11 = m4[0];
36
+ const m12 = m4[1];
37
+ const m13 = m4[2];
38
+
39
+ const scale_x = v3_length(m11, m12, m13);
40
+
41
+ const m21 = m4[4];
42
+ const m22 = m4[5];
43
+ const m23 = m4[6];
44
+
45
+ const scale_y = v3_length(m21, m22, m23);
46
+
47
+ const m31 = m4[8];
48
+ const m32 = m4[9];
49
+ const m33 = m4[10];
50
+
51
+ const scale_z = v3_length(m31, m32, m33);
52
+
53
+ const translation_x = m4[12];
54
+ const translation_y = m4[13];
55
+ const translation_z = m4[14];
56
+
57
+ // If the upper-left 3x3 has a negative determinant the matrix encodes a reflection; fold that sign into
58
+ // one scale axis (matching three.js, which negates scale.x) so the extracted rotation is a proper rotation
59
+ // rather than a mirror (which the quaternion extraction below would decode incorrectly).
60
+ const det =
61
+ m11 * (m22 * m33 - m23 * m32)
62
+ - m12 * (m21 * m33 - m23 * m31)
63
+ + m13 * (m21 * m32 - m22 * m31);
64
+
65
+ const signed_scale_x = det < 0 ? -scale_x : scale_x;
66
+
67
+ // extract rotation matrix
68
+ // take care of potential division by 0 when scale is 0. Result is inexact, but we get don't break the system at least
69
+ const is1 = signed_scale_x !== 0 ? 1 / signed_scale_x : 1e7;
70
+ const is2 = scale_y !== 0 ? 1 / scale_y : 1e7;
71
+ const is3 = scale_z !== 0 ? 1 / scale_z : 1e7;
72
+
73
+ const sm11 = m11 * is1;
74
+ const sm12 = m12 * is1;
75
+ const sm13 = m13 * is1;
76
+
77
+ const sm21 = m21 * is2;
78
+ const sm22 = m22 * is2;
79
+ const sm23 = m23 * is2;
80
+
81
+ const sm31 = m31 * is3;
82
+ const sm32 = m32 * is3;
83
+ const sm33 = m33 * is3;
84
+
85
+ // Convert the rotation matrix to a quaternion.
86
+ // This algorithm comes from "Quaternion Calculus and Fast Animation", Ken Shoemake, 1987 SIGGRAPH course notes
87
+ // @see https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/src/Geometry/Quaternion.h#L813
88
+ // NOTE: `sm` is stored column-major, so the row-major element `m_ij` used by the algorithm is `sm_ji`
89
+ const trace = sm11 + sm22 + sm33;
90
+
91
+ let x, y, z, w, s;
92
+
93
+ if (trace > 0) {
94
+
95
+ s = Math.sqrt(trace + 1.0);
96
+
97
+ w = 0.5 * s;
98
+
99
+ s = 0.5 / s;
100
+
101
+ x = (sm23 - sm32) * s;
102
+ y = (sm31 - sm13) * s;
103
+ z = (sm12 - sm21) * s;
104
+
105
+ } else if (sm11 > sm22 && sm11 > sm33) {
106
+
107
+ s = Math.sqrt(1.0 + sm11 - sm22 - sm33);
108
+
109
+ x = 0.5 * s;
110
+
111
+ s = 0.5 / s;
112
+
113
+ w = (sm23 - sm32) * s;
114
+ y = (sm21 + sm12) * s;
115
+ z = (sm31 + sm13) * s;
116
+
117
+ } else if (sm22 > sm33) {
118
+
119
+ s = Math.sqrt(1.0 + sm22 - sm11 - sm33);
120
+
121
+ y = 0.5 * s;
122
+
123
+ s = 0.5 / s;
124
+
125
+ w = (sm31 - sm13) * s;
126
+ x = (sm21 + sm12) * s;
127
+ z = (sm32 + sm23) * s;
128
+
129
+ } else {
130
+
131
+ s = Math.sqrt(1.0 + sm33 - sm11 - sm22);
132
+
133
+ z = 0.5 * s;
134
+
135
+ s = 0.5 / s;
136
+
137
+ w = (sm12 - sm21) * s;
138
+ x = (sm31 + sm13) * s;
139
+ y = (sm32 + sm23) * s;
140
+
141
+ }
142
+
143
+ // write out results
144
+
145
+ translation[translation_offset] = translation_x;
146
+ translation[translation_offset + 1] = translation_y;
147
+ translation[translation_offset + 2] = translation_z;
148
+
149
+ rotation[rotation_offset] = x;
150
+ rotation[rotation_offset + 1] = y;
151
+ rotation[rotation_offset + 2] = z;
152
+ rotation[rotation_offset + 3] = w;
153
+
154
+ scale[scale_offset] = signed_scale_x;
155
+ scale[scale_offset + 1] = scale_y;
156
+ scale[scale_offset + 2] = scale_z;
157
+ }
@@ -3,8 +3,8 @@
3
3
  * Higher value means more similarity.
4
4
  * @param {string} first
5
5
  * @param {string} second
6
- * @param {number} first_length
7
- * @param {number} second_length
6
+ * @param {number} first_length length of the first string
7
+ * @param {number} second_length length of the second string
8
8
  * @return {number}
9
9
  */
10
10
  export function string_jaro_distance(first: string, second: string, first_length: number, second_length: number): number;
@@ -8,16 +8,16 @@ import { min2 } from "../../math/min2.js";
8
8
  * Higher value means more similarity.
9
9
  * @param {string} first
10
10
  * @param {string} second
11
- * @param {number} first_length
12
- * @param {number} second_length
11
+ * @param {number} first_length length of the first string
12
+ * @param {number} second_length length of the second string
13
13
  * @return {number}
14
14
  */
15
15
  export function string_jaro_distance(
16
16
  first, second,
17
17
  first_length, second_length
18
18
  ) {
19
- assert.isString(first,'first');
20
- assert.isString(second,'second');
19
+ assert.isString(first, 'first');
20
+ assert.isString(second, 'second');
21
21
 
22
22
  // TODO can do better for short strings under 32 characters by using int32 bitmask. This would avoid allocation entirely
23
23
  const matches1 = BitSet.fixedSize(first_length);
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../../src/engine/Engine.js"],"names":[],"mappings":";AAuDA;IAoEI;;;;;;;;OAQG;IACH,8FANW,aAAa,EA0OvB;IA3RD;;;OAGG;IACH,UAFU,cAAc,GAAC,IAAI,CAEb;IAEhB;;;OAGG;IACH,OAFU,WAAW,GAAC,IAAI,CAEb;IAEb,qBAA4B;IAE5B;;;;;;;;;OASG;IACH,0BAFU,uBAAuB,CAEe;IAEhD;;;OAGG;IACH,kBAFU,mBAAmB,CAEO;IAEpC;;;;OAIG;IACH,iBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,mBAFU,kBAAkB,CAEa;IAmBrC;;;OAGG;IACH,yBAAwB;IAKxB;;;OAGG;IACH,aAFU,gBAAgB,CAEe;IAGzC,yCAAkE;IAK9D,mBAAkC;IAMtC;;;OAGG;IACH,cAFU,aAAa,MAAM,CAAC,CAK5B;IAEF,8CAiCE;IA4BF;;;OAGG;IACH,SAFU,WAAW,CAEoB;IAEzC;;;OAGG;IACH,oCAA0C;IAE1C;;;OAGG;IACH,sCAFU,2BAA2B,CAE+B;IAEpE,yBAAoC;IAGpC;;OAEG;IACH,aAAkB;IAElB;;;OAGG;IACH,SAFU,OAAO,CAEwB;IAGzC,2BAAsC;IAOtC,+BAA6E;IA4C7E;;;OAGG;IACH,KAFU,SAAS,CAEO;IAE1B;;;OAGG;IACH,uBAFU,YAAY,CAEqD;IAI3E;;;;MAIC;IAaD;;;OAGG;IACH,kBAFU,OAAO,CAEW;IAiGhC,wBAgCC;IApBG,oBAAwB;IAsB5B,2BAgCC;IAED,oBAiBC;IAED;;;OAGG;IACH,+CAUC;IAED,eA6BC;IAED;;;OAGG;IACH,sBAmDC;IAqBD;;OAEG;IACH,sBA2BC;IAED,aAEC;IAED;;OAEG;IACH,4BAOC;IAIL;;;OAGG;IACH,mBAFU,OAAO,CAEQ;;CAPxB;+BAhrB8B,8BAA8B;wBAUrC,wBAAwB;0BApBtB,0CAA0C;wCAc5B,iDAAiD;oCAGrD,iCAAiC;mBAElD,wBAAwB;+BArBZ,gDAAgD;iCAO9C,+CAA+C;6BAFnD,yBAAyB;uCAIf,6DAA6D;4BASxE,0BAA0B;+BApBvB,iCAAiC;4CAapB,qDAAqD;AAgBjG;IACI,gDAA2D;IAC3D,0BAAkC;IAClC,iCAAyC;CAC5C;6BAlC4B,sCAAsC;4DAHP,OAAO;sBA8B7C,mBAAmB;yBAJhB,yBAAyB;8BALpB,kCAAkC;2BADrC,mCAAmC;8BADhC,kCAAkC;sBAZ1C,+BAA+B;+BAKtB,qCAAqC;8BAItC,wBAAwB;4BAX1B,kCAAkC;oBAH1C,yBAAyB"}
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../../src/engine/Engine.js"],"names":[],"mappings":";AAuDA;IAoEI;;;;;;;;OAQG;IACH,8FANW,aAAa,EAwOvB;IAzRD;;;OAGG;IACH,UAFU,cAAc,GAAC,IAAI,CAEb;IAEhB;;;OAGG;IACH,OAFU,WAAW,GAAC,IAAI,CAEb;IAEb,qBAA4B;IAE5B;;;;;;;;;OASG;IACH,0BAFU,uBAAuB,CAEe;IAEhD;;;OAGG;IACH,kBAFU,mBAAmB,CAEO;IAEpC;;;;OAIG;IACH,iBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,mBAFU,kBAAkB,CAEa;IAmBrC;;;OAGG;IACH,yBAAwB;IAKxB;;;OAGG;IACH,aAFU,gBAAgB,CAEe;IAGzC,yCAAkE;IAK9D,mBAAkC;IAMtC;;;OAGG;IACH,cAFU,aAAa,MAAM,CAAC,CAK5B;IAEF,8CAiCE;IA4BF;;;OAGG;IACH,SAFU,WAAW,CAEoB;IAEzC;;;OAGG;IACH,oCAA0C;IAE1C;;;OAGG;IACH,sCAFU,2BAA2B,CAE+B;IAEpE,yBAAoC;IAGpC;;OAEG;IACH,aAAkB;IAElB;;;OAGG;IACH,SAFU,OAAO,CAEwB;IAGzC,2BAAsC;IAOtC,+BAA6E;IA4C7E;;;OAGG;IACH,KAFU,SAAS,CAEO;IAE1B;;;OAGG;IACH,uBAFU,YAAY,CAEqD;IAI3E;;;;MAIC;IAWD;;;OAGG;IACH,kBAFU,OAAO,CAEW;IAiGhC,wBAgCC;IApBG,oBAAwB;IAsB5B,2BAgCC;IAED,oBAiBC;IAED;;;OAGG;IACH,+CAUC;IAED,eA6BC;IAED;;;OAGG;IACH,sBAmDC;IAqBD;;OAEG;IACH,sBA2BC;IAED,aAEC;IAED;;OAEG;IACH,4BAOC;IAIL;;;OAGG;IACH,mBAFU,OAAO,CAEQ;;CAPxB;+BA9qB8B,8BAA8B;wBAUrC,wBAAwB;0BApBtB,0CAA0C;wCAc5B,iDAAiD;oCAGrD,iCAAiC;mBAElD,wBAAwB;+BArBZ,gDAAgD;iCAO9C,+CAA+C;6BAFnD,yBAAyB;uCAIf,6DAA6D;4BASxE,0BAA0B;+BApBvB,iCAAiC;4CAapB,qDAAqD;AAgBjG;IACI,gDAA2D;IAC3D,0BAAkC;IAClC,iCAAyC;CAC5C;6BAlC4B,sCAAsC;4DAHP,OAAO;sBA8B7C,mBAAmB;yBAJhB,yBAAyB;8BALpB,kCAAkC;2BADrC,mCAAmC;8BADhC,kCAAkC;sBAZ1C,+BAA+B;+BAKtB,qCAAqC;8BAItC,wBAAwB;4BAX1B,kCAAkC;oBAH1C,yBAAyB"}
@@ -339,8 +339,6 @@ class Engine {
339
339
  gamepad: new GamepadDevice()
340
340
  };
341
341
 
342
- //init level engine
343
-
344
342
  this.devices.pointer.start();
345
343
  this.devices.keyboard.start();
346
344
  this.devices.gamepad.start();
@@ -1 +1 @@
1
- {"version":3,"file":"SoundAssetLoader.d.ts","sourceRoot":"","sources":["../../../../../src/engine/asset/loaders/SoundAssetLoader.js"],"names":[],"mappings":"AAGA;IACI;;;OAGG;IACH,qBAFW,YAAY,EAUtB;IALG;;;OAGG;IACH,cAFU,YAAY,CAEK;IAG/B,6EA6BC;CACJ;4BAhD2B,kBAAkB"}
1
+ {"version":3,"file":"SoundAssetLoader.d.ts","sourceRoot":"","sources":["../../../../../src/engine/asset/loaders/SoundAssetLoader.js"],"names":[],"mappings":"AAGA;IACI;;;OAGG;IACH,qBAFW,YAAY,EAUtB;IALG;;;OAGG;IACH,cAFU,YAAY,CAEK;IAG/B,6EAwCC;CACJ;4BA3D2B,kBAAkB"}
@@ -20,13 +20,24 @@ export class SoundAssetLoader extends AssetLoader {
20
20
  // Load a sound file using an ArrayBuffer XMLHttpRequest.
21
21
  const request = new XMLHttpRequest();
22
22
 
23
- request.open("GET", this.resolvePath(path), true);
23
+ const url = this.resolvePath(path);
24
+
25
+ request.open("GET", url, true);
24
26
 
25
27
  request.responseType = "arraybuffer";
26
28
 
27
29
  const context = this.audioContext;
28
30
 
29
31
  request.onload = function (e) {
32
+ //onload fires for any completed request, 404 included -- onerror only covers
33
+ //network-level failure. Without this check the error page's bytes reach
34
+ //decodeAudioData, which fails with "Unable to decode audio data": an error that
35
+ //blames the file's contents when the file was simply never found.
36
+ if (request.status !== 0 && (request.status < 200 || request.status >= 300)) {
37
+ failure(new Error(`failed to load sound '${url}': HTTP ${request.status} ${request.statusText}`));
38
+ return;
39
+ }
40
+
30
41
  //decode works asynchronously, this is important to prevent lag in main thread
31
42
  context.decodeAudioData(request.response, function (buffer) {
32
43
  const byteSize = e.total;
@@ -15,6 +15,15 @@ declare class GUIElementSystem extends System<any> {
15
15
  * @type {Object<View>}
16
16
  */
17
17
  groups: any;
18
+ /**
19
+ * Contexts of {@link handleComponentVisibilityChange}, keyed by entity. Signal handlers are
20
+ * matched on the handle *and* the context, so the context has to survive until unlink,
21
+ * otherwise the handler stays subscribed for the lifetime of the component.
22
+ * @private
23
+ * @readonly
24
+ * @type {Map<number, object>}
25
+ */
26
+ private readonly visibilityContexts;
18
27
  containerView: View;
19
28
  /**
20
29
  * @type {ModuleRegistry}
@@ -1 +1 @@
1
- {"version":3,"file":"GUIElementSystem.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/gui/GUIElementSystem.js"],"names":[],"mappings":"AAiCA,gFAAiF;;AAEjF;IAyBI;;;;;OAKG;IACH,2BAJW,IAAI,kBAqCd;IA9DD,gBAaG;IAEH,oCAA4B;IAE5B;;;OAGG;IACH,YAAY;IA2BR,oBAAkC;IAGlC;;OAEG;IACH,8BAA0C;IAE1C;;;OAGG;IACH,eAAoB;IAIxB,gCAGC;IAED,iCAEC;IAED;;;;OAIG;IACH,2BAHW,UAAU,UACV,MAAM,QA6DhB;IAED;;;;OAIG;IACH,2BAHW,UAAU,UACV,MAAM,QAoBhB;IAED;;;;OAIG;IACH,gBAHW,UAAU,qBAiDpB;IAED;;;;OAIG;IACH,kBAHW,UAAU,qBAiBpB;CACJ;uBAhRsB,cAAc;sBAFf,qCAAqC;uBAGhB,iBAAiB;iBAF3C,uBAAuB"}
1
+ {"version":3,"file":"GUIElementSystem.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/gui/GUIElementSystem.js"],"names":[],"mappings":"AAiCA,gFAAiF;;AAEjF;IAmCI;;;;;OAKG;IACH,2BAJW,IAAI,kBAqCd;IAxED,gBAaG;IAEH,oCAA4B;IAE5B;;;OAGG;IACH,YAAY;IAEZ;;;;;;;OAOG;IACH,oCAA+B;IA2B3B,oBAAkC;IAGlC;;OAEG;IACH,8BAA0C;IAE1C;;;OAGG;IACH,eAAoB;IAIxB,gCAGC;IAED,iCAEC;IAED;;;;OAIG;IACH,2BAHW,UAAU,UACV,MAAM,QA6DhB;IAED;;;;OAIG;IACH,2BAHW,UAAU,UACV,MAAM,QAoBhB;IAED;;;;OAIG;IACH,gBAHW,UAAU,qBAqDpB;IAED;;;;OAIG;IACH,kBAHW,UAAU,qBAuBpB;CACJ;uBApSsB,cAAc;sBAFf,qCAAqC;uBAGhB,iBAAiB;iBAF3C,uBAAuB"}
@@ -58,6 +58,16 @@ class GUIElementSystem extends System {
58
58
  */
59
59
  groups = {};
60
60
 
61
+ /**
62
+ * Contexts of {@link handleComponentVisibilityChange}, keyed by entity. Signal handlers are
63
+ * matched on the handle *and* the context, so the context has to survive until unlink,
64
+ * otherwise the handler stays subscribed for the lifetime of the component.
65
+ * @private
66
+ * @readonly
67
+ * @type {Map<number, object>}
68
+ */
69
+ visibilityContexts = new Map();
70
+
61
71
  /**
62
72
  *
63
73
  * @param {View} containerView
@@ -245,11 +255,15 @@ class GUIElementSystem extends System {
245
255
  this.attachComponent(component, entity);
246
256
  }
247
257
 
248
- component.visible.onChanged.add(handleComponentVisibilityChange, {
258
+ const visibilityContext = {
249
259
  el: component,
250
260
  system: this,
251
261
  entity
252
- });
262
+ };
263
+
264
+ this.visibilityContexts.set(entity, visibilityContext);
265
+
266
+ component.visible.onChanged.add(handleComponentVisibilityChange, visibilityContext);
253
267
  }
254
268
 
255
269
  /**
@@ -258,7 +272,13 @@ class GUIElementSystem extends System {
258
272
  * @param entity
259
273
  */
260
274
  unlink(component, entity) {
261
- component.visible.onChanged.remove(handleComponentVisibilityChange);
275
+ const visibilityContext = this.visibilityContexts.get(entity);
276
+
277
+ if (visibilityContext !== undefined) {
278
+ this.visibilityContexts.delete(entity);
279
+
280
+ component.visible.onChanged.remove(handleComponentVisibilityChange, visibilityContext);
281
+ }
262
282
 
263
283
  if (component.visible.getValue()) {
264
284
  this.detachComponent(component, entity);
@@ -1 +1 @@
1
- {"version":3,"file":"ViewportPositionSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/gui/position/ViewportPositionSystem.js"],"names":[],"mappings":";AAwBA;IACI,+BAoBC;IAjBG,8DAAkD;IAElD,kEAEC;IAED,kBAAgC;IAEhC,yCAME;IAEF,SAAc;IAGlB,2CAEC;IAED,4CAEC;IAED;;;OAGG;IACH,sBAHW,UAAU,MACV,gBAAgB,QAkE1B;IAED;;;;;OAKG;IACH,SAJW,gBAAgB,MAChB,UAAU,qBA8BpB;IAED;;;;;OAKG;IACH,WAJW,gBAAgB,MAChB,UAAU,qBAmBpB;IAgGL;;;OAGG;IACH,mCAFU,OAAO,CAEwC;CAjGxD;uBAlLsB,iBAAiB;uBACjB,kBAAkB;6BAEZ,uBAAuB;4CAJR,uDAAuD;8BALrE,iDAAiD"}
1
+ {"version":3,"file":"ViewportPositionSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/gui/position/ViewportPositionSystem.js"],"names":[],"mappings":";AAwBA;IACI,+BAoBC;IAjBG,8DAAkD;IAElD,kEAEC;IAED,kBAAgC;IAEhC,yCAME;IAEF,SAAc;IAGlB,2CAEC;IAED,4CAEC;IAED;;;OAGG;IACH,sBAHW,UAAU,MACV,gBAAgB,QAkE1B;IAED;;;;;OAKG;IACH,SAJW,gBAAgB,MAChB,UAAU,qBA8BpB;IAED;;;;;OAKG;IACH,WAJW,gBAAgB,MAChB,UAAU,qBAqBpB;IAgGL;;;OAGG;IACH,mCAFU,OAAO,CAEwC;CAjGxD;uBApLsB,iBAAiB;uBACjB,kBAAkB;6BAEZ,uBAAuB;4CAJR,uDAAuD;8BALrE,iDAAiD"}
@@ -175,9 +175,11 @@ class ViewportPositionSystem extends System {
175
175
  vp.offset.onChanged.remove(updatePosition, eventContext);
176
176
  vp.anchor.onChanged.remove(updatePosition, eventContext);
177
177
  vp.enabled.onChanged.remove(updatePosition, eventContext);
178
- }
179
178
 
180
- this.entityManager.dataset.removeEntityEventListener(entity, GUIElementEvent.Initialized, updatePosition, eventContext);
179
+ el.view.size.onChanged.remove(updatePosition, eventContext);
180
+
181
+ this.entityManager.dataset.removeEntityEventListener(entity, GUIElementEvent.Initialized, updatePosition, eventContext);
182
+ }
181
183
 
182
184
  el.view.removeClass(CSS_CLASS);
183
185
  }