@woosh/meep-engine 2.47.34 → 2.47.36

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 (62) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/build/meep.cjs +43 -21
  3. package/build/meep.min.js +1 -1
  4. package/build/meep.module.js +43 -21
  5. package/editor/tools/FoliagePaintTool.js +3 -3
  6. package/editor/tools/GridPaintTool.js +2 -2
  7. package/package.json +1 -1
  8. package/src/core/binary/dec2hex.js +9 -0
  9. package/src/core/binary/hex2dec.js +8 -0
  10. package/src/core/color/Color.js +8 -0
  11. package/src/core/color/ColorUtils.js +2 -2
  12. package/src/core/color/{parseHex.js → hex2rgb.js} +3 -5
  13. package/src/core/color/rgb2hex.js +1 -4
  14. package/src/core/geom/3d/aabb/aabb3_intersects_aabb3.js +1 -1
  15. package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.js +65 -0
  16. package/src/core/geom/3d/topology/struct/TopoMesh.js +9 -3
  17. package/src/core/geom/AABB2.js +1 -1
  18. package/src/core/geom/Rectangle.js +2 -2
  19. package/src/core/math/computeGreatestCommonDivisor.js +30 -3
  20. package/src/core/math/{intersects1D.js → interval/intersects1D.js} +1 -1
  21. package/src/core/math/{overlap1D.js → interval/overlap1D.js} +1 -1
  22. package/src/core/math/mix.js +5 -7
  23. package/src/core/math/random/randomUint8.js +10 -0
  24. package/src/core/math/spline/spline_bezier3.js +26 -0
  25. package/src/core/math/spline/spline_bezier3_bounds.js +87 -0
  26. package/src/core/model/node-graph/node/NodeInstance.js +1 -0
  27. package/src/core/process/task/Task.js +8 -6
  28. package/src/engine/achievements/AchievementManager.js +1 -1
  29. package/src/engine/animation/TransitionFunctions.js +1 -1
  30. package/src/engine/animation/curve/AnimationCurve.js +93 -1
  31. package/src/engine/animation/curve/Keyframe.js +20 -0
  32. package/src/engine/animation/curve/compression/prototypeCurveCompression.js +3 -1
  33. package/src/engine/ecs/components/MeshCollider.js +5 -0
  34. package/src/engine/ecs/components/MonsterAI.js +5 -0
  35. package/src/engine/ecs/fow/shader/FogOfWarRenderer.js +1 -1
  36. package/src/engine/ecs/guid/GUID.js +257 -0
  37. package/src/engine/ecs/guid/GUID.spec.js +41 -0
  38. package/src/engine/ecs/guid/GUIDSerializationAdapter.js +25 -0
  39. package/src/engine/ecs/storage/binary/BinaryClassSerializationAdapter.js +11 -12
  40. package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +23 -9
  41. package/src/engine/graphics/camera/CameraShake.js +1 -1
  42. package/src/engine/graphics/ecs/camera/CameraClippingPlaneComputer.js +1 -1
  43. package/src/engine/graphics/ecs/decal/v2/Decal.js +8 -6
  44. package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts +3 -0
  45. package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +76 -0
  46. package/src/engine/intelligence/behavior/behavior_to_dot.js +11 -1
  47. package/src/engine/intelligence/behavior/decorator/AbstractDecoratorBehavior.js +6 -0
  48. package/src/engine/intelligence/behavior/util/behavior_traverse_tree.js +35 -0
  49. package/src/engine/scene/transitionToScene.js +4 -1
  50. package/src/view/elements/radial/RadialText.js +1 -1
  51. package/src/core/math/bezierCurve.js +0 -22
  52. /package/src/core/math/{isValueBetween.js → interval/isValueBetween.js} +0 -0
  53. /package/src/core/math/{isValueBetween.spec.js → interval/isValueBetween.spec.js} +0 -0
  54. /package/src/core/math/{isValueBetweenInclusive.js → interval/isValueBetweenInclusive.js} +0 -0
  55. /package/src/core/math/{isValueBetweenInclusive.spec.js → interval/isValueBetweenInclusive.spec.js} +0 -0
  56. /package/src/core/math/{overlap1D.spec.js → interval/overlap1D.spec.js} +0 -0
  57. /package/src/core/math/{cubicCurve.js → spline/cubicCurve.js} +0 -0
  58. /package/src/core/math/{cubicCurve.spec.js → spline/cubicCurve.spec.js} +0 -0
  59. /package/src/core/math/{makeCubicCurve.js → spline/makeCubicCurve.js} +0 -0
  60. /package/src/core/math/{makeCubicCurve.spec.js → spline/makeCubicCurve.spec.js} +0 -0
  61. /package/src/core/math/{quadraticCurve.js → spline/quadraticCurve.js} +0 -0
  62. /package/src/core/math/{quadraticCurve.spec.js → spline/quadraticCurve.spec.js} +0 -0
