@woosh/meep-engine 2.33.24 → 2.33.28

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 (126) hide show
  1. package/core/binary/BitSet.js +151 -167
  2. package/core/binary/BitSet.spec.js +99 -1
  3. package/core/binary/ValidatingBitSetWrapper.js +81 -0
  4. package/core/bvh2/aabb3/AABB3.js +3 -10
  5. package/core/bvh2/binary/IndexedBinaryBVH.js +1 -1
  6. package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +5 -1
  7. package/core/bvh2/traversal/__detailed_box_volume_intersection.js +22 -5
  8. package/core/cache/Cache.d.ts +4 -2
  9. package/core/cache/Cache.js +5 -2
  10. package/core/collection/HashMap.d.ts +9 -2
  11. package/core/collection/HashSet.d.ts +7 -2
  12. package/core/collection/HashSet.js +7 -2
  13. package/core/collection/array/binarySearchHighIndex.js +1 -1
  14. package/core/collection/array/copyArray.js +2 -2
  15. package/core/collection/array/typed/typed_array_copy.js +1 -1
  16. package/core/geom/3d/frustum/array_setFromProjectionMatrix.js +3 -3
  17. package/core/geom/3d/normal/hemioct/unit_hemioct.spec.js +1 -1
  18. package/core/geom/3d/shape/AbstractShape3D.js +37 -1
  19. package/core/geom/3d/shape/TransformedShape3D.js +121 -10
  20. package/core/geom/3d/shape/TransformedShape3D.spec.js +33 -0
  21. package/core/geom/3d/shape/UnionShape3D.js +255 -0
  22. package/core/geom/3d/shape/UnitCubeShape3D.js +88 -0
  23. package/core/geom/3d/shape/UnitCubeShape3D.spec.js +42 -0
  24. package/core/geom/3d/shape/UnitSphereShape3D.js +39 -0
  25. package/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +48 -0
  26. package/core/geom/3d/shape/util/shape_to_visual_entity.js +159 -0
  27. package/core/geom/random/randomPointInSphere.js +3 -2
  28. package/core/json/resolvePathByArray.js +2 -2
  29. package/core/model/ObservedBoolean.d.ts +2 -0
  30. package/core/parser/simple/Token.d.ts +13 -0
  31. package/core/parser/simple/Token.js +61 -27
  32. package/{engine/graphics/render/forward_plus/materials → core/primitives/strings}/insert_after.js +3 -0
  33. package/core/primitives/strings/insert_after_or_replace.js +27 -0
  34. package/editor/process/symbolic/makeHelperBoxGeometry.js +44 -0
  35. package/editor/tools/FoliagePaintTool.js +4 -4
  36. package/editor/view/ecs/EntityEditor.js +2 -2
  37. package/editor/view/ecs/components/particles/ParticleEmitterController.js +2 -2
  38. package/engine/EngineHarness.js +1 -0
  39. package/engine/animation/AnimationUtils.js +5 -5
  40. package/engine/asset/loaders/GLTFAssetLoader.js +52 -1
  41. package/engine/asset/loaders/image/ImageDecoderWorker.js +4 -3
  42. package/engine/asset/loaders/image/ImageRGBADataAsset.js +3 -2
  43. package/engine/asset/loaders/image/ImageRGBADataLoader.js +3 -3
  44. package/engine/asset/loaders/image/codec/NativeImageDecoder.js +2 -1
  45. package/engine/asset/loaders/image/png/PNG.js +113 -6
  46. package/engine/asset/loaders/image/png/PNGReader.js +5 -0
  47. package/engine/asset/loaders/material/bitmap2sampler_gl.js +1 -1
  48. package/engine/asset/loaders/material/computeImageBitmapEquality.js +6 -1
  49. package/engine/asset/loaders/material/computeTextureEquality.js +40 -49
  50. package/engine/ecs/EntityBuilder.js +25 -5
  51. package/engine/ecs/EntityComponentDataset.js +1 -1
  52. package/engine/ecs/attachment/AttachmentBinding.js +8 -0
  53. package/engine/ecs/attachment/AttachmentSystem.js +4 -0
  54. package/engine/ecs/attachment/TransformAttachmentBinding.js +14 -44
  55. package/engine/ecs/components/Tag.js +27 -6
  56. package/engine/ecs/foliage/InstancedFoliage.js +277 -266
  57. package/engine/ecs/foliage/ecs/Foliage2System.js +7 -7
  58. package/engine/ecs/foliage/ecs/InstancedMeshComponent.js +37 -0
  59. package/engine/ecs/foliage/ecs/{Foliage2.js → InstancedMeshLayer.js} +3 -45
  60. package/engine/ecs/foliage/ecs/InstancedMeshSerializationAdapter.js +6 -5
  61. package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +7 -6
  62. package/engine/ecs/fow/FogOfWar.js +4 -0
  63. package/engine/ecs/fow/FogOfWarSystem.js +2 -0
  64. package/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +2 -0
  65. package/engine/ecs/storage/binary/BinarySerializationRegistry.js +1 -1
  66. package/engine/ecs/system/AbstractContextSystem.js +1 -1
  67. package/engine/ecs/systems/TagSystem.js +17 -0
  68. package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +12 -16
  69. package/engine/ecs/transform/Transform.js +19 -6
  70. package/engine/graphics/GraphicsEngine.js +11 -6
  71. package/engine/graphics/composit/CompositLayer.js +17 -4
  72. package/engine/graphics/composit/CompositingStages.js +8 -0
  73. package/engine/graphics/composit/LayerCompositer.js +35 -6
  74. package/engine/graphics/ecs/highlight/plugin/OutlineRenderPlugin.js +11 -7
  75. package/engine/graphics/ecs/light/Light.js +2 -0
  76. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +5 -1
  77. package/engine/graphics/ecs/mesh-v2/DrawMode.js +5 -0
  78. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +32 -18
  79. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +14 -72
  80. package/engine/graphics/geometry/instancing/rewriteMaterial.js +70 -0
  81. package/engine/graphics/material/manager/MaterialManager.js +2 -1
  82. package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +6 -4
  83. package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -2
  84. package/engine/graphics/particles/ParticleEmitterLibrary.js +3 -0
  85. package/engine/graphics/particles/ecs/{ParticleEmitterSystem2.js → ParticleEmitterSystem.js} +17 -9
  86. package/engine/graphics/particles/particular/engine/ParticularEngine.js +8 -2
  87. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +14 -25
  88. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitterFlag.js +5 -0
  89. package/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +90 -2
  90. package/engine/graphics/particles/particular/engine/emitter/ParticlePool.spec.js +7 -7
  91. package/engine/graphics/particles/particular/engine/renderers/billboard/BILLBOARD_PARTICLE_SPECIFICATION.js +15 -12
  92. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +262 -51
  93. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +81 -48
  94. package/engine/graphics/particles/particular/engine/shader/debugAtlas.js +14 -0
  95. package/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +141 -0
  96. package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +148 -54
  97. package/engine/graphics/particles/particular/engine/utils/volume/lut_to_sampler.js +27 -0
  98. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +544 -164
  99. package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +15 -10
  100. package/engine/graphics/render/forward_plus/materials/FP_INJECTION_POINT_ACCUMULATION.js +1 -0
  101. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +32 -0
  102. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_DECODE_PARS.js +51 -0
  103. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +25 -0
  104. package/engine/graphics/render/forward_plus/materials/FPlusDebugMaterial.js +3 -3
  105. package/engine/graphics/render/forward_plus/materials/ForwardPlusThreeMaterial.js +1 -1
  106. package/engine/graphics/render/forward_plus/materials/fp_build_fragment_shader.js +31 -120
  107. package/engine/graphics/render/forward_plus/materials/fp_build_vertex_lighting_shared.js +35 -0
  108. package/engine/graphics/render/forward_plus/materials/fp_build_vertex_shader.js +4 -5
  109. package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +10 -3
  110. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +588 -53
  111. package/engine/graphics/render/forward_plus/prototypeLightManager.js +31 -6
  112. package/engine/graphics/render/forward_plus/query/point_light_inside_volume.js +10 -9
  113. package/engine/graphics/shaders/TerrainShader.js +4 -5
  114. package/engine/graphics/shadows/ShadowMapRenderer.js +8 -2
  115. package/engine/graphics/texture/atlas/ManagedTextureAtlas.js +12 -1
  116. package/engine/graphics/texture/sampler/Sampler2D.js +3 -1
  117. package/engine/graphics/texture/sampler/convertTexture2Sampler2D.js +1 -1
  118. package/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.js +66 -0
  119. package/engine/graphics/util/composeMatrix4.js +33 -23
  120. package/engine/graphics/util/decompose_matrix_4_array.js +61 -0
  121. package/engine/intelligence/behavior/ecs/BehaviorComponent.js +30 -14
  122. package/engine/knowledge/database/StaticKnowledgeDataTable.js +6 -1
  123. package/engine/navigation/ecs/components/Path.js +0 -5
  124. package/package.json +1 -1
  125. package/view/minimap/gl/MinimapWorldGL.js +12 -5
  126. package/core/geom/3d/shape/CompositeShape.js +0 -60
