@woosh/meep-engine 2.47.23 → 2.47.26

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 (31) hide show
  1. package/build/meep.cjs +544 -342
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +544 -342
  4. package/editor/tools/SelectionTool.js +17 -17
  5. package/editor/view/EditorView.js +4 -5
  6. package/editor/view/ecs/EntityList.js +0 -2
  7. package/package.json +1 -1
  8. package/src/core/geom/3d/topology/samples/sampleFloodFill.js +8 -8
  9. package/src/core/json/abstractJSONSerializer.js +1 -1
  10. package/src/engine/ecs/EntityComponentDataset.js +28 -3
  11. package/src/engine/ecs/EntityManager.js +264 -221
  12. package/src/engine/ecs/System.d.ts +2 -0
  13. package/src/engine/ecs/System.js +37 -30
  14. package/src/engine/ecs/gui/menu/radial/RadialContextMenu.js +0 -4
  15. package/src/engine/ecs/systems/TimerSystem.js +61 -41
  16. package/src/engine/ecs/terrain/util/obtainTerrain.js +2 -3
  17. package/src/engine/graphics/GraphicsEngine.js +4 -3
  18. package/src/engine/graphics/ecs/camera/Camera.js +37 -0
  19. package/src/engine/graphics/ecs/camera/filter/setup_filtered_camera_controller.js +78 -0
  20. package/src/engine/graphics/ecs/camera/pp/NOTES.md +48 -0
  21. package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +164 -0
  22. package/src/engine/graphics/ecs/camera/pp/Perfect_Panning.png +0 -0
  23. package/src/engine/graphics/ecs/camera/pp/Zooming.png +0 -0
  24. package/src/engine/graphics/ecs/camera/pp/pan_a.png +0 -0
  25. package/src/engine/graphics/ecs/camera/pp/pan_b.png +0 -0
  26. package/src/engine/graphics/ecs/mesh/MeshSystem.js +1 -1
  27. package/src/engine/graphics/make_ray_from_viewport_position.js +28 -0
  28. package/src/engine/input/devices/PointerDevice.js +32 -0
  29. package/src/engine/intelligence/behavior/decorator/RepeatBehavior.js +17 -8
  30. package/src/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js +2 -2
  31. package/src/engine/intelligence/behavior/primitive/SucceedingBehavior.js +9 -5