@@ -1,4 +1,4 @@
1
- import { makeCubicCurve } from "../../core/math/makeCubicCurve.js";
1
+ import { makeCubicCurve } from "../../core/math/spline/makeCubicCurve.js";
2
2
 
3
3
  /**
4
4
  *
@@ -1,5 +1,7 @@
1
1
  import { inverseLerp } from "../../../core/math/inverseLerp.js";
2
2
  import { lerp } from "../../../core/math/lerp.js";
3
+ import { invokeObjectToJSON } from "../../../core/model/object/invokeObjectToJSON.js";
4
+ import { Keyframe } from "./Keyframe.js";
3
5
 
4
6
  /**
5
7
  *
@@ -39,10 +41,72 @@ export class AnimationCurve {
39
41
  this.keys = [];
40
42
  }
41
43
 
44
+ /**
45
+ *
46
+ * @param {Keyframe} key
47
+ */
48
+ add(key) {
49
+ // TODO figure out the right place to insert the key
50
+ this.keys.push(key);
51
+ }
52
+
53
+ /**
54
+ *
55
+ * @param {Keyframe} key
56
+ * @returns {boolean}
57
+ */
58
+ remove(key) {
59
+ const i = this.keys.indexOf(key);
60
+
61
+ if (i === -1) {
62
+ return false;
63
+ }
64
+
65
+ this.keys.splice(i, 1);
66
+
67
+ return true;
68
+ }
69
+
70
+ /**
71
+ * Remove all keys
72
+ */
73
+ clear() {
74
+ this.keys.splice(0, this.keys.length);
75
+ }
76
+
77
+ /**
78
+ *
79
+ * @param {Keyframe[]} keys
80
+ * @returns {AnimationCurve}
81
+ */
82
+ static from(keys) {
83
+ const curve = new AnimationCurve();
84
+
85
+ const key_count = keys.length;
86
+
87
+ for (let i = 0; i < key_count; i++) {
88
+ curve.add(keys[i]);
89
+ }
90
+
91
+ for (let i = 0; i < key_count; i++) {
92
+ curve.smoothTangents(i, 1);
93
+ }
94
+
95
+ return curve;
96
+ }
97
+
98
+ /**
99
+ * Number of keys
100
+ * @returns {number}
101
+ */
102
+ get length() {
103
+ return this.keys.length;
104
+ }
105
+
42
106
 
43
107
  /**
44
108
  *
45
- * @param {number} t
109
+ * @param {number} t time in seconds
46
110
  * @return {number}
47
111
  */
48
112
  evaluate(t) {
@@ -108,4 +172,32 @@ export class AnimationCurve {
108
172
  }
109
173
 
110
174
  }
175
+
176
+ smoothAllTangents(){
177
+ const n = this.length;
178
+ for (let i = 0; i < n; i++) {
179
+ this.smoothTangents(i,0);
180
+ }
181
+ }
182
+
183
+ toJSON() {
184
+ return {
185
+ keys: this.keys.map(invokeObjectToJSON)
186
+ };
187
+ }
188
+
189
+ fromJSON({ keys }) {
190
+ this.clear();
191
+
192
+ for (let i = 0; i < keys.length; i++) {
193
+
194
+ const keyframe = new Keyframe();
195
+
196
+ keyframe.fromJSON(keys[i]);
197
+
198
+ this.add(keyframe);
199
+
200
+ }
201
+
202
+ }
111
203
  }