@@ -0,0 +1,141 @@
1
+ import Signal from "../../../../../../../core/events/signal/Signal.js";
2
+ import { DataType2TypedArrayConstructorMapping } from "../../../../../../../core/collection/table/DataType2TypedArrayConstructorMapping.js";
3
+ import { array_copy } from "../../../../../../../core/collection/array/copyArray.js";
4
+ import { min2 } from "../../../../../../../core/math/min2.js";
5
+ import { assert } from "../../../../../../../core/assert.js";
6
+
7
+ export class AttributeValue {
8
+ constructor() {
9
+ /**
10
+ * Attribute spec
11
+ * @type {AttributeSpec}
12
+ */
13
+ this.__spec = null;
14
+
15
+ /**
16
+ *
17
+ * @type {number[]}
18
+ */
19
+ this.__value = [];
20
+
21
+ /**
22
+ *
23
+ * @type {ParameterLookupTable}
24
+ * @private
25
+ */
26
+ this.__lut = null;
27
+
28
+ /**
29
+ *
30
+ * @type {Signal}
31
+ */
32
+ this.onValueChange = new Signal();
33
+ }
34
+
35
+ /**
36
+ * @param {AttributeSpec} s
37
+ */
38
+ set spec(s) {
39
+ this.__spec = s;
40
+ this.init();
41
+ }
42
+
43
+ /**
44
+ *
45
+ * @returns {AttributeSpec}
46
+ */
47
+ get spec() {
48
+ return this.__spec;
49
+ }
50
+
51
+ /**
52
+ * Will generate actual typed value storage
53
+ */
54
+ init() {
55
+ const spec = this.__spec;
56
+
57
+ const TAC = DataType2TypedArrayConstructorMapping[spec.type];
58
+
59
+ const new_storage = new TAC(spec.itemSize);
60
+
61
+ array_copy(this.__value, 0, new_storage, 0, min2(this.__value.length, new_storage.length));
62
+
63
+ this.__value = new_storage;
64
+ }
65
+
66
+ /**
67
+ * @param {ParameterLookupTable} v
68
+ */
69
+ set lookup(v) {
70
+ this.__lut = v;
71
+ }
72
+
73
+ /**
74
+ *
75
+ * @returns {ParameterLookupTable}
76
+ */
77
+ get lookup() {
78
+ return this.__lut;
79
+ }
80
+
81
+ /**
82
+ *
83
+ * @param {number} v
84
+ */
85
+ write_lookup_value(v) {
86
+ assert.isNumber(v, 'v');
87
+
88
+ if (this.__lut === null) {
89
+ throw new Error('No lookup table attached');
90
+ }
91
+
92
+ const r = [];
93
+
94
+ this.__lut.sample(v, r);
95
+
96
+ this.write_value(r);
97
+ }
98
+
99
+ /**
100
+ *
101
+ * @param {number[]} v
102
+ */
103
+ write_value_silent(v) {
104
+ this.onValueChange.mute();
105
+ this.write_value(v);
106
+ this.onValueChange.unmute();
107
+ }
108
+
109
+ /**
110
+ *
111
+ * @param {number[]} v
112
+ */
113
+ write_value(v) {
114
+ let change_flag = false;
115
+
116
+ const itemSize = this.__spec.itemSize;
117
+
118
+ for (let i = 0; i < itemSize; i++) {
119
+ const old = this.__value[i];
120
+
121
+ this.__value[i] = v[i];
122
+
123
+ if (this.__value[i] !== old) {
124
+ // stored value has changed
125
+ change_flag = true;
126
+ }
127
+ }
128
+
129
+ if (change_flag) {
130
+ this.onValueChange.send0();
131
+ }
132
+ }
133
+
134
+ /**
135
+ *
136
+ * @param {number[]} destination
137
+ */
138
+ read_value(destination) {
139
+ array_copy(this.__value, 0, destination, 0, this.spec.itemSize);
140
+ }
141
+ }
@@ -1,17 +1,6 @@
1
1
  import { ParticleEmitterFlag } from "../../emitter/ParticleEmitterFlag.js";
