@woosh/meep-engine 2.47.28 → 2.47.31

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.
@@ -54198,9 +54198,8 @@ class Vector1 extends Number {
54198
54198
  constructor(x = 0) {
54199
54199
  super();
54200
54200
 
54201
- assert.equal(typeof x, "number", `X must be of type "number", instead was "${typeof x}"`);
54202
-
54203
- assert.ok(!Number.isNaN(x), `X must be a valid number, instead was NaN`);
54201
+ assert.isNumber( x, 'x');
54202
+ assert.notNaN(x, 'x');
54204
54203
 
54205
54204
  this.x = x;
54206
54205
 
@@ -99956,13 +99955,12 @@ const BehaviorStatus = {
99956
99955
  * @template CTX
99957
99956
  */
99958
99957
  class Behavior {
99959
- constructor() {
99960
- /**
99961
- * Any internal state used by the behavior
99962
- * @type {CTX|null}
99963
- */
99964
- this.context = null;
99965
- }
99958
+
99959
+ /**
99960
+ * Any internal state used by the behavior
99961
+ * @type {CTX|null}
99962
+ */
99963
+ context = null;
99966
99964
 
99967
99965
  /**
99968
99966
  * Main update function. Every behavior executes some logic, some behaviors are long-running and some are instantaneous
@@ -120383,7 +120381,8 @@ class LightManager {
120383
120381
  this.__visible_decals.onRemoved.add(this.__handle_visible_decal_removed, this);
120384
120382
 
120385
120383
  /**
120386
- *
120384
+ * Data needs to be re-written into the data texture
120385
+ * Usually set when source lights change
120387
120386
  * @type {boolean}
120388
120387
  * @private
120389
120388
  */
@@ -120399,6 +120398,10 @@ class LightManager {
120399
120398
  // window.light_manager = this; // DEBUG
120400
120399
  }
120401
120400
 
120401
+ requestDataUpdate() {
120402
+ this.__light_data_needs_update = true;
120403
+ }
120404
+
120402
120405
  /**
120403
120406
  * Please set this to false if you have a lot of overlapping decals in the scene
120404
120407
  * Overlapping decals can provide filtering artifacts due to incorrect mipmap level detection by WebGL
@@ -121189,17 +121192,17 @@ class LightManager {
121189
121192
  assert.isNumber(x, 'x');
121190
121193
  assert.isNonNegativeInteger(x, 'x');
121191
121194
  assert.isFiniteNumber(x, 'x');
121192
- assert.greaterThan(x,0,'x must be > 0');
121195
+ assert.greaterThan(x, 0, 'x must be > 0');
121193
121196
 
121194
121197
  assert.isNumber(y, 'y');
121195
121198
  assert.isNonNegativeInteger(y, 'y');
121196
121199
  assert.isFiniteNumber(y, 'y');
121197
- assert.greaterThan(y,0,'y must be > 0');
121200
+ assert.greaterThan(y, 0, 'y must be > 0');
121198
121201
 
121199
121202
  assert.isNumber(z, 'z');
121200
121203
  assert.isNonNegativeInteger(z, 'z');
121201
121204
  assert.isFiniteNumber(z, 'z');
121202
- assert.greaterThan(z,0,'z must be > 0');
121205
+ assert.greaterThan(z, 0, 'z must be > 0');
121203
121206
 
121204
121207
  const r = this.__tiles_resolution;
121205
121208
 
@@ -121228,6 +121231,15 @@ class LightManager {
121228
121231
  );
121229
121232
  }
121230
121233
 
121234
+ /**
121235
+ *
121236
+ * @param {AbstractLight} light
121237
+ * @returns {boolean}
121238
+ */
121239
+ hasLight(light) {
121240
+ return this.#metadata_map.has(light.id);
121241
+ }
121242
+
121231
121243
  /**
121232
121244
  *
121233
121245
  * @param {AbstractLight} light
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.47.28",
8
+ "version": "2.47.31",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -20,9 +20,8 @@ class Vector1 extends Number {
20
20
  constructor(x = 0) {
21
21
  super();
22
22
 
23
- assert.equal(typeof x, "number", `X must be of type "number", instead was "${typeof x}"`);
24
-
25
- assert.ok(!Number.isNaN(x), `X must be a valid number, instead was NaN`);
23
+ assert.isNumber( x, 'x');
24
+ assert.notNaN(x, 'x');
26
25
 
27
26
  this.x = x;
28
27
 
@@ -1,3 +1,5 @@
1
+ import {Color} from "../../../../../core/color/Color";
2
+
1
3
  export class Decal {
2
4
  /**
3
5
  * Path to image
@@ -8,4 +10,6 @@ export class Decal {
8
10
  * Draw order, higher values will be drawn on top of lower values when there's an overlap
9
11
  */
10
12
  priority: number
13
+
14
+ readonly color: Color
11
15
  }
@@ -76,6 +76,14 @@ class Context extends SystemEntityContext {
76
76
  return this.components[1];
77
77
  }
78
78
 
79
+ /**
80
+ *
81
+ * @returns {Decal}
82
+ */
83
+ getDecalComponent() {
84
+ return this.components[0];
85
+ }
86
+
79
87
  __update_transform() {
80
88
  /**
81
89
  *
@@ -92,11 +100,7 @@ class Context extends SystemEntityContext {
92
100
 
93
101
  async __load_texture() {
94
102
 
95
- /**
96
- *
97
- * @type {Decal}
98
- */
99
- const decal_spec = this.components[0];
103
+ const decal_spec = this.getDecalComponent();
100
104
 
101
105
  const _uri = decal_spec.uri;
102
106
 
@@ -124,6 +128,17 @@ class Context extends SystemEntityContext {
124
128
  decal_spec.__cached_uri = _uri;
125
129
  }
126
130
 
131
+ rebuild() {
132
+ const plugin = this.getPlugin();
133
+ const lm = plugin.getLightManager();
134
+
135
+ if (this.__fp_decal === null || !lm.hasLight(this.__fp_decal)) {
136
+ return;
137
+ }
138
+
139
+ lm.requestDataUpdate();
140
+ }
141
+
127
142
  link() {
128
143
  const plugin = this.getPlugin();
129
144
 
@@ -133,17 +148,12 @@ class Context extends SystemEntityContext {
133
148
 
134
149
  this.__fp_decal = fpDecal;
135
150
 
136
-
137
151
  this.__update_transform();
138
152
 
139
153
  const transform = this.getTransform();
140
154
  transform.subscribeAllChanges(this.__update_transform, this);
141
155
 
142
- /**
143
- *
144
- * @type {Decal}
145
- */
146
- const decal_spec = this.components[0];
156
+ const decal_spec = this.getDecalComponent();
147
157
 
148
158
  // propagate draw priority onto decal
149
159
  Object.defineProperties(fpDecal, {
@@ -152,13 +162,15 @@ class Context extends SystemEntityContext {
152
162
  return decal_spec.priority;
153
163
  }
154
164
  },
155
- 'color':{
156
- get(){
165
+ 'color': {
166
+ get() {
157
167
  return decal_spec.color;
158
168
  }
159
169
  }
160
170
  });
161
171
 
172
+ decal_spec.color.onChanged.add(this.rebuild, this);
173
+
162
174
  this.__load_texture().then(() => {
163
175
 
164
176
  if (!this.__is_linked) {
@@ -195,6 +207,10 @@ class Context extends SystemEntityContext {
195
207
  const transform = this.getTransform();
196
208
  transform.subscribeAllChanges(this.__update_transform, this);
197
209
 
210
+ const decal_spec = this.getDecalComponent();
211
+
212
+ decal_spec.color.onChanged.remove(this.rebuild, this);
213
+
198
214
  this.#bvh_leaf.unlink();
199
215
 
200
216
  super.unlink();
@@ -325,7 +341,7 @@ export class FPDecalSystem extends AbstractContextSystem {
325
341
  continue;
326
342
  }
327
343
 
328
- if(!filter_function.call(filter_function_context,entity,decal)){
344
+ if (!filter_function.call(filter_function_context, entity, decal)) {
329
345
  continue;
330
346
  }
331
347
 
@@ -327,7 +327,8 @@ export class LightManager {
327
327
  this.__visible_decals.onRemoved.add(this.__handle_visible_decal_removed, this);
328
328
 
329
329
  /**
330
- *
330
+ * Data needs to be re-written into the data texture
331
+ * Usually set when source lights change
331
332
  * @type {boolean}
332
333
  * @private
333
334
  */
@@ -343,6 +344,10 @@ export class LightManager {
343
344
  // window.light_manager = this; // DEBUG
344
345
  }
345
346
 
347
+ requestDataUpdate() {
348
+ this.__light_data_needs_update = true;
349
+ }
350
+
346
351
  /**
347
352
  * Please set this to false if you have a lot of overlapping decals in the scene
348
353
  * Overlapping decals can provide filtering artifacts due to incorrect mipmap level detection by WebGL
@@ -1133,17 +1138,17 @@ export class LightManager {
1133
1138
  assert.isNumber(x, 'x');
1134
1139
  assert.isNonNegativeInteger(x, 'x');
1135
1140
  assert.isFiniteNumber(x, 'x');
1136
- assert.greaterThan(x,0,'x must be > 0');
1141
+ assert.greaterThan(x, 0, 'x must be > 0');
1137
1142
 
1138
1143
  assert.isNumber(y, 'y');
1139
1144
  assert.isNonNegativeInteger(y, 'y');
1140
1145
  assert.isFiniteNumber(y, 'y');
1141
- assert.greaterThan(y,0,'y must be > 0');
1146
+ assert.greaterThan(y, 0, 'y must be > 0');
1142
1147
 
1143
1148
  assert.isNumber(z, 'z');
1144
1149
  assert.isNonNegativeInteger(z, 'z');
1145
1150
  assert.isFiniteNumber(z, 'z');
1146
- assert.greaterThan(z,0,'z must be > 0');
1151
+ assert.greaterThan(z, 0, 'z must be > 0');
1147
1152
 
1148
1153
  const r = this.__tiles_resolution;
1149
1154
 
@@ -1172,6 +1177,15 @@ export class LightManager {
1172
1177
  );
1173
1178
  }
1174
1179
 
1180
+ /**
1181
+ *
1182
+ * @param {AbstractLight} light
1183
+ * @returns {boolean}
1184
+ */
1185
+ hasLight(light) {
1186
+ return this.#metadata_map.has(light.id);
1187
+ }
1188
+
1175
1189
  /**
1176
1190
  *
1177
1191
  * @param {AbstractLight} light
@@ -6,13 +6,12 @@ import { BehaviorStatus } from "./BehaviorStatus.js";
6
6
  * @template CTX
7
7
  */
8
8
  export class Behavior {
9
- constructor() {
10
- /**
11
- * Any internal state used by the behavior
12
- * @type {CTX|null}
13
- */
14
- this.context = null;
15
- }
9
+
10
+ /**
11
+ * Any internal state used by the behavior
12
+ * @type {CTX|null}
13
+ */
14
+ context = null;
16
15
 
17
16
  /**
18
17
  * Main update function. Every behavior executes some logic, some behaviors are long-running and some are instantaneous
@@ -0,0 +1,42 @@
1
+ import { Behavior } from "../Behavior.js";
2
+ import { BehaviorStatus } from "../BehaviorStatus.js";
3
+ import { AbstractDecoratorBehavior } from "./AbstractDecoratorBehavior.js";
4
+
5
+ /**
6
+ * Inverts result of the source behavior, success becomes failure, failure becomes success
7
+ */
8
+ export class InvertStatusBehavior extends AbstractDecoratorBehavior {
9
+ /**
10
+ *
11
+ * @param {Behavior} source
12
+ */
13
+ constructor(source) {
14
+ super();
15
+
16
+ this.setSource(source);
17
+ }
18
+
19
+ /**
20
+ *
21
+ * @param {Behavior} source
22
+ * @return {InvertStatusBehavior}
23
+ */
24
+ static from(source) {
25
+ return new InvertStatusBehavior(source);
26
+ }
27
+
28
+ tick(timeDelta) {
29
+ let r = this.__source.tick(timeDelta);
30
+
31
+ if (r === BehaviorStatus.Succeeded) {
32
+ r = BehaviorStatus.Failed;
33
+ } else if (r === BehaviorStatus.Failed) {
34
+ r = BehaviorStatus.Succeeded;
35
+ }
36
+
37
+ return r;
38
+ }
39
+ }
40
+
41
+ InvertStatusBehavior.typeName = "InverterBehavior";
42
+
@@ -0,0 +1,33 @@
1
+ import {
2
+ ObjectBasedClassSerializationAdapter
3
+ } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
4
+ import { InvertStatusBehavior } from "./InvertStatusBehavior.js";
5
+
6
+ export class InvertStatusBehaviorSerializationAdapter extends ObjectBasedClassSerializationAdapter {
7
+ constructor() {
8
+ super();
9
+
10
+ this.klass = InvertStatusBehavior;
11
+ this.version = 0;
12
+ }
13
+
14
+ /**
15
+ *
16
+ * @param {BinaryBuffer} buffer
17
+ * @param {InvertStatusBehavior} value
18
+ */
19
+ serialize(buffer, value) {
20
+ this.objectAdapter.serialize(buffer, value.getSource())
21
+ }
22
+
23
+ /**
24
+ *
25
+ * @param {BinaryBuffer} buffer
26
+ * @param {InvertStatusBehavior} value
27
+ */
28
+ deserialize(buffer, value) {
29
+ const source = this.objectAdapter.deserialize(buffer);
30
+
31
+ value.setSource(source);
32
+ }
33
+ }
@@ -3,6 +3,7 @@ import { BehaviorStatus } from "../BehaviorStatus.js";
3
3
  import { AbstractDecoratorBehavior } from "./AbstractDecoratorBehavior.js";
4
4
 
5
5
  /**
6
+ * @deprecated use {@link RepeatUntilSuccessBehavior} in conjunction with {@link InvertStatusBehavior} instead
6
7
  * @extends {Behavior}
7
8
  */
8
9
  export class RepeatUntilFailureBehavior extends AbstractDecoratorBehavior {
@@ -38,28 +39,24 @@ export class RepeatUntilFailureBehavior extends AbstractDecoratorBehavior {
38
39
  * @param {number} [limit]
39
40
  */
40
41
  static from(source, limit = Infinity) {
41
- const r = new RepeatUntilFailureBehavior();
42
-
43
- r.setSource(source);
44
- r.__limit = limit;
45
-
46
- return r;
42
+ return new RepeatUntilFailureBehavior(source, limit);
47
43
  }
48
44
 
49
45
  tick(timeDelta) {
50
46
  const s = this.__source.tick(timeDelta);
51
47
 
52
- if (s !== BehaviorStatus.Succeeded) {
48
+ if (s === BehaviorStatus.Failed) {
49
+ return BehaviorStatus.Succeeded;
53
50
 
51
+ } else if (s === BehaviorStatus.Running) {
54
52
  return s;
55
-
56
53
  }
57
54
 
58
55
  this.__iterator++;
59
56
 
60
57
  if (this.__iterator >= this.__limit) {
61
58
 
62
- return BehaviorStatus.Succeeded;
59
+ return BehaviorStatus.Failed;
63
60
  } else {
64
61
  //re-initialize the source behavior
65
62
  this.__source.initialize(this.context);
@@ -1,75 +0,0 @@
1
- import { Behavior } from "../Behavior.js";
2
- import { BehaviorStatus } from "../BehaviorStatus.js";
3
- import {
4
- ObjectBasedClassSerializationAdapter
5
- } from "../../../ecs/storage/binary/object/ObjectBasedClassSerializationAdapter.js";
6
- import { AbstractDecoratorBehavior } from "./AbstractDecoratorBehavior.js";
7
-
8
- /**
9
- * Inverts result of the source behavior, success becomes failure, failure becomes success
10
- */
11
- export class InverterBehavior extends AbstractDecoratorBehavior {
12
- /**
13
- *
14
- * @param {Behavior} source
15
- */
16
- constructor(source) {
17
- super();
18
-
19
- this.setSource(source);
20
- }
21
-
22
- /**
23
- *
24
- * @param {Behavior} source
25
- * @return {InverterBehavior}
26
- */
27
- static from(source) {
28
- const b = new InverterBehavior(source);
29
-
30
- return b;
31
- }
32
-
33
- tick(timeDelta) {
34
- let r = this.__source.tick(timeDelta);
35
-
36
- if (r === BehaviorStatus.Succeeded) {
37
- r = BehaviorStatus.Failed;
38
- } else if (r === BehaviorStatus.Failed) {
39
- r = BehaviorStatus.Succeeded;
40
- }
41
-
42
- return r;
43
- }
44
- }
45
-
46
- InverterBehavior.typeName = "InverterBehavior";
47
-
48
- export class InverterBehaviorSerializationAdapter extends ObjectBasedClassSerializationAdapter {
49
- constructor() {
50
- super();
51
-
52
- this.klass = InverterBehavior;
53
- this.version = 0;
54
- }
55
-
56
- /**
57
- *
58
- * @param {BinaryBuffer} buffer
59
- * @param {InverterBehavior} value
60
- */
61
- serialize(buffer, value) {
62
- this.objectAdapter.serialize(buffer, value.getSource())
63
- }
64
-
65
- /**
66
- *
67
- * @param {BinaryBuffer} buffer
68
- * @param {InverterBehavior} value
69
- */
70
- deserialize(buffer, value) {
71
- const source = this.objectAdapter.deserialize(buffer);
72
-
73
- value.setSource(source);
74
- }
75
- }