@woosh/meep-engine 2.33.24 → 2.33.25

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 (74) hide show
  1. package/core/bvh2/binary/IndexedBinaryBVH.js +1 -1
  2. package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +5 -1
  3. package/core/bvh2/traversal/__detailed_box_volume_intersection.js +22 -5
  4. package/core/collection/array/binarySearchHighIndex.js +1 -1
  5. package/core/collection/array/copyArray.js +2 -2
  6. package/core/geom/3d/normal/hemioct/unit_hemioct.spec.js +1 -1
  7. package/core/geom/3d/shape/AbstractShape3D.js +9 -0
  8. package/core/geom/3d/shape/CompositeShape.js +188 -8
  9. package/core/geom/3d/shape/TransformedShape3D.js +58 -2
  10. package/core/geom/3d/shape/UnitCubeShape3D.js +11 -0
  11. package/core/geom/3d/shape/UnitSphereShape3D.js +8 -0
  12. package/core/geom/3d/shape/util/shape_to_visual_entity.js +159 -0
  13. package/core/geom/random/randomPointInSphere.js +3 -2
  14. package/core/json/resolvePathByArray.js +2 -2
  15. package/{engine/graphics/render/forward_plus/materials → core/primitives/strings}/insert_after.js +3 -0
  16. package/core/primitives/strings/insert_after_or_replace.js +27 -0
  17. package/editor/process/symbolic/makeHelperBoxGeometry.js +44 -0
  18. package/editor/view/ecs/EntityEditor.js +2 -2
  19. package/editor/view/ecs/components/particles/ParticleEmitterController.js +2 -2
  20. package/engine/EngineHarness.js +1 -0
  21. package/engine/animation/AnimationUtils.js +5 -5
  22. package/engine/ecs/EntityBuilder.js +25 -5
  23. package/engine/ecs/attachment/AttachmentBinding.js +8 -0
  24. package/engine/ecs/attachment/AttachmentSystem.js +4 -0
  25. package/engine/ecs/attachment/TransformAttachmentBinding.js +14 -44
  26. package/engine/ecs/components/Tag.js +27 -6
  27. package/engine/ecs/fow/FogOfWar.js +4 -0
  28. package/engine/ecs/fow/FogOfWarSystem.js +2 -0
  29. package/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +2 -0
  30. package/engine/ecs/system/AbstractContextSystem.js +1 -1
  31. package/engine/ecs/systems/TagSystem.js +17 -0
  32. package/engine/ecs/transform/Transform.js +19 -6
  33. package/engine/graphics/GraphicsEngine.js +11 -6
  34. package/engine/graphics/composit/CompositLayer.js +17 -4
  35. package/engine/graphics/composit/CompositingStages.js +8 -0
  36. package/engine/graphics/composit/LayerCompositer.js +35 -6
  37. package/engine/graphics/ecs/highlight/plugin/OutlineRenderPlugin.js +11 -7
  38. package/engine/graphics/ecs/light/Light.js +2 -0
  39. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +5 -1
  40. package/engine/graphics/ecs/mesh-v2/DrawMode.js +5 -0
  41. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +32 -18
  42. package/engine/graphics/particles/ParticleEmitterLibrary.js +3 -0
  43. package/engine/graphics/particles/ecs/{ParticleEmitterSystem2.js → ParticleEmitterSystem.js} +17 -9
  44. package/engine/graphics/particles/particular/engine/ParticularEngine.js +8 -2
  45. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +14 -25
  46. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitterFlag.js +5 -0
  47. package/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +90 -2
  48. package/engine/graphics/particles/particular/engine/emitter/ParticlePool.spec.js +7 -7
  49. package/engine/graphics/particles/particular/engine/renderers/billboard/BILLBOARD_PARTICLE_SPECIFICATION.js +15 -12
  50. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +262 -51
  51. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +80 -46
  52. package/engine/graphics/particles/particular/engine/shader/debugAtlas.js +14 -0
  53. package/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +141 -0
  54. package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +148 -54
  55. package/engine/graphics/particles/particular/engine/utils/volume/lut_to_sampler.js +27 -0
  56. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +542 -165
  57. package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +12 -6
  58. package/engine/graphics/render/forward_plus/materials/FP_INJECTION_POINT_ACCUMULATION.js +1 -0
  59. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +32 -0
  60. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_DECODE_PARS.js +51 -0
  61. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +25 -0
  62. package/engine/graphics/render/forward_plus/materials/fp_build_fragment_shader.js +31 -120
  63. package/engine/graphics/render/forward_plus/materials/fp_build_vertex_lighting_shared.js +35 -0
  64. package/engine/graphics/render/forward_plus/materials/fp_build_vertex_shader.js +4 -5
  65. package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +10 -3
  66. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +588 -53
  67. package/engine/graphics/render/forward_plus/prototypeLightManager.js +29 -4
  68. package/engine/graphics/shaders/TerrainShader.js +4 -5
  69. package/engine/graphics/util/composeMatrix4.js +33 -23
  70. package/engine/graphics/util/decompose_matrix_4_array.js +61 -0
  71. package/engine/intelligence/behavior/ecs/BehaviorComponent.js +30 -14
  72. package/engine/knowledge/database/StaticKnowledgeDataTable.js +6 -1
  73. package/engine/navigation/ecs/components/Path.js +0 -5
  74. package/package.json +1 -1
