@woosh/meep-engine 2.84.5 → 2.84.8

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 (27) hide show
  1. package/build/meep.cjs +139 -84
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +139 -84
  4. package/package.json +1 -1
  5. package/src/core/collection/array/arrayIndexByEquality.js +1 -0
  6. package/src/core/collection/list/List.js +26 -18
  7. package/src/core/collection/list/List.spec.js +73 -0
  8. package/src/core/primitives/numbers/number_count_decimals.js +30 -0
  9. package/src/core/primitives/numbers/number_pretty_print.js +7 -29
  10. package/src/core/primitives/strings/string_format_camel_to_kebab.js +2 -0
  11. package/src/core/primitives/strings/string_strip_trailing.js +22 -0
  12. package/src/core/primitives/strings/string_strip_trailing.spec.js +27 -0
  13. package/src/core/process/worker/WorkerBuilder.js +5 -1
  14. package/src/core/process/worker/WorkerProxy.js +3 -2
  15. package/src/engine/ecs/Entity.spec.js +33 -0
  16. package/src/engine/ecs/EntityComponentDataset.js +17 -11
  17. package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +8 -1
  18. package/src/engine/graphics/camera/CameraShake.js +1 -127
  19. package/src/engine/graphics/camera/CameraShakeBehavior.js +91 -0
  20. package/src/engine/graphics/camera/CameraShakeTraumaBehavior.js +38 -0
  21. package/src/engine/graphics/ecs/animation/animator/AnimationGraphSystem.js +9 -23
  22. package/src/engine/graphics/ecs/animation/animator/blending/BlendStateMatrix.js +11 -6
  23. package/src/engine/graphics/ecs/animation/animator/graph/AnimationGraph.js +20 -12
  24. package/src/engine/graphics/ecs/animation/animator/graph/AnimationState.js +3 -3
  25. package/src/engine/graphics/ecs/path/tube/build/estimatePathViaIterativeIntegral.js +1 -1
  26. package/src/view/View.js +52 -30
  27. package/src/view/writeCssTransformMatrix.js +26 -0
package/build/meep.cjs CHANGED
@@ -61118,6 +61118,7 @@ function objectsEqual(a, b) {
61118
61118
  }
61119
61119
 
61120
61120
  /**
61121
+ * Works similarly to `Array.prototype.indexOf`, but instead of strict equality - uses provided equality method
61121
61122
  * @template T
61122
61123
  * @param {T[]} array
61123
61124
  * @param {T} element
@@ -61221,7 +61222,7 @@ class List {
61221
61222
  this.data = array !== undefined ? array.slice() : [];
61222
61223
 
61223
61224
  /**
61224
- *
61225
+ * Number of elements in the list
61225
61226
  * @type {number}
61226
61227
  */
61227
61228
  this.length = this.data.length;