2
- import {
3
- PARTICLE_ATTRIBUTE_AGE,
4
- PARTICLE_ATTRIBUTE_BLEND,
5
- PARTICLE_ATTRIBUTE_COLOR,
6
- PARTICLE_ATTRIBUTE_DEATH_AGE,
7
- PARTICLE_ATTRIBUTE_LAYER_POSITION,
8
- PARTICLE_ATTRIBUTE_POSITION,
9
- PARTICLE_ATTRIBUTE_SIZE,
10
- PARTICLE_ATTRIBUTE_SIZE_INITIAL,
11
- PARTICLE_ATTRIBUTE_VELOCITY
12
- } from "../../emitter/PARTICLE_ATTRIBUTES.js";
2
+ import { PARTICLE_ATTRIBUTE_DEATH_AGE, PARTICLE_ATTRIBUTE_POSITION } from "../../emitter/PARTICLE_ATTRIBUTES.js";
13
3
  import { EmissionShapeType } from "../../emitter/EmissionShapeType.js";
14
- import { computeEmissionFunction } from "../../emitter/computeEmissionFunction.js";
15
4
  import { Matrix4 } from "three";
16
5
  import { composeMatrix4 } from "../../../../../util/composeMatrix4.js";
17
6
  import Quaternion from "../../../../../../../core/geom/Quaternion.js";
