@woosh/meep-engine 2.27.0 → 2.30.0

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 (55) hide show
  1. package/core/geom/3d/plane_computeConvex3PlaneIntersection.js +17 -25
  2. package/core/geom/AABB2.d.ts +2 -0
  3. package/core/geom/GeometryMath.js +0 -127
  4. package/core/geom/random/randomPointInBox.js +12 -0
  5. package/core/geom/random/randomPointInCircle.js +18 -0
  6. package/core/geom/random/randomPointInPoint.js +8 -0
  7. package/core/geom/random/randomPointInSphere.js +31 -0
  8. package/core/geom/random/randomPointOnBox.js +33 -0
  9. package/core/geom/random/randomPointOnSphere.js +27 -0
  10. package/core/math/noise/sdnoise.js +24 -39
  11. package/core/process/worker/WorkerBuilder.js +5 -1
  12. package/editor/process/symbolic/makeParticleEmitterSymbolicDisplay.js +1 -1
  13. package/editor/view/ecs/components/particles/ParticleLayerController.js +2 -4
  14. package/engine/Engine.d.ts +5 -1
  15. package/engine/Engine.js +35 -17
  16. package/engine/EngineHarness.js +9 -1
  17. package/engine/animation/AnimationUtils.js +8 -0
  18. package/engine/asset/AssetManager.js +14 -3
  19. package/engine/asset/loaders/image/codec/CodecWithFallback.js +1 -1
  20. package/engine/asset/loaders/image/png/PNGReader.js +19 -21
  21. package/engine/ecs/EntityManager.js +10 -0
  22. package/engine/ecs/terrain/overlay/TerrainOverlay.js +8 -1
  23. package/engine/graphics/camera/makeOrbitalCameraController.js +2 -3
  24. package/engine/graphics/ecs/camera/topdown/ComputeCameraFacingVector.js +21 -0
  25. package/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +2 -0
  26. package/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +26 -0
  27. package/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +4 -24
  28. package/engine/graphics/ecs/mesh/applyTransform.js +5 -7
  29. package/engine/graphics/particles/particular/engine/ParticularEngine.js +1 -0
  30. package/engine/graphics/particles/particular/engine/emitter/EmissionFromType.js +8 -0
  31. package/engine/graphics/particles/particular/engine/emitter/EmissionShapeType.js +9 -0
  32. package/engine/graphics/particles/particular/engine/emitter/PARTICLE_ATTRIBUTES.js +3 -0
  33. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +61 -36
  34. package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js +17 -20
  35. package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.spec.js +3 -1
  36. package/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +30 -10
  37. package/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +4 -6
  38. package/engine/graphics/particles/particular/engine/parameter/ParameterTrackSet.js +6 -3
  39. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +271 -1
  40. package/engine/graphics/particles/particular/engine/renderers/billboard/prototypeBillboardRenderer.js +164 -0
  41. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +10 -555
  42. package/engine/graphics/particles/particular/engine/simulator/AbstractSimulationStep.js +6 -0
  43. package/engine/graphics/particles/particular/engine/simulator/SimulationStepFixedPhysics.js +16 -1
  44. package/engine/graphics/particles/particular/engine/simulator/update_parameters.js +41 -0
  45. package/engine/graphics/render/buffer/FrameBufferManager.js +2 -0
  46. package/engine/graphics/render/visibility/IncrementalDeltaSet.js +5 -0
  47. package/engine/graphics/render/visibility/VisibilityComputer.js +6 -6
  48. package/engine/graphics/render/visibility/VisibilityFilter.js +10 -0
  49. package/engine/navigation/ecs/components/Path.d.ts +7 -0
  50. package/engine/navigation/ecs/components/Path.js +33 -49
  51. package/engine/navigation/ecs/path_following/PathFollower.d.ts +5 -15
  52. package/package.json +3 -3
  53. package/view/elements/progress/segmented/SegmentedResourceBarView.js +7 -0
  54. package/view/minimap/Minimap.js +1 -1
  55. package/view/util/DomSizeObserver.js +59 -10
