@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
@@ -293,7 +293,7 @@ AssetManager.prototype.hasLoaderForType = function (type) {
293
293
  * @returns {AssetLoader|undefined}
294
294
  */
295
295
  AssetManager.prototype.getLoaderByType = function (type) {
296
- assert.typeOf(type, 'string', 'type');
296
+ assert.isString(type, 'type');
297
297
 
298
298
  return this.loaders[type];
299
299
  };
@@ -305,9 +305,20 @@ AssetManager.prototype.getLoaderByType = function (type) {
305
305
  * @throws if a loader is already registered for the given type
306
306
  */
307
307
  AssetManager.prototype.registerLoader = async function (type, loader) {
308
+ assert.isString(type, 'type');
309
+
310
+ const existing_loader = this.getLoaderByType(type);
308
311
 
309
- if (this.getLoaderByType(type) !== undefined) {
310
- throw new Error(`Loader for type '${type}' is already registered`);
312
+ if (existing_loader !== undefined) {
313
+ if (existing_loader === loader) {
314
+ // all is well, already registered
315
+ return existing_loader;
316
+ } else if (existing_loader.__proto__ === loader.__proto__) {
317
+ console.warn(`Another instance of this loader is already registered for type '${type}'. Ignoring.`);
318
+ return existing_loader;
319
+ } else {
320
+ throw new Error(`Loader for type '${type}' is already registered`);
321
+ }
311
322
  }
312
323
 
313
324
  if (typeof loader === "function") {
@@ -17,7 +17,7 @@ export class CodecWithFallback extends Codec {
17
17
  async decode(data) {
18
18
 
19
19
  try {
20
- return this.main.decode(data);
20
+ return await this.main.decode(data);
21
21
  } catch (e) {
22
22
  logger.warn(`Main codec failed, will attempt fallback. Error: ${e}`);
23
23
 
@@ -7,19 +7,6 @@ import { PNG } from './PNG.js';
7
7
  import { BinaryBuffer } from "../../../../../core/binary/BinaryBuffer.js";
8
8
  import { isArrayEqualStrict } from "../../../../../core/collection/array/isArrayEqualStrict.js";
9
9
 
10
- var inflate = function (data, callback) {
11
- let result;
12
-
13
- try {
14
- result = zlib.inflate(new Uint8Array(data));
15
-
16
- callback(null, result);
17
- } catch (e) {
18
- callback(e);
19
- }
20
-
21
- };
22
-
23
10
  function readUInt32(buffer, offset) {
24
11
  return (buffer[offset] << 24) +
25
12
  (buffer[offset + 1] << 16) +
@@ -294,11 +281,14 @@ PNGReader.prototype.unFilterNone = function (scanline, scanline_offset, pixels,
294
281
  PNGReader.prototype.unFilterSub = function (scanline, scanline_offset, pixels, bpp, of, length) {
295
282
  var i = 0;
296
283
 
297
- for (; i < bpp; i++) pixels[of + i] = scanline[i + scanline_offset];
284
+ for (; i < bpp; i++) {
285
+ pixels[of + i] = scanline[i + scanline_offset];
286
+ }
298
287
 
299
288
  for (; i < length; i++) {
300
289
  // Raw(x) + Raw(x - bpp)
301
- pixels[of + i] = (scanline[i + scanline_offset] + pixels[of + i - bpp]) & 0xFF;
290
+ const of_i = of + i;
291
+ pixels[of_i] = (scanline[i + scanline_offset] + pixels[of_i - bpp]) & 0xFF;
302
292
  }
303
293
  };
304
294
 
@@ -336,19 +326,26 @@ PNGReader.prototype.unFilterAverage = function (scanline, scanline_offset, pixel
336
326
  }
337
327
  // Prior(x) == 0 && Raw(x - bpp) != 0 (right shift, prevent doubles)
338
328
  for (; i < length; i++) {
339
- pixels[of + i] = (scanline[i + scanline_offset] + (pixels[of + i - bpp] >> 1)) & 0xFF;
329
+ const of_i = of + i;
330
+ pixels[of_i] = (scanline[i + scanline_offset] + (pixels[of_i - bpp] >> 1)) & 0xFF;
340
331
  }
341
332
  } else {
342
333
  // Prior(x) != 0 && Raw(x - bpp) == 0
343
334
  for (; i < bpp; i++) {
344
- pixels[of + i] = (scanline[i + scanline_offset] + (pixels[of - length + i] >> 1)) & 0xFF;
335
+ const of_i = of + i;
336
+
337
+ pixels[of_i] = (scanline[i + scanline_offset] + (pixels[of_i - length] >> 1)) & 0xFF;
345
338
  }
346
339
  // Prior(x) != 0 && Raw(x - bpp) != 0
347
340
  for (; i < length; i++) {
348
341
  byte = scanline[i + scanline_offset];
349
- prev = pixels[of + i - bpp];
350
- prior = pixels[of + i - length];
351
- pixels[of + i] = (byte + (prev + prior >> 1)) & 0xFF;
342
+
343
+ const of_i = of + i;
344
+
345
+ prev = pixels[of_i - bpp];
346
+ prior = pixels[of_i - length];
347
+
348
+ pixels[of_i] = (byte + (prev + prior >> 1)) & 0xFF;
352
349
  }
353
350
  }
354
351
  };
@@ -387,10 +384,11 @@ PNGReader.prototype.unFilterPaeth = function (scanline, scanline_offset, pixels,
387
384
  pixels[of + i] = (scanline[i + scanline_offset] + pixels[of + i - bpp]) & 0xFF;
388
385
  }
389
386
  } else {
387
+ const of1 = of - length;
390
388
  // Prior(x) != 0 && Raw(x - bpp) == 0
391
389
  // paethPredictor(x, 0, 0) is always x
392
390
  for (; i < bpp; i++) {
393
- pixels[of + i] = (scanline[i + scanline_offset] + pixels[of + i - length]) & 0xFF;
391
+ pixels[of + i] = (scanline[i + scanline_offset] + pixels[of1 + i]) & 0xFF;
394
392
  }
395
393
  // Prior(x) != 0 && Raw(x - bpp) != 0
396
394
  for (; i < length; i++) {
@@ -699,6 +699,16 @@ EntityManager.prototype.startSystem = function (system, successCallback, errorCa
699
699
  * @param {function} errorCallback executed if entity manager encounters an error during startup
700
700
  */
701
701
  EntityManager.prototype.startup = function (readyCallback, errorCallback) {
702
+ if (this.state === EntityManagerState.Starting) {
703
+ throw new IllegalStateException(`System is currently in starting state`);
704
+ }
705
+
706
+ if (this.state === EntityManagerState.Running) {
707
+ // already running, do nothing
708
+ readyCallback();
709
+ return;
710
+ }
711
+
702
712
  assert.isFunction(readyCallback, 'readyCallback');
703
713
  assert.isFunction(errorCallback, 'errorCallback');
704
714
 
@@ -224,7 +224,14 @@ export class TerrainOverlay {
224
224
 
225
225
  const ctx = this.context2d;
226
226
 
227
- const imageData = ctx.createImageData(this.size.x, this.size.y);
227
+ const size = this.size;
228
+
229
+ if (size.x === 0 || size.y === 0) {
230
+ // nothing to write
231
+ return;
232
+ }
233
+
234
+ const imageData = ctx.createImageData(size.x, size.y);
228
235
 
229
236
  const array = imageData.data;
230
237
 
@@ -1,4 +1,4 @@
1
- import TopDownCameraController from "../ecs/camera/topdown/TopDownCameraController.js";
1
+ import TopDownCameraController, { rotate_from_view } from "../ecs/camera/topdown/TopDownCameraController.js";
2
2
  import InputController from "../../input/ecs/components/InputController.js";
3
3
  import { decodeMouseEventButtons } from "../../input/devices/PointerDevice.js";
4
4
  import EntityBuilder from "../../ecs/EntityBuilder.js";
@@ -34,8 +34,7 @@ export function makeOrbitalCameraController({
34
34
 
35
35
  const cameraController = getCameraController();
36
36
 
37
- cameraController.yaw += delta.x * sensitivity;
38
- cameraController.pitch -= delta.y * sensitivity;
37
+ rotate_from_view(delta.x * sensitivity, delta.y * sensitivity, cameraController, cameraController);
39
38
  }
40
39
 
41
40
  /**
@@ -0,0 +1,21 @@
1
+ import Quaternion from "../../../../../core/geom/Quaternion.js";
2
+ import Vector3 from "../../../../../core/geom/Vector3.js";
3
+
4
+ const q = new Quaternion();
5
+
6
+ /**
7
+ *
8
+ * @param {number} yaw
9
+ * @param {number} pitch
10
+ * @param roll
11
+ * @param {Vector3} result
12
+ */
13
+ export function computeCameraFacingVector(yaw, pitch, roll, result) {
14
+ q.__setFromEuler(pitch, yaw, roll, 'ZYX');
15
+ q.normalize();
16
+
17
+ result.copy(Vector3.forward);
18
+ result.applyQuaternion(q);
19
+ result.normalize();
20
+
21
+ }
@@ -28,4 +28,6 @@ export default class TopDownCameraController {
28
28
  public fromJSON(j: any): void
29
29
 
30
30
  static pan(delta: Vector2, object: Object3D, element: Element, targetDistance: number, fov: number, result: Vector3, multiplier?: Vector3): void
31
+
32
+ static rotate(delta_x: number, delta_y: number, input: TopDownCameraController, output: TopDownCameraController): void
31
33
  }
@@ -10,9 +10,34 @@ import { Euler, Matrix4 } from "three";
10
10
 
11
11
  const m4 = new Matrix4();
12
12
  const euler = new Euler();
13
+ const scratch_vector3 = new Vector3();
13
14
 
14
15
  const panOffset = new Vector3();
15
16
 
17
+ /**
18
+ *
19
+ * @param {number} displacement_x
20
+ * @param {number} displacement_y
21
+ * @param {TopDownCameraController} input
22
+ * @param {TopDownCameraController} output rotation delta
23
+ */
24
+ export function rotate_from_view(displacement_x, displacement_y, input, output) {
25
+
26
+ euler.set(input.pitch, input.yaw, input.roll)
27
+ m4.makeRotationFromEuler(euler);
28
+
29
+ const up = scratch_vector3;
30
+ scratch_vector3.copy(Vector3.up);
31
+
32
+ up.applyMatrix4_three(m4);
33
+
34
+ // detect when camera is upside-down
35
+ const y_multiplier = up.y <= 0 ? -1 : 1;
36
+
37
+ output.pitch -= displacement_y;
38
+ output.yaw += displacement_x * y_multiplier;
39
+ }
40
+
16
41
  /**
17
42
  * pass in distance in world space to move left
18
43
  * @param {number} distance
@@ -236,6 +261,7 @@ class TopDownCameraController {
236
261
  TopDownCameraController.typeName = "TopDownCameraController";
237
262
 
238
263
  TopDownCameraController.pan = pan;
264
+ TopDownCameraController.rotate = rotate_from_view;
239
265
 
240
266
  export default TopDownCameraController;
241
267
 
@@ -13,7 +13,6 @@ import { System } from '../../../../ecs/System.js';
13
13
  import TopDownCameraController from './TopDownCameraController.js';
14
14
 
15
15
  import { Euler as ThreeEuler } from 'three';
16
- import Quaternion from "../../../../../core/geom/Quaternion.js";
17
16
 
18
17
 
19
18
  const v3_scratch = new Vector3();
@@ -74,25 +73,6 @@ export function computeTopDownTransform(control, result) {
74
73
  result.position.copy(v3_scratch);
75
74
  }
76
75
 
77
- const q = new Quaternion();
78
-
79
- /**
80
- *
81
- * @param {number} yaw
82
- * @param {number} pitch
83
- * @param roll
84
- * @param {Vector3} result
85
- */
86
- export function computeCameraFacingVector(yaw, pitch, roll, result) {
87
- q.__setFromEuler(pitch, yaw, roll, 'ZYX');
88
- q.normalize();
89
-
90
- result.copy(Vector3.forward);
91
- result.applyQuaternion(q);
92
- result.normalize();
93
-
94
- }
95
-
96
76
  /**
97
77
  *
98
78
  * @param {Transform} transform
@@ -123,11 +103,11 @@ export function setCameraControllerFromTransform(transform, controller, distance
123
103
 
124
104
  controller.distance = distance;
125
105
 
126
- const targetOffset = direction.clone()
127
- .multiplyScalar(controller.distance);
106
+ const targetOffset = direction.clone();
107
+ targetOffset.multiplyScalar(controller.distance);
128
108
 
129
- const target = transform.position.clone()
130
- .sub(targetOffset);
109
+ const target = transform.position.clone();
110
+ target.sub(targetOffset);
131
111
 
132
112
  controller.target.copy(target)
133
113
  }
@@ -1,9 +1,5 @@
1
1
  import { Transform } from "../../../ecs/transform/Transform.js";
2
- import { copyToVector3 } from "./copyToVector3.js";
3
- import { setThreeObjectRotation } from "./setThreeObjectRotation.js";
4
2
  import { setTransform } from "./setTransform.js";
5
- import { updateMeshTransform } from "./updateMeshTransform.js";
6
- import { updateNodeByTransformAndBBB } from "./updateNodeByTransformAndBBB.js";
7
3
 
8
4
  /**
9
5
  * @readonly
@@ -27,10 +23,12 @@ export function applyTransform(component, transform) {
27
23
  */
28
24
  let _t;
29
25
 
30
- if (component.asset.has_root_transform) {
26
+ const asset = component.asset;
27
+
28
+ if (asset.has_root_transform) {
31
29
  _t = scratch_transform;
32
30
 
33
- _t.multiplyTransforms(component.asset.root_transform, transform);
31
+ _t.multiplyTransforms(transform, asset.root_transform);
34
32
 
35
33
  // console.log("root transform");
36
34
  } else {
@@ -38,4 +36,4 @@ export function applyTransform(component, transform) {
38
36
  }
39
37
 
40
38
  setTransform(_t, component);
41
- }
39
+ }
@@ -132,6 +132,7 @@ ParticularEngine.prototype.advanceEmitter = function (emitter, timeDelta) {
132
132
 
133
133
  const step = steps[type];
134
134
 
135
+ step.emitter = emitter;
135
136
  step.timeDelta = timeDelta;
136
137
  step.particles = emitter.particles;
137
138
  step.layer_parameters[j] = stepDefinition.parameters;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @readonly
3
+ * @enum {number}
4
+ */
5
+ export const EmissionFromType = {
6
+ Shell: 0,
7
+ Volume: 1
8
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @readonly
3
+ * @enum {number}
4
+ */
5
+ export const EmissionShapeType = {
6
+ Sphere: 0,
7
+ Box: 1,
8
+ Point: 3
9
+ };
@@ -3,7 +3,10 @@ export const PARTICLE_ATTRIBUTE_AGE = 1;
3
3
  export const PARTICLE_ATTRIBUTE_DEATH_AGE = 2;
4
4
  export const PARTICLE_ATTRIBUTE_UV = 3;
5
5
  export const PARTICLE_ATTRIBUTE_SIZE = 4;
6
+ export const PARTICLE_ATTRIBUTE_SIZE_INITIAL = 11;
6
7
  export const PARTICLE_ATTRIBUTE_LAYER_POSITION = 5;
7
8
  export const PARTICLE_ATTRIBUTE_VELOCITY = 6;
8
9
  export const PARTICLE_ATTRIBUTE_ROTATION = 7;
9
10
  export const PARTICLE_ATTRIBUTE_ROTATION_SPEED = 8;
11
+ export const PARTICLE_ATTRIBUTE_COLOR = 9;
12
+ export const PARTICLE_ATTRIBUTE_BLEND = 10;
@@ -4,13 +4,6 @@ import { lerp } from "../../../../../../core/math/lerp.js";
4
4
  import { max2 } from "../../../../../../core/math/max2.js";
5
5
  import { min2 } from "../../../../../../core/math/min2.js";
6
6
  import { ParticleAttributeType, ParticleDataType } from "../../group/ParticleGroup.js";
7
- import {
8
- randomPointInBox,
9
- randomPointInPoint,
10
- randomPointInSphere,
11
- randomPointOnBox,
12
- randomPointOnSphere
13
- } from "../../../../../../core/geom/GeometryMath.js";
14
7
  import { Box3, BufferGeometry, Frustum, Matrix4, Points, PointsMaterial } from 'three';
15
8
  import { frustumFromCamera } from "../../../../ecs/camera/CameraSystem.js";
16
9
  import { ParticlePool } from "./ParticlePool.js";
@@ -18,28 +11,37 @@ import { ParticleParameter } from "../parameter/ParticleParameter.js";
18
11
  import { ParameterSet } from "../parameter/ParameterSet.js";
19
12
  import { assert } from "../../../../../../core/assert.js";
20
13
  import { LeafNode } from "../../../../../../core/bvh2/LeafNode.js";
21
- import { EmissionFromType, EmissionShapeType, ParticleLayer } from "./ParticleLayer.js";
14
+ import { ParticleLayer } from "./ParticleLayer.js";
22
15
  import { ParticleParameters } from "./ParticleParameters.js";
23
16
  import { BlendingType } from "../../../../texture/sampler/BlendingType.js";
24
17
  import Quaternion from "../../../../../../core/geom/Quaternion.js";
25
- import { computeHashIntegerArray} from "../../../../../../core/math/MathUtils.js";
18
+ import { computeHashIntegerArray } from "../../../../../../core/math/MathUtils.js";
26
19
  import { ParticleSpecification } from "../../group/ParticleSpecification.js";
27
20
  import { ParticleAttribute } from "../../group/ParticleAttribute.js";
28
21
  import { ParticleEmitterFlag } from "./ParticleEmitterFlag.js";
29
22
  import { AABB3 } from "../../../../../../core/bvh2/aabb3/AABB3.js";
30
23
  import {
31
24
  PARTICLE_ATTRIBUTE_AGE,
25
+ PARTICLE_ATTRIBUTE_BLEND,
32
26
  PARTICLE_ATTRIBUTE_DEATH_AGE,
33
27
  PARTICLE_ATTRIBUTE_LAYER_POSITION,
34
28
  PARTICLE_ATTRIBUTE_POSITION,
35
29
  PARTICLE_ATTRIBUTE_ROTATION,
36
30
  PARTICLE_ATTRIBUTE_ROTATION_SPEED,
37
31
  PARTICLE_ATTRIBUTE_SIZE,
32
+ PARTICLE_ATTRIBUTE_SIZE_INITIAL,
38
33
  PARTICLE_ATTRIBUTE_UV,
39
34
  PARTICLE_ATTRIBUTE_VELOCITY
40
35
  } from "./PARTICLE_ATTRIBUTES.js";
41
36
  import { composeMatrix4 } from "../../../../util/composeMatrix4.js";
42
-
37
+ import { randomPointInPoint } from "../../../../../../core/geom/random/randomPointInPoint.js";
38
+ import { randomPointInSphere } from "../../../../../../core/geom/random/randomPointInSphere.js";
39
+ import { randomPointOnSphere } from "../../../../../../core/geom/random/randomPointOnSphere.js";
40
+ import { randomPointInBox } from "../../../../../../core/geom/random/randomPointInBox.js";
41
+ import { randomPointOnBox } from "../../../../../../core/geom/random/randomPointOnBox.js";
42
+ import { EmissionFromType } from "./EmissionFromType.js";
43
+ import { EmissionShapeType } from "./EmissionShapeType.js";
44
+ import { update_parameters } from "../simulator/update_parameters.js";
43
45
 
44
46
  const EMPTY_GEOMETRY = new BufferGeometry();
45
47
 
@@ -635,7 +637,7 @@ export class ParticleEmitter {
635
637
 
636
638
  build() {
637
639
 
638
- this.particles = new ParticlePool(particleSpecification);
640
+ this.particles = new ParticlePool(PARTICULAR_PARTICLE_SPECIFICATION);
639
641
 
640
642
  //make overallocation a bit more aggressive to prevent frequent resizing
641
643
  this.particles.shrinkFactor = 0.5;
@@ -934,7 +936,10 @@ export class ParticleEmitter {
934
936
  const layerPosition = layerIndex / this.layers.length;
935
937
 
936
938
  //compute transform matrix of the emitter
937
- composeMatrix4(matrix4, this.position, this.rotation, this.scale);
939
+ const emitter_position = this.position;
940
+ const last_spawn_position = this.__lastSpawnPosition;
941
+
942
+ composeMatrix4(matrix4, emitter_position, this.rotation, this.scale);
938
943
 
939
944
  let time = -layer.timeSinceLastEmission;
940
945
 
@@ -955,9 +960,9 @@ export class ParticleEmitter {
955
960
 
956
961
  if (this.getFlag(ParticleEmitterFlag.PositionChanged)) {
957
962
  //compute position in between
958
- matrix4.elements[12] = lerp(this.position.x, this.__lastSpawnPosition.x, f);
959
- matrix4.elements[13] = lerp(this.position.y, this.__lastSpawnPosition.y, f);
960
- matrix4.elements[14] = lerp(this.position.z, this.__lastSpawnPosition.z, f);
963
+ matrix4.elements[12] = lerp(emitter_position.x, last_spawn_position.x, f);
964
+ matrix4.elements[13] = lerp(emitter_position.y, last_spawn_position.y, f);
965
+ matrix4.elements[14] = lerp(emitter_position.z, last_spawn_position.z, f);
961
966
  }
962
967
 
963
968
  //apply emitter transform
@@ -1001,17 +1006,22 @@ export class ParticleEmitter {
1001
1006
  //write particle size
1002
1007
  const size = layer.particleSize.sampleRandom(random);
1003
1008
 
1004
- particles.writeAttributeScalar(ref, PARTICLE_ATTRIBUTE_SIZE, size);
1009
+ particles.writeAttributeScalar(ref, PARTICLE_ATTRIBUTE_SIZE_INITIAL, size);
1005
1010
 
1006
1011
  //write UV
1007
1012
  const atlasPatch = layer.__atlasPatch;
1008
1013
  if (atlasPatch !== null) {
1009
1014
  const uv = atlasPatch.uv;
1010
1015
 
1011
- const u0 = uv.position.x;
1012
- const v0 = uv.position.y;
1013
- const u1 = uv.size.x;
1014
- const v1 = uv.size.y;
1016
+ const uv_position = uv.position;
1017
+
1018
+ const u0 = uv_position.x;
1019
+ const v0 = uv_position.y;
1020
+
1021
+ const uv_size = uv.size;
1022
+
1023
+ const u1 = uv_size.x;
1024
+ const v1 = uv_size.y;
1015
1025
 
1016
1026
  particles.writeAttributeVector4(ref, PARTICLE_ATTRIBUTE_UV, u0, v0, u1, v1);
1017
1027
  } else {
@@ -1019,6 +1029,10 @@ export class ParticleEmitter {
1019
1029
  }
1020
1030
 
1021
1031
  particles.writeAttributeScalar(ref, PARTICLE_ATTRIBUTE_LAYER_POSITION, layerPosition);
1032
+
1033
+ update_parameters(ref, particles, layer, initialAge / deathAge);
1034
+
1035
+ particles.writeAttributeScalar(ref,PARTICLE_ATTRIBUTE_BLEND,this.blendingMode);
1022
1036
  }
1023
1037
 
1024
1038
  //update time buffer
@@ -1116,7 +1130,7 @@ export class ParticleEmitter {
1116
1130
  //write size
1117
1131
  const size = layer.particleSize.sampleRandom(random);
1118
1132
 
1119
- particles.writeAttributeScalar(ref, PARTICLE_ATTRIBUTE_SIZE, size);
1133
+ particles.writeAttributeScalar(ref, PARTICLE_ATTRIBUTE_SIZE_INITIAL, size);
1120
1134
 
1121
1135
  //write UV
1122
1136
  const atlasPatch = layer.__atlasPatch;
@@ -1125,10 +1139,15 @@ export class ParticleEmitter {
1125
1139
  //patch exists, write it
1126
1140
  const uv = atlasPatch.uv;
1127
1141
 
1128
- const u0 = uv.position.x;
1129
- const v0 = uv.position.y;
1130
- const u1 = uv.size.x;
1131
- const v1 = uv.size.y;
1142
+ const uv_position = uv.position;
1143
+
1144
+ const u0 = uv_position.x;
1145
+ const v0 = uv_position.y;
1146
+
1147
+ const uv_size = uv.size;
1148
+
1149
+ const u1 = uv_size.x;
1150
+ const v1 = uv_size.y;
1132
1151
 
1133
1152
  particles.writeAttributeVector4(ref, PARTICLE_ATTRIBUTE_UV, u0, v0, u1, v1);
1134
1153
  } else {
@@ -1138,6 +1157,9 @@ export class ParticleEmitter {
1138
1157
 
1139
1158
  particles.writeAttributeScalar(ref, PARTICLE_ATTRIBUTE_LAYER_POSITION, layerPosition);
1140
1159
 
1160
+ update_parameters(ref, particles, layer, initialAge / deathAge);
1161
+
1162
+ particles.writeAttributeScalar(ref,PARTICLE_ATTRIBUTE_BLEND,this.blendingMode);
1141
1163
  }
1142
1164
 
1143
1165
  if (spritesNeedUpdate) {
@@ -1240,17 +1262,20 @@ const defaultPointsMaterial = new PointsMaterial({ color: 0xFFFFFF });
1240
1262
 
1241
1263
 
1242
1264
  //build particle spec
1243
- const particleSpecification = new ParticleSpecification();
1244
-
1245
- particleSpecification.add(new ParticleAttribute('position', ParticleAttributeType.Vector3, ParticleDataType.Float32));
1246
- particleSpecification.add(new ParticleAttribute('age', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1247
- particleSpecification.add(new ParticleAttribute('deathAge', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1248
- particleSpecification.add(new ParticleAttribute('atlasPatch', ParticleAttributeType.Vector4, ParticleDataType.Float32));
1249
- particleSpecification.add(new ParticleAttribute('size', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1250
- particleSpecification.add(new ParticleAttribute('layerPosition', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1251
- particleSpecification.add(new ParticleAttribute('velocity', ParticleAttributeType.Vector3, ParticleDataType.Float32));
1252
- particleSpecification.add(new ParticleAttribute('rotation', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1253
- particleSpecification.add(new ParticleAttribute('rotationSpeed', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1265
+ export const PARTICULAR_PARTICLE_SPECIFICATION = new ParticleSpecification();
1266
+
1267
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('position', ParticleAttributeType.Vector3, ParticleDataType.Float32));
1268
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('age', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1269
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('deathAge', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1270
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('atlasPatch', ParticleAttributeType.Vector4, ParticleDataType.Float32));
1271
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('size', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1272
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('layerPosition', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1273
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('velocity', ParticleAttributeType.Vector3, ParticleDataType.Float32));
1274
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('rotation', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1275
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('rotationSpeed', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1276
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('color', ParticleAttributeType.Vector4, ParticleDataType.Float32));
1277
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('blending', ParticleAttributeType.Scalar, ParticleDataType.Uint8));
1278
+ PARTICULAR_PARTICLE_SPECIFICATION.add(new ParticleAttribute('size_initial', ParticleAttributeType.Scalar, ParticleDataType.Float32));
1254
1279
 
1255
1280
 
1256
1281
  const frustum = new Frustum();
@@ -10,25 +10,8 @@ import List from "../../../../../../core/collection/list/List.js";
10
10
  import { SimulationStepType } from "../simulator/SimulationStepType.js";
11
11
  import { computeStringHash } from "../../../../../../core/primitives/strings/computeStringHash.js";
12
12
  import { computeConeBoundingBox } from "../../../../../../core/geom/3d/cone/computeConeBoundingBox.js";
13
-
14
- /**
15
- * @readonly
16
- * @enum {number}
17
- */
18
- const EmissionShapeType = {
19
- Sphere: 0,
20
- Box: 1,
21
- Point: 3
22
- };
23
-
24
- /**
25
- * @readonly
26
- * @enum {number}
27
- */
28
- const EmissionFromType = {
29
- Shell: 0,
30
- Volume: 1
31
- };
13
+ import { EmissionFromType } from "./EmissionFromType.js";
14
+ import { EmissionShapeType } from "./EmissionShapeType.js";
32
15
 
33
16
  function ParticleLayer() {
34
17
  /**
@@ -97,7 +80,16 @@ function ParticleLayer() {
97
80
  */
98
81
  this.parameterTracks = new ParameterTrackSet();
99
82
 
83
+ /**
84
+ *
85
+ * @type {Vector3}
86
+ */
100
87
  this.position = new Vector3(0, 0, 0);
88
+
89
+ /**
90
+ *
91
+ * @type {Vector3}
92
+ */
101
93
  this.scale = new Vector3(1, 1, 1);
102
94
 
103
95
  /**
@@ -127,6 +119,11 @@ function ParticleLayer() {
127
119
  this.steps = new List();
128
120
 
129
121
  this.scaledSpriteHalfSize = -1;
122
+
123
+ /**
124
+ *
125
+ * @type {AABB3}
126
+ */
130
127
  this.baseBoundingBox = new AABB3(0, 0, 0, 0, 0, 0);
131
128
  }
132
129
 
@@ -381,4 +378,4 @@ ParticleLayer.prototype.fromBinaryBuffer = function (buffer) {
381
378
  this.scaledSpriteHalfSize = -1;
382
379
  };
383
380
 
384
- export { ParticleLayer, EmissionShapeType, EmissionFromType };
381
+ export { ParticleLayer };
@@ -1,7 +1,9 @@
1
- import { EmissionFromType, EmissionShapeType, ParticleLayer } from "./ParticleLayer.js";
1
+ import { ParticleLayer } from "./ParticleLayer.js";
2
2
  import { ParameterLookupTable } from "../parameter/ParameterLookupTable.js";
3
3
  import { ParameterTrack } from "../parameter/ParameterTrack.js";
4
4
  import { BinaryBuffer } from "../../../../../../core/binary/BinaryBuffer.js";
5
+ import { EmissionFromType } from "./EmissionFromType.js";
6
+ import { EmissionShapeType } from "./EmissionShapeType.js";
5
7
 
6
8
  function sampleA() {
7
9
  const layer0 = new ParticleLayer();