@@ -19,6 +8,10 @@ import { ParticleEmitter } from "../../emitter/ParticleEmitter.js";
19
8
  import { Transform } from "../../../../../../ecs/transform/Transform.js";
20
9
  import EntityBuilder from "../../../../../../ecs/EntityBuilder.js";
21
10
  import { vec3 } from "gl-matrix";
11
+ import { AttributeValue } from "./AttributeValue.js";
12
+ import { PARTICULAR_PARTICLE_SPECIFICATION } from "../../emitter/PARTICULAR_PARTICLE_SPECIFICATION.js";
13
+ import { SerializationMetadata } from "../../../../../../ecs/components/SerializationMetadata.js";
14
+ import { UnitCubeShape3D } from "../../../../../../../core/geom/3d/shape/UnitCubeShape3D.js";
22
15
 
23
16
  /**
24
17
  *
@@ -69,6 +62,25 @@ function computeEmitterVolume(emitter, transform) {
69
62
  return layer_volume_sum * scale_volume;
70
63
  }
71
64
 
65
+ const DEFAULT_ATTRIBUTE_VALUES = {
66
+ color: [1, 1, 1, 1],
67
+ age: [0],
68
+ velocity: [0, 0, 0],
69
+ deathAge: [99999999],
70
+ layerPosition: [0],
71
+ rotation: [0],
72
+ rotationSpeed: [0],
73
+ blending: [0],
74
+ size: [1],
75
+ initial_size: [1]
76
+ };
77
+
78
+ const EXPOSED_ATTRIBUTES = [
79
+ "color",
80
+ "size",
81
+ "blending"
82
+ ];
83
+
72
84
  export class ParticleVolume {
73
85
 
74
86
  constructor() {
@@ -220,9 +232,17 @@ export class ParticleVolume {
220
232
  */
221
233
  this.__density = 1;
222
234
 
235
+ /**
236
+ *
237
+ * @type {AbstractShape3D}
238
+ * @private
239
+ */
240
+ this.__shape = new UnitCubeShape3D();
241
+
223
242
  const eb = new EntityBuilder();
224
243
 
225
244
  eb.add(this.__emitter)
245
+ .add(SerializationMetadata.Transient)
226
246
  .add(this.__transform);
227
247
 
228
248
  /**
@@ -230,6 +250,53 @@ export class ParticleVolume {
230
250
  * @type {EntityBuilder}
231
251
  */
232
252
  this.entity = eb;