@@ -52,8 +52,6 @@ class LayerCompositer {
52
52
 
53
53
  layer.renderTarget.dispose();
54
54
 
55
- this.scene.remove(layer.object);
56
-
57
55
  return true;
58
56
  }
59
57
 
@@ -113,8 +111,6 @@ class LayerCompositer {
113
111
 
114
112
  this.layerTargets.push(layer);
115
113
 
116
- this.scene.add(layer.object);
117
-
118
114
  return true;
119
115
  }
120
116
 
@@ -138,13 +134,46 @@ class LayerCompositer {
138
134
 
139
135
  /**
140
136
  *
141
- * @param {WebGLRenderer} renderer
137
+ * @param {number} stage
138
+ * @private
142
139
  */
143
- composite(renderer) {
140
+ __prepare_scene_for_stage(stage) {
141
+ const layers = this.layerTargets;
142
+ const layer_count = layers.length;
143
+
144
+ const scene = this.scene;
145
+
146
+ let child_count = 0;
147
+
148
+ for (let i = 0; i < layer_count; i++) {
149
+ const layer = layers[i];
150
+
151
+ if (layer.stage !== stage) {
152
+ continue;
153
+ }
154
+
155
+ scene.children[child_count++] = layer.object;
156
+
157
+ layer.on.preRender.send0();
158
+ }
159
+
160
+ scene.children.length = child_count;
161
+ }
162
+
163
+ /**
164
+ *
165
+ * @param {THREE.WebGLRenderer} renderer
166
+ * @param {number} stage
167
+ */
168
+ composite(renderer, stage) {
169
+ assert.isNonNegativeInteger(stage, 'stage');
170
+
144
171
  if (!this.hasActiveLayers()) {
145
172
  return;
146
173
  }
147
174
 
175
+ this.__prepare_scene_for_stage(stage);
176
+
148
177
  const camera = this.camera;
149
178
  const scene = this.scene;
150
179
 
@@ -7,6 +7,7 @@ import { HighlightRenderGroup } from "../renderer/HighlightRenderGroup.js";
7
7
  import { ObjectPoolFactory } from "../../../../../core/model/object/ObjectPoolFactory.js";
8
8
  import { HighlightRenderElement } from "../renderer/HighlightRenderElement.js";
9
9
  import { noop } from "../../../../../core/function/Functions.js";
10
+ import { CompositingStages } from "../../../composit/CompositingStages.js";
10
11
 
11
12
  export class OutlineRenderPlugin extends EnginePlugin {
12
13
  constructor() {
@@ -99,12 +100,14 @@ export class OutlineRenderPlugin extends EnginePlugin {
99
100
 
100
101
  /**
101
102
  *
102
- * @param {WebGLRenderer} renderer
103
- * @param {Camera} camera
104
- * @param {ThreeScene} scene
105
103
  * @private
106
104
  */
107
- __render(renderer, camera, scene) {
105
+ __render() {
106
+ const engine = this.engine;
107
+ const graphics = engine.graphics;
108
+
109
+ const camera = graphics.camera;
110
+
108
111
  // collect elements
109
112
  const source_count = this.__sources.length;
110
113
 
@@ -139,11 +142,12 @@ export class OutlineRenderPlugin extends EnginePlugin {
139
142
 
140
143
  viewport_size.process(this.__set_viewport_size, this);
141
144
 
142
- graphics.on.preComposite.add(this.__render, this);
143
-
144
145
  // create compositing layer
145
146
  this.__compositing_layer = graphics.layerComposer.createLayer(this.__renderer.__renderTargetFinal, BlendingType.MultiplyAdd);
146
147
  this.__compositing_layer.name = "Silhouette Outline";
148
+ this.__compositing_layer.stage = CompositingStages.POST_TRANSPARENT;
149
+
150
+ this.__compositing_layer.on.preRender.add(this.__render, this);
147
151
 
148
152
 
149
153
  // set rendering resolution
@@ -156,7 +160,7 @@ export class OutlineRenderPlugin extends EnginePlugin {
156
160
 
157
161
  const graphics = this.engine.graphics;
158
162
 
159
- graphics.on.preComposite.remove(this.__render, this);
163
+ this.__compositing_layer.on.preRender.remove(this.__render, this);
160
164
 
161
165
  graphics.viewport.size.onChanged.remove(this.__set_viewport_size, this);
162
166
 
@@ -109,6 +109,8 @@ export class Light {
109
109
 
110
110
  if (json.castShadow !== undefined) {
111
111
  this.castShadow.fromJSON(json.castShadow);
112
+ } else {
113
+ this.castShadow.set(false);
112
114
  }
113
115
 
114
116
  const actual_type = this.type.getValue();
@@ -99,7 +99,8 @@ export class ThreeLightBinding extends LightBinding {
99
99
  */
100
100
  const cache = this.__system.__three_light_cache;
101
101
 
102
- threeEnsureLightObject(this.__c_light, cache);
102
+ const c_light = this.__c_light;
103
+ threeEnsureLightObject(c_light, cache);
103
104
 
104
105
  super.link(ctx);
105
106
  }
@@ -112,6 +113,9 @@ export class ThreeLightBinding extends LightBinding {
112
113
 
113
114
  cache.release(this.__three_getLight());
114
115
 
116
+ // clear bound light
117
+ this.__c_light.__threeObject = null;
118
+
115
119
  this.__shadowmap_unlink();
116
120
 
117
121
  super.unlink(ctx);
@@ -0,0 +1,5 @@
1
+ export const DrawMode = {
2
+ Triangles: 0,
3
+ Lines: 2,
4
+ LineSegments: 3
5
+ };
@@ -1,9 +1,10 @@
1
- import { Mesh, Quaternion } from "three";
1
+ import { Line, LineSegments, Mesh } from "three";
2
2
  import { updateNodeByMatrix4AndBBB } from "../mesh/updateNodeByTransformAndBBB.js";
3
3
  import { LeafNode } from "../../../../core/bvh2/LeafNode.js";
4
4
  import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
5
+ import { DrawMode } from "./DrawMode.js";
6
+ import { applyTransformToThreeObject } from "../mesh/applyTransformToThreeObject.js";
5
7
 
6
- const _q = new Quaternion();
7
8
  const _aabb3 = new AABB3();
8
9
 
9
10
  export class ShadedGeometry {
@@ -19,6 +20,12 @@ export class ShadedGeometry {
19
20
  */
20
21
  this.material = null;
21
22
 
23
+ /**
24
+ *
25
+ * @type {DrawMode|number}
26
+ */
27
+ this.mode = DrawMode.Triangles;
28
+
22
29
  /**
23
30
  *
24
31
  * @type {THREE.Object3D|null}
@@ -34,6 +41,19 @@ export class ShadedGeometry {
34
41
  this.__bvh_leaf = new LeafNode(this, 0, 0, 0, 0, 0, 0);
35
42
  }
36
43
 
44
+ __build_object() {
45
+ const mode = this.mode;
46
+ if (mode === DrawMode.Triangles) {
47
+ this.__cached_object = new Mesh(this.geometry, this.material);
48
+ } else if (mode === DrawMode.Lines) {
49
+ this.__cached_object = new Line(this.geometry, this.material);
50
+ } else if (mode === DrawMode.LineSegments) {
51
+ this.__cached_object = new LineSegments(this.geometry, this.material);
52
+ } else {
53
+ throw new Error(`Unsupported draw mode '${mode}'`);
54
+ }
55
+ }
56
+
37
57
  get bvh() {
38
58
  return this.__bvh_leaf;
39
59
  }
@@ -42,10 +62,12 @@ export class ShadedGeometry {
42
62
  *
43
63
  * @param {THREE.BufferGeometry} geometry
44
64
  * @param {THREE.Material} material
65
+ * @param draw_mode
45
66
  */
46
- from(geometry, material) {
67
+ from(geometry, material, draw_mode = DrawMode.Triangles) {
47
68
  this.geometry = geometry;
48
69
  this.material = material;
70
+ this.mode = draw_mode;
49
71
 
50
72
  // ensure that geometry has a bounding box
51
73
  if (geometry.boundingBox === null) {
@@ -53,7 +75,7 @@ export class ShadedGeometry {
53
75
  }
54
76
 
55
77
  if (this.__cached_object === null) {
56
- this.__cached_object = new Mesh(geometry, material);
78
+ this.__build_object();
57
79
  } else {
58
80
  this.__cached_object.material = material;
59
81
  this.__cached_object.geometry = geometry;
@@ -64,12 +86,13 @@ export class ShadedGeometry {
64
86
  *
65
87
  * @param geometry
66
88
  * @param material
89
+ * @param mode
67
90
  * @return {ShadedGeometry}
68
91
  */
69
- static from(geometry, material) {
92
+ static from(geometry, material, mode) {
70
93
  const r = new ShadedGeometry();
71
94
 
72
- r.from(geometry, material);
95
+ r.from(geometry, material, mode);
73
96
 
74
97
  return r;
75
98
  }
@@ -77,6 +100,7 @@ export class ShadedGeometry {
77
100
  updateTransform() {
78
101
  // update matrix
79
102
  this.__cached_object.updateMatrix();
103
+ this.__cached_object.updateMatrixWorld();
80
104
 
81
105
  // update bounds
82
106
 
@@ -116,9 +140,7 @@ export class ShadedGeometry {
116
140
  */
117
141
  setRotationByComponents(x, y, z, w) {
118
142
 
119
- _q.set(x, y, z, w);
120
-
121
- this.__cached_object.rotation.setFromQuaternion(_q);
143
+ this.__cached_object.quaternion.set(x, y, z, w);
122
144
 
123
145
  this.updateTransform();
124
146
  }
@@ -140,15 +162,7 @@ export class ShadedGeometry {
140
162
  * @param {Transform} t
141
163
  */
142
164
  applyTransform(t) {
143
- // TODO this can be optimized quite a lot
144
- const position = t.position;
145
- this.setPositionByComponents(position.x, position.y, position.z);
146
-
147
- const rotation = t.rotation;
148
- this.setRotationByComponents(rotation.x, rotation.y, rotation.z, rotation.w);
149
-
150
- const scale = t.scale;
151
- this.setScaleByComponents(scale.x, scale.y, scale.z);
165
+ applyTransformToThreeObject(this.__cached_object, t);
152
166
 
153
167
  this.updateTransform();
154
168
  }
@@ -2,6 +2,9 @@ import { ParticleEmitter } from "./particular/engine/emitter/ParticleEmitter.js"
2
2
  import { GameAssetType } from "../../asset/GameAssetType.js";
3
3
  import { assert } from "../../../core/assert.js";
4
4
 
5
+ /**
6
+ * @deprecated Use "Effect" API to achieve the same results
7
+ */
5
8
  export class ParticleEmitterLibrary {
6
9
  /**
7
10
  *
@@ -8,6 +8,7 @@ import { ParticleEmitterLibrary } from "../ParticleEmitterLibrary.js";
8
8
  import { GameAssetType } from "../../../asset/GameAssetType.js";
9
9
  import { ImageRGBADataLoader } from "../../../asset/loaders/image/ImageRGBADataLoader.js";
10
10
  import { StandardFrameBuffers } from "../../StandardFrameBuffers.js";
11
+ import { assert } from "../../../../core/assert.js";
11
12
 
12
13
  /**
13
14
  *
@@ -28,36 +29,38 @@ function putEmitterToSleep(emitter) {
28
29
  emitter.setFlag(ParticleEmitterFlag.Sleeping);
29
30
  }
30
31
 
31
- export class ParticleEmitterSystem2 extends System {
32
+ export class ParticleEmitterSystem extends System {
32
33
  /**
33
34
  *
34
35
  * @extends {System.<ParticleEmitter>}
35
36
  * @constructor
36
- * @param {AssetManager} assetManager
37
- * @param {GraphicsEngine} graphicsEngine
37
+ * @param {Engine} engine
38
38
  */
39
- constructor(assetManager, graphicsEngine) {
39
+ constructor(engine) {
40
40
  super();
41
41
 
42
+ assert.defined(engine, 'engine');
43
+ assert.equal(engine.isEngine, true, 'engine.isEngine !== true');
44
+
42
45
  this.dependencies = [ParticleEmitter, Transform];
43
46
 
44
47
  /**
45
48
  *
46
49
  * @type {GraphicsEngine}
47
50
  */
48
- this.graphicsEngine = graphicsEngine;
51
+ this.graphicsEngine = engine.graphics;
49
52
 
50
53
  /**
51
54
  *
52
55
  * @type {AssetManager}
53
56
  */
54
- this.assetManager = assetManager;
57
+ this.assetManager = engine.assetManager;
55
58
 
56
59
  /**
57
60
  *
58
61
  * @type {ParticularEngine}
59
62
  */
60
- this.particleEngine = new ParticularEngine(assetManager);
63
+ this.particleEngine = new ParticularEngine(engine.assetManager, engine.graphics.getMaterialManager());
61
64
 
62
65
  /**
63
66
  *
@@ -72,14 +75,19 @@ export class ParticleEmitterSystem2 extends System {
72
75
  this.bvh = null;
73
76
 
74
77
  /**
75
- *
78
+ * @deprecated Use "Effect" API to achieve the same results
76
79
  * @type {ParticleEmitterLibrary}
77
80
  */
78
- this.library = new ParticleEmitterLibrary(assetManager);
81
+ this.__library = new ParticleEmitterLibrary(engine.assetManager);
79
82
 
80
83
  this.__handlers = [];
81
84
  }
82
85
 
86
+ get library() {
87
+ console.warn('Deprecated, use "Effect" API to achieve the same results');
88
+ return this.__library;
89
+ }
90
+
83
91
  get componentClass() {
84
92
  return ParticleEmitter;
85
93
  }
@@ -8,8 +8,14 @@ import { SimulationStepApplyForce } from "./simulator/SimulationStepApplyForce.j
8
8
  import { SimulationStepCurlNoiseVelocity } from "./simulator/SimulationStepCurlNoiseVelocity.js";
9
9
 
10
10
 
11
- function ParticularEngine(assetManager) {
12
- this.shaderManager = new ShaderManager(assetManager);
11
+ /**
12
+ *
13
+ * @param {AssetManager} assetManager
14
+ * @param {MaterialManager} material_manager
15
+ * @constructor
16
+ */
17
+ function ParticularEngine(assetManager, material_manager) {
18
+ this.shaderManager = new ShaderManager(assetManager, material_manager);
13
19
 
14
20
  /**
15
21
  *
@@ -272,6 +272,7 @@ export class ParticleEmitter {
272
272
  softDepth: !this.getFlag(ParticleEmitterFlag.DepthSoftDisabled),
273
273
  velocityAlign: this.getFlag(ParticleEmitterFlag.AlignOnVelocity),
274
274
  depthSort: this.getFlag(ParticleEmitterFlag.DepthSorting),
275
+ receiveLight: this.getFlag(ParticleEmitterFlag.Lit),
275
276
  blendingMode: this.blendingMode,
276
277
  layers: this.layers.toJSON()
277
278
  };
@@ -330,6 +331,12 @@ export class ParticleEmitter {
330
331
  this.writeFlag(ParticleEmitterFlag.DepthSorting, true);
331
332
  }
332
333
 
334
+ if (typeof json.receiveLight === "boolean") {
335
+ this.writeFlag(ParticleEmitterFlag.Lit, json.receiveLight);
336
+ } else {
337
+ this.clearFlag(ParticleEmitterFlag.Lit);
338
+ }
339
+
333
340
  this.layers.fromJSON(json.layers, ParticleLayer);
334
341
 
335
342
  this.writeFlag(ParticleEmitterFlag.Built, false);
@@ -484,33 +491,15 @@ export class ParticleEmitter {
484
491
  //retire dead particles
485
492
  const particles = this.particles;
486
493
 
487
- const liveParticleCount = particles.size();
494
+ particles.computeAttributeVector3AxisAlignedBoundingBox(PARTICLE_ATTRIBUTE_POSITION, scratch_array);
488
495
 
489
- let bounds_x0 = Infinity;
490
- let bounds_y0 = Infinity;
491
- let bounds_z0 = Infinity;
496
+ let bounds_x0 = scratch_array[0];
497
+ let bounds_y0 = scratch_array[1];
498
+ let bounds_z0 = scratch_array[2];
492
499
 
493
- let bounds_x1 = -Infinity;
494
- let bounds_y1 = -Infinity;
495
- let bounds_z1 = -Infinity;
496
-
497
- for (let i = 0; i < liveParticleCount; i++) {
498
-
499
- particles.readAttributeVector3(i, PARTICLE_ATTRIBUTE_POSITION, position);
500
-
501
- const p_x = position[0];
502
- const p_y = position[1];
503
- const p_z = position[2];
504
-
505
- //update bounds
506
- bounds_x0 = min2(bounds_x0, p_x);
507
- bounds_y0 = min2(bounds_y0, p_y);
508
- bounds_z0 = min2(bounds_z0, p_z);
509
-
510
- bounds_x1 = max2(bounds_x1, p_x);
511
- bounds_y1 = max2(bounds_y1, p_y);
512
- bounds_z1 = max2(bounds_z1, p_z);
513
- }
500
+ let bounds_x1 = scratch_array[3];
501
+ let bounds_y1 = scratch_array[4];
502
+ let bounds_z1 = scratch_array[5];
514
503
 
515
504
  //expand bounds by maximum sprite size
516
505
  const extents = this.computeSpriteMaxHalfSize();
@@ -59,4 +59,9 @@ export const ParticleEmitterFlag = {
59
59
  * Rotation of each particle will adjusted to world velocity vector
60
60
  */
61
61
  AlignOnVelocity: 8192,
62
+
63
+ /**
64
+ * Whether or not the particle should respond to lights
65
+ */
66
+ Lit: 16384
62
67
  };
@@ -5,6 +5,8 @@ import ObservedValue from "../../../../../../core/model/ObservedValue.js";
5
5
  import { typed_array_copy } from "../../../../../../core/collection/array/typed/typed_array_copy.js";
6
6
  import { assert } from "../../../../../../core/assert.js";
7
7
  import { compute_typed_array_constructor_from_data_type } from "../../../../../../core/collection/table/DataType2TypedArrayConstructorMapping.js";
8
+ import { min2 } from "../../../../../../core/math/min2.js";
9
+ import { max2 } from "../../../../../../core/math/max2.js";
8
10
 
9
11
  const SHRINK_THRESHOLD = 64;
10
12
  const GROW_MIN_STEP = 32;
@@ -218,11 +220,11 @@ export class ParticlePool {
218
220
  const addressA = offsetA + j;
219
221
  const addressB = offsetB + j;
220
222
 
221
- const elementA = array[addressA];
223
+ const temp = array[addressA];
222
224
 
223
225
  array[addressA] = array[addressB];
224
226
 
225
- array[addressB] = elementA;
227
+ array[addressB] = temp;
226
228
  }
227
229
  }
228
230
  }
@@ -505,6 +507,92 @@ export class ParticlePool {
505
507
  array[address + 3] = w;
506
508
  }
507
509
 
510
+ /**
511
+ * Write the same attribute value for every particle.
512
+ * Assumes particles are packed (no holes).
513
+ * @param {number} attribute_index
514
+ * @param {number[]|Float32Array|Uint8Array|Uint16Array|Int8Array|Int32Array} value
515
+ */
516
+ writeAttributeForAllArray(attribute_index, value) {
517
+ const attribute = this.attributes[attribute_index];
518
+
519
+ const itemSize = attribute.itemSize;
520
+
521
+ if (value.length < itemSize) {
522
+ throw new Error(`Argument underflow, attribute.itemSize is '${itemSize}', but supplier argument's length is '${value.length}'`);
523
+ }
524
+
525
+ const n = this.size();
526
+
527
+ const destination = attribute.array;
528
+
529
+ let k;
530
+ for (let i = 0; i < n; i++) {
531
+ const offset = i * itemSize;
532
+
533
+ for (k = 0; k < itemSize; k++) {
534
+ destination[offset + k] = value[k];
535
+ }
536
+ }
537
+
538
+ // mark for update
539
+ attribute.needsUpdate = true;
540
+ attribute.updateRange.count = n;
541
+ attribute.updateRange.offset = 0;
542
+ }
543
+
544
+ /**
545
+ *
546
+ * @param {number} attribute_index
547
+ * @param {number[]} result
548
+ */
549
+ computeAttributeVector3AxisAlignedBoundingBox(attribute_index, result) {
550
+ const attribute = this.attributes[attribute_index];
551
+ const item_size = attribute.itemSize;
552
+
553
+ if (item_size !== 3) {
554
+ throw new Error(`Attribute item_size is expected to be 3, instead was '${item_size}'`);
555
+ }
556
+
557
+ let bounds_x0 = Infinity;
558
+ let bounds_y0 = Infinity;
559
+ let bounds_z0 = Infinity;
560
+
561
+ let bounds_x1 = -Infinity;
562
+ let bounds_y1 = -Infinity;
563
+ let bounds_z1 = -Infinity;
564
+
565
+ const particle_count = this.size();
566
+
567
+ const data = attribute.array;
568
+
569
+ for (let i = 0; i < particle_count; i++) {
570
+ const particle_address = i * 3;
571
+
572
+ const x = data[particle_address];
573
+ const y = data[particle_address + 1];
574
+ const z = data[particle_address + 2];
575
+
576
+ bounds_x0 = min2(bounds_x0, x);
577
+ bounds_y0 = min2(bounds_y0, y);
578
+ bounds_z0 = min2(bounds_z0, z);
579
+
580
+ bounds_x1 = max2(bounds_x1, x);
581
+ bounds_y1 = max2(bounds_y1, y);
582
+ bounds_z1 = max2(bounds_z1, z);
583
+ }
584
+
585
+ // read out
586
+ result[0] = bounds_x0;
587
+ result[1] = bounds_y0;
588
+ result[2] = bounds_z0;
589
+
590
+ result[3] = bounds_x1;
591
+ result[4] = bounds_y1;
592
+ result[5] = bounds_z1;
593
+
594
+ }
595
+
508
596
  dispose() {
509
597
  const bufferGeometry = this.geometry.getValue();
510
598
 
@@ -1,17 +1,17 @@
1
1
  import { ParticlePool } from "./ParticlePool.js";
2
- import { ParticleSpecification } from "../../group/ParticleSpecification.js";
3
- import { ParticleAttribute } from "../../group/ParticleAttribute.js";
4
- import { ParticleDataType } from "../../group/ParticleDataType.js";
5
- import { ParticleAttributeType } from "../../group/ParticleAttributeType.js";
2
+ import { VertexDataSpec } from "../../../../geometry/VertexDataSpec.js";
3
+ import { DataType } from "../../../../../../core/collection/table/DataType.js";
4
+ import { AttributeSpec } from "../../../../geometry/AttributeSpec.js";
6
5
 
7
6
  /**
8
7
  *
9
8
  * @returns {ParticlePool}
10
9
  */
11
10
  function samplePool() {
12
- const specification = new ParticleSpecification();
13
- specification.add(new ParticleAttribute('a', ParticleAttributeType.Scalar, ParticleDataType.Float32));
14
- specification.add(new ParticleAttribute('b', ParticleAttributeType.Vector4, ParticleDataType.Float32));
11
+ const specification = new VertexDataSpec();
12
+
13
+ specification.add(AttributeSpec.fromJSON({name:'a', type:DataType.Float32, itemSize:1}));
14
+ specification.add(AttributeSpec.fromJSON({name:'b', type:DataType.Float32, itemSize:4}));
15
15
 
16
16
  const pool = new ParticlePool(specification);
17
17
 
@@ -1,7 +1,6 @@
1
- import { ParticleSpecification } from "../../../group/ParticleSpecification.js";
2
- import { ParticleAttribute } from "../../../group/ParticleAttribute.js";
3
- import { ParticleAttributeType } from "../../../group/ParticleAttributeType.js";
4
- import { ParticleDataType } from "../../../group/ParticleDataType.js";
1
+ import { VertexDataSpec } from "../../../../../geometry/VertexDataSpec.js";
2
+ import { AttributeSpec } from "../../../../../geometry/AttributeSpec.js";
3
+ import { DataType } from "../../../../../../../core/collection/table/DataType.js";
5
4
 
6
5
  export const BILLBOARD_PARTICLE_ATTRIBUTE_POSITION = 0;
7
6
  export const BILLBOARD_PARTICLE_ATTRIBUTE_UV = 1;
@@ -10,12 +9,16 @@ export const BILLBOARD_PARTICLE_ATTRIBUTE_VELOCITY = 3;
10
9
  export const BILLBOARD_PARTICLE_ATTRIBUTE_COLOR = 5;
11
10
  export const BILLBOARD_PARTICLE_ATTRIBUTE_BLEND = 6;
12
11
 
13
- export const BILLBOARD_PARTICLE_SPECIFICATION = new ParticleSpecification();
12
+ export const BILLBOARD_PARTICLE_SPECIFICATION = new VertexDataSpec();
14
13
 
15
- BILLBOARD_PARTICLE_SPECIFICATION.add(new ParticleAttribute('position', ParticleAttributeType.Vector3, ParticleDataType.Float32));
16
- BILLBOARD_PARTICLE_SPECIFICATION.add(new ParticleAttribute('atlasPatch', ParticleAttributeType.Vector4, ParticleDataType.Float32));
17
- BILLBOARD_PARTICLE_SPECIFICATION.add(new ParticleAttribute('size', ParticleAttributeType.Scalar, ParticleDataType.Float32));
18
- BILLBOARD_PARTICLE_SPECIFICATION.add(new ParticleAttribute('velocity', ParticleAttributeType.Vector3, ParticleDataType.Float32));
19
- BILLBOARD_PARTICLE_SPECIFICATION.add(new ParticleAttribute('rotation', ParticleAttributeType.Scalar, ParticleDataType.Float32));
20
- BILLBOARD_PARTICLE_SPECIFICATION.add(new ParticleAttribute('color', ParticleAttributeType.Vector4, ParticleDataType.Float32));
21
- BILLBOARD_PARTICLE_SPECIFICATION.add(new ParticleAttribute('blending', ParticleAttributeType.Scalar, ParticleDataType.Uint8));
14
+ BILLBOARD_PARTICLE_SPECIFICATION.add(AttributeSpec.fromJSON({ name: 'position', itemSize: 3, type: DataType.Float32 }));
15
+ BILLBOARD_PARTICLE_SPECIFICATION.add(AttributeSpec.fromJSON({
16
+ name: 'atlasPatch',
17
+ itemSize: 4,
18
+ type: DataType.Float32
19
+ }));
20
+ BILLBOARD_PARTICLE_SPECIFICATION.add(AttributeSpec.fromJSON({ name: 'size', itemSize: 1, type: DataType.Float32 }));
21
+ BILLBOARD_PARTICLE_SPECIFICATION.add(AttributeSpec.fromJSON({ name: 'velocity', itemSize: 3, type: DataType.Float32 }));
22
+ BILLBOARD_PARTICLE_SPECIFICATION.add(AttributeSpec.fromJSON({ name: 'rotation', itemSize: 1, type: DataType.Float32 }));
23
+ BILLBOARD_PARTICLE_SPECIFICATION.add(AttributeSpec.fromJSON({ name: 'color', itemSize: 1, type: DataType.Float32 }));
24
+ BILLBOARD_PARTICLE_SPECIFICATION.add(AttributeSpec.fromJSON({ name: 'blending', itemSize: 1, type: DataType.Uint8 }));