package/build/meep.cjs CHANGED
@@ -70582,33 +70582,32 @@ function array_copy_unique(source, source_position, destination, destination_pos
70582
70582
  * @template C
70583
70583
  */
70584
70584
  class System {
70585
- constructor() {
70586
70585
 
70587
- /**
70588
- *
70589
- * @type {EntityManager}
70590
- */
70591
- this.entityManager = null;
70586
+ /**
70587
+ * @protected
70588
+ * @type {EntityManager}
70589
+ */
70590
+ entityManager = null;
70592
70591
 
70593
- /**
70594
- *
70595
- * @type {ObservedValue.<System.State>}
70596
- */
70597
- this.state = new ObservedValue(System.State.INITIAL);
70592
+ /**
70593
+ * @readonly
70594
+ * @type {ObservedValue.<System.State>}
70595
+ */
70596
+ state = new ObservedValue(System.State.INITIAL);
70598
70597
 
70599
- /**
70600
- * Other components which have to be present before the system links component
70601
- * @type {Array}
70602
- */
70603
- this.dependencies = [];
70598
+ /**
70599
+ * Other components which have to be present before the system links component
70600
+ * @type {Array}
70601
+ */
70602
+ dependencies = [];
70603
+
70604
+ /**
70605
+ * Component types that are used internally by the system
70606
+ * Declaring this helps EntityManager to ensure that all relevant component types are properly registered for the system
70607
+ * @type {Array}
70608
+ */
70609
+ components_used = [];
70604
70610
 
70605
- /**
70606
- * Component types that are used internally by the system
70607
- * Declaring this helps EntityManager to ensure that all relevant component types are properly registered for the system
70608
- * @type {Array}
70609
- */
70610
- this.components_used = [];
70611
- }
70612
70611
 
70613
70612
  /**
70614
70613
  * @returns {[]}
@@ -70639,15 +70638,22 @@ class System {
70639
70638
 
70640
70639
  }
70641
70640
 
70642
- /**
70643
- *
70644
- * @param {number} timeDelta Time in seconds
70645
- */
70646
- update(timeDelta) {
70647
-
70648
- }
70649
70641
  }
70650
70642
 
70643
+ /**
70644
+ * Fixed update function, every step happens with the same exact time increment
70645
+ * useful for systems that must have a fixed time step to be predictable and stable, such as physics
70646
+ * @param {number} timeDelta in seconds
70647
+ */
70648
+ System.prototype.fixedUpdate = noop; // by assigning NO-OP we enable a simple check, whether running the update would be useful
70649
+
70650
+
70651
+ /**
70652
+ * This update is generally synchronized with the render loop
70653
+ * @param {number} timeDelta Time in seconds
70654
+ */
70655
+ System.prototype.update = noop; // by assigning NO-OP we enable a simple check, whether running the update would be useful
70656
+
70651
70657
  Object.defineProperties(System.prototype, {
70652
70658
  /**
70653
70659
  * @deprecated
@@ -70997,6 +71003,113 @@ const ProjectionType = {
70997
71003
  Orthographic: "orthographic"
70998
71004
  };
70999
71005
 
71006
+ /**
71007
+ * Created by Alex on 20/02/2017.
71008
+ */
71009
+
71010
+ /**
71011
+ *
71012
+ * @param {Vector3} out Result will be written here
71013
+ * @param {number} originX Ray origin
71014
+ * @param {number} originY Ray origin
71015
+ * @param {number} originZ Ray origin
71016
+ * @param {number} directionX Ray direction
71017
+ * @param {number} directionY Ray direction
71018
+ * @param {number} directionZ Ray direction
71019
+ * @param {number} normalX Plane normal
71020
+ * @param {number} normalY Plane normal
71021
+ * @param {number} normalZ Plane normal
71022
+ * @param {number} dist Plane distance
71023
+ * @returns {boolean} true if intersection is found, false otherwise
71024
+ */
71025
+ function computePlaneRayIntersection(out, originX, originY, originZ, directionX, directionY, directionZ, normalX, normalY, normalZ, dist) {
71026
+ const denom = v3_dot(directionX, directionY, directionZ, normalX, normalY, normalZ);
71027
+
71028
+ const p = v3_dot(normalX, normalY, normalZ, originX, originY, originZ) + dist;
71029
+
71030
+ if (denom !== 0) {
71031
+
71032
+ const t = -p / denom;
71033
+
71034
+ if (t < 0) {
71035
+ return false;
71036
+ }
71037
+
71038
+ out.set(
71039
+ directionX * t + originX,
71040
+ directionY * t + originY,
71041
+ directionZ * t + originZ
71042
+ );
71043
+
71044
+ return true;
71045
+
71046
+ } else {
71047
+
71048
+ if (p === 0) {
71049
+
71050
+ out.set(originX, originY, originZ);
71051
+
71052
+ return true;
71053
+
71054
+ } else {
71055
+
71056
+ //no intersection
71057
+ return false;
71058
+
71059
+ }
71060
+
71061
+ }
71062
+ }
71063
+
71064
+ /**
71065
+ *
71066
+ * @param {Float32Array|number[]|vec3} result
71067
+ * @param {number} result_offset
71068
+ * @param {number} x0
71069
+ * @param {number} y0
71070
+ * @param {number} z0
71071
+ * @param {number} x1
71072
+ * @param {number} y1
71073
+ * @param {number} z1
71074
+ * @param {number} normalX
71075
+ * @param {number} normalY
71076
+ * @param {number} normalZ
71077
+ * @param {number} dist
71078
+ * @returns {boolean}
71079
+ */
71080
+ function plane3_computeLineSegmentIntersection(
71081
+ result, result_offset,
71082
+ x0, y0, z0,
71083
+ x1, y1, z1,
71084
+ normalX, normalY, normalZ, dist
71085
+ ) {
71086
+
71087
+ const directionX = x1 - x0;
71088
+ const directionY = y1 - y0;
71089
+ const directionZ = z1 - z0;
71090
+
71091
+ const denom = v3_dot(directionX, directionY, directionZ, normalX, normalY, normalZ);
71092
+
71093
+ if (denom === 0) {
71094
+ return false;
71095
+ }
71096
+
71097
+ const p = v3_dot(normalX, normalY, normalZ, x0, y0, z0) + dist;
71098
+
71099
+ const t = -p / denom;
71100
+
71101
+ if (t < 0 || t > 1) {
71102
+ return false;
71103
+ }
71104
+
71105
+ result[result_offset] = directionX * t + x0;
71106
+ result[result_offset + 1] = directionY * t + y0;
71107
+ result[result_offset + 2] = directionZ * t + z0;
71108
+
71109
+ return true;
71110
+
71111
+ }
71112
+
71000
71113
  /**
71001
71114
  * Created by Alex on 31/12/2014.
71002
71115
  */
@@ -71208,6 +71321,42 @@ class Camera {
71208
71321
  return true;
71209
71322
  }
71210
71323
 
71324
+ /**
71325
+ *
71326
+ * @param {Vector3} out
71327
+ * @param {number} origin_x
71328
+ * @param {number} origin_y
71329
+ * @param {number} origin_z
71330
+ * @param {number} direction_x
71331
+ * @param {number} direction_y
71332
+ * @param {number} direction_z
71333
+ * @param {number} plane_index
71334
+ */
71335
+ rayPlaneIntersection(
71336
+ out,
71337
+ origin_x, origin_y, origin_z,
71338
+ direction_x, direction_y, direction_z,
71339
+ plane_index
71340
+ ) {
71341
+
71342
+ assert.isNonNegativeInteger(plane_index, 'plane_index');
71343
+ assert.lessThanOrEqual(plane_index, 5, `plane_index must be <= 5, was ${plane_index}`);
71344
+
71345
+ frustum_from_camera(this.object, scratch_frustum$1);
71346
+
71347
+ const plane = scratch_frustum$1.planes[plane_index];
71348
+
71349
+ assert.defined(plane, 'plane');
71350
+
71351
+ computePlaneRayIntersection(
71352
+ out,
71353
+ origin_x, origin_y, origin_z,
71354
+ direction_x, direction_y, direction_z,
71355
+ plane.normal.x, plane.normal.y, plane.normal.z,
71356
+ plane.constant
71357
+ );
71358
+ }
71359
+
71211
71360
  /**
71212
71361
  *
71213
71362
  * @param {number} x
@@ -73861,26 +74010,25 @@ const EntityManagerState = {
73861
74010
  */
73862
74011
  function EntityManager() {
73863
74012
  /**
73864
- *
73865
- * @type {Array.<System>}
74013
+ * @readonly
74014
+ * @type {System[]}
73866
74015
  */
73867
74016
  this.systems = [];
73868
74017
 
73869
74018
  /**
73870
- *
73871
- * @type {Array<EntityObserver>}
74019
+ * @readonly
74020
+ * @type {EntityObserver[]}
73872
74021
  */
73873
74022
  this.systemObservers = [];
73874
74023
 
74024
+ /**
74025
+ * @readonly
74026
+ */
73875
74027
  this.on = {
73876
74028
  systemStarted: new Signal(),
73877
74029
  systemStopped: new Signal(),
73878
74030
  systemAdded: new Signal(),
73879
74031
  systemRemoved: new Signal(),
73880
- /**
73881
- * @deprecated
73882
- */
73883
- reset: new Signal()
73884
74032
  };
73885
74033
 
73886
74034
  /**
@@ -73889,6 +74037,19 @@ function EntityManager() {
73889
74037
  */
73890
74038
  this.state = EntityManagerState.Initial;
73891
74039
 
74040
+ /**
74041
+ * @private
74042
+ * @readonly
74043
+ * @type {Map<System, number>}
74044
+ */
74045
+ this.systemAccumulatedFixedStepTime = new Map();
74046
+
74047
+ /**
74048
+ * In seconds
74049
+ * @type {number}
74050
+ */
74051
+ this.fixedUpdateStepSize = 0.015;
74052
+
73892
74053
  /**
73893
74054
  *
73894
74055
  * @type {EntityComponentDataset}
@@ -73963,170 +74124,6 @@ EntityManager.prototype.attachDataSet = function (dataset) {
73963
74124
  });
73964
74125
  };
73965
74126
 
73966
- /**
73967
- * @deprecated
73968
- * @returns {number}
73969
- */
73970
- EntityManager.prototype.createEntity = function () {
73971
- console.warn("EntityManager.createEntity is deprecated");
73972
-
73973
- return this.dataset.createEntity();
73974
- };
73975
-
73976
- /**
73977
- * @deprecated
73978
- * @param id
73979
- */
73980
- EntityManager.prototype.createEntitySpecific = function (id) {
73981
- console.warn("EntityManager.createEntitySpecific is deprecated");
73982
- this.dataset.createEntitySpecific(id);
73983
- };
73984
-
73985
-
73986
- /**
73987
- * @deprecated
73988
- * Remove association of specified component type from entity
73989
- * @param {Number} entityId
73990
- * @param {Number} componentType
73991
- */
73992
- EntityManager.prototype.removeComponentFromEntity = function (entityId, componentType) {
73993
- console.warn("EntityManager.removeComponentFromEntity is deprecated");
73994
-
73995
- this.dataset.removeComponentFromEntityByIndex(entityId, componentType);
73996
- };
73997
-
73998
- /**
73999
- * @deprecated use dataset directly
74000
- * Retrieves component instance associated with entity
74001
- * @template T
74002
- * @param {Number} entityId
74003
- * @param {class.<T>} componentClass
74004
- * @returns {T|null}
74005
- * @nosideeffects
74006
- */
74007
- EntityManager.prototype.getComponent = function (entityId, componentClass) {
74008
- return this.dataset.getComponent(entityId, componentClass);
74009
- };
74010
-
74011
- /**
74012
- *
74013
- * @param {number} entityIndex
74014
- * @returns {boolean}
74015
- */
74016
- EntityManager.prototype.entityExists = function (entityIndex) {
74017
- if (this.dataset === null) {
74018
- //no dataset - no entities
74019
- return false;
74020
- }
74021
- return this.dataset.entityExists(entityIndex);
74022
- };
74023
-
74024
- /**
74025
- * same as getComponent when component exists, if component is not associated with the entity, callback will be invoked once when it is added.
74026
- * @param {Number} entityId
74027
- * @param {Class} componentClass
74028
- * @param {function} callback
74029
- * @param {*} [thisArg]
74030
- */
74031
- EntityManager.prototype.getComponentAsync = function (entityId, componentClass, callback, thisArg) {
74032
- const self = this;
74033
- const component = this.getComponent(entityId, componentClass);
74034
-
74035
- function handler(options) {
74036
- if (options.klass === componentClass) {
74037
- self.removeEntityEventListener(entityId, EventType.ComponentAdded, handler);
74038
- callback.call(thisArg, options.instance);
74039
- }
74040
- }
74041
-
74042
- if (component === void 0 || component === null) {
74043
- this.addEntityEventListener(entityId, EventType.ComponentAdded, handler);
74044
- } else {
74045
- callback.call(thisArg, component);
74046
- }
74047
- };
74048
-
74049
- /**
74050
- * @deprecated Use {@link EntityManager#dataset} direction
74051
- * @param entity
74052
- * @returns {Array}
74053
- */
74054
- EntityManager.prototype.getComponents = function (entity) {
74055
- console.warn("EntityManager.getComponents is deprecated");
74056
-
74057
- return this.dataset.getAllComponents(entity);
74058
- };
74059
-
74060
- /**
74061
- * @deprecated
74062
- * Retrieves component instance associated with entity
74063
- * @param {Number} entityId
74064
- * @param {Number} componentType
74065
- * @returns {*|undefined} component of specified type or undefined if it was not found
74066
- */
74067
- EntityManager.prototype.getComponentByType = function (entityId, componentType) {
74068
- console.warn("EntityManager.getComponentByType is deprecated");
74069
- return this.dataset.getComponentByIndex(entityId, componentType);
74070
- };
74071
-
74072
- /**
74073
- * @deprecated
74074
- * does traversal on a subset of entities which have specified components.
74075
- * @example traverseEntities([Transform,Renderable,Tag],function(transform, renderable, tag, entity){ ... }, this);
74076
- * @param {Array.<class>} classes
74077
- * @param {Function} callback
74078
- * @param {Object} [thisArg] specifies context object on which callbacks are to be called, optional
74079
- */
74080
- EntityManager.prototype.traverseEntities = function (classes, callback, thisArg) {
74081
- if (this.dataset === null) {
74082
- //no data to traverse
74083
- return;
74084
- }
74085
- this.dataset.traverseEntities(classes, callback, thisArg);
74086
- };
74087
-
74088
- /**
74089
- * @deprecated
74090
- * @param entity
74091
- * @param eventName
74092
- * @param listener
74093
- */
74094
- EntityManager.prototype.addEntityEventListener = function (entity, eventName, listener) {
74095
- this.dataset.addEntityEventListener(entity, eventName, listener);
74096
- };
74097
-
74098
- /**
74099
- * @deprecated
74100
- * @param {number} entity
74101
- * @param {string} eventName
74102
- * @param {function} listener
74103
- */
74104
- EntityManager.prototype.removeEntityEventListener = function (entity, eventName, listener) {
74105
- this.dataset.removeEntityEventListener(entity, eventName, listener);
74106
- };
74107
-
74108
- /**
74109
- * @deprecated use dataset directly instead
74110
- * @param entity
74111
- * @param eventName
74112
- * @param event
74113
- */
74114
- EntityManager.prototype.sendEvent = function (entity, eventName, event) {
74115
- this.dataset.sendEvent(entity, eventName, event);
74116
- };
74117
-
74118
- /**
74119
- * @deprecated
74120
- * @param {function} klazz
74121
- * @param {function(component: *, entity: number):boolean} callback
74122
- * @param {*} [thisArg]
74123
- * @deprecated
74124
- */
74125
- EntityManager.prototype.traverseComponents = function (klazz, callback, thisArg) {
74126
- if (this.dataset !== null) {
74127
- this.dataset.traverseComponents(klazz, callback, thisArg);
74128
- }
74129
- };
74130
74127
 
74131
74128
  /**
74132
74129
  * @template T
@@ -74158,33 +74155,6 @@ EntityManager.prototype.getSystem = function (systemClass) {
74158
74155
  return null;
74159
74156
  };
74160
74157
 
74161
- /**
74162
- * @deprecated Use {@link #getSystem} instead
74163
- * @template T,C
74164
- * @param {C} klazz
74165
- * @returns {System|T}
74166
- */
74167
- EntityManager.prototype.getOwnerSystemByComponentClass = function (klazz) {
74168
- const index = this.getOwnerSystemIdByComponentClass(klazz);
74169
- return this.systems[index];
74170
- };
74171
-
74172
- /**
74173
- * @deprecated
74174
- * @param {function} clazz
74175
- * @returns {number} value >= 0, representing system Id, or -1 if system was not found
74176
- */
74177
- EntityManager.prototype.getOwnerSystemIdByComponentClass = function (clazz) {
74178
- const systems = this.systems;
74179
- let i = 0;
74180
- const l = systems.length;
74181
- for (; i < l; i++) {
74182
- if (systems[i].componentClass === clazz) {
74183
- return i;
74184
- }
74185
- }
74186
- return -1;
74187
- };
74188
74158
 
74189
74159
  /**
74190
74160
  * @template T
@@ -74206,19 +74176,6 @@ EntityManager.prototype.getComponentClassByName = function (className) {
74206
74176
  return null;
74207
74177
  };
74208
74178
 
74209
- /**
74210
- *
74211
- * @param {System} system
74212
- * @param {number} timeDelta
74213
- */
74214
- function tryUpdateSystem(system, timeDelta) {
74215
- try {
74216
- system.update(timeDelta);
74217
- } catch (e) {
74218
- console.error(`Failed to update system '${computeSystemName(system)}': `, e);
74219
- }
74220
- }
74221
-
74222
74179
  /**
74223
74180
  * Advance simulation forward by a specified amount of time
74224
74181
  * @param {number} timeDelta in seconds, real number
@@ -74228,12 +74185,51 @@ EntityManager.prototype.simulate = function (timeDelta) {
74228
74185
  assert.notNaN(timeDelta, 'timeDelta');
74229
74186
  assert.greaterThanOrEqual(timeDelta, 0, 'timeDelta must be >= 0');
74230
74187
 
74188
+ /**
74189
+ *
74190
+ * @type {System[]}
74191
+ */
74231
74192
  const systems = this.systems;
74232
- let i = 0;
74233
- const l = systems.length;
74234
- for (; i < l; i++) {
74193
+
74194
+ const system_count = systems.length;
74195
+
74196
+ const fixed_step = this.fixedUpdateStepSize;
74197
+ const accumulatedTime = this.systemAccumulatedFixedStepTime;
74198
+
74199
+ for (let i = 0; i < system_count; i++) {
74200
+
74235
74201
  const system = systems[i];
74236
- tryUpdateSystem(system, timeDelta);
74202
+
74203
+ if (system.fixedUpdate !== noop) {
74204
+ let accumulated_time = accumulatedTime.get(system) + timeDelta;
74205
+
74206
+
74207
+ while (accumulated_time > fixed_step) {
74208
+
74209
+ try {
74210
+ system.fixedUpdate(fixed_step);
74211
+ } catch (e) {
74212
+ console.error(`Failed during fixedUpdate of system '${computeSystemName(system)}': `, e);
74213
+ }
74214
+
74215
+ accumulated_time -= fixed_step;
74216
+ }
74217
+
74218
+ // record whatever remains
74219
+ accumulatedTime.set(system, accumulated_time);
74220
+
74221
+ }
74222
+
74223
+ if (system.update !== noop) {
74224
+
74225
+ try {
74226
+ system.update(timeDelta);
74227
+ } catch (e) {
74228
+ console.error(`Failed during update of system '${computeSystemName(system)}': `, e);
74229
+ }
74230
+
74231
+ }
74232
+
74237
74233
  }
74238
74234
  };
74239
74235
 
@@ -74356,6 +74352,8 @@ EntityManager.prototype.addSystem = async function (system) {
74356
74352
  this.dataset.addObserver(linkObserver);
74357
74353
  }
74358
74354
 
74355
+ this.systemAccumulatedFixedStepTime.set(system, 0);
74356
+
74359
74357
  this.on.systemAdded.send1(system);
74360
74358
 
74361
74359
  await startup_promise;
@@ -74399,6 +74397,8 @@ EntityManager.prototype.removeSystem = async function (system) {
74399
74397
  });
74400
74398
  });
74401
74399
 
74400
+ this.systemAccumulatedFixedStepTime.delete(system);
74401
+
74402
74402
  this.on.systemRemoved.send1(system);
74403
74403
  };
