@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
@@ -1,4 +1,4 @@
1
- import Vector3, { v3_dot } from "../Vector3.js";
1
+ import { v3_dot } from "../Vector3.js";
2
2
 
3
3
 
4
4
  /**
@@ -22,10 +22,6 @@ export function plane_three_computeConvex3PlaneIntersection(result, a, b, c) {
22
22
  );
23
23
  }
24
24
 
25
- const bxc = new Vector3();
26
- const cxa = new Vector3();
27
- const axb = new Vector3();
28
-
29
25
  /**
30
26
  * NOTE: Based on Intersection of 3 planes, Graphics Gems 1 pg 305
31
27
  * @param {Vector3} result
@@ -57,23 +53,19 @@ export function plane_computeConvex3PlaneIntersection(
57
53
  float3 r = -P0.w * bxc - P1.w * cxa - P2.w * axb;
58
54
  return r * (1 / dot(P0.xyz, bxc));
59
55
  */
56
+ const bxc_x = b_normal_y * c_normal_z - b_normal_z * c_normal_y;
57
+ const bxc_y = b_normal_z * c_normal_x - b_normal_x * c_normal_z;
58
+ const bxc_z = b_normal_x * c_normal_y - b_normal_y * c_normal_x;
60
59
 
61
- bxc._crossVectors(
62
- b_normal_x, b_normal_y, b_normal_z,
63
- c_normal_x, c_normal_y, c_normal_z
64
- );
60
+ const cxa_x = c_normal_y * a_normal_z - c_normal_z * a_normal_y;
61
+ const cxa_y = c_normal_z * a_normal_x - c_normal_x * a_normal_z;
62
+ const cxa_z = c_normal_x * a_normal_y - c_normal_y * a_normal_x;
65
63
 
66
- cxa._crossVectors(
67
- c_normal_x, c_normal_y, c_normal_z,
68
- a_normal_x, a_normal_y, a_normal_z
69
- );
70
-
71
- axb._crossVectors(
72
- a_normal_x, a_normal_y, a_normal_z,
73
- b_normal_x, b_normal_y, b_normal_z
74
- );
64
+ const axb_x = a_normal_y * b_normal_z - a_normal_z * b_normal_y;
65
+ const axb_y = a_normal_z * b_normal_x - a_normal_x * b_normal_z;
66
+ const axb_z = a_normal_x * b_normal_y - a_normal_y * b_normal_x;
75
67
 
76
- const determinant = v3_dot(a_normal_x, a_normal_y, a_normal_z, bxc.x, bxc.y, bxc.z);
68
+ const determinant = v3_dot(a_normal_x, a_normal_y, a_normal_z, bxc_x, bxc_y, bxc_z);
77
69
 