@@ -61271,7 +61272,7 @@ class List {
61271
61272
  this.data.push(el);
61272
61273
  const oldLength = this.length;
61273
61274
 
61274
- this.length++;
61275
+ this.length = oldLength + 1;
61275
61276
 
61276
61277
  this.on.added.send2(el, oldLength);
61277
61278
  return this;
@@ -61790,30 +61791,30 @@ class List {
61790
61791
  }
61791
61792
 
61792
61793
  /**
61793
- *
61794
+ * @deprecated use `#reset` directly in combination with `this.on.removed` signal
61794
61795
  * @param {function(element:T,index:number)} callback
61795
61796
  * @param {*} [thisArg]
61796
61797
  */
61797
61798
  resetViaCallback(callback, thisArg) {
61799
+
61798
61800
  const length = this.length;
61799
- if (length > 0) {
61800
61801
 
61801
- const removed = this.on.removed;
61802
+ const removed = this.on.removed;
61803
+
61804
+ const data = this.data;
61802
61805
 
61803
- const oldElements = this.data;
61806
+ for (let i = length - 1; i >= 0; i--) {
61807
+ const element = data[i];
61804
61808
 
61805
- //only signal if there are listeners attached
61806
- for (let i = length - 1; i >= 0; i--) {
61807
- const element = oldElements[i];
61808
- // decrement data length gradually to allow handlers access to the rest of the elements
61809
- this.data.length = i;
61810
- this.length = i;
61811
- removed.send2(element, i);
61809
+ // decrement data length gradually to allow handlers access to the rest of the elements
61810
+ data.length = i;
61811
+ this.length = i;
61812
61812
 
61813
- callback.call(thisArg, element, i);
61814
- }
61813
+ removed.send2(element, i);
61815
61814
 
61815
+ callback.call(thisArg, element, i);
61816
61816
  }
61817
+
61817
61818
  }
61818
61819
 
61819
61820
  reset() {
@@ -62033,11 +62034,19 @@ class List {
62033
62034
  }
62034
62035
 
62035
62036
  /**
62036
- *
62037
+ * First element in the list
62038
+ * @returns {T|undefined}
62039
+ */
62040
+ first() {
62041
+ return this.get(0);
62042
+ }
62043
+
62044
+ /**
62045
+ * Last element in the list
62037
62046
  * @return {T|undefined}
62038
62047
  */
62039
62048
  last() {
62040
- return this.data[this.length - 1];
62049
+ return this.get(this.length - 1);
62041
62050
  }
62042
62051
 
62043
62052
  /**
@@ -63121,10 +63130,11 @@ class WorkerProxy {
63121
63130
  }
63122
63131
 
63123
63132
  /**
63133
+ * Invoke a given method on the worker, as defined by the `WorkerBuilder`
63124
63134
  * @template T
63125
- * @param {number} name
63135
+ * @param {number} name Method's name
63126
63136
  * @param {Array} args
63127
- * @return {Promise<T>}
63137
+ * @return {Promise<T>} eventual result of the invoked method
63128
63138
  */
63129
63139
  $submitRequest(name, args) {
63130
63140
  const pending = this.__pending[name];
@@ -63347,6 +63357,10 @@ class WorkerBuilder {
63347
63357
  functions = [];
63348
63358
  preamble = new LineBuilder();
63349
63359
 
63360
+ /**
63361
+ *
63362
+ * @param {string} code
63363
+ */
63350
63364
  addCode(code) {
63351
63365
  this.preamble.add(code);
63352
63366
  }
@@ -79749,28 +79763,19 @@ function m3_cm_compose_transform(
79749
79763
  }
79750
79764
 
79751
79765
  /**
79752
- * @author Alex Goldring, 2018
79753
- * @copyright Alex Goldring 2018
79766
+ * Smallest safe increment for a Float32
79767
+ * @see https://www.cplusplus.com/reference/cfloat/
79768
+ * @see https://bitbashing.io/comparing-floats.html
79769
+ * @type {number}
79754
79770
  */
79755
-
79756
-
79757
-
79758
- const scratch_m3_0 = new Float32Array(9);
79759
-
79771
+ const FLT_EPSILON_32 = 1.192092896E-7;
79772
+
79760
79773
  /**
79761
- * @see https://dev.opera.com/articles/understanding-the-css-transforms-matrix/
79762
- * @param domElement
79763
- * @param {Vector2} position
79764
- * @param {Vector2} scale
79765
- * @param {number} rotation angle in radians
79774
+ *
79775
+ * @param {Float32Array} m3
79776
+ * @param {HTMLElement} domElement
79766
79777
  */
79767
- function setElementTransform(domElement, position, scale, rotation) {
79768
-
79769
- const m3 = scratch_m3_0;
79770
-
79771
- m3_cm_compose_transform(m3, position.x, position.y, scale.x, scale.y, 0, 0, rotation);
79772
-
79773
-
79778
+ function writeCssTransformMatrix(m3, domElement) {
79774
79779
  /*
79775
79780
  * CSS matrix is:
79776
79781
  * a c e
@@ -79790,7 +79795,13 @@ function setElementTransform(domElement, position, scale, rotation) {
79790
79795
  const style = domElement.style;
79791
79796
 
79792
79797
  style.transform = transform;
79793
- }
79798
+ }
79799
+
79800
+ /**
79801
+ * @author Alex Goldring, 2018
79802
+ * @copyright Alex Goldring 2018
79803
+ */
79804
+
79794
79805
 
79795
79806
  /**
79796
79807
  *
@@ -79829,6 +79840,9 @@ const INITIAL_FLAGS = ViewFlags.Visible;
79829
79840
  * @class
79830
79841
  */
79831
79842
  class View {
79843
+ #transform_written = new Float32Array(9);
79844
+ #transform_current = new Float32Array(9);
79845
+
79832
79846
  /**
79833
79847
  * @constructor
79834
79848
  */
@@ -79853,31 +79867,32 @@ class View {
79853
79867
  this.flags = INITIAL_FLAGS;
79854
79868
 
79855
79869
  /**
79856
- *
79870
+ * @readonly
79857
79871
  * @type {Vector2}
79858
79872
  */
79859
79873
  const position = this.position = new Vector2(0, 0);
79860
79874
 
79861
79875
  /**
79862
- *
79876
+ * @readonly
79863
79877
  * @type {Vector1}
79864
79878
  */
79865
79879
  const rotation = this.rotation = new Vector1(0);
79866
79880
 
79867
79881
  /**
79868
- *
79882
+ * @readonly
79869
79883
  * @type {Vector2}
79870
79884
  */
79871
79885
  const scale = this.scale = new Vector2(1, 1);
79872
79886
 
79873
79887
  /**
79874
- *
79888
+ * @readonly
79875
79889
  * @type {Vector2}
79876
79890
  */
79877
79891
  const size = this.size = new Vector2(0, 0);
79878
79892
 
79879
79893
  /**
79880
79894
  * Origin from which rotation and scaling is applied
79895
+ * @readonly
79881
79896
  * @type {Vector2}
79882
79897
  */
79883
79898
  this.transformOrigin = new Vector2(0.5, 0.5);
@@ -80015,7 +80030,41 @@ class View {
80015
80030
  * @private
80016
80031
  */
80017
80032
  __updateTransform() {
80018
- setElementTransform(this.el, this.position, this.scale, this.rotation.getValue());
80033
+ const position = this.position;
80034
+ const scale = this.scale;
80035
+ const rotation = this.rotation.getValue();
80036
+
80037
+ m3_cm_compose_transform(this.#transform_current, position.x, position.y, scale.x, scale.y, 0, 0, rotation);
80038
+
80039
+ this.#tryWriteTransform();
80040
+ }
80041
+
80042
+ #tryWriteTransform() {
80043
+
80044
+ const current = this.#transform_current;
80045
+ const written = this.#transform_written;
80046
+
80047
+ for (let i = 0; i < 9; i++) {
80048
+ const a = current[i];
80049
+ const b = written[i];
80050
+
80051
+ if (epsilonEquals(a, b, FLT_EPSILON_32)) {
80052
+ // common path
80053
+ continue;
80054
+ }
80055
+
80056
+ this.#writeTransform();
80057
+ return true;
80058
+
80059
+ }
80060
+
80061
+ return false;
80062
+ }
80063
+
80064
+ #writeTransform() {
80065
+ writeCssTransformMatrix(this.#transform_current, this.el);
80066
+
80067
+ this.#transform_written.set(this.#transform_current);
80019
80068
  }
80020
80069
 
80021
80070
  /**
@@ -93079,10 +93128,10 @@ class EntityComponentDataset {
93079
93128
 
93080
93129
  /**
93081
93130
  *
93082
- * @param {number} entityIndex
93131
+ * @param {number} entity_id
93083
93132
  */
93084
- removeEntity(entityIndex) {
93085
- if (!this.entityExists(entityIndex)) {
93133
+ removeEntity(entity_id) {
93134
+ if (!this.entityExists(entity_id)) {
93086
93135
  // entity doesn't exist
93087
93136
  return;
93088
93137
  }
@@ -93090,26 +93139,31 @@ class EntityComponentDataset {
93090
93139
  const componentOccupancy = this.componentOccupancy;
93091
93140
  const typeCount = this.componentTypeCount;
93092
93141
 
93093
- const occupancyStart = entityIndex * typeCount;
93142
+ const occupancyStart = entity_id * typeCount;
93094
93143
  const occupancyEnd = occupancyStart + typeCount;
93095
93144
 
93096
- for (let i = componentOccupancy.nextSetBit(occupancyStart); i < occupancyEnd && i !== -1; i = componentOccupancy.nextSetBit(i + 1)) {
93145
+ // remove all components from the entity
93146
+ for (
93147
+ let i = componentOccupancy.nextSetBit(occupancyStart);
93148
+ i < occupancyEnd && i !== -1;
93149
+ i = componentOccupancy.nextSetBit(i + 1)
93150
+ ) {
93097
93151
  const componentIndex = i % typeCount;
93098
- this.removeComponentFromEntityByIndex_Unchecked(entityIndex, componentIndex, i);
93152
+ this.removeComponentFromEntityByIndex_Unchecked(entity_id, componentIndex, i);
93099
93153
  }
93100
93154
 
93101
93155
  //dispatch event
93102
- this.sendEvent(entityIndex, EventType.EntityRemoved, entityIndex);
93156
+ this.sendEvent(entity_id, EventType.EntityRemoved, entity_id);
93103
93157
 
93104
93158
  //purge all event listeners
93105
- delete this.__entityEventListeners[entityIndex];
93106
- delete this.__entityAnyEventListeners[entityIndex];
93159
+ delete this.__entityEventListeners[entity_id];
93160
+ delete this.__entityAnyEventListeners[entity_id];
93107
93161
 
93108
- this.entityOccupancy.set(entityIndex, false);
93162
+ this.entityOccupancy.set(entity_id, false);
93109
93163
 
93110
93164
  this.entityCount--;
93111
93165
 
93112
- this.onEntityRemoved.send1(entityIndex);
93166
+ this.onEntityRemoved.send1(entity_id);
93113
93167
  }
93114
93168
 
93115
93169
  /**
@@ -93159,6 +93213,7 @@ class EntityComponentDataset {
93159
93213
  }
93160
93214
 
93161
93215
  /**
93216
+ * This method doesn't perform any checks, make sure you understand what you are doing when using it
93162
93217
  * @private
93163
93218
  * @param {number} entityIndex
93164
93219
  * @param {number} componentIndex
@@ -96086,40 +96141,38 @@ LinearValue.prototype.fromJSON = function (json) {
96086
96141
 
96087
96142
  /**
96088
96143
  *
96089
- * @param {number} x
96090
- * @param {string} [separator=',']
96144
+ * @param {string} string
96145
+ * @param {string} trailing_sequence
96091
96146
  * @returns {string}
96092
96147
  */
96093
- function number_format_by_thousands(x, separator = ',') {
96148
+ function string_strip_trailing(string, trailing_sequence) {
96149
+ const trailing_sequence_length = trailing_sequence.length;
96094
96150
 
96095
- return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
96151
+ if (trailing_sequence_length <= 0) {
96152
+ // special case to avoid infinite looping
96153
+ return string;
96154
+ }
96155
+
96156
+ let end_index = string.length;
96157
+
96158
+ while (string.substring(end_index - trailing_sequence_length, end_index) === trailing_sequence) {
96159
+ end_index -= trailing_sequence_length;
96160
+ }
96161
+
96162
+ return string.substring(0, end_index);
96096
96163
  }
96097
96164
 
96098
96165
  /**
96099
96166
  *
96100
- * @param {string} value
96101
- * @returns {number}
96167
+ * @param {number} x
96168
+ * @param {string} [separator=',']
96169
+ * @returns {string}
96102
96170
  */
96103
- function countDecimals(value) {
96104
- if (value % 1 === 0) {
96105
- //whole number
96106
- return 0;
96107
- }
96108
- const s = value.toString();
96109
- const index = s.indexOf('.');
96110
-
96111
- if (index === -1) {
96112
- return 0;
96113
- }
96114
-
96115
- //find last 0
96116
- let endIndex = s.length - 1;
96117
- for (; endIndex > index && s.charAt(endIndex) === "0"; endIndex--) {
96118
-
96119
- }
96120
- return endIndex - index;
96121
- }
96171
+ function number_format_by_thousands(x, separator = ',') {
96122
96172
 
96173
+ return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
96174
+ }
96175
+
96123
96176
  /**
96124
96177
  *
96125
96178
  * @param {number} value
@@ -96130,10 +96183,12 @@ function number_pretty_print(value) {
96130
96183
  const MAX_DECIMALS = 2;
96131
96184
 
96132
96185
  const fraction = value % 1;
96133
- if (fraction !== 0 && Math.abs(value) < 100) {
96134
- const decimals = countDecimals(value.toFixed(MAX_DECIMALS));
96135
- const decimalsToPrint = Math.min(decimals, MAX_DECIMALS);
96136
- return value.toFixed(decimalsToPrint);
96186
+
96187
+ const would_produce_decimals = fraction * Math.pow(10, MAX_DECIMALS) > 0;
96188
+
96189
+ if (would_produce_decimals && Math.abs(value) < 100) {
96190
+ const truncated = value.toFixed(MAX_DECIMALS);
96191
+ return string_strip_trailing(truncated, "0");
96137
96192
  } else {
96138
96193
  //no fraction
96139
96194
  return number_format_by_thousands(value - fraction, ",");