@woosh/meep-engine 2.43.37 → 2.43.39

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.
@@ -39,6 +39,69 @@ export class AABB3 {
39
39
  this.setBounds(x0, y0, z0, x1, y1, z1);
40
40
  }
41
41
 
42
+ * [Symbol.iterator]() {
43
+
44
+ yield this.x0;
45
+ yield this.y0;
46
+ yield this.z0;
47
+
48
+ yield this.x1;
49
+ yield this.y1;
50
+ yield this.z1;
51
+
52
+ }
53
+
54
+ get 0() {
55
+ return this.x0;
56
+ }
57
+
58
+
59
+ get 1() {
60
+ return this.y0;
61
+ }
62
+
63
+ get 2() {
64
+ return this.z0;
65
+ }
66
+
67
+
68
+ get 3() {
69
+ return this.x1;
70
+ }
71
+
72
+
73
+ get 4() {
74
+ return this.y1;
75
+ }
76
+
77
+ get 5() {
78
+ return this.z1;
79
+ }
80
+
81
+ set 0(v) {
82
+ this.x0 = v;
83
+ }
84
+
85
+ set 1(v) {
86
+ this.y0 = v;
87
+ }
88
+
89
+ set 2(v) {
90
+ this.z0 = v;
91
+ }
92
+
93
+ set 3(v) {
94
+ this.x1 = v;
95
+ }
96
+
97
+ set 4(v) {
98
+ this.y1 = v;
99
+ }
100
+
101
+ set 5(v) {
102
+ this.z1 = v;
103
+ }
104
+
42
105
  /**
43
106
  *
44
107
  * @param {number} x
@@ -816,17 +879,17 @@ export class AABB3 {
816
879
  }
817
880
 
818
881
  /**
819
- *
820
- * @param {number} v
882
+ * Expands the box in all directions by the given amount
883
+ * @param {number} extra
821
884
  */