78
70
  if (determinant === 0) {
79
71
  // planes are not convex, there is no intersection
@@ -82,13 +74,13 @@ export function plane_computeConvex3PlaneIntersection(
82
74
 
83
75
  const d = 1 / determinant;
84
76
 
85
- bxc.multiplyScalar(-a_constant);
86
- cxa.multiplyScalar(-b_constant);
87
- axb.multiplyScalar(-c_constant);
77
+ const neg_a_constant = -a_constant;
78
+ const neg_b_constant = -b_constant;
79
+ const neg_c_constant = -c_constant;
88
80
 
89
- const x = (bxc.x + cxa.x + axb.x) * d;
90
- const y = (bxc.y + cxa.y + axb.y) * d;
91
- const z = (bxc.z + cxa.z + axb.z) * d;
81
+ const x = (bxc_x * neg_a_constant + cxa_x * neg_b_constant + axb_x * neg_c_constant) * d;
82
+ const y = (bxc_y * neg_a_constant + cxa_y * neg_b_constant + axb_y * neg_c_constant) * d;
83
+ const z = (bxc_z * neg_a_constant + cxa_z * neg_b_constant + axb_z * neg_c_constant) * d;
92
84
 
93
85
  result.set(
94
86
  x,
@@ -19,4 +19,6 @@ export default class AABB2 {
19
19
  computeArea(): number
20
20
 
21
21
  grow(size: number): void
22
+
23
+ setNegativelyInfiniteBounds(): void
22
24
  }
@@ -1,4 +1,3 @@
1
- import { PI2 } from "../math/MathUtils.js";
2
1
  import { SurfacePoint3 } from "./3d/SurfacePoint3.js";
3
2
  import { computeTriangleRayIntersection } from "./3d/triangle/computeTriangleRayIntersection.js";
4
3
 
@@ -32,129 +31,3 @@ export function rayTriangleIntersection(result, rayOrigin, rayDirection, a, b, c
32
31
  return hit_found;
33
32
  }
34
33
 
35
- /**
36
- * Pick a random point within a unit circle
37
- * Based on: https://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly
38
- * @param {function} random
39
- * @param {Vector2} result
40
- */
41
- export function randomPointInCircle(random, result) {
42
- const r = Math.sqrt(random());
43
-
44
- const theta = random() * PI2;
45
-
46
- const x = r * Math.cos(theta);
47
- const y = r * Math.sin(theta);
48
-
49
- result.set(x, y);
50
- }
51
-
52
- /**
53
- * Volumetric sampling method, since sample volume is a point, it simply sets result to origin
54
- * @param {function} random
55
- * @param {Vector3} result
56
- */
57
- export function randomPointInPoint(random, result) {
58
- result.set(0, 0, 0);
59
- }
60
-
61
- /**
62
- *
63
- * @see based on python code suggested here: https://stackoverflow.com/questions/5408276/sampling-uniformly-distributed-random-points-inside-a-spherical-volume
64
- * @param {function} random
65
- * @param {Vector3} result
66
- */
67
- export function randomPointInSphere(random, result) {
68
- const phi = PI2 * random();
69
-
70
- const cosTheta = random() * 2 - 1;
71
-
72
- const u = random() * 0.5;
73
-
74
- const theta = Math.acos(cosTheta);
75
-
76
- const r = Math.cbrt(u);
77
-
78
- const sinTheta = Math.sin(theta);
79
-
80
- //compute coordinates
81
- const x = r * sinTheta * Math.cos(phi);
82
- const y = r * sinTheta * Math.sin(phi);
83
- const z = r * cosTheta;
84
-
85
- //write the result
86
- result.set(x, y, z);
87
- }
88
-
89
- /**
90
- *
91
- * @see based on python code suggested here: https://stackoverflow.com/questions/5408276/sampling-uniformly-distributed-random-points-inside-a-spherical-volume
92
- * @param {function} random
93
- * @param {Vector3} result
94
- */
95
- export function randomPointOnSphere(random, result) {
96
- const phi = Math.PI * 2 * random();
97
-
98
- const cosTheta = random() * 2 - 1;
99
-
100
- const theta = Math.acos(cosTheta);
101
-
102
- const sinTheta = Math.sin(theta);
103
-
104
- const r = 0.5;
105
-
106
- //compute coordinates
107
- const x = r * sinTheta * Math.cos(phi);
108
- const y = r * sinTheta * Math.sin(phi);
109
- const z = r * cosTheta;
110
-
111
- //write the result
112
- result.set(x, y, z);
113
- }
114
-
115
- /**
116
- *
117
- * @param {function} random
118
- * @param {Vector3} result
119
- */
120
- export function randomPointInBox(random, result) {
121
- const x = random() - 0.5;
122
- const y = random() - 0.5;
123
- const z = random() - 0.5;
124
-
125
- result.set(x, y, z);
126
- }
127
-
128
- /**
129
- *
130
- * @param {function} random
131
- * @param {Vector3} result
132
- */
133
- export function randomPointOnBox(random, result) {
134
- //pick a side
135
- const side = random();
136
-
137
- //determine axis of the side
138
- const axis = side % 0.5;
139
-
140
- //convert side and axis to a fixed value for the axis
141
- const fixedAxis = side > 0.5 ? -0.5 : 0.5;
142
-
143
- let x, y, z;
144
-
145
- if (axis < 0.16666666666) {
146
- x = fixedAxis;
147
- y = random() - 0.5;
148
- z = random() - 0.5;
149
- } else if (axis < 0.33333333333) {
150
- x = random() - 0.5;
151
- y = fixedAxis;
152
- z = random() - 0.5;
153
- } else {
154
- x = random() - 0.5;
155
- y = random() - 0.5;
156
- z = fixedAxis;
157
- }
158
-
159
- result.set(x, y, z);
160
- }
@@ -0,0 +1,12 @@
1
+ /**
2
+ *
3
+ * @param {function} random
4
+ * @param {Vector3} result
5
+ */
6
+ export function randomPointInBox(random, result) {
7
+ const x = random() - 0.5;
8
+ const y = random() - 0.5;
9
+ const z = random() - 0.5;
10
+
11
+ result.set(x, y, z);
12
+ }
@@ -0,0 +1,18 @@
1
+ import { PI2 } from "../../math/MathUtils.js";
2
+
3
+ /**
4
+ * Pick a random point within a unit circle
5
+ * Based on: https://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly
6
+ * @param {function} random
7
+ * @param {Vector2} result
8
+ */
9
+ export function randomPointInCircle(random, result) {
10
+ const r = Math.sqrt(random());
11
+
12
+ const theta = random() * PI2;
13
+
14
+ const x = r * Math.cos(theta);
15
+ const y = r * Math.sin(theta);
16
+
17
+ result.set(x, y);
18
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Volumetric sampling method, since sample volume is a point, it simply sets result to origin
3
+ * @param {function} random
4
+ * @param {Vector3} result
5
+ */
6
+ export function randomPointInPoint(random, result) {
7
+ result.set(0, 0, 0);
8
+ }
@@ -0,0 +1,31 @@
1
+ import { PI2 } from "../../math/MathUtils.js";
2
+
3
+ /**
4
+ *
5
+ * @see based on python code suggested here: https://stackoverflow.com/questions/5408276/sampling-uniformly-distributed-random-points-inside-a-spherical-volume
6
+ * @param {function} random
7
+ * @param {Vector3} result
8
+ */
9
+ export function randomPointInSphere(random, result) {
10
+ const phi = PI2 * random();
11
+
12
+ const cosTheta = random() * 2 - 1;
13
+
14
+ const u = random() * 0.5;
15
+
16
+ const theta = Math.acos(cosTheta);
17
+
18
+ const r = Math.cbrt(u);
19
+
20
+ const sinTheta = Math.sin(theta);
21
+
22
+ //compute coordinates
23
+ const rst = r * sinTheta;
24
+
25
+ const x = rst * Math.cos(phi);
26
+ const y = rst * Math.sin(phi);
27
+ const z = r * cosTheta;
28
+
29
+ //write the result
30
+ result.set(x, y, z);
31
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ *
3
+ * @param {function} random
4
+ * @param {Vector3} result
5
+ */
6
+ export function randomPointOnBox(random, result) {
7
+ //pick a side
8
+ const side = random();
9
+
10
+ //determine axis of the side
11
+ const axis = side % 0.5;
12
+
13
+ //convert side and axis to a fixed value for the axis
14
+ const fixedAxis = side > 0.5 ? -0.5 : 0.5;
15
+
16
+ let x, y, z;
17
+
18
+ if (axis < 0.16666666666) {
19
+ x = fixedAxis;
20
+ y = random() - 0.5;
21
+ z = random() - 0.5;
22
+ } else if (axis < 0.33333333333) {
23
+ x = random() - 0.5;
24
+ y = fixedAxis;
25
+ z = random() - 0.5;
26
+ } else {
27
+ x = random() - 0.5;
28
+ y = random() - 0.5;
29
+ z = fixedAxis;
30
+ }
31
+
32
+ result.set(x, y, z);
33
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ *
3
+ * @see based on python code suggested here: https://stackoverflow.com/questions/5408276/sampling-uniformly-distributed-random-points-inside-a-spherical-volume
4
+ * @param {function} random
5
+ * @param {Vector3} result
6
+ */
7
+ export function randomPointOnSphere(random, result) {
8
+ const phi = Math.PI * 2 * random();
9
+
10
+ const cosTheta = random() * 2 - 1;
11
+
12
+ const theta = Math.acos(cosTheta);
13
+
14
+ const sinTheta = Math.sin(theta);
15
+
16
+ const r = 0.5;
17
+
18
+ //compute coordinates
19
+ const rst = r * sinTheta;
20
+
21
+ const x = rst * Math.cos(phi);
22
+ const y = rst * Math.sin(phi);
23
+ const z = r * cosTheta;
24
+
25
+ //write the result
26
+ result.set(x, y, z);
27
+ }
@@ -1,29 +1,3 @@
1
- /**
2
- *
3
- * Ported from C code by Stefan Gustavson by @Alex Goldring
4
- * @source http://weber.itn.liu.se/~stegu/aqsis/DSOs/DSOnoises.html
5
- * ================
6
- *
7
- * This is an implementation of Perlin "simplex noise" over one
8
- * dimension (x), two dimensions (x,y), three dimensions (x,y,z)
9
- * and four dimensions (x,y,z,w). The analytic derivative is
10
- * returned, to make it possible to do lots of fun stuff like
11
- * flow animations, curl noise, analytic antialiasing and such.
12
- *
13
- * Visually, this noise is exactly the same as the plain version of
14
- * simplex noise provided in the file "snoise1234.c". It just returns
15
- * all partial derivatives in addition to the scalar noise value.
16
- *
17
- * 2012-01-12: Slight update to compile with MSVC (declarations moved).
18
- *
19
- * @author Alexander Goldring 2020
20
- * @author Stefan Gustavson 2003-2012
21
- */
22
-
23
- function fastfloor(v) {
24
- return v | 0;
25
- }
26
-
27
1
  const v2_array = [];
28
2
  const v3_array = [];
29
3
  const v4_array = [];
@@ -222,7 +196,7 @@ function grad4(result, hash) {
222
196
  * @returns {number}
223
197
  */
224
198
  function sdnoise1(derivatives, x) {
225
- const i0 = fastfloor(x);
199
+ const i0 = x | 0;
226
200
  const i1 = i0 + 1;
227
201
 
228
202
  const x0 = x - i0;
@@ -303,8 +277,8 @@ function sdnoise2(derivatives, x, y) {
303
277
  const xs = x + s;
304
278
  const ys = y + s;
305
279
 
306
- let ii, i = fastfloor(xs);
307
- let jj, j = fastfloor(ys);
280
+ let ii, i = xs | 0;
281
+ let jj, j = ys | 0;
308
282
 
309
283
  const t = (float)(i + j) * G2;
310
284
  const X0 = i - t; /* Unskew the cell origin back to (x,y) space */
@@ -458,9 +432,11 @@ export function sdnoise3(derivatives, x, y, z) {
458
432
  const k = zs | 0;
459
433
 
460
434
  const t = (i + j + k) * G3;
435
+
461
436
  const X0 = i - t; /* Unskew the cell origin back to (x,y,z) space */
462
437
  const Y0 = j - t;
463
438
  const Z0 = k - t;
439
+
464
440
  const x0 = x - X0; /* The x,y,z distances from the cell origin */
465
441
  const y0 = y - Y0;
466
442
  const z0 = z - Z0;
@@ -529,12 +505,18 @@ export function sdnoise3(derivatives, x, y, z) {
529
505
  const x1 = x0 - i1 + G3; /* Offsets for second corner in (x,y,z) coords */
530
506
  const y1 = y0 - j1 + G3;
531
507
  const z1 = z0 - k1 + G3;
532
- const x2 = x0 - i2 + 2.0 * G3; /* Offsets for third corner in (x,y,z) coords */
533
- const y2 = y0 - j2 + 2.0 * G3;
534
- const z2 = z0 - k2 + 2.0 * G3;
535
- const x3 = x0 - 1.0 + 3.0 * G3; /* Offsets for last corner in (x,y,z) coords */
536
- const y3 = y0 - 1.0 + 3.0 * G3;
537
- const z3 = z0 - 1.0 + 3.0 * G3;
508
+
509
+ const G6 = G3 + G3;
510
+
511
+ const x2 = x0 - i2 + G6; /* Offsets for third corner in (x,y,z) coords */
512
+ const y2 = y0 - j2 + G6;
513
+ const z2 = z0 - k2 + G6;
514
+
515
+ const G9 = G6 + G3;
516
+
517
+ const x3 = x0 - 1.0 + G9; /* Offsets for last corner in (x,y,z) coords */
518
+ const y3 = y0 - 1.0 + G9;
519
+ const z3 = z0 - 1.0 + G9;
538
520
 
539
521
  /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */
540
522
  const ii = i % 256;
@@ -632,16 +614,19 @@ export function sdnoise3(derivatives, x, y, z) {
632
614
  let dnoise_dz = temp0 * z0;
633
615
 
634
616
  const temp1 = t21 * t1 * (gx1 * x1 + gy1 * y1 + gz1 * z1);
617
+
635
618
  dnoise_dx += temp1 * x1;
636
619
  dnoise_dy += temp1 * y1;
637
620
  dnoise_dz += temp1 * z1;
638
621
 
639
622
  const temp2 = t22 * t2 * (gx2 * x2 + gy2 * y2 + gz2 * z2);
623
+
640
624
  dnoise_dx += temp2 * x2;
641
625
  dnoise_dy += temp2 * y2;
642
626
  dnoise_dz += temp2 * z2;
643
627
 
644
628
  const temp3 = t23 * t3 * (gx3 * x3 + gy3 * y3 + gz3 * z3);
629
+
645
630
  dnoise_dx += temp3 * x3;
646
631
  dnoise_dy += temp3 * y3;
647
632
  dnoise_dz += temp3 * z3;
@@ -699,10 +684,10 @@ export function sdnoise4(derivatives, x, y, z, w) {
699
684
  const zs = z + s;
700
685
  const ws = w + s;
701
686
 
702
- let ii, i = fastfloor(xs);
703
- let jj, j = fastfloor(ys);
704
- let kk, k = fastfloor(zs);
705
- let ll, l = fastfloor(ws);
687
+ let ii, i = xs | 0;
688
+ let jj, j = ys | 0;
689
+ let kk, k = zs | 0;
690
+ let ll, l = ws | 0;
706
691
 
707
692
  const t = (i + j + k + l) * G4; // Factor for 4D unskewing
708
693
  const X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
@@ -125,7 +125,11 @@ WorkerBuilder.prototype.build = function () {
125
125
  ' if(method === undefined){',
126
126
  ' sendError(new Error("API named \'"+methodName+"\' was not found."));',
127
127
  ' }else{',
128
- ' method.apply(null,parameters).then(sendResult, sendError);',
128
+ ' try{',
129
+ ' method.apply(null,parameters).then(sendResult, sendError);',
130
+ ' }catch(e){',
131
+ ' sendError(e);',
132
+ ' }',
129
133
  ' }',
130
134
  '};'
131
135
  ]);
@@ -1,10 +1,10 @@
1
1
  import { make3DSymbolicDisplay } from "./make3DSymbolicDisplay.js";
2
2
  import { Transform } from "../../../engine/ecs/transform/Transform.js";
3
3
  import { BoxBufferGeometry, Group, Line, LineBasicMaterial, Mesh, MeshBasicMaterial } from "three";
4
- import { EmissionShapeType } from "../../../engine/graphics/particles/particular/engine/emitter/ParticleLayer.js";
5
4
  import { buildThreeJSHelperEntity } from "./buildThreeJSHelperEntity.js";
6
5
  import { ParticleEmitter } from "../../../engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js";
7
6
  import { makeHelperSphereGeometry } from "./makeHelperSphereGeometry.js";
7
+ import { EmissionShapeType } from "../../../engine/graphics/particles/particular/engine/emitter/EmissionShapeType.js";
8
8
 
9
9
  /**
10
10
  *
@@ -1,8 +1,4 @@
1
1
  import GuiControl from "../../../../../view/controller/controls/GuiControl.js";
2
- import {
3
- EmissionFromType,
4
- EmissionShapeType
5
- } from "../../../../../engine/graphics/particles/particular/engine/emitter/ParticleLayer.js";
6
2
  import DatGuiController from "../DatGuiController.js";
7
3
  import Vector3Control from "../../../../../view/controller/controls/Vector3Control.js";
8
4
  import NumericIntervalControl from "../../../../../view/controller/controls/NumericIntervalControl.js";
@@ -12,6 +8,8 @@ import { ParameterTrack } from "../../../../../engine/graphics/particles/particu
12
8
  import { ParameterTrackController } from "./ParameterTrackController.js";
13
9
  import { ParticleParameters } from "../../../../../engine/graphics/particles/particular/engine/emitter/ParticleParameters.js";
14
10
  import { ParameterLookupTable } from "../../../../../engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js";
11
+ import { EmissionFromType } from "../../../../../engine/graphics/particles/particular/engine/emitter/EmissionFromType.js";
12
+ import { EmissionShapeType } from "../../../../../engine/graphics/particles/particular/engine/emitter/EmissionShapeType.js";
15
13
 
16
14
  class ParticleLayerController extends GuiControl {
17
15
  /**
@@ -9,8 +9,12 @@ import {EntityManager} from "./ecs/EntityManager";
9
9
  import View from "../view/View";
10
10
  import Ticker from "./simulation/Ticker";
11
11
 
12
+ export interface IEngineInitializationOptions {
13
+ entityManager?: EntityManager
14
+ }
15
+
12
16
  export default class Engine {
13
- constructor(platform: EnginePlatform);
17
+ constructor(platform: EnginePlatform, options?: IEngineInitializationOptions);
14
18
 
15
19
  public get viewStack(): View
16
20
 
package/engine/Engine.js CHANGED
@@ -52,9 +52,10 @@ class Engine {
52
52
  /**
53
53
  *
54
54
  * @param {EnginePlatform} platform
55
+ * @param {EntityManager} [entityManager]
55
56
  * @constructor
56
57
  */
57
- constructor(platform) {
58
+ constructor(platform, { entityManager } = {}) {
58
59
  assert.defined(platform, 'platform');
59
60
 
60
61
  /**
@@ -81,6 +82,21 @@ class Engine {
81
82
  */
82
83
  this.performance = new MetricCollection();
83
84
 
85
+ const using_external_entity_manager = entityManager !== undefined;
86
+
87
+ //setup entity component system
88
+ if (using_external_entity_manager) {
89
+ // external entity manager provided
90
+ this.entityManager = entityManager;
91
+ } else {
92
+ this.entityManager = new EntityManager();
93
+ }
94
+
95
+ /**
96
+ *
97
+ * @type {Ticker}
98
+ */
99
+ this.ticker = new Ticker();
84
100
 
85
101
  this.__performacne_monitor = new PeriodicConsolePrinter(15, () => {
86
102
  const metrics = this.performance;
@@ -112,6 +128,22 @@ class Engine {
112
128
  return `FPS: ${v_fps}, RENDER: ${v_render}ms, SIMULATION: ${v_sim}ms`;
113
129
  });
114
130
 
131
+
132
+ if (!using_external_entity_manager) {
133
+ // subscribe simulator to common ticker
134
+ this.ticker.subscribe(timeDelta => {
135
+ const t0 = performance.now();
136
+ this.entityManager.simulate(timeDelta);
137
+
138
+ const t1 = performance.now();
139
+ const duration = (t1 - t0) / 1000;
140
+
141
+ // record frame time
142
+ this.performance.get(METRIC_ID_SIMULATION).record(duration);
143
+ });
144
+ }
145
+
146
+
115
147
  this.initialize();
116
148
  }
117
149
 
@@ -168,9 +200,6 @@ class Engine {
168
200
  this.localization = new Localization();
169
201
  this.localization.setAssetManager(this.assetManager);
170
202
 
171
- //setup entity component system
172
- const em = this.entityManager = new EntityManager();
173
-
174
203
 
175
204
  const innerWidth = window.innerWidth / 3;
176
205
  const innerHeight = window.innerHeight / 3;
@@ -182,7 +211,7 @@ class Engine {
182
211
  *
183
212
  * @type {GraphicsEngine}
184
213
  */
185
- const ge = this.graphics = new GraphicsEngine(this.camera, em);
214
+ const ge = this.graphics = new GraphicsEngine(this.camera, this.entityManager);
186
215
 
187
216
  try {
188
217
  ge.start();
@@ -208,18 +237,6 @@ class Engine {
208
237
  */
209
238
  this.gui = new GUIEngine();
210
239
 
211
- this.ticker = new Ticker();
212
- this.ticker.subscribe(timeDelta => {
213
- const t0 = performance.now();
214
- this.entityManager.simulate(timeDelta);
215
-
216
- const t1 = performance.now();
217
- const duration = (t1 - t0) / 1000;
218
-
219
- // record frame time
220
- this.performance.get(METRIC_ID_SIMULATION).record(duration);
221
- });
222
-
223
240
  /**
224
241
  * @readonly
225
242
  * @type {SceneManager}
@@ -492,6 +509,7 @@ class Engine {
492
509
 
493
510
  const frame_delay = (t1 - t0) / 1000;
494
511
 
512
+ // swap variables
495
513
  t0 = t1;
496
514
 
497
515
  // record metric
@@ -24,6 +24,8 @@ import WaterSystem from "./graphics/ecs/water/WaterSystem.js";
24
24
  import KeyboardCameraController from "./input/ecs/controllers/KeyboardCameraController.js";
25
25
  import { EngineConfiguration } from "./EngineConfiguration.js";
26
26
  import { JsonAssetLoader } from "./asset/loaders/JsonAssetLoader.js";
27
+ import { logger } from "./logging/GlobalLogger.js";
28
+ import { ConsoleLoggerBackend } from "./logging/ConsoleLoggerBackend.js";
27
29
 
28
30
  /**
29
31
  *
@@ -77,6 +79,8 @@ export class EngineHarness {
77
79
 
78
80
  window.engine = this.engine;
79
81
 
82
+ logger.addBackend(new ConsoleLoggerBackend());
83
+
80
84
  this.p = null;
81
85
  }
82
86
 
@@ -321,7 +325,7 @@ export class EngineHarness {
321
325
 
322
326
  /**
323
327
  *
324
- * @param {number} cameraEntity
328
+ * @param {number} [cameraEntity]
325
329
  * @param {Engine} engine
326
330
  * @param {number} [sensitivity]
327
331
  * @param {Element} domElement
@@ -335,6 +339,10 @@ export class EngineHarness {
335
339
  sensitivity = 0.01
336
340
  }) {
337
341
 
342
+ if (cameraEntity === undefined) {
343
+ cameraEntity = ecd.getAnyComponent(Camera).entity;
344
+ }
345
+
338
346
  const em = engine.entityManager;
339
347
 
340
348
  if (em.getSystem(InputControllerSystem) === null) {
@@ -164,8 +164,16 @@ export function removeEntityWithMeshParticlesEffect(
164
164
  //prevent further interactions
165
165
  removeComponentsExcept(ecd, entity, [Mesh, ParticleEmitter, Trail2D, Transform]);
166
166
 
167
+ /**
168
+ *
169
+ * @type {Transform}
170
+ */
167
171
  const originalTransform = ecd.getComponent(entity, Transform);
168
172
 
173
+ if (originalTransform === undefined) {
174
+ throw new Error(`entity ${entity} doesn't have Transform`);
175
+ }
176
+
169
177
  //create particle emitter
170
178
  const effectBuilder = new EntityBuilder();
171
179
  const effectEntity = effectBuilder