@@ -43,4 +43,24 @@ export class Keyframe {
43
43
 
44
44
  return r;
45
45
  }
46
+
47
+ toJSON() {
48
+ return {
49
+ value: this.value,
50
+ time: this.time,
51
+ inTangent: this.inTangent,
52
+ outTangent: this.outTangent
53
+ }
54
+ };
55
+
56
+ fromJSON({
57
+ value, time, inTangent, outTangent
58
+ }) {
59
+
60
+ this.value = value;
61
+ this.time = time;
62
+ this.inTangent = inTangent;
63
+ this.outTangent = outTangent;
64
+ }
65
+
46
66
  }
@@ -134,7 +134,9 @@ async function main(engine) {
134
134
  return curve;
135
135
  }
136
136
 
137
- const curve = sample_curve_2();
137
+ const curve = sample_curve_4();
138
+
139
+ curve.smoothAllTangents();
138
140
 
139
141
  const ecd = engine.entityManager.dataset;
140
142
 
@@ -3,6 +3,11 @@
3
3
  */
4
4
 
5
5
 
6
+ /**
7
+ * @deprecated
8
+ * @param options
9
+ * @constructor
10
+ */
6
11
  function MeshCollider(options) {
7
12
  this.tags = options.tags.slice();
8
13
  }
@@ -3,6 +3,11 @@
3
3
  */
4
4
 
5
5
 
6
+ /**
7
+ * @deprecated
8
+ * @param options
9
+ * @constructor
10
+ */
6
11
  function MonsterAI(options) {
7
12
  this.chaseDistance = options.chaseDistance || 0;
8
13
  }
@@ -2,7 +2,7 @@ import { buildScreenSpaceFogOfWarShader } from "./screenSpaceFogOfWarShader.js";
2
2
  import { assert } from "../../../../core/assert.js";
3
3
  import { Mesh, OrthographicCamera, Scene } from "three";
4
4
  import { FULL_SCREEN_TRIANGLE_GEOMETRY } from "../../../graphics/geometry/FULL_SCREEN_TRIANGLE_GEOMETRY.js";
5
- import { isValueBetweenInclusive } from "../../../../core/math/isValueBetweenInclusive.js";
5
+ import { isValueBetweenInclusive } from "../../../../core/math/interval/isValueBetweenInclusive.js";
6
6
 