253
+
254
+ /**
255
+ *
256
+ * @type {Object<AttributeValue>}
257
+ */
258
+ this.attributes = {};
259
+
260
+ this.init_attributes();
261
+ }
262
+
263
+ get shape() {
264
+ return this.__shape;
265
+ }
266
+
267
+ /**
268
+ * @private
269
+ */
270
+ init_attributes() {
271
+ const spec = PARTICULAR_PARTICLE_SPECIFICATION;
272
+
273
+ for (let i = 0; i < spec.attributes.length; i++) {
274
+ const attributeSpec = spec.attributes[i];
275
+
276
+ const av = new AttributeValue();
277
+ av.spec = attributeSpec;
278
+
279
+ const attribute_name = attributeSpec.name;
280
+
281
+ if (!EXPOSED_ATTRIBUTES.includes(attribute_name)) {
282
+ // don't expose attribute
283
+ continue;
284
+ }
285
+
286
+ const default_value = DEFAULT_ATTRIBUTE_VALUES[attribute_name];
287
+
288
+ if (default_value !== undefined) {
289
+ av.write_value(default_value);
290
+ }
291
+
292
+ this.attributes[attribute_name] = av;
293
+
294
+ const attribute_index = i;
295
+
296
+ av.onValueChange.add(() => {
297
+ this.__write_attribute(attribute_index);
298
+ });
299
+ }
233
300
  }
234
301
 
235
302
  get emitter() {
@@ -240,17 +307,37 @@ export class ParticleVolume {
240
307
  return this.__transform;
241
308
  }
242
309
 
310
+ /**
311
+ *
312
+ * @param {number} [density]
313
+ * @param {number} [particle_size]
314
+ * @param {AbstractShape3D} [shape]
315
+ * @param {boolean} sort
316
+ * @param {string} [sprite]
317
+ */
243
318
  from({
244
319
  density = 1,
245
320
  particle_size = 1,
246
- }) {
321
+ shape = new UnitCubeShape3D(),
322
+ sort = false,
323
+ sprite = "data/textures/particle/smokeparticle.png"
324
+ } = {}) {
247
325
 
248
326
  this.__density = density;
327
+ this.__shape = shape;
249
328
 
250
- this.__emitter.layers.get(0).particleSize.set(particle_size, particle_size);
329
+ this.__emitter.writeFlag(ParticleEmitterFlag.DepthSorting, sort);
330
+ this.__emitter.layers.get(0).imageURL = sprite;
251
331
 
332
+ const attributes = this.attributes;
333
+
334
+ attributes.size.write_value_silent([particle_size]);
252
335
  }
253
336
 