74404
74404
 
@@ -74697,17 +74697,208 @@ EntityManager.prototype.shutdown = function (readyCallback, errorCallback) {
74697
74697
  });
74698
74698
  };
74699
74699
 
74700
+
74701
+ /**
74702
+ * @deprecated
74703
+ * @returns {number}
74704
+ */
74705
+ EntityManager.prototype.createEntity = function () {
74706
+ console.warn("EntityManager.createEntity is deprecated");
74707
+
74708
+ return this.dataset.createEntity();
74709
+ };
74710
+
74711
+ /**
74712
+ * @deprecated
74713
+ * @param id
74714
+ */
74715
+ EntityManager.prototype.createEntitySpecific = function (id) {
74716
+ console.warn("EntityManager.createEntitySpecific is deprecated");
74717
+ this.dataset.createEntitySpecific(id);
74718
+ };
74719
+
74720
+
74721
+ /**
74722
+ * @deprecated
74723
+ * Remove association of specified component type from entity
74724
+ * @param {Number} entityId
74725
+ * @param {Number} componentType
74726
+ */
74727
+ EntityManager.prototype.removeComponentFromEntity = function (entityId, componentType) {
74728
+ console.warn("EntityManager.removeComponentFromEntity is deprecated");
74729
+
74730
+ this.dataset.removeComponentFromEntityByIndex(entityId, componentType);
74731
+ };
74732
+
74733
+ /**
74734
+ * @deprecated use dataset directly
74735
+ * Retrieves component instance associated with entity
74736
+ * @template T
74737
+ * @param {Number} entityId
74738
+ * @param {class.<T>} componentClass
74739
+ * @returns {T|null}
74740
+ * @nosideeffects
74741
+ */
74742
+ EntityManager.prototype.getComponent = function (entityId, componentClass) {
74743
+ console.warn("EntityManager.getComponent is deprecated");
74744
+
74745
+ return this.dataset.getComponent(entityId, componentClass);
74746
+ };
74747
+
74748
+ /**
74749
+ * @deprecated use {@link EntityComponentDataset.entityExists} instead
74750
+ * @param {number} entityIndex
74751
+ * @returns {boolean}
74752
+ */
74753
+ EntityManager.prototype.entityExists = function (entityIndex) {
74754
+ console.warn("EntityManager.entityExists is deprecated");
74755
+ if (this.dataset === null) {
74756
+ //no dataset - no entities
74757
+ return false;
74758
+ }
74759
+ return this.dataset.entityExists(entityIndex);
74760
+ };
74761
+
74762
+
74763
+ /**
74764
+ * @deprecated Use {@link EntityManager#dataset} direction
74765
+ * @param entity
74766
+ * @returns {Array}
74767
+ */
74768
+ EntityManager.prototype.getComponents = function (entity) {
74769
+ console.warn("EntityManager.getComponents is deprecated");
74770
+
74771
+ return this.dataset.getAllComponents(entity);
74772
+ };
74773
+
74774
+ /**
74775
+ * @deprecated
74776
+ * Retrieves component instance associated with entity
74777
+ * @param {Number} entityId
74778
+ * @param {Number} componentType
74779
+ * @returns {*|undefined} component of specified type or undefined if it was not found
74780
+ */
74781
+ EntityManager.prototype.getComponentByType = function (entityId, componentType) {
74782
+ console.warn("EntityManager.getComponentByType is deprecated");
74783
+ return this.dataset.getComponentByIndex(entityId, componentType);
74784
+ };
74785
+
74786
+ /**
74787
+ * @deprecated
74788
+ * does traversal on a subset of entities which have specified components.
74789
+ * @example traverseEntities([Transform,Renderable,Tag],function(transform, renderable, tag, entity){ ... }, this);
74790
+ * @param {Array.<class>} classes
74791
+ * @param {Function} callback
74792
+ * @param {Object} [thisArg] specifies context object on which callbacks are to be called, optional
74793
+ */
74794
+ EntityManager.prototype.traverseEntities = function (classes, callback, thisArg) {
74795
+ console.warn("EntityManager.traverseEntities is deprecated");
74796
+
74797
+ if (this.dataset === null) {
74798
+ //no data to traverse
74799
+ return;
74800
+ }
74801
+ this.dataset.traverseEntities(classes, callback, thisArg);
74802
+ };
74803
+
74804
+ /**
74805
+ * @deprecated
74806
+ * @param entity
74807
+ * @param eventName
74808
+ * @param listener
74809
+ */
74810
+ EntityManager.prototype.addEntityEventListener = function (entity, eventName, listener) {
74811
+ console.warn("EntityManager.addEntityEventListener is deprecated");
74812
+ this.dataset.addEntityEventListener(entity, eventName, listener);
74813
+ };
74814
+
74700
74815
  /**
74701
74816
  * @deprecated
74817
+ * @param {number} entity
74818
+ * @param {string} eventName
74819
+ * @param {function} listener
74820
+ */
74821
+ EntityManager.prototype.removeEntityEventListener = function (entity, eventName, listener) {
74822
+ console.warn("EntityManager.removeEntityEventListener is deprecated");
74823
+ this.dataset.removeEntityEventListener(entity, eventName, listener);
74824
+ };
74825
+
74826
+ /**
74827
+ * @deprecated use dataset directly instead
74828
+ * @param entity
74829
+ * @param eventName
74830
+ * @param event
74831
+ */
74832
+ EntityManager.prototype.sendEvent = function (entity, eventName, event) {
74833
+ console.warn("EntityManager.sendEvent is deprecated");
74834
+ this.dataset.sendEvent(entity, eventName, event);
74835
+ };
74836
+
74837
+ /**
74838
+ * @deprecated
74839
+ * @param {function} klazz
74840
+ * @param {function(component: *, entity: number):boolean} callback
74841
+ * @param {*} [thisArg]
74842
+ * @deprecated
74843
+ */
74844
+ EntityManager.prototype.traverseComponents = function (klazz, callback, thisArg) {
74845
+ console.warn("EntityManager.traverseComponents is deprecated");
74846
+ if (this.dataset !== null) {
74847
+ this.dataset.traverseComponents(klazz, callback, thisArg);
74848
+ }
74849
+ };
74850
+
74851
+ /**
74852
+ * @deprecated Use {@link #getSystem} instead
74853
+ * @template T,C
74854
+ * @param {C} klazz
74855
+ * @returns {System|T}
74856
+ */
74857
+ EntityManager.prototype.getOwnerSystemByComponentClass = function (klazz) {
74858
+
74859
+ console.warn("EntityManager.getOwnerSystemByComponentClass is deprecated, use .getSystem instead");
74860
+ const index = this.getOwnerSystemIdByComponentClass(klazz);
74861
+ return this.systems[index];
74862
+ };
74863
+
74864
+ /**
74865
+ * @deprecated
74866
+ * @param {function} clazz
74867
+ * @returns {number} value >= 0, representing system Id, or -1 if system was not found
74868
+ */
74869
+ EntityManager.prototype.getOwnerSystemIdByComponentClass = function (clazz) {
74870
+ console.warn("EntityManager.getOwnerSystemIdByComponentClass is deprecated, use .getSystem instead");
74871
+
74872
+ const systems = this.systems;
74873
+ let i = 0;
74874
+ const l = systems.length;
74875
+ for (; i < l; i++) {
74876
+ if (systems[i].componentClass === clazz) {
74877
+ return i;
74878
+ }
74879
+ }
74880
+ return -1;
74881
+ };
74882
+
74883
+
74884
+ /**
74885
+ * same as getComponent when component exists, if component is not associated with the entity, callback will be invoked once when it is added.
74886
+ * @param {Number} entityId
74887
+ * @param {Class} componentClass
74888
+ * @param {function} callback
74889
+ * @param {*} [thisArg]
74702
74890
  */
