@woosh/meep-engine 2.47.1 → 2.47.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.
@@ -8,212 +8,222 @@ import { intersects1D } from "../math/intersects1D.js";
8
8
  import { overlap1D } from "../math/overlap1D.js";
9
9
 
10
10
 
11
- /**
12
- *
13
- * @param {number} x
14
- * @param {number} y
15
- * @param {number} width
16
- * @param {number} height
17
- * @constructor
18
- */
19
- function Rectangle(x = 0, y = 0, width = 0, height = 0) {
11
+ class Rectangle {
12
+ /**
13
+ *
14
+ * @param {number} x
15
+ * @param {number} y
16
+ * @param {number} width
17
+ * @param {number} height
18
+ * @constructor
19
+ */
20
+ constructor(x = 0, y = 0, width = 0, height = 0) {
21
+
22
+ /**
23
+ * @readonly
24
+ * @type {Vector2}
25
+ */
26
+ this.position = new Vector2(x, y);
27
+
28
+ /**
29
+ * @readonly
30
+ * @type {Vector2}
31
+ */
32
+ this.size = new Vector2(width, height);
33
+ }
20
34
 
21
35
  /**
22
- * @type {Vector2}
36
+ *
37
+ * @param {number} x
38
+ * @param {number} y
39
+ * @param {number} width
40
+ * @param {number} height
23
41
  */
24
- this.position = new Vector2(x, y);
42
+ set(x, y, width, height) {
43
+ this.size.set(width, height);
44
+ this.position.set(x, y);
45
+ }
25
46
 
26
47
  /**
27
- * @type {Vector2}
48
+ *
49
+ * @returns {Rectangle}
28
50
  */
29
- this.size = new Vector2(width, height);
30
- }
51
+ clone() {
52
+ return new Rectangle(this.position.x, this.position.y, this.size.x, this.size.y);
53
+ }
31
54
 
32
- /**
33
- *
34
- * @param {number} x
35
- * @param {number} y
36
- * @param {number} width
37
- * @param {number} height
38
- */
39
- Rectangle.prototype.set = function set(x, y, width, height) {
40
- this.size.set(width, height);
41
- this.position.set(x, y);
42
- };
55
+ /**
56
+ *
57
+ * @param {Rectangle} other
58
+ */
59
+ copy(other) {
60
+ this.position.copy(other.position);
61
+ this.size.copy(other.size);
62
+ }
43
63
 
44
- /**
45
- *
46
- * @returns {Rectangle}
47
- */
48
- Rectangle.prototype.clone = function () {
49
- return new Rectangle(this.position.x, this.position.y, this.size.x, this.size.y);
50
- };
64
+ /**
65
+ *
66
+ * @param {number} x0
67
+ * @param {number} y0
68
+ * @param {number} x1
69
+ * @param {number} y1
70
+ * @returns {boolean}
71
+ */
72
+ _intersects(x0, y0, x1, y1) {
73
+ const p = this.position;
74
+ const s = this.size;
51
75
 
52
- /**
53
- *
54
- * @param {Rectangle} other
55
- */
56
- Rectangle.prototype.copy = function (other) {
57
- this.position.copy(other.position);
58
- this.size.copy(other.size);
59
- };
76
+ const _x0 = p.x;
77
+ const _y0 = p.y;
60
78
 
61
- /**
62
- *
63
- * @param {number} x0
64
- * @param {number} y0
65
- * @param {number} x1
66
- * @param {number} y1
67
- * @returns {boolean}
68
- */
69
- Rectangle.prototype._intersects = function (x0, y0, x1, y1) {
70
- const p = this.position;
71
- const s = this.size;
79
+ return intersects1D(x0, x1, _x0, s.x + _x0) && intersects1D(y0, y1, _y0, _y0 + s.y);
80
+ }
72
81
 
73
- const _x0 = p.x;
74
- const _y0 = p.y;
82
+ /**
83
+ *
84
+ * @param {Rectangle} other
85
+ * @returns {boolean}
86
+ */
87
+ intersects(other) {
88
+ const x0 = other.position.x;
89
+ const y0 = other.position.y;
90
+ const y1 = other.size.y + y0;
91
+ const x1 = other.size.x + x0;
92
+ return this._intersects(x0, y0, x1, y1);
93
+ }
75
94
 
76
- return intersects1D(x0, x1, _x0, s.x + _x0) && intersects1D(y0, y1, _y0, _y0 + s.y);
77
- };
95
+ /**
96
+ *
97
+ * @param {number} x0
98
+ * @param {number} y0
99
+ * @param {number} x1
100
+ * @param {number} y1
101
+ * @returns {boolean}
102
+ */
103
+ _overlaps(x0, y0, x1, y1) {
104
+ const p = this.position;
105
+ const s = this.size;
78
106
 
79
- /**
80
- *
81
- * @param {Rectangle} other
82
- * @returns {boolean}
83
- */
84
- Rectangle.prototype.intersects = function (other) {
85
- const x0 = other.position.x;
86
- const y0 = other.position.y;
87
- const y1 = other.size.y + y0;
88
- const x1 = other.size.x + x0;
89
- return this._intersects(x0, y0, x1, y1);
90
- };
107
+ const _x0 = p.x;
108
+ const _y0 = p.y;
91
109
 
92
- /**
93
- *
94
- * @param {number} x0
95
- * @param {number} y0
96
- * @param {number} x1
97
- * @param {number} y1
98
- * @returns {boolean}
99
- */
100
- Rectangle.prototype._overlaps = function (x0, y0, x1, y1) {
101
- const p = this.position;
102
- const s = this.size;
110
+ return overlap1D(x0, x1, _x0, s.x + _x0) && overlap1D(y0, y1, _y0, _y0 + s.y);
111
+ }
103
112
 
104
- const _x0 = p.x;
105
- const _y0 = p.y;
113
+ overlaps(other) {
114
+ const x0 = other.position.x;
115
+ const y0 = other.position.y;
116
+ const y1 = other.size.y + y0;
117
+ const x1 = other.size.x + x0;
118
+ return this._overlaps(x0, y0, x1, y1);
119
+ }
106
120
 
107
- return overlap1D(x0, x1, _x0, s.x + _x0) && overlap1D(y0, y1, _y0, _y0 + s.y);
108
- };
121
+ _resizeToFit(x0, y0, x1, y1) {
122
+ const size = this.size;
109
123
 
110
- Rectangle.prototype.overlaps = function (other) {
111
- const x0 = other.position.x;
112
- const y0 = other.position.y;
113
- const y1 = other.size.y + y0;
114
- const x1 = other.size.x + x0;
115
- return this._overlaps(x0, y0, x1, y1);
116
- };
124
+ const _x0 = this.position.x;
125
+ const _y0 = this.position.y;
117
126
 
118
- Rectangle.prototype._resizeToFit = function (x0, y0, x1, y1) {
119
- const size = this.size;
127
+ let _y1 = size.y + _y0;
128
+ let _x1 = size.x + _x0;
120
129
 
121
- const _x0 = this.position.x;
122
- const _y0 = this.position.y;
130
+ if (Number.isNaN(_x1)) {
131
+ _x1 = -Infinity;
132
+ }
133
+ if (Number.isNaN(_y1)) {
134
+ _y1 = -Infinity;
135
+ }
123
136
 
124
- let _y1 = size.y + _y0;
125
- let _x1 = size.x + _x0;
137
+ const nX0 = min2(x0, _x0);
138
+ const nY0 = min2(y0, _y0);
139
+ const nX1 = max2(x1, _x1);
140
+ const nY1 = max2(y1, _y1);
126
141
 
127
- if (Number.isNaN(_x1)) {
128
- _x1 = -Infinity;
129
- }
130
- if (Number.isNaN(_y1)) {
131
- _y1 = -Infinity;
142
+ this.position.set(nX0, nY0);
143
+ size.set(nX1 - nX0, nY1 - nY0);
132
144
  }
133
145
 
134
- const nX0 = min2(x0, _x0);
135
- const nY0 = min2(y0, _y0);
136
- const nX1 = max2(x1, _x1);
137
- const nY1 = max2(y1, _y1);
146
+ resizeToFit(other) {
147
+ const x0 = other.position.x;
148
+ const y0 = other.position.y;
149
+ const y1 = other.size.y + y0;
150
+ const x1 = other.size.x + x0;
138
151
 
139
- this.position.set(nX0, nY0);
140
- size.set(nX1 - nX0, nY1 - nY0);
141
- };
152
+ return this._resizeToFit(x0, y0, x1, y1);
153
+ }
142
154
 
143
- Rectangle.prototype.resizeToFit = function (other) {
144
- const x0 = other.position.x;
145
- const y0 = other.position.y;
146
- const y1 = other.size.y + y0;
147
- const x1 = other.size.x + x0;
155
+ _contains(x0, y0, x1, y1) {
156
+ const size = this.size;
148
157
 
149
- return this._resizeToFit(x0, y0, x1, y1);
150
- };
158
+ const _x0 = this.position.x;
159
+ const _y0 = this.position.y;
151
160
 
152
- Rectangle.prototype._contains = function (x0, y0, x1, y1) {
153
- const size = this.size;
161
+ const _y1 = size.y + _y0;
162
+ const _x1 = size.x + _x0;
154
163
 
155
- const _x0 = this.position.x;
156
- const _y0 = this.position.y;
164
+ return x0 >= _x0 && x1 <= _x1 && y0 >= _y0 && y1 <= _y1;
165
+ }
157
166
 
158
- const _y1 = size.y + _y0;
159
- const _x1 = size.x + _x0;
167
+ contains(other) {
168
+ const x0 = other.position.x;
169
+ const y0 = other.position.y;
170
+ const y1 = other.size.y + y0;
171
+ const x1 = other.size.x + x0;
160
172
 
161
- return x0 >= _x0 && x1 <= _x1 && y0 >= _y0 && y1 <= _y1;
162
- };
173
+ return this._contains(x0, y0, x1, y1);
174
+ }
163
175
 
164
- Rectangle.prototype.contains = function (other) {
165
- const x0 = other.position.x;
166
- const y0 = other.position.y;
167
- const y1 = other.size.y + y0;
168
- const x1 = other.size.x + x0;
176
+ /**
177
+ *
178
+ * @param {Vector2} result
179
+ */
180
+ computeCenter(result) {
181
+ const p = this.position;
182
+ const s = this.size;
169
183
 
170
- return this._contains(x0, y0, x1, y1);
171
- };
184
+ const x = p.x + s.x / 2;
185
+ const y = p.y + s.y / 2;
172
186
 
173
- /**
174
- *
175
- * @param {Vector2} result
176
- */
177
- Rectangle.prototype.computeCenter = function (result) {
178
- const p = this.position;
179
- const s = this.size;
187
+ result.set(x, y);
188
+ }
180
189
 
181
- const x = p.x + s.x / 2;
182
- const y = p.y + s.y / 2;
190
+ /**
191
+ *
192
+ * @return {number}
193
+ */
194
+ computeArea() {
195
+ return this.size.x * this.size.y;
196
+ }
183
197
 
184
- result.set(x, y);
185
- };
198
+ /**
199
+ *
200
+ * @param {Array.<number>|Float32Array|Float64Array|Uint8Array} target
201
+ * @param {number} [targetOffset=0]
202
+ */
203
+ toArray(target, targetOffset = 0) {
204
+ target[targetOffset] = this.position.x;
205
+ target[targetOffset + 1] = this.position.y;
206
+ target[targetOffset + 2] = this.size.x;
207
+ target[targetOffset + 3] = this.size.y;
208
+ }
186
209
 
187
- /**
188
- *
189
- * @return {number}
190
- */
191
- Rectangle.prototype.computeArea = function () {
192
- return this.size.x * this.size.y;
193
- };
210
+ toJSON() {
211
+ return {
212
+ position: this.position.toJSON(),
213
+ size: this.size.toJSON()
214
+ };
215
+ }
216
+
217
+ fromJSON(json) {
218
+ this.position.fromJSON(json.position);
219
+ this.size.fromJSON(json.size);
220
+ }
221
+ }
194
222
 
195
223
  /**
196
- *
197
- * @param {Array.<number>|Float32Array|Float64Array|Uint8Array} target
198
- * @param {number} [targetOffset=0]
224
+ * @readonly
225
+ * @type {boolean}
199
226
  */
200
- Rectangle.prototype.toArray = function (target, targetOffset = 0) {
201
- target[targetOffset] = this.position.x;
202
- target[targetOffset + 1] = this.position.y;
203
- target[targetOffset + 2] = this.size.x;
204
- target[targetOffset + 3] = this.size.y;
205
- };
206
-
207
- Rectangle.prototype.toJSON = function () {
208
- return {
209
- position: this.position.toJSON(),
210
- size: this.size.toJSON()
211
- };
212
- };
213
-
214
- Rectangle.prototype.fromJSON = function (json) {
215
- this.position.fromJSON(json.position);
216
- this.size.fromJSON(json.size);
217
- };
227
+ Rectangle.prototype.isRectangle = true;
218
228
 
219
229
  export default Rectangle;
@@ -126,6 +126,7 @@ export class NodeGraph {
126
126
  /**
127
127
  * Merge foreign nodes and associated connections into this graph
128
128
  * New node instances and connections will be created to reflect these inside this graph
129
+ * NOTE: parameters on merged nodes are shallow copies
129
130
  * @param {NodeInstance[]} nodes
130
131
  * @param {Connection[]} [connections]
131
132
  * @returns {{connections:Connection[], nodes:NodeInstance[]}} local created instances
@@ -145,7 +146,15 @@ export class NodeGraph {
145
146
 
146
147
  for (let i = 0; i < additional_node_count; i++) {
147
148
  const other_node = nodes[i];
148
- this_nodes[other_node.id] = this.createNode(other_node.description);
149
+
150
+ const this_node_id = this.createNode(other_node.description);
151
+ this_nodes[other_node.id] = this_node_id;
152
+
153
+ // copy parameters
154
+ const this_node = this.getNode(this_node_id);
155
+
156
+ this_node.setParameters(other_node.parameters);
157
+
149
158
  }
150
159
 
151
160
  // create connections
@@ -3,6 +3,8 @@ import List from "../../../collection/list/List.js";
3
3
  import { NodeInstancePortReference } from "./NodeInstancePortReference.js";
4
4
  import { PortDirection } from "./PortDirection.js";
5
5
  import { isArrayEqual } from "../../../collection/array/isArrayEqual.js";
6
+ import { objectDeepEquals } from "../../object/objectDeepEquals.js";
7
+ import Signal from "../../../events/signal/Signal.js";
6
8
 
7
9
  /**
8
10
  *
@@ -33,10 +35,9 @@ export class NodeInstance {
33
35
 
34
36
  /**
35
37
  * Internal instance data
36
- * @type {Array}
38
+ * @type {Object}
37
39
  */
38
- this.parameters = [];
39
-
40
+ this.parameters = {};
40
41
 
41
42
  /**
42
43
  * @transient
@@ -49,6 +50,27 @@ export class NodeInstance {
49
50
  * @type {List<Connection>}
50
51
  */
51
52
  this.connections = new List();
53
+
54
+ /**
55
+ * @readonly
56
+ */
57
+ this.on = {
58
+ /**
59
+ * @readonly
60
+ * @type {Signal<string, *, *>}
61
+ */
62
+ parameterChanged: new Signal(),
63
+ /**
64
+ * @readonly
65
+ * @type {Signal<string, *>}
66
+ */
67
+ parameterAdded: new Signal(),
68
+ /**
69
+ * @readonly
70
+ * @type {Signal<string, *>}
71
+ */
72
+ parameterRemoved: new Signal(),
73
+ };
52
74
  }
53
75
 
54
76
  /**
@@ -133,31 +155,83 @@ export class NodeInstance {
133
155
  }
134
156
 
135
157
  /**
136
- *
137
- * @param {number} id
138
- * @returns {string|number|boolean}
158
+ * @template T
159
+ * @param {string} id
160
+ * @returns {T|undefined}
139
161
  */
140
162
  getParameterValue(id) {
163
+ assert.isString(id, 'id');
164
+
141
165
  return this.parameters[id];
142
166
  }
143
167
 
144
168
  /**
145
- *
146
- * @param {number} id
147
- * @param {string|number|boolean} value
169
+ * @template T
170
+ * @param {string} id
171
+ * @param {T} value
148
172
  */
149
173
  setParameterValue(id, value) {
150
- this.parameters[id] = value;
174
+ assert.isString(id, 'id');
175
+ assert.defined(value, 'value');
176
+
177
+ const parameters = this.parameters;
178
+
179
+ const old_value = parameters[id];
180
+
181
+ if (old_value === value) {
182
+ return;
183
+ }
184
+
185
+ parameters[id] = value;
186
+
187
+ if (old_value === undefined) {
188
+ this.on.parameterAdded.send2(id, value);
189
+ }
190
+
191
+ this.on.parameterChanged.send3(id, value, old_value);
151
192
  }
152
193
 
153
194
  /**
154
195
  *
155
- * @param {[]} parameters
196
+ * @param {string} id
197
+ * @returns {boolean}
198
+ */
199
+ deleteParameter(id) {
200
+ assert.isString(id, 'id');
201
+
202
+ const parameters = this.parameters;
203
+
204
+ if (!parameters.hasOwnProperty(id)) {
205
+ return false;
206
+ }
207
+
208
+ const existing = parameters[id];
209
+
210
+ delete parameters[id];
211
+
212
+ this.on.parameterRemoved.send2(id, existing);
213
+
214
+ return true;
215
+ }
216
+
217
+ /**
218
+ * Will overwrite only those properties that are present in the hash
219
+ * @param {Object} partial_hash
156
220
  */
157
- setParameters(parameters) {
158
- assert.isArray(parameters, 'parameters');
221
+ setParameters(partial_hash) {
222
+ assert.defined(partial_hash, 'parameters')
223
+
224
+ for (const key in partial_hash) {
225
+
226
+ this.setParameterValue(key, partial_hash[key]);
159
227
 
160
- this.parameters = parameters;
228
+ }
229
+ }
230
+
231
+ clearParameters(){
232
+ for (const key in this.parameters) {
233
+ this.deleteParameter(key);
234
+ }
161
235
  }
162
236
 
163
237
  /**
@@ -179,8 +253,9 @@ export class NodeInstance {
179
253
  });
180
254
 
181
255
  //clear parameters
182
- this.parameters.splice(0, this.parameters.length);
256
+ this.clearParameters();
183
257
 
258
+ // TODO address parameters in NodeDescription as well
184
259
  //populate parameter defaults
185
260
  node.parameters.forEach(pd => {
186
261
  this.parameters[pd.id] = pd.defaultValue;
@@ -220,7 +295,7 @@ export class NodeInstance {
220
295
  return this.id === other.id
221
296
  && this.description === other.description
222
297
  && isArrayEqual(this.endpoints, other.endpoints)
223
- && isArrayEqual(this.parameters, other.parameters)
298
+ && objectDeepEquals(this.parameters, other.parameters)
224
299
  ;
225
300
  }
226
301
 
@@ -2,6 +2,9 @@ import { BinaryClassSerializationAdapter } from "../../storage/binary/BinaryClas
2
2
  import { FogOfWar } from "../FogOfWar.js";
3
3
  import { serializeRowFirstTable } from "../../../../core/collection/table/serializeRowFirstTable.js";
4
4
  import { deserializeRowFirstTable } from "../../../../core/collection/table/deserializeRowFirstTable.js";
5
+ import {
6
+ Sampler2DSerializationAdapter
7
+ } from "../../../graphics/texture/sampler/serialization/Sampler2DSerializationAdapter.js";
5
8
 
6
9
  export class FogOfWarSerializationAdapter extends BinaryClassSerializationAdapter {
7
10
  constructor() {
@@ -9,6 +12,8 @@ export class FogOfWarSerializationAdapter extends BinaryClassSerializationAdapte
9
12
 
10
13
  this.klass = FogOfWar;
11
14
  this.version = 1;
15
+
16
+ this.__sampler_serializer = new Sampler2DSerializationAdapter();
12
17
  }
13
18
 
14
19
  /**
@@ -35,7 +40,7 @@ export class FogOfWarSerializationAdapter extends BinaryClassSerializationAdapte
35
40
 
36
41
  buffer.writeUint32(color);
37
42
 
38
- value.sampler.toBinaryBuffer(buffer);
43
+ this.__sampler_serializer.serialize(buffer,value.sampler);
39
44
 
40
45
  //serialize reveal state
41
46
  serializeRowFirstTable(buffer, value.fadeMask);
@@ -68,7 +73,7 @@ export class FogOfWarSerializationAdapter extends BinaryClassSerializationAdapte
68
73
  color_a / 255
69
74
  );
70
75
 
71
- value.sampler.fromBinaryBuffer(buffer);
76
+ this.__sampler_serializer.deserialize(buffer,value.sampler);
72
77
 
73
78
  //deserialize reveal state
74
79
  deserializeRowFirstTable(buffer, value.fadeMask);