7
7
  /**
8
8
  *
@@ -0,0 +1,257 @@
1
+ import { seededRandom } from "../../../core/math/random/seededRandom.js";
2
+ import { randomUint8 } from "../../../core/math/random/randomUint8.js";
3
+ import { is_typed_array_equals } from "../../../core/collection/array/typed/is_typed_array_equals.js";
4
+ import { dec2hex } from "../../../core/binary/dec2hex.js";
5
+ import { array_copy } from "../../../core/collection/array/copyArray.js";
6
+
7
+ // Previous uuid creation time
8
+ let _lastMSecs = 0;
9
+ let _lastNSecs = 0;
10
+
11
+ const random = seededRandom(Date.now());
12
+
13
+ /**
14
+ *
15
+ * @param {Uint8Array} result
16
+ * @param {number} result_offset
17
+ * @param {function():number} random
18
+ * @param {number} count
19
+ */
20
+ function randomBytes(result, result_offset, random, count) {
21
+ for (let i = 0; i < count; i++) {
22
+
23
+ result[result_offset + i] = randomUint8(random);
24
+
25
+ }
26
+ }
27
+
28
+ // node and clockseq need to be initialized to random values.
29
+ let _nodeId = new Uint8Array(6);
30
+
31
+ // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
32
+ randomBytes(_nodeId, 0, random, 6);
33
+ _nodeId[0] |= 0x01;
34
+
35
+ // Per 4.2.2, randomize (14 bit) clockseq
36
+ let _clockseq = ((randomUint8(random) << 8) | randomUint8(random)) & 0x3fff;
37
+
38
+ /**
39
+ * Globally unique identifier
40
+ */
41
+ export class GUID {
42
+ #data = new Uint8Array(16);
43
+
44
+ constructor() {
45
+ this.v1();
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param {number[]|Uint8Array|ArrayLike<number>} bytes
51
+ */
52
+ set data(bytes) {
53
+ array_copy(bytes, 0, this.#data, 0, 16);
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @returns {Uint8Array}
59
+ */
60
+ get data() {
61
+ return this.#data;
62
+ }
63
+
64
+ /**
65
+ * Generate Variant 1 UUID
66
+ * @see https://github.com/uuidjs/uuid/blob/8f028c4ea42ce41a9a9dc5fa634abe525b2e2066/src/v1.js#L17
67
+ */
68
+ v1() {
69
+
70
+ const b = this.#data;
71
+
72
+ let clockseq = _clockseq;
73
+
74
+ // UUID timestamps are 100 nano-second units since the Gregorian epoch,
75
+ // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
76
+ // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
77
+ // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
78
+ let msecs = Date.now();
79
+
80
+ // Per 4.2.1.2, use count of uuid's generated during the current clock
81
+ // cycle to simulate higher resolution clock
82
+ let nsecs = _lastNSecs + 1;
83
+
84
+ // Time since last uuid creation (in msecs)
85
+ const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000;
86
+
87
+ // Per 4.2.1.2, Bump clockseq on clock regression
88
+ if (dt < 0) {
89
+ clockseq = (clockseq + 1) & 0x3fff;
90
+ }
91
+
92
+ // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
93
+ // time interval
94
+ if ((dt < 0 || msecs > _lastMSecs)) {
95
+ nsecs = 0;
96
+ }
97
+
98
+ // Per 4.2.1.2 Throw error if too many uuids are requested
99
+ if (nsecs >= 10000) {
100
+ throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
101
+ }
102
+
103
+ _lastMSecs = msecs;
104
+ _lastNSecs = nsecs;
105
+ _clockseq = clockseq;
106
+
107
+ // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
108
+ msecs += 12219292800000;
109
+
110
+ let i = 0
111
+ // `time_low`
112
+ const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
113
+ b[i++] = (tl >>> 24) & 0xff;
114
+ b[i++] = (tl >>> 16) & 0xff;
115
+ b[i++] = (tl >>> 8) & 0xff;
116
+ b[i++] = tl & 0xff;
117
+
118
+ // `time_mid`
119
+ const tmh = ((msecs / 0x100000000) * 10000) & 0xfffffff;
120
+ b[i++] = (tmh >>> 8) & 0xff;
121
+ b[i++] = tmh & 0xff;
122
+
123
+ // `time_high_and_version`
124
+ b[i++] = ((tmh >>> 24) & 0xf) | 0x10; // include version
125
+ b[i++] = (tmh >>> 16) & 0xff;
126
+
127
+ // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
128
+ b[i++] = (clockseq >>> 8) | 0x80;
129
+
130
+ // `clock_seq_low`
131
+ b[i++] = clockseq & 0xff;
132
+
133
+ // `node`
134
+ for (let n = 0; n < 6; ++n) {
135
+ b[i + n] = _nodeId[n];
136
+ }
137
+ }
138
+
139
+ /***
140
+ * String in UUID format
141
+ * @see https://github.com/uuidjs/uuid/blob/8f028c4ea42ce41a9a9dc5fa634abe525b2e2066/src/parse.js#L3
142
+ * @param {string} string
143
+ */
144
+ parse(string) {
145
+ let v;
146
+ const arr = this.#data;
147
+
148
+ // Parse ########-....-....-....-............
149
+ arr[0] = (v = parseInt(string.slice(0, 8), 16)) >>> 24;
150
+ arr[1] = (v >>> 16) & 0xff;
151
+ arr[2] = (v >>> 8) & 0xff;
152
+ arr[3] = v & 0xff;
153
+
154
+ // Parse ........-####-....-....-............
155
+ arr[4] = (v = parseInt(string.slice(9, 13), 16)) >>> 8;
156
+ arr[5] = v & 0xff;
157
+
158
+ // Parse ........-....-####-....-............
159
+ arr[6] = (v = parseInt(string.slice(14, 18), 16)) >>> 8;
160
+ arr[7] = v & 0xff;
161
+
162
+ // Parse ........-....-....-####-............
163
+ arr[8] = (v = parseInt(string.slice(19, 23), 16)) >>> 8;
164
+ arr[9] = v & 0xff;
165
+
166
+ // Parse ........-....-....-....-############
167
+ // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
168
+ arr[10] = ((v = parseInt(string.slice(24, 36), 16)) / 0x10000000000) & 0xff;
169
+ arr[11] = (v / 0x100000000) & 0xff;
170
+ arr[12] = (v >>> 24) & 0xff;
171
+ arr[13] = (v >>> 16) & 0xff;
172
+ arr[14] = (v >>> 8) & 0xff;
173
+ arr[15] = v & 0xff;
174
+ }
175
+
176
+ /**
177
+ * @see https://github.com/uuidjs/uuid/blob/8f028c4ea42ce41a9a9dc5fa634abe525b2e2066/src/stringify.js#L16
178
+ * @returns {string}
179
+ */
180
+ toString() {
181
+ const bytes = this.#data;
182
+
183
+ return (
184
+ dec2hex(bytes[0]) +
185
+ dec2hex(bytes[1]) +
186
+ dec2hex(bytes[2]) +
187
+ dec2hex(bytes[3]) +
188
+ '-' +
189
+ dec2hex(bytes[4]) +
190
+ dec2hex(bytes[5]) +
191
+ '-' +
192
+ dec2hex(bytes[6]) +
193
+ dec2hex(bytes[7]) +
194
+ '-' +
195
+ dec2hex(bytes[8]) +
196
+ dec2hex(bytes[9]) +
197
+ '-' +
198
+ dec2hex(bytes[10]) +
199
+ dec2hex(bytes[11]) +
200
+ dec2hex(bytes[12]) +
201
+ dec2hex(bytes[13]) +
202
+ dec2hex(bytes[14]) +
203
+ dec2hex(bytes[15])
204
+ );
205
+ }
206
+
207
+ /**
208
+ *
209
+ * @param {GUID} other
210
+ */
211
+ copy(other) {
212
+ this.#data.set(other.#data);
213
+ }
214
+
215
+ /**
216
+ *
217
+ * @param {GUID} other
218
+ * @returns {boolean}
219
+ */
220
+ equals(other) {
221
+ return is_typed_array_equals(this.#data, other.#data);
222
+ }
223
+
224
+ /**
225
+ * @returns {number}
226
+ */
227
+ hash() {
228
+ const data = this.#data;
229
+
230
+ // use some non-metadata bytes as a hash
231
+ return data[0]
232
+ | data[1] << 8
233
+ | data[2] << 16
234
+ | data[3] << 24
235
+ ;
236
+ }
237
+
238
+ toJSON() {
239
+ return this.toString();
240
+ }
241
+
242
+ fromJSON(v) {
243
+ this.parse(v);
244
+ }
245
+ }
246
+
247
+ /**
248
+ * @readonly
249
+ * @type {string}
250
+ */
251
+ GUID.typeName = "GUID";
252
+
253
+ /**
254
+ * @readonly
255
+ * @type {boolean}
256
+ */
257
+ GUID.prototype.isGUID = true;
@@ -0,0 +1,41 @@
1
+ import { GUID } from "./GUID.js";
2
+
3
+ test("uniqueness out of 2", () => {
4
+ const a = new GUID();
5
+ const b = new GUID();
6
+
7
+ expect(a.equals(b)).toBe(false);
8
+ });
9
+
10
+
11
+ test("equality", () => {
12
+ const a = new GUID();
13
+ const b = new GUID();
14
+
15
+ a.parse("a88bb73a-c89f-11ed-afa1-0242ac120002");
16
+ b.parse("a88bb73a-c89f-11ed-afa1-0242ac120002");
17
+
18
+ expect(a.equals(b)).toBe(true);
19
+
20
+ b.parse("bb75b300-c89f-11ed-afa1-0242ac120002");
21
+
22
+ expect(a.equals(b)).toBe(false);
23
+ });
24
+
25
+ test("hash stability", () => {
26
+ const guid = new GUID();
27
+
28
+ expect(guid.hash()).toBe(guid.hash());
29
+ });
30
+
31
+
32
+ test("to/from JSON consistency", () => {
33
+ const a = new GUID();
34
+ a.parse("bb75b300-c89f-11ed-afa1-0242ac120002");
35
+
36
+ const b = new GUID();
37
+
38
+ b.fromJSON(a.toJSON());
39
+
40
+ expect(b.equals(a)).toBe(true)
41
+ });
@@ -0,0 +1,25 @@
1
+ import { BinaryClassSerializationAdapter } from "../storage/binary/BinaryClassSerializationAdapter.js";
2
+ import { GUID } from "./GUID.js";
3
+
4
+ export class GUIDSerializationAdapter extends BinaryClassSerializationAdapter {
5
+ klass = GUID
6
+ version = 0
7
+
8
+ /**
9
+ *
10
+ * @param buffer
11
+ * @param {GUID} value
12
+ */
13
+ serialize(buffer, value) {
14
+ buffer.writeUint8Array(value.data, 0, 16);
15
+ }
16
+
17
+ /**
18
+ *
19
+ * @param buffer
20
+ * @param {GUID} value
21
+ */
22
+ deserialize(buffer, value) {
23
+ buffer.readUint8Array(value.data, 0, 16);
24
+ }
25
+ }
@@ -1,17 +1,16 @@
1
1
  export class BinaryClassSerializationAdapter {
2
- constructor() {
3
- /**
4
- * @protected
5
- * @type {Class}
6
- */
7
- this.klass = null;
8
2
 
9
- /**
10
- * @protected
11
- * @type {number}
12
- */
13
- this.version = 0;
14
- }
3
+ /**
4
+ * @protected
5
+ * @type {Class}
6
+ */
7
+ klass = null;
8
+
9
+ /**
10
+ * @protected
11
+ * @type {number}
12
+ */
13
+ version = 0;
15
14
 
16
15
  /**
17
16
  * @template T
@@ -5,14 +5,21 @@ import { assert } from "../../../../core/assert.js";
5
5
  import TerrainSystem from "../ecs/TerrainSystem.js";
6
6
  import Task from "../../../../core/process/task/Task.js";
7
7
  import { TaskSignal } from "../../../../core/process/task/TaskSignal.js";
8
+ import { max2 } from "../../../../core/math/max2.js";
9
+ import { clamp01 } from "../../../../core/math/clamp01.js";
8
10
 
9
11
  /**
10
12
  *
11
13
  * @param {EntityManager} em
12
14
  * @param {EntityComponentDataset} ecd
15
+ * @param {number} [timeout] in seconds
13
16
  * @returns {Task}
14
17
  */
15
- export function loadVisibleTerrainTiles(em, ecd) {
18
+ export function loadVisibleTerrainTiles({
19
+ em,
20
+ ecd,
21
+ timeout = 10
22
+ }) {
16
23
 
17
24
  let totalTiles = 0;
18
25
  let loadedTiles = 0;
@@ -22,7 +29,14 @@ export function loadVisibleTerrainTiles(em, ecd) {
22
29
 
23
30
  let failureFlag = false;
24
31
 
32
+ const timeout_milliseconds = timeout * 1000;
33
+
34
+ let start_time = 0;
35
+
25
36
  function init() {
37
+
38
+ start_time = Date.now();
39
+
26
40
  const attemptId = attempt;
27
41
 
28
42
  //force update by camera controller, to ensure correct focus is set
@@ -82,6 +96,11 @@ export function loadVisibleTerrainTiles(em, ecd) {
82
96
  initializer: init,
83
97
 
84
98
  cycleFunction() {
99
+ if (Date.now() > start_time + timeout_milliseconds) {
100
+ // timed out
101
+ return TaskSignal.EndFailure;
102
+ }
103
+
85
104
  if (failureFlag) {
86
105
  return TaskSignal.EndFailure;
87
106
  }
@@ -94,17 +113,12 @@ export function loadVisibleTerrainTiles(em, ecd) {
94
113
  },
95
114
 
96
115
  computeProgress() {
97
- if (totalTiles === 0) {
98
- return 0;
99
- }
100
116
 
101
- const f = loadedTiles / totalTiles;
117
+ const loaded_fraction = totalTiles === 0 ? 0 : loadedTiles / totalTiles;
102
118
 
103
- if (f >= 1) {
104
- return 1;
105
- }
119
+ const timeout_fraction = (Date.now() - start_time) / timeout_milliseconds;
106
120
 
107
- return f;
121
+ return clamp01(max2(loaded_fraction, timeout_fraction));
108
122
  }
109
123
  });
110
124
 
@@ -6,7 +6,7 @@ import { Behavior } from "../../intelligence/behavior/Behavior.js";
6
6
  import { BehaviorStatus } from "../../intelligence/behavior/BehaviorStatus.js";
7
7
  import Quaternion from "../../../core/geom/Quaternion.js";
8
8
  import { clamp01 } from "../../../core/math/clamp01.js";
9
- import { makeCubicCurve } from "../../../core/math/makeCubicCurve.js";
9
+ import { makeCubicCurve } from "../../../core/math/spline/makeCubicCurve.js";
10
10
 
11
11
  export class CameraShakeTraumaBehavior extends Behavior {
12
12
 
@@ -1,6 +1,6 @@
1
1
  import { Frustum as ThreeFrustum } from "three";
2
2
  import { v3_dot } from "../../../../core/geom/v3_dot.js";
3
- import { isValueBetweenInclusive } from "../../../../core/math/isValueBetweenInclusive.js";
3
+ import { isValueBetweenInclusive } from "../../../../core/math/interval/isValueBetweenInclusive.js";
4
4
  import { frustum_from_camera } from "./frustum_from_camera.js";
5
5
  import { is_valid_distance_value } from "./is_valid_distance_value.js";
6
6
 
@@ -1,5 +1,6 @@
1
1
  import { Color } from "../../../../../core/color/Color.js";
2
2
  import { computeStringHash } from "../../../../../core/primitives/strings/computeStringHash.js";
3
+ import { assert } from "../../../../../core/assert.js";
3
4
 
4
5
  export class Decal {
5
6
  constructor() {
@@ -54,8 +55,13 @@ export class Decal {
54
55
  fromJSON({
55
56
  uri,
56
57
  priority = 0,
57
- color
58
+ color = '#FFFFFF'
58
59
  }) {
60
+
61
+ assert.isString(uri, 'uri');
62
+ assert.isNumber(priority, 'priority');
63
+ assert.notNaN(priority, 'priority');
64
+
59
65
  this.uri = uri;
60
66
  this.priority = priority;
61
67
 
@@ -65,11 +71,7 @@ export class Decal {
65
71
  this.__cached_uri = null;
66
72
  }
67
73
 
68
- if (color !== undefined) {
69
- this.color.parse(color);
70
- } else {
71
- this.color.set(1, 1, 1, 1);
72
- }
74
+ this.color.parse(color);
73
75
  }
74
76
 
75
77
  hash() {
@@ -14,4 +14,7 @@ export class FPDecalSystem extends System<Decal, Transform> {
14
14
  filter_function?: (entity: number, mesh: Decal) => boolean,
15
15
  filter_function_context?: any
16
16
  ): { entity: number, component: Decal, contact: SurfacePoint3 }[]
17
+
18
+
19
+ queryOverlapFrustum(result: number[], result_offset: number, planes: number[]): number
17
20
  }