74703
- EntityManager.prototype.reset = function () {
74704
- console.warn("EntityManager.reset is deprecated and should no longer be used, reset dataset instead");
74891
+ EntityManager.prototype.getComponentAsync = function (entityId, componentClass, callback, thisArg) {
74892
+ console.warn("EntityManager.getComponentAsync is deprecated");
74705
74893
 
74706
- this.dataset.clear();
74894
+ const dataset = this.dataset;
74707
74895
 
74708
- this.on.reset.send0();
74896
+ if (dataset === undefined) {
74897
+ throw new Error('No dataset attached');
74898
+ }
74899
+
74900
+ dataset.getComponentAsync(entityId, componentClass, callback, thisArg);
74709
74901
 
74710
- console.log("Entity Manager completed reset");
74711
74902
  };
74712
74903
 
74713
74904
  /**
@@ -86589,59 +86780,6 @@ function aabb_build_frustum(result, x0, y0, z0, x1, y1, z1) {
86589
86780
  result[23] = z1;
86590
86781
  }
86591
86782
 
86592
- /**
86593
- * Created by Alex on 20/02/2017.
86594
- */
86595
-
86596
- /**
86597
- *
86598
- * @param {Float32Array|number[]|vec3} result
86599
- * @param {number} result_offset
86600
- * @param {number} x0
86601
- * @param {number} y0
86602
- * @param {number} z0
86603
- * @param {number} x1
86604
- * @param {number} y1
86605
- * @param {number} z1
86606
- * @param {number} normalX
86607
- * @param {number} normalY
86608
- * @param {number} normalZ
86609
- * @param {number} dist
86610
- * @returns {boolean}
86611
- */
86612
- function plane3_computeLineSegmentIntersection(
86613
- result, result_offset,
86614
- x0, y0, z0,
86615
- x1, y1, z1,
86616
- normalX, normalY, normalZ, dist
86617
- ) {
86618
-
86619
- const directionX = x1 - x0;
86620
- const directionY = y1 - y0;
86621
- const directionZ = z1 - z0;
86622
-
86623
- const denom = v3_dot(directionX, directionY, directionZ, normalX, normalY, normalZ);
86624
-
86625
- if (denom === 0) {
86626
- return false;
86627
- }
86628
-
86629
- const p = v3_dot(normalX, normalY, normalZ, x0, y0, z0) + dist;
86630
-
86631
- const t = -p / denom;
86632
-
86633
- if (t < 0 || t > 1) {
86634
- return false;
86635
- }
86636
-
86637
- result[result_offset] = directionX * t + x0;
86638
- result[result_offset + 1] = directionY * t + y0;
86639
- result[result_offset + 2] = directionZ * t + z0;
86640
-
86641
- return true;
86642
-
86643
- }
86644
-
86645
86783
  /**
86646
86784
  * Bitfields, mapping a corner index to bitfield with attached edges
86647
86785
  * @type {number[]}
@@ -95871,7 +96009,7 @@ GraphicsEngine.prototype.start = function () {
95871
96009
  /**
95872
96010
  * @see https://registry.khronos.org/webgl/specs/latest/1.0/#5.2
95873
96011
  */
95874
- powerPreference:"high-performance"
96012
+ powerPreference: "high-performance"
95875
96013
  };