822
- grow(v) {
823
- this.x0 -= v;
824
- this.y0 -= v;
825
- this.z0 -= v;
885
+ grow(extra) {
886
+ this.x0 -= extra;
887
+ this.y0 -= extra;
888
+ this.z0 -= extra;
826
889
 
827
- this.x1 += v;
828
- this.y1 += v;
829
- this.z1 += v;
890
+ this.x1 += extra;
891
+ this.y1 += extra;
892
+ this.z1 += extra;
830
893
  }
831
894
 
832
895
  /**
@@ -847,82 +910,6 @@ export class AABB3 {
847
910
  }
848
911
 
849
912
 
850
- /**
851
- *
852
- * @param {BinaryBuffer} buffer
853
- * @param {AABB3} box
854
- * @param {number} x0
855
- * @param {number} y0
856
- * @param {number} z0
857
- * @param {number} x1
858
- * @param {number} y1
859
- * @param {number} z1
860
- */
861
- export function serializeAABB3Encoded_v0(buffer, box, x0, y0, z0, x1, y1, z1) {
862
- let header = 0;
863
-
864
- if (box.x0 === x0) {
865
- header |= 1;
866
- }
867
-
868
- if (box.x1 === x1) {
869
- header |= 2;
870
- }
871
-
872
- if (box.y0 === y0) {
873
- header |= 4;
874
- }
875
-
876
- if (box.y1 === y1) {
877
- header |= 8;
878
- }
879
-
880
- if (box.z0 === z0) {
881
- header |= 16;
882
- }
883
-
884
- if (box.z1 === z1) {
885
- header |= 32;
886
- }
887
-
888
- buffer.writeUint8(header);
889
-
890
- //compute value ranges
891
- const xD = x1 - x0;
892
- const yD = y1 - y0;
893
- const zD = z1 - z0;
894
-
895
- if ((header & 1) === 0) {
896
- const _x0 = (((box.x0 - x0) / xD) * 65535) | 0;
897
- buffer.writeUint16(_x0);
898
- }
899
-
900
- if ((header & 2) === 0) {
901
- const _x1 = (((box.x1 - x0) / xD) * 65535) | 0;
902
- buffer.writeUint16(_x1);
903
- }
904
-
905
- if ((header & 4) === 0) {
906
- const _y0 = (((box.y0 - y0) / yD) * 65535) | 0;
907
- buffer.writeUint16(_y0);
908
- }
909
-
910
- if ((header & 8) === 0) {
911
- const _y1 = (((box.y1 - y0) / yD) * 65535) | 0;
912
- buffer.writeUint16(_y1);
913
- }
914
-
915
- if ((header & 16) === 0) {
916
- const _z0 = (((box.z0 - z0) / zD) * 65535) | 0;
917
- buffer.writeUint16(_z0);
918
- }
919
-
920
- if ((header & 32) === 0) {
921
- const _z1 = (((box.z1 - z0) / zD) * 65535) | 0;
922
- buffer.writeUint16(_z1);
923
- }
924
- }
925
-
926
913
  /**
927
914
  * @readonly
928
915
  * @type {boolean}
@@ -0,0 +1,75 @@
1
+ /**
2
+ *
3
+ * @param {BinaryBuffer} buffer
4
+ * @param {AABB3} box
5
+ * @param {number} x0
6
+ * @param {number} y0
7
+ * @param {number} z0
8
+ * @param {number} x1
9
+ * @param {number} y1
10
+ * @param {number} z1
11
+ */
12
+ export function serializeAABB3Encoded_v0(buffer, box, x0, y0, z0, x1, y1, z1) {
13
+ let header = 0;
14
+
15
+ if (box.x0 === x0) {
16
+ header |= 1;
17
+ }
18
+
19
+ if (box.x1 === x1) {
20
+ header |= 2;
21
+ }
22
+
23
+ if (box.y0 === y0) {
24
+ header |= 4;
25
+ }
26
+
27
+ if (box.y1 === y1) {
28
+ header |= 8;
29
+ }
30
+
31
+ if (box.z0 === z0) {
32
+ header |= 16;
33
+ }
34
+
35
+ if (box.z1 === z1) {
36
+ header |= 32;
37
+ }
38
+
39
+ buffer.writeUint8(header);
40
+
41
+ //compute value ranges
42
+ const xD = x1 - x0;
43
+ const yD = y1 - y0;
44
+ const zD = z1 - z0;
45
+
46
+ if ((header & 1) === 0) {
47
+ const _x0 = (((box.x0 - x0) / xD) * 65535) | 0;
48
+ buffer.writeUint16(_x0);
49
+ }
50
+
51
+ if ((header & 2) === 0) {
52
+ const _x1 = (((box.x1 - x0) / xD) * 65535) | 0;
53
+ buffer.writeUint16(_x1);
54
+ }
55
+
56
+ if ((header & 4) === 0) {
57
+ const _y0 = (((box.y0 - y0) / yD) * 65535) | 0;
58
+ buffer.writeUint16(_y0);
59
+ }
60
+
61
+ if ((header & 8) === 0) {
62
+ const _y1 = (((box.y1 - y0) / yD) * 65535) | 0;
63
+ buffer.writeUint16(_y1);
64
+ }
65
+
66
+ if ((header & 16) === 0) {
67
+ const _z0 = (((box.z0 - z0) / zD) * 65535) | 0;
68
+ buffer.writeUint16(_z0);
69
+ }
70
+
71
+ if ((header & 32) === 0) {
72
+ const _z1 = (((box.z1 - z0) / zD) * 65535) | 0;
73
+ buffer.writeUint16(_z1);
74
+ }
75
+ }
@@ -1,5 +1,5 @@
1
- import { serializeAABB3Encoded_v0 } from "../aabb3/AABB3.js";
2
1
  import { serializeAABB3 } from "../aabb3/serializeAABB3.js";
2
+ import { serializeAABB3Encoded_v0 } from "../aabb3/serializeAABB3Encoded_v0.js";
3
3
 
4
4
  /**
5
5
  *
@@ -177,7 +177,7 @@ export class HashMap {
177
177
  // mix the input hash to minimize potential impact of poor hash function spread
178
178
  const mixed_hash = (hash >>> 16) ^ hash;
179
179
 
180
- // ensure index is non-negative
180
+ // force index to unsigned integer
181
181
  const index = mixed_hash >>> 0;
182
182
 
183
183
  return index % this.__bucket_count;
@@ -194,7 +194,9 @@ export class HashMap {
194
194
 
195
195
  assert.isFiniteNumber(bucket_index, 'hash');
196
196
 
197
- let bucket = this.records[bucket_index];
197
+ const records = this.records;
198
+
199
+ let bucket = records[bucket_index];
198
200
 
199
201
  if (bucket === undefined) {
200
202
 
@@ -202,7 +204,7 @@ export class HashMap {
202
204
 
203
205
  bucket = [];
204
206
 
205
- this.records[bucket_index] = bucket;
207
+ records[bucket_index] = bucket;
206
208
 
207
209
  } else {
208
210
 
@@ -218,7 +220,11 @@ export class HashMap {
218
220
 
219
221
  if (entryKey === key || this.keyEqualityFunction(entryKey, key)) {
220
222
 
223
+ // found record with matching key, replace the value
224
+
221
225
  entry.value = value;
226
+
227
+ // done, return
222
228
  return;
223
229
 
224
230
  }
@@ -237,7 +243,7 @@ export class HashMap {
237
243
  const load = new_size / this.__bucket_count;
238
244
 
239
245
  if (load > this.__load_factor) {
240
- // increase table size
246
+ // current load is too high, increase table size
241
247
  this.setBucketCount(this.__bucket_count * 2);
242
248
  }
243
249
  }
@@ -276,7 +282,9 @@ export class HashMap {
276
282
  }
277
283
 
278
284
  /**
285
+ * If key exists in the map - returns stored value, if it doesn't - invokes `compute` function and stores produced value in the map; then returns that value
279
286
  *
287
+ * Inspired by Java's implementation
280
288
  * @param {K} key
281
289
  * @param {function(K):V} compute
282
290
  * @param {*} [compute_context]
@@ -402,14 +410,14 @@ export class HashMap {
402
410
  */
403
411
  rebuild() {
404
412
 
405
- let h, i, l;
413
+ let string_bucket_index, i, l;
406
414
 
407
415
  const records = this.records;
408
416
 
409
- for (h in records) {
410
- const stored_bucket_index = parseInt(h);
417
+ for (string_bucket_index in records) {
418
+ const stored_bucket_index = parseInt(string_bucket_index);
411
419
 
412
- if (!records.hasOwnProperty(h)) {
420
+ if (!records.hasOwnProperty(string_bucket_index)) {
413
421
  continue;
414
422
  }
415
423
 
@@ -1,3 +1,5 @@
1
+ import { assert } from "../../../assert.js";
2
+
1
3
  /**
2
4
  * NOTE: Based on Transforming Axis-Aligned Bounding Boxes by Jim Arvo from "Graphics Gems", Academic Press, 1990
3
5
  * NOTE: {@link result} and {@link aabb} must be different objects
@@ -6,6 +8,8 @@
6
8
  * @param {number[]} matrix 4x4 matrix
7
9
  */
8
10
  export function aabb3_matrix4_project(result, aabb, matrix) {
11
+ assert.notEqual(result, aabb, 'input and output must not be the same for algorithm to work correctly');
12
+
9
13
  // extract translation from matrix
10
14
  result[0] = result[3] = matrix[12];
11
15
  result[1] = result[4] = matrix[13];
@@ -0,0 +1,30 @@
1
+ /**
2
+ * evaluate the basis functions
3
+ * shBasis is an Array[ 9 ]
4
+ *
5
+ * @param {number} x
6
+ * @param {number} y
7
+ * @param {number} z
8
+ * @param {number[]|ArrayLike<number>|Float32Array|Float64Array} shBasis
9
+ */
10
+ export function sh3_basis_at(x, y, z, shBasis) {
11
+
12
+ // normal is assumed to be unit length
13
+
14
+
15
+ // band 0
16
+ shBasis[0] = 0.282095;
17
+
18
+ // band 1
19
+ shBasis[1] = 0.488603 * y;
20
+ shBasis[2] = 0.488603 * z;
21
+ shBasis[3] = 0.488603 * x;
22
+
23
+ // band 2
24
+ shBasis[4] = 1.092548 * x * y;
25
+ shBasis[5] = 1.092548 * y * z;
26
+ shBasis[6] = 0.315392 * (3 * z * z - 1);
27
+ shBasis[7] = 1.092548 * x * z;
28
+ shBasis[8] = 0.546274 * (x * x - y * y);
29
+
30
+ }
@@ -27,21 +27,22 @@ export function sh3_sample_by_direction(
27
27
  let channel_value;
28
28
 
29
29
  for (let i = 0; i < dimension_count; i++) {
30
+ const offset = harmonics_offset + dimension_count * i;
30
31
 
31
32
  // band 0
32
- channel_value = harmonics[harmonics_offset + i] * 0.282095;
33
+ channel_value = harmonics[offset] * 0.282095;
33
34
 
34
35
  // band 1
35
- channel_value += harmonics[harmonics_offset + dimension_count + i] * 0.488603 * y;
36
- channel_value += harmonics[harmonics_offset + dimension_count * 2 + i] * 0.488603 * z;
37
- channel_value += harmonics[harmonics_offset + dimension_count * 3 + i] * 0.488603 * x;
36
+ channel_value += harmonics[offset + 1] * 0.488603 * y;
37
+ channel_value += harmonics[offset + 2] * 0.488603 * z;
38
+ channel_value += harmonics[offset + 3] * 0.488603 * x;
38
39
 
39
40
  // band 2
40
- channel_value += harmonics[harmonics_offset + dimension_count * 4 + i] * 1.092548 * (x * y);
41
- channel_value += harmonics[harmonics_offset + dimension_count * 5 + i] * 1.092548 * (y * z);
42
- channel_value += harmonics[harmonics_offset + dimension_count * 6 + i] * 0.315392 * (3.0 * z * z - 1.0);
43
- channel_value += harmonics[harmonics_offset + dimension_count * 7 + i] * 1.092548 * (x * z);
44
- channel_value += harmonics[harmonics_offset + dimension_count * 8 + i] * 0.546274 * (x * x - y * y);
41
+ channel_value += harmonics[offset + 4] * 1.092548 * (x * y);
42
+ channel_value += harmonics[offset + 5] * 1.092548 * (y * z);
43
+ channel_value += harmonics[offset + 6] * 0.315392 * (3.0 * z * z - 1.0);
44
+ channel_value += harmonics[offset + 7] * 1.092548 * (x * z);
45
+ channel_value += harmonics[offset + 8] * 0.546274 * (x * x - y * y);
45
46
 
46
47
  // write out
47
48
  result[result_offset + i] = channel_value;
@@ -13,6 +13,11 @@ export default class Quaternion {
13
13
  public z: number
14
14
  public w: number
15
15
 
16
+ 0: number
17
+ 1: number
18
+ 2: number
19
+ 3: number
20
+
16
21
  readonly onChanged: Signal<number, number, number, number, number, number, number, number>;
17
22
 
18
23
  set(x: number, y: number, z: number, w: number): void
@@ -61,9 +66,9 @@ export default class Quaternion {
61
66
 
62
67
  fromJSON(j: any): void
63
68
 
64
- readFromArray(array: ArrayLike<number>, offset: number): void
69
+ readFromArray(array: ArrayLike<number>, offset?: number): void
65
70
 
66
- writeToArray(array: ArrayLike<number>, offset: number): void
71
+ writeToArray(array: ArrayLike<number>, offset?: number): void
67
72
 
68
73
  asArray(): number[]
69
74
  }
@@ -154,6 +154,22 @@ class Quaternion {
154
154
  return this.w;
155
155
  }
156
156
 
157
+ set 0(v) {
158
+ this.x = v;
159
+ }
160
+
161
+ set 1(v) {
162
+ this.y = v;
163
+ }
164
+
165
+ set 2(v) {
166
+ this.z = v;
167
+ }
168
+
169
+ set 3(v) {
170
+ this.w = v;
171
+ }
172
+
157
173
  /**
158
174
  *
159
175
  * @param {number} fx forward vector
@@ -1655,7 +1671,7 @@ class Quaternion {
1655
1671
  * @param {number[]} array
1656
1672
  * @param {number} offset
1657
1673
  */
1658
- readFromArray(array, offset) {
1674
+ readFromArray(array, offset=0) {
1659
1675
  this.set(
1660
1676
  array[offset],
1661
1677
  array[offset + 1],
@@ -1669,7 +1685,7 @@ class Quaternion {
1669
1685
  * @param {number[]} array
1670
1686
  * @param {number} offset
1671
1687
  */
1672
- writeToArray(array, offset) {
1688
+ writeToArray(array, offset=0) {
1673
1689
  array[offset] = this.x;
1674
1690
  array[offset + 1] = this.y;
1675
1691
  array[offset + 2] = this.z;
@@ -1,7 +1,17 @@
1
+ import Signal from "../events/signal/Signal";
2
+
1
3
  export default class Vector1 {
2
4
  x: number
3
5
 
4
- set(v: number)
6
+ 0: number
7
+
8
+ readonly onChanged: Signal<number,number>
9
+
10
+ constructor()
11
+
12
+ constructor(x: number)
13
+
14
+ set(v: number) : void
5
15
 
6
16
  getValue(): number
7
17
 
@@ -13,5 +23,13 @@ export default class Vector1 {
13
23
 
14
24
  process(callback: (x) => any): void
15
25
 
26
+ toJSON(): any
27
+
28
+ fromJSON(j: any): void
29
+
30
+ readFromArray(array: ArrayLike<number>, offset?: number): void
31
+
32
+ writeToArray(array: ArrayLike<number>, offset?: number): void
33
+
16
34
  asArray(): number[]
17
35
  }
@@ -223,7 +223,7 @@ class Vector1 extends Number {
223
223
  * @param {number[]} array
224
224
  * @param {number} offset
225
225
  */
226
- readFromArray(array, offset) {
226
+ readFromArray(array, offset=0) {
227
227
  this.set(array[offset]);
228
228
  }
229
229
 
@@ -232,7 +232,7 @@ class Vector1 extends Number {
232
232
  * @param {number[]} array
233
233
  * @param {number} offset
234
234
  */
235
- writeToArray(array, offset) {
235
+ writeToArray(array, offset=0) {
236
236
  array[offset] = this.x;
237
237
  }
238
238
 
@@ -268,6 +268,14 @@ class Vector1 extends Number {
268
268
  return a.x - b.x;
269
269
  }
270
270
 
271
+ get 0() {
272
+ return this.x;
273
+ }
274
+
275
+ set 0(v) {
276
+ this.x = v;
277
+ }
278
+
271
279
  * [Symbol.iterator]() {
272
280
 
273
281
  yield this.x;
@@ -4,6 +4,9 @@ export default class Vector2 {
4
4
  x: number
5
5
  y: number
6
6
 
7
+ 0: number
8
+ 1: number
9
+
7
10
  public readonly onChanged: Signal<number, number, number, number>
8
11
 
9
12
  constructor(x: number, y: number)
@@ -36,5 +39,9 @@ export default class Vector2 {
36
39
 
37
40
  isZero(): boolean
38
41
 
42
+ readFromArray(array: ArrayLike<number>, offset?: number): void
43
+
44
+ writeToArray(array: ArrayLike<number>, offset?: number): void
45
+
39
46
  asArray():number[]
40
47
  }
@@ -46,7 +46,7 @@ class Vector2 {
46
46
  * @param {number[]} array
47
47
  * @param {number} offset
48
48
  */
49
- readFromArray(array, offset) {
49
+ readFromArray(array, offset = 0) {
50
50
  this.set(
51
51
  array[offset],
52
52
  array[offset + 1]
@@ -58,15 +58,15 @@ class Vector2 {
58
58
  * @param {number[]} array
59
59
  * @param {number} offset
60
60
  */
61
- writeToArray(array, offset) {
61
+ writeToArray(array, offset = 0) {
62
62
  array[offset] = this.x;
63
63
  array[offset + 1] = this.y;
64
64
  }
65
65
 
66
- asArray(){
66
+ asArray() {
67
67
  const r = [];
68
68
 
69
- this.writeToArray(r,0);
69
+ this.writeToArray(r, 0);
70
70
 
71
71
  return r;
72
72
  }
@@ -588,6 +588,23 @@ class Vector2 {
588
588
  return this.x === other.x && this.y === other.y;
589
589
  }
590
590
 
591
+ get 0() {
592
+ return this.x;
593
+ }
594
+
595
+ get 1() {
596
+ return this.y;
597
+ }
598
+
599
+ set 0(v) {
600
+ this.x = v;
601
+ }
602
+
603
+ set 1(v) {
604
+ this.y = v;
605
+ }
606
+
607
+
591
608
  * [Symbol.iterator]() {
592
609
 
593
610
  yield this.x;
@@ -47,7 +47,7 @@ export default class Vector3 implements Vector3Like {
47
47
 
48
48
  ceil(): void
49
49
 
50
- multiplyVectors(a:Vector3Like,b:Vector3Like):void
50
+ multiplyVectors(a: Vector3Like, b: Vector3Like): void
51
51
 
52
52
  _multiply(x: number, y: number, z: number): void
53
53
 
@@ -91,11 +91,11 @@ export default class Vector3 implements Vector3Like {
91
91
 
92
92
  toJSON(): any
93
93
 
94
- fromJSON(json: { x?: number, y?: number, z?: number })
94
+ fromJSON(json: { x?: number, y?: number, z?: number } | number): void
95
95
 
96
- readFromArray(array: number[] | ArrayLike<number>, offset: number): void
96
+ readFromArray(array: number[] | ArrayLike<number>, offset?: number): void
97
97
 
98
- writeToArray(array: number[] | ArrayLike<number>, offset: number): void
98
+ writeToArray(array: number[] | ArrayLike<number>, offset?: number): void
99
99
 
100
100
  asArray(): number[]
101
101
 
@@ -38,7 +38,7 @@ class Vector3 {
38
38
  * @param {number[]} array
39
39
  * @param {number} offset
40
40
  */
41
- readFromArray(array, offset) {
41
+ readFromArray(array, offset=0) {
42
42
  this.set(
43
43
  array[offset],
44
44
  array[offset + 1],
@@ -51,7 +51,7 @@ class Vector3 {
51
51
  * @param {number[]} array
52
52
  * @param {number} offset
53
53
  */
54
- writeToArray(array, offset) {
54
+ writeToArray(array, offset=0) {
55
55
  array[offset] = this.x;
56
56
  array[offset + 1] = this.y;
57
57
  array[offset + 2] = this.z;
@@ -806,7 +806,7 @@ class Vector3 {
806
806
  }
807
807
 
808
808
  toString() {
809
- return `[x:${this.x},y:${this.y},z:${this.z}]`;
809
+ return `[x:${this.x}, y:${this.y}, z:${this.z}]`;
810
810
  }
811
811
 
812
812
  /**
@@ -952,6 +952,31 @@ class Vector3 {
952
952
  return hash;
953
953
  }
954
954
 
955
+
956
+ get 0() {
957
+ return this.x;
958
+ }
959
+
960
+ get 1() {
961
+ return this.y;
962
+ }
963
+
964
+ get 2() {
965
+ return this.z;
966
+ }
967
+
968
+ set 0(v) {
969
+ this.x = v;
970
+ }
971
+
972
+ set 1(v) {
973
+ this.y = v;
974
+ }
975
+
976
+ set 2(v) {
977
+ this.z = v;
978
+ }
979
+
955
980
  * [Symbol.iterator]() {
956
981
 
957
982
  yield this.x;
@@ -15,6 +15,11 @@ export default class Vector4 {
15
15
  z: number
16
16
  w: number
17
17
 
18
+ 0: number
19
+ 1: number
20
+ 2: number
21
+ 3: number
22
+
18
23
  public readonly onChanged: Signal<number, number, number, number, number, number, number, number>;
19
24
 
20
25
  constructor()
@@ -25,9 +30,9 @@ export default class Vector4 {
25
30
 
26
31
  copy(other: Vector4Like): void
27
32
 
28
- readFromArray(array:ArrayLike<number>, offset:number):void
33
+ readFromArray(array:ArrayLike<number>, offset?:number):void
29
34
 
30
- writeToArray(array:ArrayLike<number>, offset:number):void
35
+ writeToArray(array:ArrayLike<number>, offset?:number):void
31
36
 
32
37
  asArray(): number[]
33
38
 
@@ -105,11 +105,11 @@ class Vector4 {
105
105
  * @constructor
106
106
  * @class
107
107
  */
108
- constructor(x, y, z, w) {
109
- this.x = (typeof x === "number") ? x : 0;
110
- this.y = (typeof x === "number") ? y : 0;
111
- this.z = (typeof z === "number") ? z : 0;
112
- this.w = (typeof w === "number") ? w : 1;
108
+ constructor(x = 0, y = 0, z = 0, w = 0) {
109
+ this.x = x;
110
+ this.y = y;
111
+ this.z = z;
112
+ this.w = w;
113
113
 
114
114
  this.onChanged = new Signal();
115
115
  }
@@ -135,7 +135,7 @@ class Vector4 {
135
135
  * @param {number[]} array
136
136
  * @param {number} offset
137
137
  */
138
- readFromArray(array, offset) {
138
+ readFromArray(array, offset = 0) {
139
139
  this.set(
140
140
  array[offset],
141
141
  array[offset + 1],
@@ -149,7 +149,7 @@ class Vector4 {
149
149
  * @param {number[]} array
150
150
  * @param {number} offset
151
151
  */
152
- writeToArray(array, offset) {
152
+ writeToArray(array, offset = 0) {
153
153
  array[offset] = this.x;
154
154
  array[offset + 1] = this.y;
155
155
  array[offset + 2] = this.z;
@@ -18,37 +18,37 @@ export function computeObjectHash(value, depth = 3) {
18
18
 
19
19
  let hash = 0;
20
20
 
21
- for (let p in value) {
21
+ const pType = typeof value;
22
+
23
+ if (pType === "string") {
24
+ hash = computeStringHash(value);
25
+ } else if (pType === "number") {
26
+ hash = computeHashFloat(value);
27
+ } else if (pType === "boolean") {
28
+ hash = value ? 1 : 0;
29
+ } else if (pType === "object") {
30
+
31
+ if (depth <= 0) {
32
+ hash = 3;
33
+ } else {
34
+
35
+ for (let p in value) {
22
36
 
23
- hash = ((hash << 5) - hash) + computeStringHash(p);
37
+ const pNameHash = computeStringHash(p);
24
38
 
25
- const pValue = value[p];
39
+ const pValue = value[p];
26
40
 
27
- const pType = typeof pValue;
41
+ const pHash = pNameHash ^ computeObjectHash(pValue, depth - 1);
28
42
 
29
- let pHash;
30
- if (pType === "string") {
31
- pHash = computeStringHash(pValue);
32
- } else if (pType === "number") {
33
- pHash = computeHashFloat(pValue);
34
- } else if (pType === "boolean") {
35
- pHash = pValue ? 1 : 0;
36
- } else if (pType === "object") {
43
+ hash = ((hash << 5) - hash) + pHash;
37
44
 
38
- if (depth <= 0) {
39
- pHash = 3;
40
- } else {
41
- pHash = computeObjectHash(pValue, depth - 1);
45
+ hash |= 0; // Convert to 32bit integer
42
46
  }
43
47
 
44
- } else {
45
- pHash = 0;
46
48
  }
47
49
 
48
- hash = ((hash << 5) - hash) + pHash;
49
-
50
- hash |= 0; // Convert to 32bit integer
51
50
  }
52
51
 
52
+
53
53
  return hash;
54
54
  }
@@ -0,0 +1,42 @@
1
+ import { computeObjectHash } from "./computeObjectHash.js";
2
+
3
+ /**
4
+ *
5
+ * @param {number} hash
6
+ */
7
+ function validateHash(hash){
8
+ expect(typeof hash).toBe('number');
9
+ expect(hash).not.toBeNaN();
10
+ expect(Number.isFinite(hash)).toBe(true);
11
+ expect(Number.isInteger(hash)).toBe(true);
12
+ }
13
+
14
+ test('primitives produce valid hash',()=>{
15
+ validateHash( computeObjectHash(undefined));
16
+ validateHash( computeObjectHash(null));
17
+ validateHash( computeObjectHash(0));
18
+ validateHash( computeObjectHash(1));
19
+ validateHash( computeObjectHash(""));
20
+ validateHash( computeObjectHash("hello"));
21
+ validateHash( computeObjectHash(false));
22
+ validateHash( computeObjectHash(true));
23
+ validateHash( computeObjectHash({}));
24
+ });
25
+
26
+ test('nested object hash is stable',()=>{
27
+ const test_object = {
28
+ a:{
29
+ b:7
30
+ },
31
+ c: "hello"
32
+ };
33
+
34
+ expect(computeObjectHash(test_object)).toEqual(computeObjectHash(test_object));
35
+
36
+ expect(computeObjectHash(test_object)).not.toEqual(computeObjectHash({
37
+ a:{
38
+ b:5
39
+ },
40
+ c: "hello"
41
+ }));
42
+ });
@@ -18,7 +18,7 @@ export interface IEngineInitializationOptions {
18
18
  export default class Engine {
19
19
  constructor(platform: EnginePlatform, options?: IEngineInitializationOptions);
20
20
 
21
- public get viewStack(): View
21
+ readonly viewStack: View
22
22
 
23
23
  public readonly entityManager: EntityManager
24
24
  public readonly sceneManager: SceneManager
@@ -28,33 +28,35 @@ export class Transform {
28
28
  constructor() {
29
29
 
30
30
  /**
31
- *
31
+ * World-space position
32
32
  * @type {Vector3}
33
33
  * @readonly
34
34
  */
35
35
  this.position = new Vector3(0, 0, 0);
36
36
 
37
37
  /**
38
- *
38
+ * World-space rotation
39
39
  * @type {Quaternion}
40
40
  * @readonly
41
41
  */
42
42
  this.rotation = new Quaternion(0, 0, 0, 1);
43
43
 
44
44
  /**
45
- *
45
+ * World-space scale
46
46
  * @type {Vector3}
47
47
  * @readonly
48
48
  */
49
49
  this.scale = new Vector3(1, 1, 1);
50
50
 
51
51
  /**
52
+ * World-space transform matrix, position, rotation and scale must match, but shear can be different
52
53
  * @readonly
53
54
  * @type {Float32Array}
54
55
  */
55
56
  this.matrix = allocate_transform_m4();
56
57
 
57
58
  /**
59
+ * Various bit flags, see {@link TransformFlags}
58
60
  * @protected
59
61
  * @type {number}
60
62
  */
@@ -136,7 +138,6 @@ export class Transform {
136
138
  return (this.flags & flag) === flag;
137
139
  }
138
140
 
139
-
140
141
  updateMatrix() {
141
142
  compose_matrix4_array(this.matrix, this.position, this.rotation, this.scale);
142
143
  }
@@ -275,7 +276,7 @@ export class Transform {
275
276
  }
276
277
 
277
278
  /**
278
- *
279
+ * @deprecated use `fromMatrix4` directly instead
279
280
  * @param {THREE.Matrix4} matrix
280
281
  */
281
282
  fromThreeMatrix4(matrix) {
@@ -283,7 +284,7 @@ export class Transform {
283
284
  }
284
285
 
285
286
  /**
286
- *
287
+ * @deprecated use `toMatrix4` directly instead
287
288
  * @param {Matrix4} matrix
288
289
  */
289
290
  toThreeMatrix(matrix) {
@@ -314,6 +315,12 @@ export class Transform {
314
315
  compose_matrix4_array(result, this.position, this.rotation, this.scale);
315
316
  }
316
317
 
318
+ /**
319
+ * reset transform, resulting transform is an identity matrix
320
+ * - position: [0,0,0]
321
+ * - rotation: [0,0,0,1]
322
+ * - scale: [1,1,1]
323
+ */
317
324
  makeIdentity() {
318
325
  this.position.copy(Vector3.zero);
319
326
  this.rotation.copy(Quaternion.identity);
@@ -335,11 +342,16 @@ Transform.prototype.isTransform = true;
335
342
 
336
343
 
337
344
  /**
345
+ * @deprecated use {@link Quaternion.rotateTowards} instead
338
346
  * @param {Quaternion} sourceQuaternion
339
347
  * @param {Vector3} targetVector
340
348
  * @param {Number} limit
341
349
  */
342
- Transform.adjustRotation = function (sourceQuaternion, targetVector, limit) {
343
- sourceQuaternion.lookRotation(targetVector, Vector3.up);
350
+ Transform.adjustRotation = function (sourceQuaternion, targetVector, limit = Infinity) {
351
+ const q = new Quaternion();
352
+
353
+ q.lookRotation(targetVector);
354
+
355
+ sourceQuaternion.rotateTowards(q, limit);
344
356
  };
345
357
 
@@ -50,7 +50,7 @@ export class ShadedGeometry {
50
50
  this.material = null;
51
51
 
52
52
  /**
53
- *
53
+ * Optional extra material used for shadowmaps
54
54
  * @type {THREE.Material|null}
55
55
  */
56
56
  this.depth_material = null;
@@ -84,7 +84,7 @@ export class ShadedGeometry {
84
84
  this.__entity = -1;
85
85
 
86
86
  /**
87
- *
87
+ * Transient, cached for convenience. Associated transform component from the same entity
88
88
  * @type {Transform|null}
89
89
  * @private
90
90
  */
@@ -20,7 +20,10 @@ export class InstancedRendererAdapter extends AbstractRenderAdapter {
20
20
  */
21
21
  this.__instanced_meshes = new HashMap({
22
22
  keyHashFunction(sg) {
23
- return sg.geometry.id ^ sg.material.id ^ sg.mode;
23
+ return sg.geometry.id
24
+ ^ sg.material.id
25
+ ^ sg.mode
26
+ ;
24
27
  },
25
28
  keyEqualityFunction(a, b) {
26
29
  return a.material.id === b.material.id
@@ -29,40 +29,10 @@ import { build_three_object } from "../ecs/mesh-v2/build_three_object.js";
29
29
  import { ShadedGeometryFlags } from "../ecs/mesh-v2/ShadedGeometryFlags.js";
30
30
  import { v3_length_sqr } from "../../../core/geom/v3_length_sqr.js";
31
31
  import { sh3_dering_optimize_positive } from "../../../core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js";
32
+ import { sh3_basis_at } from "../../../core/geom/3d/sphere/harmonics/sh3_basis_at.js";
32
33
 
33
34
  const TEMP_CONTACT = new SurfacePoint3();
34
35
 
35
- /**
36
- * evaluate the basis functions
37
- * shBasis is an Array[ 9 ]
38
- *
39
- * @param {number} x
40
- * @param {number} y
41
- * @param {number} z
42
- * @param {number[]|ArrayLike<number>|Float32Array|Float64Array} shBasis
43
- */
44
- function getBasisAt(x, y, z, shBasis) {
45
-
46
- // normal is assumed to be unit length
47
-
48
-
49
- // band 0
50
- shBasis[0] = 0.282095;
51
-
52
- // band 1
53
- shBasis[1] = 0.488603 * y;
54
- shBasis[2] = 0.488603 * z;
55
- shBasis[3] = 0.488603 * x;
56
-
57
- // band 2
58
- shBasis[4] = 1.092548 * x * y;
59
- shBasis[5] = 1.092548 * y * z;
60
- shBasis[6] = 0.315392 * (3 * z * z - 1);
61
- shBasis[7] = 1.092548 * x * z;
62
- shBasis[8] = 0.546274 * (x * x - y * y);
63
-
64
- }
65
-
66
36
  /**
67
37
  *
68
38
  * @param {Uint8Array} data
@@ -160,7 +130,7 @@ function fromCubeRenderTarget(data, renderer, cubeRenderTarget) {
160
130
  normal_z /= length;
161
131
 
162
132
  // evaluate SH basis functions in direction dir
163
- getBasisAt(normal_x, normal_y, normal_z, sh_basis);
133
+ sh3_basis_at(normal_x, normal_y, normal_z, sh_basis);
164
134
 
165
135
  // pixel color, already in linear space so no sRGB->Linear conversion necessary
166
136
 
@@ -266,7 +236,7 @@ class CubeRenderer {
266
236
  //
267
237
  // object3D.material.color.copy(source_material.color);
268
238
  // } else {
269
- object3D.material = source_material.clone();
239
+ object3D.material = source_material.clone();
270
240
  // }
271
241
 
272
242
  applyTransformToThreeObject(object3D, t);
@@ -2,50 +2,17 @@ import { BehaviorStatus } from "./BehaviorStatus.js";
2
2
 
3
3
  /**
4
4
  * Base class of behavior tree implementation
5
+ * @template CTX
5
6
  */
6
7
  export class Behavior {
7
8
  constructor() {
8
9
  /**
9
10
  * Any internal state used by the behavior
10
- * @type {*}
11
+ * @type {CTX|null}
11
12
  */
12
13
  this.context = null;
13
14
  }
14
15
 
15
- /**
16
- * @deprecated
17
- * @private
18
- * @returns {BehaviorStatus}
19
- */
20
- get __status() {
21
- throw new Error('Deprecated');
22
- }
23
-
24
- /**
25
- * @deprecated
26
- * @param {BehaviorStatus} v
27
- * @private
28
- */
29
- set __status(v) {
30
- throw new Error('Deprecated');
31
- }
32
-
33
- /**
34
- * @deprecated
35
- * @returns {BehaviorStatus}
36
- */
37
- getStatus() {
38
- throw new Error('Deprecated');
39
- }
40
-
41
- /**
42
- * @deprecated
43
- * @param {BehaviorStatus} s
44
- */
45
- setStatus(s) {
46
- throw new Error('Deprecated');
47
- }
48
-
49
16
  /**
50
17
  * Main update function
51
18
  * @param {number} timeDelta time step in seconds
@@ -11,6 +11,12 @@ export class EnginePlugin extends BaseProcess {
11
11
  * @private
12
12
  */
13
13
  this.__dependencies = [];
14
+
15
+ /**
16
+ *
17
+ * @type {Engine|null}
18
+ */
19
+ this.engine = null;
14
20
  }
15
21
 
16
22
  attach() {
@@ -1,13 +1,12 @@
1
1
  import { DomElementBinding } from "./DomElementBinding.js";
2
+ import { EnginePlugin } from "../../plugin/EnginePlugin.js";
3
+ import { array_remove_first } from "../../../core/collection/array/array_remove_first.js";
2
4
 
3
- export class DomElementManager {
5
+ export class DomElementProcessorManager extends EnginePlugin {
4
6
  constructor() {
5
- /**
6
- *
7
- * @type {Engine|null}
8
- * @private
9
- */
10
- this.__engine = null;
7
+ super();
8
+
9
+ this.id = "dom-element-processor-manager";
11
10
 
12
11
  /**
13
12
  *
@@ -59,6 +58,23 @@ export class DomElementManager {
59
58
  this.__descriptors.push(descriptor);
60
59
  }
61
60
 
61
+ /**
62
+ *
63
+ * @param {DomElementBindingDescription} descriptor
64
+ * @return {boolean}
65
+ */
66
+ deregister(descriptor) {
67
+ if (array_remove_first(this.__descriptors, descriptor)) {
68
+ // element removed
69
+
70
+ // TODO cleanup whatever effects have been applied to elements matching the descriptor
71
+ return true;
72
+ } else {
73
+ // not found
74
+ return false;
75
+ }
76
+ }
77
+
62
78
  /**
63
79
  *
64
80
  * @param {sequence<MutationRecord>} mutations_list
@@ -215,17 +231,7 @@ export class DomElementManager {
215
231
  * @return {Engine|null}
216
232
  */
217
233
  getEngine() {
218
- return this.__engine;
219
- }
220
-
221
- /**
222
- *
223
- * @param {Engine} engine
224
- */
225
- initialize(engine) {
226
-
227
- this.__engine = engine;
228
-
234
+ return this.engine;
229
235
  }
230
236
 
231
237
  /**
@@ -258,6 +264,25 @@ export class DomElementManager {
258
264
 
259
265
  }
260
266
 
267
+ async startup() {
268
+ const view = this.getEngine().viewStack;
269
+
270
+ this.link(view.el);
271
+
272
+ return super.startup();
273
+ }
274
+
275
+ async shutdown() {
276
+
277
+ this.unlink();
278
+
279
+ return super.shutdown();
280
+ }
281
+
282
+ /**
283
+ *
284
+ * @param {Element} root
285
+ */
261
286
  link(root) {
262
287
 
263
288
  this.__root = root;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "productName": "Meep",
6
6
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.43.37",
8
+ "version": "2.43.39",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",