@woosh/meep-engine 3.18.0 → 3.20.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.
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleCurveEditorView.js +303 -120
- package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleGradientEditorView.js +108 -63
- package/editor/view/particles/effect/ParticleGraphEditorView.js +2 -2
- package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
- package/editor/view/particles/effect/ParticleNodeParametersView.js +7 -46
- package/editor/view/particles/effect/particle-editor.css +60 -30
- package/package.json +1 -2
- package/samples/engine/README.md +1 -1
- package/src/core/binary/compression/decompress_bytes.d.ts +13 -0
- package/src/core/binary/compression/decompress_bytes.d.ts.map +1 -0
- package/src/core/binary/compression/decompress_bytes.js +28 -0
- package/src/core/collection/array/array_group_by.d.ts.map +1 -1
- package/src/core/collection/array/array_group_by.js +2 -11
- package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/HeightMapShape3D.js +4 -9
- package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +67 -22
- package/src/core/model/object/optional_clone.d.ts +7 -0
- package/src/core/model/object/optional_clone.d.ts.map +1 -0
- package/src/core/model/object/optional_equality.d.ts +10 -0
- package/src/core/model/object/optional_equality.d.ts.map +1 -0
- package/src/{shade/descriptor/util → core/model/object}/optional_equality.js +2 -2
- package/src/core/model/object/optional_hash.d.ts +9 -0
- package/src/core/model/object/optional_hash.d.ts.map +1 -0
- package/src/{shade/descriptor/util → core/model/object}/optional_hash.js +3 -3
- package/src/engine/asset/Asset.d.ts +1 -1
- package/src/engine/asset/Asset.d.ts.map +1 -1
- package/src/engine/asset/Asset.js +3 -1
- package/src/engine/asset/loaders/image/ImageDecoderWorker.js +12 -27
- package/src/engine/asset/loaders/image/prototypePNG.js +8 -7
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.d.ts.map +1 -1
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +9 -10
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
- package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +266 -0
- package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -0
- package/src/engine/graphics/ecs/particles/ParticleEffect.js +439 -0
- package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +58 -0
- package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -0
- package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +219 -0
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +178 -25
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/GPUParticleEmitterSystem.js +809 -310
- package/src/format/image/png/PNGReader.d.ts +7 -6
- package/src/format/image/png/PNGReader.d.ts.map +1 -1
- package/src/format/image/png/PNGReader.js +13 -12
- package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts +3 -2
- package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
- package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +5 -4
- package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts +3 -2
- package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts.map +1 -1
- package/src/format/image/png/chunk/png_chunk_decode_zTXt.js +5 -4
- package/src/format/image/png/png_inflate.d.ts +3 -3
- package/src/format/image/png/png_inflate.d.ts.map +1 -1
- package/src/format/image/png/png_inflate.js +29 -39
- package/src/format/texture/ktx2/ktx2_read.d.ts +4 -4
- package/src/format/texture/ktx2/ktx2_read.d.ts.map +1 -1
- package/src/format/texture/ktx2/ktx2_read.js +18 -21
- package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.js +1 -1
- package/src/shade/descriptor/binding/BindGroupLayoutEntry.js +3 -3
- package/src/shade/descriptor/pipeline/PipelineDescriptorBase.js +1 -1
- package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +1 -1
- package/src/shade/descriptor/pipeline/render/ColorTargetState.js +3 -3
- package/src/shade/descriptor/pipeline/render/FragmentState.js +1 -1
- package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.js +3 -3
- package/src/shade/playground/particle_ecs/README.md +203 -0
- package/src/shade/playground/particle_ecs/bonfire_editor.d.ts +39 -0
- package/src/shade/playground/particle_ecs/bonfire_editor.d.ts.map +1 -0
- package/src/shade/playground/particle_ecs/bonfire_editor.js +315 -0
- package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +145 -0
- package/src/shade/playground/particle_ecs/bonfire_effects.d.ts.map +1 -0
- package/src/shade/playground/particle_ecs/bonfire_effects.js +202 -0
- package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts +23 -0
- package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts.map +1 -0
- package/src/shade/playground/particle_ecs/bonfire_sprites.js +315 -0
- package/src/shade/playground/particle_ecs/bonfire_world.d.ts +86 -0
- package/src/shade/playground/particle_ecs/bonfire_world.d.ts.map +1 -0
- package/src/shade/playground/particle_ecs/bonfire_world.js +303 -0
- package/src/shade/playground/particle_ecs/effects/embers.json +1634 -0
- package/src/shade/playground/particle_ecs/effects/flame.json +1882 -0
- package/src/shade/playground/particle_ecs/effects/smoke.json +1860 -0
- package/src/shade/playground/particle_ecs/effects/soot.json +1606 -0
- package/src/shade/playground/particle_ecs/index.html +330 -0
- package/src/shade/playground/particle_ecs/main.d.ts +2 -0
- package/src/shade/playground/particle_ecs/main.d.ts.map +1 -0
- package/src/shade/playground/particle_ecs/main.js +566 -0
- package/src/shade/playground/particle_ecs/moonlit_environment.d.ts +16 -0
- package/src/shade/playground/particle_ecs/moonlit_environment.d.ts.map +1 -0
- package/src/shade/playground/particle_ecs/moonlit_environment.js +144 -0
- package/src/shade/playground/particle_editor/README.md +5 -4
- package/src/shade/playground/particle_system/particle_prototype.d.ts +7 -9
- package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_prototype.js +7 -9
- package/src/shade/playground/profile_hotkey.d.ts +58 -0
- package/src/shade/playground/profile_hotkey.d.ts.map +1 -0
- package/src/shade/playground/profile_hotkey.js +325 -0
- package/src/shade/playground/ssr_motion/README.md +22 -0
- package/src/shade/playground/ssr_motion/index.html +18 -0
- package/src/shade/playground/ssr_motion/main.d.ts +2 -0
- package/src/shade/playground/ssr_motion/main.d.ts.map +1 -0
- package/src/shade/playground/ssr_motion/main.js +149 -0
- package/src/shade/playground/ssr_variance/README.md +105 -0
- package/src/shade/playground/ssr_variance/capture.d.ts +16 -0
- package/src/shade/playground/ssr_variance/capture.d.ts.map +1 -0
- package/src/shade/playground/ssr_variance/capture.js +96 -0
- package/src/shade/playground/ssr_variance/index.html +23 -0
- package/src/shade/playground/ssr_variance/main.d.ts +2 -0
- package/src/shade/playground/ssr_variance/main.d.ts.map +1 -0
- package/src/shade/playground/ssr_variance/main.js +246 -0
- package/src/shade/playground/ssr_variance/reference.d.ts +18 -0
- package/src/shade/playground/ssr_variance/reference.d.ts.map +1 -0
- package/src/shade/playground/ssr_variance/reference.js +78 -0
- package/src/shade/playground/ssr_variance/scene.d.ts +11 -0
- package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -0
- package/src/shade/playground/ssr_variance/scene.js +61 -0
- package/src/shade/playground/ssr_variance/statistics.d.ts +44 -0
- package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -0
- package/src/shade/playground/ssr_variance/statistics.js +51 -0
- package/src/shade/renderer/geometry/Geometry.d.ts.map +1 -1
- package/src/shade/renderer/geometry/Geometry.js +4 -7
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts.map +1 -1
- package/src/shade/renderer/loader/gltf/tiny-gltf.js +9 -3
- package/src/shade/renderer/loader/usd/usd_decode_image.d.ts +4 -4
- package/src/shade/renderer/loader/usd/usd_decode_image.d.ts.map +1 -1
- package/src/shade/renderer/loader/usd/usd_decode_image.js +4 -4
- package/src/shade/renderer/material/StandardShadeMaterial.js +2 -2
- package/src/shade/renderer/particles/DESIGN.md +745 -702
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +3 -1
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +1 -1
- package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +9 -15
- package/src/shade/renderer/particles/graph/particle_group_library.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_group_library.js +8 -3
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +0 -2
- package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_parameters.js +0 -9
- package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_node_presentation.js +0 -10
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts +2 -8
- package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph/particle_ramp.js +2 -8
- package/src/shade/renderer/particles/graph/validate_particle_graph.js +0 -6
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.js +13 -4
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts +1 -12
- package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/InstructionStream.js +1 -12
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +54 -60
- package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/ParticleVMISA.js +9 -17
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts +0 -1
- package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
- package/src/shade/renderer/particles/isa/particle_assembly.js +2 -16
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +1 -1
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +1 -1
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +0 -14
- package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +3 -17
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +15 -36
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +1 -5
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +1 -8
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +2 -11
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
- package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +2 -11
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +11 -4
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ParticleEmitter.js +431 -424
- package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js +13 -0
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts +3 -6
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +49 -17
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +0 -2
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +0 -2
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +1 -5
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +0 -2
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +1 -3
- package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/ParticleVMReference.js +4 -20
- package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
- package/src/shade/renderer/particles/vm/chunk_particle_vm.js +2 -5
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -1
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +0 -2
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -1
- package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +0 -2
- package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/SSR.js +2 -1
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +20 -5
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +19 -5
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts +4 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -0
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +137 -0
- package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +0 -8
- package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +18 -114
- package/src/shade/renderer/scene/Mesh.js +1 -1
- package/src/shade/renderer/texture/ShadeTexture.js +1 -1
- package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts +2 -2
- package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts.map +1 -1
- package/src/shade/renderer/texture/source/texel_data_from_ktx2.js +3 -3
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts +0 -19
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.js +0 -30
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts +0 -11
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.js +0 -13
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts +0 -20
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts +0 -14
- package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts.map +0 -1
- package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts +0 -50
- package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts.map +0 -1
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +0 -17
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +0 -1
- /package/src/{shade/descriptor/util → core/model/object}/optional_clone.js +0 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { float32_array_hash } from "../../../../core/collection/array/typed/float32_array_hash.js";
|
|
3
|
+
import { is_typed_array_equals } from "../../../../core/collection/array/typed/is_typed_array_equals.js";
|
|
4
|
+
import { hash_mix2 } from "../../../../core/math/hash/hash_mix2.js";
|
|
5
|
+
import { hash_mix3 } from "../../../../core/math/hash/hash_mix3.js";
|
|
6
|
+
import { optional_equality } from "../../../../core/model/object/optional_equality.js";
|
|
7
|
+
import { optional_hash } from "../../../../core/model/object/optional_hash.js";
|
|
8
|
+
import { computeHashFloat } from "../../../../core/primitives/numbers/computeHashFloat.js";
|
|
9
|
+
import { computeStringHash } from "../../../../core/primitives/strings/computeStringHash.js";
|
|
10
|
+
import {
|
|
11
|
+
EMITTER_ATTRIBUTE_ABSENT,
|
|
12
|
+
make_emitter_flags
|
|
13
|
+
} from "../../../../shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js";
|
|
14
|
+
import { EMITTER_RENDER_CHANNELS } from "../../../../shade/renderer/particles/runtime/ParticleEmitter.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* What an entity emits. Paired with a {@link ../../../ecs/transform/Transform64.js Transform64},
|
|
18
|
+
* which says where, this is the whole of an emitter in the ECS:
|
|
19
|
+
*
|
|
20
|
+
* ```js
|
|
21
|
+
* new Entity()
|
|
22
|
+
* .add(new Transform64())
|
|
23
|
+
* .add(ParticleEffect.from({ ...create_particle_effect({ layout, init, update }), spawn_rate: 400 }))
|
|
24
|
+
* .build(dataset);
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* {@link ../../../graphics3/GPUParticleEmitterSystem.js GPUParticleEmitterSystem} is what turns the
|
|
28
|
+
* pair into particles: it gives the entity a
|
|
29
|
+
* {@link ../../../../shade/renderer/particles/runtime/ParticleEmitter.js ParticleEmitter} node in
|
|
30
|
+
* the scene it owns, keeps that node where the transform says, packs {@link texture} into the
|
|
31
|
+
* scene's sprite atlas, and follows every field below. Nothing here reaches a device by itself, and
|
|
32
|
+
* an entity carrying one of these with no such system in the profile simply emits nothing.
|
|
33
|
+
*
|
|
34
|
+
* ## It is a description, and only a description
|
|
35
|
+
*
|
|
36
|
+
* Everything on it means the same thing with no renderer present: the attribute {@link layout} and
|
|
37
|
+
* the compiled {@link program} that make up an effect, the {@link texture} to draw with, the rate,
|
|
38
|
+
* the pre-warm, the blend / projection / feature {@link flags}, the render-attribute bindings and
|
|
39
|
+
* the flipbook grid. That is deliberate, and it is what makes the component the unit an editor
|
|
40
|
+
* inspects, a prefab carries and a system diffs.
|
|
41
|
+
*
|
|
42
|
+
* What is **not** here: the scene node the system built, the emitter's row in the GPU emitter table,
|
|
43
|
+
* the generation of that row, where the program was placed in the program heap, and where the
|
|
44
|
+
* texture landed in the atlas. All of that belongs to whoever registered the emitter — see
|
|
45
|
+
* {@link ../../../../shade/renderer/particles/runtime/GPUParticleEmitterContext.js} — and none of it
|
|
46
|
+
* survives a device restart, which is exactly why it is not on a component that does.
|
|
47
|
+
*
|
|
48
|
+
* There are no bounds here either. An emitter's particles are moved by arbitrary bytecode, so the
|
|
49
|
+
* box is **measured** from the live particles by a GPU pass at the end of every frame rather than
|
|
50
|
+
* authored; the one authored part of it is whether this effect opts into culling at all
|
|
51
|
+
* (`cull` in {@link flags}).
|
|
52
|
+
*
|
|
53
|
+
* ## Sharing
|
|
54
|
+
*
|
|
55
|
+
* {@link layout} and {@link program} are immutable once compiled and are meant to be shared: fifty
|
|
56
|
+
* campfires hold fifty components pointing at one compiled effect, which is what puts them on one id
|
|
57
|
+
* in the program heap and therefore in one simulation bucket. {@link copy} shares them rather than
|
|
58
|
+
* duplicating them for that reason.
|
|
59
|
+
*
|
|
60
|
+
* ## Changing one
|
|
61
|
+
*
|
|
62
|
+
* Assign to the fields. The system compares what it holds against what it last wrote to the scene
|
|
63
|
+
* node, once per frame per entity, so there is no flag to set and no signal to fire — a component
|
|
64
|
+
* whose fields have not moved costs a run of comparisons and no upload. That is a deliberate trade
|
|
65
|
+
* against the observable-per-field shape the older components use: an effect has fifteen fields,
|
|
66
|
+
* gameplay writes them in bursts, and a row is restaged whole either way.
|
|
67
|
+
*
|
|
68
|
+
* ## Saving one
|
|
69
|
+
*
|
|
70
|
+
* {@link ./ParticleEffectSerializationAdapter.js} writes all of it, the compiled program included.
|
|
71
|
+
* The VM's instruction set is a durable format by design — fixed-width opcodes and a constant pool —
|
|
72
|
+
* so a level carries the bytecode the way it carries a mesh's indices, and a shipped build needs
|
|
73
|
+
* neither the graph the effect was compiled from nor a compiler at runtime. Authoring belongs to an
|
|
74
|
+
* editor.
|
|
75
|
+
*
|
|
76
|
+
* Two things are consequently wire format: the opcode numbers, and the **order** of the attributes
|
|
77
|
+
* in {@link layout}, because the offsets in the render bindings are assigned from that order.
|
|
78
|
+
*/
|
|
79
|
+
export class ParticleEffect {
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The per-particle attribute schema: which named attributes a particle of this effect has, how
|
|
83
|
+
* wide each is, and what word of the record it sits at.
|
|
84
|
+
*
|
|
85
|
+
* `null` until an effect is assigned. An entity whose component has none is linked and idle
|
|
86
|
+
* rather than an error — an effect that is still compiling or still loading is ordinary — and it
|
|
87
|
+
* starts emitting on the frame after both this and {@link program} are set.
|
|
88
|
+
*
|
|
89
|
+
* @type {import("../../../../shade/renderer/particles/layout/ParticleLayout.js").ParticleLayout|null}
|
|
90
|
+
*/
|
|
91
|
+
layout = null;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The compiled INIT/UPDATE bytecode run for every particle. Replace the immutable program to
|
|
95
|
+
* edit the effect; do not mutate its bytecode in place.
|
|
96
|
+
*
|
|
97
|
+
* @type {import("../../../../shade/renderer/particles/isa/ParticleProgram.js").ParticleProgram|null}
|
|
98
|
+
*/
|
|
99
|
+
program = null;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Image to draw the particles with, by URL, or `null` to draw against a single white texel — so
|
|
103
|
+
* an untextured effect is a flat quad of its own colour.
|
|
104
|
+
*
|
|
105
|
+
* The system loads this through `AssetManager` and packs it into the sprite atlas its scene
|
|
106
|
+
* shares, one patch per distinct URL however many entities name it. Where it lands is the
|
|
107
|
+
* system's answer and changes on every repack, without this component changing.
|
|
108
|
+
*
|
|
109
|
+
* @type {string|null}
|
|
110
|
+
*/
|
|
111
|
+
texture = null;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Base RNG seed.
|
|
115
|
+
*
|
|
116
|
+
* Two entities running one program produce identical particles from identical seeds. `0` reads
|
|
117
|
+
* as "unset", and the emitter then takes its registration's generation instead, which no other
|
|
118
|
+
* live emitter shares — so leaving this alone is what makes fifty campfires burn differently.
|
|
119
|
+
*
|
|
120
|
+
* @type {number}
|
|
121
|
+
*/
|
|
122
|
+
seed = 0;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Continuous emission rate, particles per second. Integrated on the GPU; the CPU never counts
|
|
126
|
+
* particles.
|
|
127
|
+
*
|
|
128
|
+
* @type {number}
|
|
129
|
+
*/
|
|
130
|
+
spawn_rate = 0;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Whether the effect is currently emitting.
|
|
134
|
+
*
|
|
135
|
+
* Turning it off holds {@link spawn_rate} at zero without the caller having to remember what the
|
|
136
|
+
* rate was — which is the whole reason it exists, because "put the torch out and light it again"
|
|
137
|
+
* otherwise means every caller keeping a shadow copy of the number. Particles already alive are
|
|
138
|
+
* **not** killed: a fire that stops emitting burns down, which is what stopping a fire looks
|
|
139
|
+
* like. Kill them from the effect's own UPDATE program if an effect wants to vanish.
|
|
140
|
+
*
|
|
141
|
+
* @type {boolean}
|
|
142
|
+
*/
|
|
143
|
+
emitting = true;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Seconds this effect is run forward before it is first shown, `0` for none.
|
|
147
|
+
*
|
|
148
|
+
* A continuous effect starts empty and grows into its steady state over one particle lifetime,
|
|
149
|
+
* in front of whoever is watching. Setting this to about the effect's particle lifetime means
|
|
150
|
+
* the population on the first visible frame is the one the emitter would have had by then —
|
|
151
|
+
* spawned, aged and thinned by its own program over that long.
|
|
152
|
+
*
|
|
153
|
+
* It is paid once, on the frame the emitter is registered, by a pipeline of its own that
|
|
154
|
+
* simulates a private population and moves the result into the scene. Longer costs a longer loop
|
|
155
|
+
* on that one frame and nothing after it.
|
|
156
|
+
*
|
|
157
|
+
* @type {number}
|
|
158
|
+
*/
|
|
159
|
+
prewarm = 0;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Packed feature / blend / projection bits — see
|
|
163
|
+
* {@link ../../../../shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js make_emitter_flags}.
|
|
164
|
+
*
|
|
165
|
+
* @type {number}
|
|
166
|
+
*/
|
|
167
|
+
flags = 0;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Flipbook grid: columns, rows, over whatever region {@link texture} was packed into. `[1, 1]`
|
|
171
|
+
* is a single frame.
|
|
172
|
+
*
|
|
173
|
+
* @type {Float32Array}
|
|
174
|
+
*/
|
|
175
|
+
flipbook = new Float32Array([1, 1]);
|
|
176
|
+
|
|
177
|
+
/** @type {number} record word offset of world position, or {@link EMITTER_ATTRIBUTE_ABSENT} */
|
|
178
|
+
render_position = EMITTER_ATTRIBUTE_ABSENT;
|
|
179
|
+
/** @type {number} record word offset of size */
|
|
180
|
+
render_size = EMITTER_ATTRIBUTE_ABSENT;
|
|
181
|
+
/** @type {number} record word offset of rgba colour */
|
|
182
|
+
render_color = EMITTER_ATTRIBUTE_ABSENT;
|
|
183
|
+
/** @type {number} record word offset of roll angle, radians */
|
|
184
|
+
render_rotation = EMITTER_ATTRIBUTE_ABSENT;
|
|
185
|
+
/** @type {number} record word offset of flipbook frame index */
|
|
186
|
+
render_frame = EMITTER_ATTRIBUTE_ABSENT;
|
|
187
|
+
/** @type {number} record word offset of velocity, read by the STRETCHED projection */
|
|
188
|
+
render_velocity = EMITTER_ATTRIBUTE_ABSENT;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* The rate the emitter actually runs at: {@link spawn_rate} while {@link emitting}, and zero
|
|
192
|
+
* otherwise. What the system writes to the GPU record.
|
|
193
|
+
*
|
|
194
|
+
* @returns {number}
|
|
195
|
+
*/
|
|
196
|
+
get effective_spawn_rate() {
|
|
197
|
+
return this.emitting ? this.spawn_rate : 0;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Bind render channels to per-particle attributes of this effect, by attribute name.
|
|
202
|
+
*
|
|
203
|
+
* Channels left out of `channels` keep whatever they had; a channel that was never bound stays
|
|
204
|
+
* at {@link EMITTER_ATTRIBUTE_ABSENT}, which the passes read as "this effect has no such
|
|
205
|
+
* attribute" — the render pass substitutes a default and the sort pass treats the particle as
|
|
206
|
+
* being at the origin.
|
|
207
|
+
*
|
|
208
|
+
* Word offsets are stored rather than names because that is what the render and sort passes
|
|
209
|
+
* index a particle record with; resolving here is the only place a name is involved, which is
|
|
210
|
+
* also why this needs {@link layout} to have been set first.
|
|
211
|
+
*
|
|
212
|
+
* @param {Object<string,string>} channels channel name (see `EMITTER_RENDER_CHANNELS`) ->
|
|
213
|
+
* attribute name in this effect's layout
|
|
214
|
+
* @returns {ParticleEffect} this
|
|
215
|
+
*/
|
|
216
|
+
bind_render(channels) {
|
|
217
|
+
assert.isObject(channels, 'channels');
|
|
218
|
+
assert.notEqual(this.layout, null, 'layout must be set before render channels are bound');
|
|
219
|
+
assert.defined(this.layout, 'this.layout');
|
|
220
|
+
|
|
221
|
+
const layout = this.layout;
|
|
222
|
+
|
|
223
|
+
for (const channel of Object.keys(channels)) {
|
|
224
|
+
const offset = layout.offsetOf(channels[channel]);
|
|
225
|
+
|
|
226
|
+
switch (channel) {
|
|
227
|
+
case "position":
|
|
228
|
+
this.render_position = offset;
|
|
229
|
+
break;
|
|
230
|
+
case "size":
|
|
231
|
+
this.render_size = offset;
|
|
232
|
+
break;
|
|
233
|
+
case "color":
|
|
234
|
+
this.render_color = offset;
|
|
235
|
+
break;
|
|
236
|
+
case "rotation":
|
|
237
|
+
this.render_rotation = offset;
|
|
238
|
+
break;
|
|
239
|
+
case "frame":
|
|
240
|
+
this.render_frame = offset;
|
|
241
|
+
break;
|
|
242
|
+
case "velocity":
|
|
243
|
+
this.render_velocity = offset;
|
|
244
|
+
break;
|
|
245
|
+
default:
|
|
246
|
+
throw new Error(
|
|
247
|
+
`Unknown render channel '${channel}', expected one of ${EMITTER_RENDER_CHANNELS.join(', ')}`
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return this;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Structural equality over everything the component *is*. Two components that compare equal
|
|
257
|
+
* describe one effect, and one emitter row would serve both.
|
|
258
|
+
*
|
|
259
|
+
* The compiled program compares by its own bytecode rather than by object identity, so two
|
|
260
|
+
* components separately compiled from one graph compare equal.
|
|
261
|
+
*
|
|
262
|
+
* @param {ParticleEffect} other
|
|
263
|
+
* @returns {boolean}
|
|
264
|
+
*/
|
|
265
|
+
equals(other) {
|
|
266
|
+
if (this === other) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return this.texture === other.texture
|
|
271
|
+
&& this.seed === other.seed
|
|
272
|
+
&& this.spawn_rate === other.spawn_rate
|
|
273
|
+
&& this.emitting === other.emitting
|
|
274
|
+
&& this.prewarm === other.prewarm
|
|
275
|
+
&& this.flags === other.flags
|
|
276
|
+
&& this.render_position === other.render_position
|
|
277
|
+
&& this.render_size === other.render_size
|
|
278
|
+
&& this.render_color === other.render_color
|
|
279
|
+
&& this.render_rotation === other.render_rotation
|
|
280
|
+
&& this.render_frame === other.render_frame
|
|
281
|
+
&& this.render_velocity === other.render_velocity
|
|
282
|
+
&& is_typed_array_equals(this.flipbook, other.flipbook)
|
|
283
|
+
&& optional_equality(this.layout, other.layout)
|
|
284
|
+
&& optional_equality(this.program, other.program);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Hash over everything {@link equals} compares, in the same terms.
|
|
289
|
+
*
|
|
290
|
+
* @returns {number} int32
|
|
291
|
+
*/
|
|
292
|
+
hash() {
|
|
293
|
+
const bindings = hash_mix3(
|
|
294
|
+
hash_mix3(this.render_position, this.render_size, this.render_color),
|
|
295
|
+
hash_mix3(this.render_rotation, this.render_frame, this.render_velocity),
|
|
296
|
+
this.flags
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
const appearance = hash_mix3(
|
|
300
|
+
computeStringHash(this.texture),
|
|
301
|
+
hash_mix3(this.seed, computeHashFloat(this.spawn_rate), computeHashFloat(this.prewarm)),
|
|
302
|
+
this.emitting ? 1 : 0
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
return hash_mix3(
|
|
306
|
+
hash_mix2(bindings, float32_array_hash(this.flipbook, 0, this.flipbook.length)),
|
|
307
|
+
appearance,
|
|
308
|
+
hash_mix2(
|
|
309
|
+
optional_hash(this.layout),
|
|
310
|
+
optional_hash(this.program)
|
|
311
|
+
)
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Make this a copy of `other`: same effect, same settings.
|
|
317
|
+
*
|
|
318
|
+
* The layout and the compiled program are **shared** rather than duplicated — both are immutable
|
|
319
|
+
* once compiled, and sharing them is what puts two entities of one effect on one program id in
|
|
320
|
+
* the heap, hence in one simulation bucket.
|
|
321
|
+
*
|
|
322
|
+
* @param {ParticleEffect} other
|
|
323
|
+
* @returns {ParticleEffect} this
|
|
324
|
+
*/
|
|
325
|
+
copy(other) {
|
|
326
|
+
this.layout = other.layout;
|
|
327
|
+
this.program = other.program;
|
|
328
|
+
this.texture = other.texture;
|
|
329
|
+
|
|
330
|
+
this.seed = other.seed;
|
|
331
|
+
this.spawn_rate = other.spawn_rate;
|
|
332
|
+
this.emitting = other.emitting;
|
|
333
|
+
this.prewarm = other.prewarm;
|
|
334
|
+
this.flags = other.flags;
|
|
335
|
+
|
|
336
|
+
this.flipbook.set(other.flipbook);
|
|
337
|
+
|
|
338
|
+
this.render_position = other.render_position;
|
|
339
|
+
this.render_size = other.render_size;
|
|
340
|
+
this.render_color = other.render_color;
|
|
341
|
+
this.render_rotation = other.render_rotation;
|
|
342
|
+
this.render_frame = other.render_frame;
|
|
343
|
+
this.render_velocity = other.render_velocity;
|
|
344
|
+
|
|
345
|
+
return this;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* @returns {ParticleEffect}
|
|
350
|
+
*/
|
|
351
|
+
clone() {
|
|
352
|
+
return new ParticleEffect().copy(this);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Build a component from a plain description. Every field is optional — a component with no
|
|
357
|
+
* effect is a placeholder waiting for one — so an effect goes in by spreading what
|
|
358
|
+
* {@link ../../../../shade/renderer/particles/runtime/create_particle_effect.js create_particle_effect}
|
|
359
|
+
* returns: `ParticleEffect.from({ ...effect, spawn_rate: 100 })`.
|
|
360
|
+
*
|
|
361
|
+
* @param {object} [config]
|
|
362
|
+
* @param {import("../../../../shade/renderer/particles/layout/ParticleLayout.js").ParticleLayout} [config.layout]
|
|
363
|
+
* @param {import("../../../../shade/renderer/particles/isa/ParticleProgram.js").ParticleProgram} [config.program]
|
|
364
|
+
* @param {string|null} [config.texture] image URL to draw with
|
|
365
|
+
* @param {number} [config.seed]
|
|
366
|
+
* @param {number} [config.spawn_rate] particles/second
|
|
367
|
+
* @param {boolean} [config.emitting]
|
|
368
|
+
* @param {number} [config.prewarm] seconds of emission to run forward before the first frame
|
|
369
|
+
* @param {object} [config.flags] passed to `make_emitter_flags`
|
|
370
|
+
* @param {Object<string,string>} [config.render] render channel -> attribute name
|
|
371
|
+
* @param {ArrayLike<number>} [config.flipbook] `[columns, rows]`
|
|
372
|
+
* @returns {ParticleEffect}
|
|
373
|
+
*/
|
|
374
|
+
static from(config = {}) {
|
|
375
|
+
assert.isObject(config, 'config');
|
|
376
|
+
|
|
377
|
+
const effect = new ParticleEffect();
|
|
378
|
+
|
|
379
|
+
if (config.layout !== undefined) {
|
|
380
|
+
effect.layout = config.layout;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (config.program !== undefined) {
|
|
384
|
+
effect.program = config.program;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (config.texture !== undefined) {
|
|
388
|
+
effect.texture = config.texture;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (config.seed !== undefined) {
|
|
392
|
+
effect.seed = config.seed;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (config.spawn_rate !== undefined) {
|
|
396
|
+
effect.spawn_rate = config.spawn_rate;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (config.emitting !== undefined) {
|
|
400
|
+
effect.emitting = config.emitting;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (config.prewarm !== undefined) {
|
|
404
|
+
effect.prewarm = config.prewarm;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
effect.flags = make_emitter_flags(config.flags ?? {});
|
|
408
|
+
|
|
409
|
+
if (config.flipbook !== undefined) {
|
|
410
|
+
effect.flipbook.set(config.flipbook);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (config.render !== undefined) {
|
|
414
|
+
effect.bind_render(config.render);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return effect;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* The name this component is written under, and looked up by when a save is read. A serialization
|
|
423
|
+
* registry infers nothing from a class — see
|
|
424
|
+
* {@link ../../../ecs/storage/binary/BinarySerializationRegistry.js} — so this is what makes
|
|
425
|
+
* {@link ./ParticleEffectSerializationAdapter.js} reachable, and it is wire format: renaming the
|
|
426
|
+
* class is free, renaming this is a save-format break.
|
|
427
|
+
*
|
|
428
|
+
* @readonly
|
|
429
|
+
* @type {string}
|
|
430
|
+
*/
|
|
431
|
+
ParticleEffect.typeName = "ParticleEffect";
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Enables a fast type check, without having to import the class separately.
|
|
435
|
+
*
|
|
436
|
+
* @readonly
|
|
437
|
+
* @type {boolean}
|
|
438
|
+
*/
|
|
439
|
+
ParticleEffect.prototype.isParticleEffect = true;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary serialization for {@link ParticleEffect}.
|
|
3
|
+
*
|
|
4
|
+
* **The compiled effect is written, not a reference to one.** The VM's instruction set was designed
|
|
5
|
+
* to be a durable format — a fixed-width opcode encoding with a constant pool beside it — so a
|
|
6
|
+
* compiled program is content in exactly the way a mesh's index buffer is content, and a level that
|
|
7
|
+
* carries one needs neither the graph it came from nor a compiler at runtime. Authoring is an
|
|
8
|
+
* editor's job; a shipped build opens a save, reads instruction words, and runs them.
|
|
9
|
+
*
|
|
10
|
+
* That is also what makes the format's stability a real obligation. Two things here are wire format
|
|
11
|
+
* and cannot be renumbered without a version bump and an upgrader:
|
|
12
|
+
*
|
|
13
|
+
* - **opcodes**, whose numbers are `../../../../shade/renderer/particles/isa/ParticleVMISA.js`, and
|
|
14
|
+
* - **attribute order in the layout**, because a layout assigns word offsets sequentially from the
|
|
15
|
+
* order it is built in, and the render bindings below are those offsets. Offsets are therefore not
|
|
16
|
+
* written: they are recomputed on load from the same order, and a change to how
|
|
17
|
+
* {@link ParticleLayout} packs would silently repoint every binding in every save.
|
|
18
|
+
*
|
|
19
|
+
* ## The constant pool is written as bits
|
|
20
|
+
*
|
|
21
|
+
* The pool holds constants, not measurements, and two of them can be the same number: `-0` and `+0`
|
|
22
|
+
* are distinct pool words because a `DIV` by each disagrees about the sign of the infinity it
|
|
23
|
+
* produces, and the assembler interns with `Object.is` to keep them apart. `ParticleProgram` compares
|
|
24
|
+
* and hashes the pool through its bit view (`constant_words`) for exactly that reason.
|
|
25
|
+
*
|
|
26
|
+
* So does this. Not because a float path is known to lose something — measured on V8 it does not,
|
|
27
|
+
* `-0` survives `setFloat32` and so does a NaN's payload — but because whether a NaN survives a
|
|
28
|
+
* round trip through a JS `number` is **implementation-defined**: the language permits an engine to
|
|
29
|
+
* canonicalize, and the one this runs on is not the only one it will ever run on. Writing the words
|
|
30
|
+
* the program is already compared by makes the reload exact by construction rather than by an
|
|
31
|
+
* engine's discretion, and it means there is one representation of the pool rather than two.
|
|
32
|
+
*
|
|
33
|
+
* ## Nothing device-shaped is written
|
|
34
|
+
*
|
|
35
|
+
* There is nothing here that a device assigned: no table row, no generation, no program-heap
|
|
36
|
+
* placement, no atlas patch. Those belong to the registry that registered the emitter and are
|
|
37
|
+
* rebuilt on load like every other GPU resource. What is written is what an author typed.
|
|
38
|
+
*
|
|
39
|
+
* @author Alex Goldring
|
|
40
|
+
* @copyright Company Named Limited (c) 2026
|
|
41
|
+
*/
|
|
42
|
+
export class ParticleEffectSerializationAdapter extends BinaryClassSerializationAdapter<any> {
|
|
43
|
+
constructor();
|
|
44
|
+
klass: typeof ParticleEffect;
|
|
45
|
+
/**
|
|
46
|
+
* @param {BinaryBuffer} buffer
|
|
47
|
+
* @param {ParticleEffect} value
|
|
48
|
+
*/
|
|
49
|
+
serialize(buffer: BinaryBuffer, value: ParticleEffect): void;
|
|
50
|
+
/**
|
|
51
|
+
* @param {BinaryBuffer} buffer
|
|
52
|
+
* @param {ParticleEffect} value
|
|
53
|
+
*/
|
|
54
|
+
deserialize(buffer: BinaryBuffer, value: ParticleEffect): void;
|
|
55
|
+
}
|
|
56
|
+
import { BinaryClassSerializationAdapter } from "../../../ecs/storage/binary/BinaryClassSerializationAdapter.js";
|
|
57
|
+
import { ParticleEffect } from "./ParticleEffect.js";
|
|
58
|
+
//# sourceMappingURL=ParticleEffectSerializationAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ParticleEffectSerializationAdapter.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH;;IAEI,6BAAuB;IAGvB;;;OAGG;IACH,uCAFW,cAAc,QAmCxB;IAED;;;OAGG;IACH,yCAFW,cAAc,QA8BxB;CACJ;gDAzH+C,gEAAgE;+BACjF,qBAAqB"}
|