95876
96014
 
95877
96015
  const webGLRenderer = this.renderer = new WebGLRenderer(rendererParameters);
@@ -96002,8 +96140,9 @@ GraphicsEngine.prototype.normalizeViewportPoint = function (input, result) {
96002
96140
 
96003
96141
  const viewportSize = this.viewport.size;
96004
96142
 
96005
- const _x = input.x;
96006
- const _y = input.y;
96143
+ // shift by pixel center
96144
+ const _x = input.x + 0.5;
96145
+ const _y = input.y + 0.5;
96007
96146
 
96008
96147
  result.x = (_x / viewportSize.x) * 2 - 1;
96009
96148
  result.y = -(_y / viewportSize.y) * 2 + 1;
@@ -96325,6 +96464,27 @@ const TouchEvents = {
96325
96464
  Cancel: "touchcancel",
96326
96465
  };
96327
96466
 
96467
+ /**
96468
+ * Representation of an input device key
96469
+ */
96470
+ class InputDeviceSwitch {
96471
+ /**
96472
+ * Button press
96473
+ * @type {Signal}
96474
+ */
96475
+ down = new Signal()
96476
+ /**
96477
+ * Button release
96478
+ * @type {Signal}
96479
+ */
96480
+ up = new Signal()
96481
+ /**
96482
+ * is button currently being pressed?
96483
+ * @type {boolean}
96484
+ */
96485
+ is_down = false
96486
+ }
96487
+
96328
96488
  /**
96329
96489
  * Created by Alex on 29/01/2015.
96330
96490
  */
@@ -96691,6 +96851,13 @@ class PointerDevice {
96691
96851
  */
96692
96852
  isRunning = false;
96693
96853
 
96854
+ /**
96855
+ * The MouseEvent.buttons is a 32bit field, which means we can encode up to 32 buttons
96856
+ * @readonly
96857
+ * @type {InputDeviceSwitch[]}
96858
+ */
96859
+ buttons = new Array(32);
96860
+
96694
96861
  /**
96695
96862
  *
96696
96863
  * @param {EventTarget} domElement html element
@@ -96699,6 +96866,10 @@ class PointerDevice {
96699
96866
  constructor(domElement) {
96700
96867
  assert.defined(domElement, "domElement");
96701
96868
 
96869
+ // initialize buttons
96870
+ for (let i = 0; i < this.buttons.length; i++) {
96871
+ this.buttons[i] = new InputDeviceSwitch();
96872
+ }
96702
96873
 
96703
96874
  /**
96704
96875
  *
@@ -96740,6 +96911,16 @@ class PointerDevice {
96740
96911
  #eventHandlerMouseDown = (event) => {
96741
96912
  this.readPointerPositionFromEvent(this.position, event);
96742
96913
  this.on.down.send2(this.position, event);
96914
+
96915
+ // update button state and dispatch specific signal
96916
+ const button_index = event.button;
96917
+
96918
+ const button = this.buttons[button_index];
96919
+
96920
+ if (button !== undefined) {
96921
+ button.is_down = true;
96922
+ button.down.send0();
96923
+ }
96743
96924
  }
96744
96925
 
96745
96926
  /**
@@ -96767,6 +96948,16 @@ class PointerDevice {
96767
96948
  #eventHandlerGlobalMouseUp = (event) => {
96768
96949
  this.readPointerPositionFromEvent(this.position, event);
96769
96950
  this.#globalUp.send2(this.position, event);
96951
+
96952
+ // update button state and dispatch specific signal
96953
+ const button_index = event.button;
96954
+
96955
+ const button = this.buttons[button_index];
96956
+
96957
+ if (button !== undefined) {
96958
+ button.is_down = false;
96959
+ button.up.send0();
96960
+ }
96770
96961
  }
96771
96962
 
96772
96963
  /**
@@ -96957,27 +97148,6 @@ const KeyboardEvents = {
96957
97148
  KeyDown: 'keydown'
96958
97149
  };
96959
97150
 
96960
- /**
96961
- * Representation of an input device key
96962
- */
96963
- class InputDeviceSwitch {
96964
- /**
96965
- * Button press
96966
- * @type {Signal}
96967
- */
96968
- down = new Signal()
96969
- /**
96970
- * Button release
96971
- * @type {Signal}
96972
- */
96973
- up = new Signal()
96974
- /**
96975
- * is button currently being pressed?
96976
- * @type {boolean}
96977
- */
96978
- is_down = false
96979
- }
96980
-
96981
97151
  /**
96982
97152
  * Created by Alex on 06/03/2017.
96983
97153
  */
@@ -98375,10 +98545,35 @@ class EntityComponentDataset {
98375
98545
  }
98376
98546
 
98377
98547
  /**
98378
- *
98548
+ * same as getComponent when component exists, if component is not associated with the entity, callback will be invoked once when it is added.
98549
+ * @param {Number} entityId
98550
+ * @param {Class} componentClass
98551
+ * @param {function} callback
98552
+ * @param {*} [thisArg]
98553
+ */
98554
+ getComponentAsync (entityId, componentClass, callback, thisArg) {
98555
+ const component = this.getComponent(entityId, componentClass);
98556
+
98557
+ const handler = (options) => {
98558
+ if (options.klass === componentClass) {
98559
+ this.removeEntityEventListener(entityId, EventType.ComponentAdded, handler);
98560
+ callback.call(thisArg, options.instance);
98561
+ }
98562
+ };
98563
+
98564
+ if (component === undefined) {
98565
+ this.addEntityEventListener(entityId, EventType.ComponentAdded, handler);
98566
+ } else {
98567
+ callback.call(thisArg, component);
98568
+ }
98569
+ };
98570
+
98571
+ /**
98572
+ * Performs traversal on a subset of entities which have specified components.
98573
+ * @example traverseEntities([Transform,Renderable,Tag],function(transform, renderable, tag, entity){ ... }, this);
98379
98574
  * @param {Array} classes
98380
98575
  * @param {function:boolean?} visitor Visitor can return optional "false" to terminate traversal earlier
98381
- * @param {object} [thisArg]
98576
+ * @param {object} [thisArg] specifies context object on which callbacks are to be called, optional
98382
98577
  */
98383
98578
  traverseEntities(classes, visitor, thisArg) {
98384
98579
 
@@ -98454,7 +98649,7 @@ class EntityComponentDataset {
98454
98649
  }
98455
98650
 
98456
98651
  /**
98457
- * does traversal on a subset of entities which have only the specified components and no others
98652
+ * Performs traversal on a subset of entities which have only the specified components and no others
98458
98653
  * @example traverseEntitiesExact([Transform,Renderable,Tag],function(transform, renderable, tag, entity){ ... }, this);
98459
98654
  * @param {Array.<class>} classes
98460
98655
  * @param {Function} visitor
@@ -99860,7 +100055,7 @@ class RepeatBehavior extends AbstractDecoratorBehavior {
99860
100055
  * @type {number}
99861
100056
  * @private
99862
100057
  */
99863
- this.__limit = count;
100058
+ this.limit = count;
99864
100059
 
99865
100060
  /**
99866
100061
  *
@@ -99873,19 +100068,19 @@ class RepeatBehavior extends AbstractDecoratorBehavior {
99873
100068
  }
99874
100069
 
99875
100070
  /**
99876
- *
100071
+ * @deprecated use .limit directly instead
99877
100072
  * @param {number} v
99878
100073
  */
99879
100074
  setCount(v) {
99880
- this.__limit = v;
100075
+ this.limit = v;
99881
100076
  }
99882
100077
 
99883
100078
  /**
99884
- *
100079
+ * @deprecated use .limit directly instead
99885
100080
  * @return {number}
99886
100081
  */
99887
100082
  getCount() {
99888
- return this.__limit;
100083
+ return this.limit;
99889
100084
  }
99890
100085
 
99891
100086
  /**
@@ -99898,8 +100093,17 @@ class RepeatBehavior extends AbstractDecoratorBehavior {
99898
100093
  return new RepeatBehavior(source, count);
99899
100094
  }
99900
100095
 
100096
+ initialize(context) {
100097
+ super.initialize(context);
100098
+
100099
+ // reset iterator
100100
+ this.__iterator = 0;
100101
+ }
100102
+
99901
100103
  tick(timeDelta) {
99902
- const s = this.__source.tick(timeDelta);
100104
+ const source = this.__source;
100105
+
100106
+ const s = source.tick(timeDelta);
99903
100107
 
99904
100108
  assert.enum(s, BehaviorStatus, 'status');
99905
100109
 
@@ -99910,12 +100114,12 @@ class RepeatBehavior extends AbstractDecoratorBehavior {
99910
100114
 
99911
100115
  this.__iterator++;
99912
100116
 
99913
- if (this.__iterator >= this.__limit) {
100117
+ if (this.__iterator >= this.limit) {
99914
100118
 
99915
100119
  return BehaviorStatus.Succeeded;
99916
100120
  } else {
99917
100121
  //re-initialize the source behavior
99918
- this.__source.initialize(this.context);
100122
+ source.initialize(this.context);
99919
100123
 
99920
100124
  return BehaviorStatus.Running;
99921
100125
  }
@@ -123978,7 +124182,7 @@ function makeAlexWaterMaterial() {
123978
124182
  * @param {function(terrain:Terrain,entity:number)} [callback]
123979
124183
  * @returns {Terrain|null}
123980
124184
  */
123981
- function obtainTerrain(ecd, callback) {
124185
+ function obtainTerrain(ecd, callback=noop) {
123982
124186
  assert.notEqual(ecd, null, 'ecd is null');
123983
124187
  assert.notEqual(ecd, undefined, 'ecd is undefined');
123984
124188
 
@@ -123986,9 +124190,7 @@ function obtainTerrain(ecd, callback) {
123986
124190
 
123987
124191
  const terrain = object.component;
123988
124192
 
123989
- if (terrain !== null && typeof callback === "function") {
123990
124193
  callback(terrain, object.entity);
123991
- }
123992
124194
 
123993
124195
  return terrain;
123994
124196
  }