337
+ /**
338
+ *
339
+ * @private
340
+ */
254
341
  __ensure_initialized() {
255
342
 
256
343
  const emitter = this.__emitter;
@@ -279,8 +366,6 @@ export class ParticleVolume {
279
366
 
280
367
  const layer = emitter.layers.get(0);
281
368
 
282
- const volume_sampler = computeEmissionFunction(layer.emissionFrom, layer.emissionShape);
283
-
284
369
  const m4_transform = new Matrix4();
285
370
 
286
371
  const t = this.__transform;
@@ -298,40 +383,60 @@ export class ParticleVolume {
298
383
 
299
384
  m4_final.multiplyMatrices(m4_transform, m4_layer);
300
385
 
301
- const blending = emitter.blendingMode;
302
-
303
386
  for (let i = 0; i < particle_count; i++) {
304
387
 
305
- volume_sampler(random, v3_position, 0);
388
+ this.__shape.sample_random_point_in_volume(v3_position, 0, random);
306
389
 
307
390
  vec3.transformMat4(v3_position, v3_position, m4_final.elements);
308
391
 
309
- particles.writeAttributeScalar(i, PARTICLE_ATTRIBUTE_AGE, 0);
310
-
311
- particles.writeAttributeVector3(i, PARTICLE_ATTRIBUTE_VELOCITY, 0, 0, 0);
312
-
313
392
  particles.writeAttributeVector3(i, PARTICLE_ATTRIBUTE_POSITION, v3_position[0], v3_position[1], v3_position[2]);
393
+ }
314
394
 
315
- particles.writeAttributeScalar(i, PARTICLE_ATTRIBUTE_DEATH_AGE, 99999999);
395
+ // request bounds update
396
+ emitter.setFlag(ParticleEmitterFlag.ParticleBoundsNeedUpdate);
397
+ }
316
398
 
317
- const size = layer.particleSize.sampleRandom(random);
399
+ /**
400
+ *
401
+ * @private
402
+ */
403
+ __write_attributes() {
404
+ this.__ensure_initialized();
318
405
 
319
- particles.writeAttributeScalar(i, PARTICLE_ATTRIBUTE_SIZE_INITIAL, size);
320
- particles.writeAttributeScalar(i, PARTICLE_ATTRIBUTE_SIZE, size);
406
+ const emitter = this.__emitter;
407
+ const particles = emitter.particles;
321
408
 
322
- particles.writeAttributeScalar(i, PARTICLE_ATTRIBUTE_LAYER_POSITION, 0);
409
+ const attributes = particles.spec.attributes;
323
410
 
324
- particles.writeAttributeVector4(i, PARTICLE_ATTRIBUTE_COLOR, 1, 1, 1, 1);
411
+ for (let i = 0; i < attributes.length; i++) {
412
+ const name = attributes[i].name;
325
413
 
326
- particles.writeAttributeScalar(i, PARTICLE_ATTRIBUTE_BLEND, blending);
414
+ if (this.attributes.hasOwnProperty(name)) {
415
+ this.__write_attribute(i);
416
+ }
327
417
  }
418
+ }
328
419
 
329
- // request bounds update
330
- emitter.setFlag(ParticleEmitterFlag.ParticleBoundsNeedUpdate);
420
+ /**
421
+ *
422
+ * @param {number} index
423
+ * @private
424
+ */
425
+ __write_attribute(index) {
426
+ this.__ensure_initialized();
427
+
428
+ const emitter = this.__emitter;
429
+ const particles = emitter.particles;
430
+
431
+ const spec = particles.spec.attributes[index];
432
+
433
+ const av = this.attributes[spec.name];
434
+
435
+ particles.writeAttributeForAllArray(index, av.__value);
331
436
  }
332
437
 
333
438
  build() {
334
- const volume_value = computeEmitterVolume(this.__emitter, this.__transform);
439
+ const volume_value = this.__shape.volume;
335
440
 
336
441
  // total particle count
337
442
  const particle_count = Math.max(1, Math.ceil(volume_value * this.__density));
@@ -347,10 +452,17 @@ export class ParticleVolume {
347
452
  // "spawn" particles to occupy the entire pool
348
453
  particles.occupancy.setRange(0, particle_count - 1);
349
454
 
350
- // trigger sprite update
351
- this.__emitter.setFlag(ParticleEmitterFlag.SpritesNeedUpdate);
455
+ // set certain defaults
456
+ particles.writeAttributeForAllArray(PARTICLE_ATTRIBUTE_DEATH_AGE, [99999999]);
352
457
 
458
+ // fill out volume
353
459
  this.__distribute(Math.random);
460
+
461
+ // apply attributes
462
+ this.__write_attributes();
463
+
464
+ // trigger sprite update
465
+ this.__emitter.setFlag(ParticleEmitterFlag.SpritesNeedUpdate);
354
466
  }
355
467
 
356
468
  /**
@@ -361,24 +473,6 @@ export class ParticleVolume {
361
473
  * @param {number} a
362
474
  */
363
475
  setColor(r, g, b, a) {
364
-
365
- this.__ensure_initialized();
366
-
367
- const emitter = this.__emitter;
368
-
369
- const particles = emitter.particles;
370
-
371
- const particle_count = particles.size();
372
-
373
- for (let i = 0; i < particle_count; i++) {
374
-
375
- particles.writeAttributeVector4(i, PARTICLE_ATTRIBUTE_COLOR, r, g, b, a);
376
-
377
- }
378
-
379
- const attribute = particles.attributes[PARTICLE_ATTRIBUTE_COLOR];
380
- attribute.needsUpdate = true;
381
- attribute.updateRange.count = particle_count;
382
- attribute.updateRange.offset = 0;
476
+ this.attributes.color.write_value([r, g, b, a]);
383
477
  }
384
478
  }
@@ -0,0 +1,27 @@
1
+ import { Sampler2D } from "../../../../../texture/sampler/Sampler2D.js";
2
+
3
+ /**
4
+ *
5
+ * @param {ParameterLookupTable} lut
6
+ * @param {number} width
7
+ * @param {number} height
8
+ * @returns {Sampler2D}
9
+ */
10
+ export function lut_to_sampler(lut, width, height) {
11
+ const sampler = Sampler2D.uint8(4, width, height);
12
+
13
+ const s = [];
14
+
15
+ for (let i = 0; i < width; i++) {
16
+
17
+ lut.sample(i / (width - 1), s);
18
+ s[3] = 255;
19
+
20
+ for (let j = 0; j < height; j++) {
21
+ sampler.set(i, j, s);
22
+ }
23
+
24
+ }
25
+
26
+ return sampler;
27
+ }