@@ -0,0 +1,41 @@
1
+ import { ParticleParameters } from "../emitter/ParticleParameters.js";
2
+ import {
3
+ PARTICLE_ATTRIBUTE_COLOR,
4
+ PARTICLE_ATTRIBUTE_SIZE,
5
+ PARTICLE_ATTRIBUTE_SIZE_INITIAL
6
+ } from "../emitter/PARTICLE_ATTRIBUTES.js";
7
+
8
+ const v4 = new Float32Array(4);
9
+
10
+ /**
11
+ *
12
+ * @param {number} particle_index
13
+ * @param {ParticlePool} particles
14
+ * @param {ParticleLayer} layer
15
+ * @param {number} normalized_age
16
+ */
17
+ export function update_parameters(particle_index, particles, layer, normalized_age) {
18
+ const tracks = layer.parameterTracks;
19
+
20
+ // update color
21
+ const param_color = tracks.getTrackByName(ParticleParameters.Color);
22
+
23
+ if (param_color !== undefined) {
24
+ param_color.track.sample(normalized_age, v4);
25
+ particles.writeAttributeVector4(particle_index, PARTICLE_ATTRIBUTE_COLOR, v4[0], v4[1], v4[2], v4[3]);
26
+ }
27
+
28
+ // update size
29
+ const param_scale = tracks.getTrackByName(ParticleParameters.Scale);
30
+
31
+ const initial_size = particles.readAttributeScalar(particle_index, PARTICLE_ATTRIBUTE_SIZE_INITIAL);
32
+
33
+ if (param_scale !== undefined) {
34
+ param_scale.track.sample(normalized_age, v4);
35
+
36
+ const scale = v4[0];
37
+ particles.writeAttributeScalar(particle_index, PARTICLE_ATTRIBUTE_SIZE, scale * initial_size);
38
+ } else {
39
+ particles.writeAttributeScalar(particle_index, PARTICLE_ATTRIBUTE_SIZE, initial_size);
40
+ }
41
+ }
@@ -125,6 +125,8 @@ FrameBufferManager.prototype.computeRenderOrder = function () {
125
125
  * @returns {FrameBuffer|undefined}
126
126
  */
127
127
  FrameBufferManager.prototype.getById = function (id) {
128
+ assert.isString(id, 'id');
129
+
128
130
  return this.buffers.find(function (buffer) {
129
131
  return buffer.id === id;
130
132
  });
@@ -102,6 +102,11 @@ export class IncrementalDeltaSet {
102
102
  }
103
103
 
104
104
  clear() {
105
+ if (this.size === 0) {
106
+ // already empty
107
+ return;
108
+ }
109
+
105
110
  this.elements.splice(0, this.size);
106
111
  this.size = 0;
107
112
  this.flags.reset();
@@ -3,6 +3,11 @@ import { frustumFromCamera } from "../../ecs/camera/CameraSystem.js";
3
3
  import { assert } from "../../../../core/assert.js";
4
4
 
5
5
  const frustum = new Frustum();
6
+ /**
7
+ *
8
+ * @type {VisibilityFilter[]}
9
+ */
10
+ const objectFilters = [];
6
11
 
7
12
  export class VisibilityComputer {
8
13
  constructor() {
@@ -104,11 +109,6 @@ export class VisibilityComputer {
104
109
  //clear visible set
105
110
  layer.visibleSet.initializeUpdate();
106
111
 
107
- /**
108
- *
109
- * @type {VisibilityFilter[]}
110
- */
111
- const objectFilters = [];
112
112
  /**
113
113
  *
114
114
  * @type {function[]}
@@ -124,7 +124,7 @@ export class VisibilityComputer {
124
124
  const f = filters[i];
125
125
 
126
126
  if (f.enabled && f.layerPredicate(layer)) {
127
- objectFilters.push(f);
127
+ objectFilters[objectFilterCount] = f;
128
128
  objectFilterExecutors.push(f.objectPredicateExecute);
129
129
 
130
130
  objectFilterCount++;
@@ -1,4 +1,5 @@
1
1
  import { noop, returnTrue } from "../../../../core/function/Functions.js";
2
+ import { assert } from "../../../../core/assert.js";
2
3
 
3
4
  export class VisibilityFilter {
4
5
  constructor({
@@ -9,12 +10,21 @@ export class VisibilityFilter {
9
10
  layerPredicate = returnTrue
10
11
  }) {
11
12
 
13
+ assert.isString(name, 'name');
14
+
15
+ /**
16
+ * @type {string}
17
+ */
12
18
  this.name = name;
13
19
 
14
20
  this.objectPredicateExecute = objectPredicateExecute;
15
21
  this.objectPredicateInitialize = objectPredicateInitialize;
16
22
  this.objectPredicateFinalize = objectPredicateFinalize;
17
23
 
24
+ /**
25
+ *
26
+ * @type {function(RenderLayer): boolean}
27
+ */
18
28
  this.layerPredicate = layerPredicate;
19
29
 
20
30
  /**
@@ -3,11 +3,18 @@ import {InterpolationType} from "./InterpolationType";
3
3
 
4
4
  export default class Path {
5
5
  public interpolation: InterpolationType
6
+ /**
7
+ * Absolute length of the path
8
+ */
9
+ public readonly length: number
6
10
 
7
11
  public isEmpty(): boolean
8
12
 
9
13
  public clear(): void
10
14
 
15
+ /**
16
+ * Number of points that make up this path
17
+ */
11
18
  public getPointCount(): number
12
19
 
13
20
  public setPointCount(v: number): void
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
  import { line3_computeSegmentPointDistance_sqr } from "../../../../core/geom/LineSegment.js";
7
- import Vector3 from "../../../../core/geom/Vector3.js";
7
+ import Vector3, { v3_distance } from "../../../../core/geom/Vector3.js";
8
8
 
9
9
  import { CatmullRomCurve3 } from "three";
10
10
  import { clamp } from "../../../../core/math/clamp.js";
@@ -21,6 +21,9 @@ import { InterpolationType } from "./InterpolationType.js";
21
21
  const v3_a = new Vector3();
22
22
  const v3_b = new Vector3();
23
23
 
24
+ const scratch_v3_a = new Float32Array(3);
25
+ const scratch_v3_b = new Float32Array(3);
26
+
24
27
  /**
25
28
  *
26
29
  * @type {number[]}
@@ -58,29 +61,6 @@ class Path {
58
61
  */
59
62
  this.__data = new RowFirstTable(DEFAULT_SPEC);
60
63
 
61
- /**
62
- * TODO this needs to be moved to PathFollower
63
- * Distance offset from the previous vertex on the path
64
- * @type {number}
65
- * @deprecated
66
- */
67
- this.markerOffset = 0;
68
- /**
69
- * TODO this needs to be moved to PathFollower
70
- * Index of the previous vertex on the path
71
- * @type {number}
72
- * @deprecated
73
- */
74
- this.markerIndex = 0;
75
-
76
- /**
77
- * TODO this needs to be moved to PathFollower
78
- * Distance to the next vertex on the path
79
- * @type {number}
80
- * @deprecated
81
- */
82
- this.markerDistanceToNext = 0;
83
-
84
64
  /**
85
65
  *
86
66
  * @type {InterpolationType|number}
@@ -95,21 +75,16 @@ class Path {
95
75
  this.__length = -1;
96
76
  }
97
77
 
98
- /**
99
- * TODO this needs to be moved to PathFollower
100
- * @deprecated
101
- */
102
- terminateAtCurrentPosition() {
103
- console.warn('deprecated');
104
- const endIndex = this.markerIndex + 1;
105
-
106
- this.getCurrentPosition(v3_a);
107
- this.setPosition(endIndex, v3_a.x, v3_a.y, v3_a.z);
78
+ get markerOffset() {
79
+ throw new Error('deprecated, use PathFollower instead');
80
+ }
108
81
 
109
- this.setPointCount(endIndex);
82
+ get markerIndex() {
83
+ throw new Error('deprecated, use PathFollower instead');
84
+ }
110
85
 
111
- this.markerOffset = 0;
112
- this.markerDistanceToNext = 0;
86
+ get markerDistanceToNext() {
87
+ throw new Error('deprecated, use PathFollower instead');
113
88
  }
114
89
 
115
90
  /**
@@ -245,7 +220,7 @@ class Path {
245
220
  /**
246
221
  *
247
222
  * @param {number} index
248
- * @param {number[]} result
223
+ * @param {ArrayLike<number>|number[]|Float32Array|Float64Array} result
249
224
  * @param {number} result_offset
250
225
  */
251
226
  readPositionToArray(index, result, result_offset) {
@@ -506,16 +481,19 @@ class Path {
506
481
 
507
482
  let cursor = 0;
508
483
 
509
- let current = v3_a;
510
- let previous = v3_b;
484
+ let current = scratch_v3_a;
485
+ let previous = scratch_v3_b;
511
486
  let distance = 0;
512
487
 
513
- this.getPosition(0, previous);
488
+ this.readPositionToArray(0, previous, 0);
514
489
 
515
490
  for (let i = 1; i < pointCount; i++) {
516
- this.getPosition(i, current);
491
+ this.readPositionToArray(i, current, 0);
517
492
 
518
- distance = previous.distanceTo(current);
493
+ distance = v3_distance(
494
+ previous[0], previous[1], previous[2],
495
+ current[0], current[1], current[2]
496
+ );
519
497
 
520
498
  if (cursor + distance > absolute_distance) {
521
499
  // we found v1
@@ -867,17 +845,23 @@ class Path {
867
845
  }
868
846
 
869
847
  let r = 0;
870
- let p0 = v3_a;
871
- let p1 = v3_b;
872
848
 
873
- this.getPosition(0, p0);
849
+ let p0 = scratch_v3_a;
850
+ let p1 = scratch_v3_b;
851
+ let distance = 0;
852
+
853
+ this.readPositionToArray(0, p1, 0);
874
854
 
875
855
  for (let i = 1; i < n; i++) {
876
- this.getPosition(i, p1);
856
+ this.readPositionToArray(i, p0, 0);
857
+
858
+ distance = v3_distance(
859
+ p1[0], p1[1], p1[2],
860
+ p0[0], p0[1], p0[2]
861
+ );
877
862
 
878
- const d = p0.distanceTo(p1);
879
863
 
880
- r += d;
864
+ r += distance;
881
865
 
882
866
  // perform variable swap
883
867
  const swap_t = p0;
@@ -1,32 +1,22 @@
1
- import {BooleanVector3} from "../../../../core/model/BooleanVector3";
2
1
  import Vector1 from "../../../../core/geom/Vector1";
3
2
  import {PathFollowerFlags} from "./PathFollowerFlags";
4
3
 
5
4
  export default class PathFollower {
6
- constructor()
7
-
8
- /**
9
- *
10
- * On which axis to write rotation
11
- */
12
- readonly rotationAlignment: BooleanVector3
13
-
14
- /**
15
- *
16
- * On which axis to write position
17
- */
18
- readonly positionWriting: BooleanVector3
19
-
20
5
  /**
21
6
  * Movement speed along the path in world units per second
22
7
  */
23
8
  readonly speed: Vector1
9
+
24
10
  /**
25
11
  *
26
12
  * Speed at which path follower can adjust rotation in Rad/s
27
13
  */
28
14
  readonly rotationSpeed: Vector1
29
15
 
16
+ /**
17
+ *
18
+ * Absolute position along the path
19
+ */
30
20
  position: number
31
21
 
32
22
  flags: number
package/package.json CHANGED
@@ -4,15 +4,15 @@
4
4
  "productName": "Meep",
5
5
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
6
6
  "author": "Alexander Goldring",
7
- "version": "2.27.0",
7
+ "version": "2.30.0",
8
8
  "dependencies": {
9
9
  "fast-levenshtein": "2.0.6",
10
10
  "opentype.js": "1.3.3",
11
11
  "simplex-noise": "2.4.0",
12
- "three": "^0.129.0"
12
+ "three": "^0.132.2"
13
13
  },
14
14
  "devDependencies": {
15
15
  "babel-jest": "^26.6.3",
16
- "@types/three": "^0.128.0"
16
+ "@types/three": "^0.131.1"
17
17
  }
18
18
  }
@@ -137,6 +137,12 @@ export class SegmentedResourceBarView extends View {
137
137
  }
138
138
 
139
139
  __updateSize() {
140
+
141
+ if (this.__sizeObserver.dimensions.size.distanceSqrTo(this.__v_segments.size) < 0.5) {
142
+ // change too small, ignore
143
+ return;
144
+ }
145
+
140
146
  this.updateSegments();
141
147
  }
142
148
 
@@ -152,6 +158,7 @@ export class SegmentedResourceBarView extends View {
152
158
  */
153
159
  const size = this.__sizeObserver.dimensions.size;
154
160
 
161
+
155
162
  this.__v_segments.size.copy(size);
156
163
 
157
164
  const vSegments = this.__v_segments;
@@ -143,7 +143,7 @@ class MinimapView extends View {
143
143
  updateWorldScale();
144
144
  });
145
145
 
146
- const pointer = this.pointer = new PointerDevice(this.el);
146
+ const pointer = this.pointer = new PointerDevice(vWorld.el);
147
147
 
148
148
  function focus(x, y) {
149
149
  const worldX = (x / worldScale.x) + world.position.x;
@@ -45,6 +45,9 @@ export function resizeAABB2ToFitBoundingClientRect(el, depth, aabb) {
45
45
 
46
46
  const aabb = new AABB2();
47
47
 
48
+ /**
49
+ * Size observer of a DOM element
50
+ */
48
51
  export class DomSizeObserver {
49
52
  /**
50
53
  *
@@ -72,19 +75,47 @@ export class DomSizeObserver {
72
75
  */
73
76
  this.element = null;
74
77
 
78
+ /**
79
+ * @private
80
+ * @type {boolean}
81
+ */
75
82
  this.running = false;
76
83
 
77
- const cycle = () => {
78
- if (this.running) {
79
- this.update();
80
- requestAnimationFrame(cycle);
81
- }
82
- }
84
+ /**
85
+ *
86
+ * @type {ResizeObserver}
87
+ * @private
88
+ */
89
+ this.__dom_resize_observer = new ResizeObserver(this.__dom_resize_observer_callback.bind(this));
90
+ }
91
+
92
+ /**
93
+ *
94
+ * @param {ResizeObserverEntry[]} entries
95
+ * @param {ResizeObserver} observer
96
+ * @private
97
+ */
98
+ __dom_resize_observer_callback(entries, observer) {
99
+ const first_entry = entries[0];
100
+
101
+ /**
102
+ *
103
+ * @type {ClientRect | DOMRect}
104
+ */
105
+ const rect = first_entry.contentRect;
106
+
83
107
 
84
- this.cycle = cycle;
108
+ aabb.setNegativelyInfiniteBounds();
109
+
110
+ resizeAABB2ToFitBoundingClientRect(this.element, this.__depth, aabb);
111
+
112
+ const rectangle = this.dimensions;
113
+
114
+ rectangle.position.set(aabb.x0, aabb.y0);
115
+ rectangle.size.set(rect.width, rect.height);
85
116
  }
86
117
 
87
- update() {
118
+ synchronize() {
88
119
  aabb.setNegativelyInfiniteBounds();
89
120
 
90
121
  resizeAABB2ToFitBoundingClientRect(this.element, this.__depth, aabb);
@@ -103,7 +134,12 @@ export class DomSizeObserver {
103
134
 
104
135
  this.running = true;
105
136
 
106
- this.cycle();
137
+ // perform an immediate update
138
+ this.synchronize();
139
+
140
+ if (this.element !== null) {
141
+ this.__dom_resize_observer.observe(this.element);
142
+ }
107
143
  }
108
144
 
109
145
  /**
@@ -112,10 +148,24 @@ export class DomSizeObserver {
112
148
  */
113
149
  attach(element) {
114
150
  this.element = element;
151
+
152
+ if (this.running) {
153
+ this.__dom_resize_observer.unobserve(this.element);
154
+ }
115
155
  }
116
156
 
117
157
  stop() {
158
+
159
+ if (!this.running) {
160
+ // not running
161
+ return;
162
+ }
163
+
118
164
  this.running = false;
165
+
166
+ if (this.element !== null) {
167
+ this.__dom_resize_observer.unobserve(this.element);
168
+ }
119
169
  }
120
170
 
121
171
  /**
@@ -144,6 +194,5 @@ export class DomSizeObserver {
144
194
 
145
195
  view.on.linked.remove(this.start, this);
146
196
  view.on.unlinked.remove(this.stop, this);
147
-
148
197
  }
149
198
  }