@fps-games/vfx 0.3.2 → 0.3.4
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/CHANGELOG.md +16 -0
- package/README.md +5 -5
- package/dist/effects/treasure-attention/index.d.ts +1 -1
- package/package.json +6 -5
- package/tooling/vfx-cli.mjs +31 -22
- package/tooling/vfx-package-resolution.mjs +8 -8
- package/docs/AUTHORING_EFFECTS.md +0 -297
- package/docs/INTEGRATION.md +0 -194
- package/docs/VFX_LIBRARY_ARCHITECTURE_chatgpt.md +0 -1580
- package/docs/VFX_LIBRARY_EXECUTION_PLAN.md +0 -229
- package/docs/VFX_LIBRARY_PLAN.md +0 -546
- package/docs/hit-flash-red-method.md +0 -155
- package/docs/treasure_attention_fx_babylonjs_guide.md +0 -901
- package/docs/vfx-ab/RESULTS.md +0 -35
- package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/after.png +0 -0
- package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/before.png +0 -0
- package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/after.png +0 -0
- package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/before.png +0 -0
- package/docs/vfx-integration_chatgpt.md +0 -462
- package/docs/vfx-placement-design.md +0 -164
- package/docs/weapon-trail-visualization.html +0 -241
- package/packages/EffectPackageService.ts +0 -346
- package/packages/SceneVfxService.ts +0 -96
- package/packages/build.mesh.yellow_build_upgrade_indicator/assets/runtime/simpleMeshEffect.v1.js +0 -333
- package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.frag.glsl +0 -25
- package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.vert.glsl +0 -11
- package/packages/build.mesh.yellow_build_upgrade_indicator/assets/textures/effect_jianbian.png +0 -0
- package/packages/build.mesh.yellow_build_upgrade_indicator/effect.json +0 -927
- package/packages/build.mesh.yellow_build_upgrade_indicator/media/contact-sheet.png +0 -0
- package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.gif +0 -0
- package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.mp4 +0 -0
- package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.webm +0 -0
- package/packages/build.mesh.yellow_build_upgrade_indicator/media/thumbnail.png +0 -0
- package/packages/build.mesh.yellow_build_upgrade_indicator/metadata/description.json +0 -197
- package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-effect.original.json +0 -895
- package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-normalized-vfx-to-babylon-report.json +0 -241
- package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-overrides.json +0 -542
- package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-tuning-report.json +0 -69
- package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/asset-map.json +0 -125
- package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/lineage.json +0 -44
- package/packages/build.particle.golden_upgrade_starburst/assets/runtime/particleEmitter.v1.js +0 -210
- package/packages/build.particle.golden_upgrade_starburst/assets/textures/effect_guangdian.png +0 -0
- package/packages/build.particle.golden_upgrade_starburst/effect.json +0 -880
- package/packages/build.particle.golden_upgrade_starburst/media/contact-sheet.png +0 -0
- package/packages/build.particle.golden_upgrade_starburst/media/preview.gif +0 -0
- package/packages/build.particle.golden_upgrade_starburst/media/preview.mp4 +0 -0
- package/packages/build.particle.golden_upgrade_starburst/media/preview.webm +0 -0
- package/packages/build.particle.golden_upgrade_starburst/media/thumbnail.png +0 -0
- package/packages/build.particle.golden_upgrade_starburst/metadata/description.json +0 -161
- package/packages/build.particle.golden_upgrade_starburst/provenance/03-effect.original.json +0 -762
- package/packages/build.particle.golden_upgrade_starburst/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
- package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-overrides.json +0 -436
- package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-tuning-report.json +0 -40
- package/packages/build.particle.golden_upgrade_starburst/provenance/asset-map.json +0 -115
- package/packages/build.particle.golden_upgrade_starburst/provenance/lineage.json +0 -40
- package/packages/build.particle.orange_upgrade_transform_sparks/assets/runtime/particleEmitter.v1.js +0 -210
- package/packages/build.particle.orange_upgrade_transform_sparks/assets/textures/b5b27ab1-e740-4398-b407-848fc2b2c897.png +0 -0
- package/packages/build.particle.orange_upgrade_transform_sparks/effect.json +0 -887
- package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.gif +0 -0
- package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.mp4 +0 -0
- package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.webm +0 -0
- package/packages/build.particle.orange_upgrade_transform_sparks/media/thumbnail.png +0 -0
- package/packages/build.particle.orange_upgrade_transform_sparks/metadata/description.json +0 -179
- package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-effect.original.json +0 -859
- package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
- package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-overrides.json +0 -478
- package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-tuning-report.json +0 -40
- package/packages/build.particle.orange_upgrade_transform_sparks/provenance/asset-map.json +0 -114
- package/packages/build.particle.orange_upgrade_transform_sparks/provenance/lineage.json +0 -41
- package/packages/build.particle.wood_chip_dust_burst/assets/runtime/particleEmitter.v1.js +0 -210
- package/packages/build.particle.wood_chip_dust_burst/assets/textures/effect_yanwu4.png +0 -0
- package/packages/build.particle.wood_chip_dust_burst/assets/textures/suipian3.png +0 -0
- package/packages/build.particle.wood_chip_dust_burst/effect.json +0 -1400
- package/packages/build.particle.wood_chip_dust_burst/media/contact-sheet.png +0 -0
- package/packages/build.particle.wood_chip_dust_burst/media/preview.gif +0 -0
- package/packages/build.particle.wood_chip_dust_burst/media/preview.mp4 +0 -0
- package/packages/build.particle.wood_chip_dust_burst/media/preview.webm +0 -0
- package/packages/build.particle.wood_chip_dust_burst/media/thumbnail.png +0 -0
- package/packages/build.particle.wood_chip_dust_burst/metadata/description.json +0 -173
- package/packages/build.particle.wood_chip_dust_burst/provenance/03-effect.original.json +0 -1277
- package/packages/build.particle.wood_chip_dust_burst/provenance/03-normalized-vfx-to-babylon-report.json +0 -329
- package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-overrides.json +0 -749
- package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-tuning-report.json +0 -60
- package/packages/build.particle.wood_chip_dust_burst/provenance/asset-map.json +0 -146
- package/packages/build.particle.wood_chip_dust_burst/provenance/lineage.json +0 -69
- package/packages/effects/building-upgrade/effect.json +0 -6
- package/packages/effects/building-upgrade/index.ts +0 -387
- package/packages/effects/character-entrance/effect.json +0 -6
- package/packages/effects/character-entrance/index.ts +0 -308
- package/packages/effects/coin-burst/index.ts +0 -48
- package/packages/effects/comet-trail-flame/assets/textures/trail_5x4.webp +0 -0
- package/packages/effects/comet-trail-flame/index.ts +0 -107
- package/packages/effects/conveyor-upgrade/effect.json +0 -6
- package/packages/effects/conveyor-upgrade/index.ts +0 -401
- package/packages/effects/debris-smoke/assets/models/rock_debris.glb +0 -0
- package/packages/effects/debris-smoke/assets/textures/smoke22.webp +0 -0
- package/packages/effects/debris-smoke/index.ts +0 -102
- package/packages/effects/door_open_gold_flakes/assets/runtime/goldFlakes.v1.js +0 -397
- package/packages/effects/door_open_gold_flakes/door_open_gold_flakes.json +0 -498
- package/packages/effects/door_open_gold_flakes/index.ts +0 -11
- package/packages/effects/electric-arc/assets/textures/spark_4x4.webp +0 -0
- package/packages/effects/electric-arc/index.ts +0 -63
- package/packages/effects/energy-shield/effect.json +0 -7
- package/packages/effects/energy-shield/index.ts +0 -432
- package/packages/effects/explosion/assets/textures/baozha29.webp +0 -0
- package/packages/effects/explosion/assets/textures/glow01.webp +0 -0
- package/packages/effects/explosion/assets/textures/lizi01.webp +0 -0
- package/packages/effects/explosion/assets/textures/xulie_lizibaozha02_5x5.webp +0 -0
- package/packages/effects/explosion/index.ts +0 -115
- package/packages/effects/ground-tile-upgrade/effect.json +0 -6
- package/packages/effects/ground-tile-upgrade/index.ts +0 -410
- package/packages/effects/hit-flash/index.ts +0 -77
- package/packages/effects/laser-beam/assets/textures/laser_glow.webp +0 -0
- package/packages/effects/laser-beam/assets/textures/laser_noise.webp +0 -0
- package/packages/effects/laser-beam/index.ts +0 -6
- package/packages/effects/laser-beam-factory.ts +0 -146
- package/packages/effects/lumber-cart-suction/effect.json +0 -6
- package/packages/effects/lumber-cart-suction/index.ts +0 -399
- package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb +0 -0
- package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/.active +0 -1
- package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/1781589063890_upload.glb +0 -0
- package/packages/effects/lumber-debris-scatter/assets/runtime/solidParticleScatter.v1.js +0 -236
- package/packages/effects/lumber-debris-scatter/effect.json +0 -228
- package/packages/effects/lumber-debris-scatter/index.ts +0 -780
- package/packages/effects/lumber_vehicle_gear_spin/assets/runtime/gearSpin.v1.js +0 -202
- package/packages/effects/lumber_vehicle_gear_spin/index.ts +0 -11
- package/packages/effects/lumber_vehicle_gear_spin/lumber_vehicle_gear_spin.json +0 -338
- package/packages/effects/lumber_vehicle_upgrade_aura/assets/runtime/upgradeAura.v1.js +0 -353
- package/packages/effects/lumber_vehicle_upgrade_aura/index.ts +0 -13
- package/packages/effects/lumber_vehicle_upgrade_aura/lumber_vehicle_upgrade_aura.json +0 -365
- package/packages/effects/lumber_vehicle_wood_chips/assets/runtime/solidParticleScatter.v1.js +0 -310
- package/packages/effects/lumber_vehicle_wood_chips/index.ts +0 -11
- package/packages/effects/lumber_vehicle_wood_chips/lumber_vehicle_wood_chips.json +0 -335
- package/packages/effects/monster-hit/index.ts +0 -129
- package/packages/effects/player-upgrade/effect.json +0 -6
- package/packages/effects/player-upgrade/index.ts +0 -640
- package/packages/effects/pulse-laser-volley/assets/textures/bolt_guangshu.webp +0 -0
- package/packages/effects/pulse-laser-volley/index.ts +0 -215
- package/packages/effects/resource-collect-sparkles/effect.json +0 -6
- package/packages/effects/resource-collect-sparkles/index.ts +0 -254
- package/packages/effects/run-footstep-dust/assets/runtime/runFootstepDust.v1.js +0 -215
- package/packages/effects/run-footstep-dust/effect.json +0 -183
- package/packages/effects/run-footstep-dust/index.ts +0 -377
- package/packages/effects/space-shared.ts +0 -120
- package/packages/effects/thruster-flame/index.ts +0 -306
- package/packages/effects/treasure-attention/effect.json +0 -7
- package/packages/effects/treasure-attention/index.ts +0 -630
- package/packages/effects/tree-chop-dust/assets/textures/tree_chop_dust_atlas.png +0 -0
- package/packages/effects/tree-chop-dust/effect.json +0 -8
- package/packages/effects/tree-chop-dust/index.ts +0 -202
- package/packages/effects/tree-leaf-chop-burst/assets/runtime/particleEmitter.v1.js +0 -303
- package/packages/effects/tree-leaf-chop-burst/assets/textures/tree_leaf_chop_burst_leaf_atlas.png +0 -0
- package/packages/effects/tree-leaf-chop-burst/effect.json +0 -498
- package/packages/effects/tree-leaf-chop-burst/index.ts +0 -294
- package/packages/effects/tree_chop_dust_burst/assets/runtime/particleEmitter.v1.js +0 -318
- package/packages/effects/tree_chop_dust_burst/assets/textures/tree_chop_dust_burst_dust.png +0 -0
- package/packages/effects/tree_chop_dust_burst/index.ts +0 -13
- package/packages/effects/tree_chop_dust_burst/tree_chop_dust_burst.json +0 -412
- package/packages/effects/ufo-thread-flame/assets/textures/flame_flow.webp +0 -0
- package/packages/effects/ufo-thread-flame/assets/textures/flame_spike.webp +0 -0
- package/packages/effects/ufo-thread-flame/index.ts +0 -153
- package/packages/effects/vehicle-exhaust-smoke/assets/textures/vehicle_exhaust_smoke_atlas.png +0 -0
- package/packages/effects/vehicle-exhaust-smoke/effect.json +0 -8
- package/packages/effects/vehicle-exhaust-smoke/index.ts +0 -298
- package/packages/effects/vehicle-upgrade/effect.json +0 -6
- package/packages/effects/vehicle-upgrade/index.ts +0 -404
- package/packages/effects/weapon-trail/assets/textures/trail_wedge.png +0 -0
- package/packages/effects/weapon-trail/index.ts +0 -317
- package/packages/effects/wood-crusher-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
- package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
- package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
- package/packages/effects/wood-crusher-sawdust/index.ts +0 -43
- package/packages/effects/wood-crusher-sawdust/wood_crusher_sawdust.json +0 -592
- package/packages/effects/wood-cutter-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
- package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
- package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
- package/packages/effects/wood-cutter-sawdust/index.ts +0 -43
- package/packages/effects/wood-cutter-sawdust/wood_cutter_sawdust.json +0 -592
- package/packages/effects/wood-sawdust-effect-factory.ts +0 -194
- package/packages/effects/wood_crusher_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
- package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
- package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
- package/packages/effects/wood_crusher_sawdust/index.ts +0 -29
- package/packages/effects/wood_crusher_sawdust/wood_crusher_sawdust.json +0 -592
- package/packages/effects/wood_cutter_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
- package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
- package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
- package/packages/effects/wood_cutter_sawdust/index.ts +0 -29
- package/packages/effects/wood_cutter_sawdust/wood_cutter_sawdust.json +0 -592
- package/packages/effects/wood_peel_material_test/assets/runtime/woodPeelMaterialTest.v1.js +0 -196
- package/packages/effects/wood_peel_material_test/index.ts +0 -11
- package/packages/effects/wood_peel_material_test/wood_peel_material_test.json +0 -136
- package/packages/env.particle.forest_edge_fog/assets/runtime/particleEmitter.v1.js +0 -210
- package/packages/env.particle.forest_edge_fog/assets/textures/f12a23c4-b924-4322-a260-3d982428f1e8.png +0 -0
- package/packages/env.particle.forest_edge_fog/assets/textures/yuan.png +0 -0
- package/packages/env.particle.forest_edge_fog/effect.json +0 -854
- package/packages/env.particle.forest_edge_fog/media/preview.gif +0 -0
- package/packages/env.particle.forest_edge_fog/media/preview.mp4 +0 -0
- package/packages/env.particle.forest_edge_fog/media/preview.webm +0 -0
- package/packages/env.particle.forest_edge_fog/media/thumbnail.png +0 -0
- package/packages/env.particle.forest_edge_fog/metadata/description.json +0 -148
- package/packages/env.particle.forest_edge_fog/provenance/03-effect.original.json +0 -827
- package/packages/env.particle.forest_edge_fog/provenance/03-normalized-vfx-to-babylon-report.json +0 -196
- package/packages/env.particle.forest_edge_fog/provenance/04-preview-overrides.json +0 -432
- package/packages/env.particle.forest_edge_fog/provenance/04-preview-tuning-report.json +0 -28
- package/packages/env.particle.forest_edge_fog/provenance/asset-map.json +0 -124
- package/packages/env.particle.forest_edge_fog/provenance/lineage.json +0 -41
- package/packages/generation.ts +0 -14
- package/packages/index.ts +0 -14
- package/packages/legacy-particle-runtime.ts +0 -113
- package/packages/manifestRuntimePackage.ts +0 -519
- package/packages/registry.ts +0 -85
- package/packages/rendering.ts +0 -13
- package/packages/resource.particle.viscous_oil_suction/assets/runtime/top_disk_suction/particleEmitter.v1.js +0 -424
- package/packages/resource.particle.viscous_oil_suction/assets/textures/Glow ad.png +0 -0
- package/packages/resource.particle.viscous_oil_suction/effect.json +0 -1254
- package/packages/resource.particle.viscous_oil_suction/media/preview.gif +0 -0
- package/packages/resource.particle.viscous_oil_suction/media/preview.mp4 +0 -0
- package/packages/resource.particle.viscous_oil_suction/media/preview.webm +0 -0
- package/packages/resource.particle.viscous_oil_suction/media/thumbnail.png +0 -0
- package/packages/resource.particle.viscous_oil_suction/metadata/description.json +0 -122
- package/packages/resource.particle.viscous_oil_suction/provenance/03-effect.original.json +0 -1051
- package/packages/resource.particle.viscous_oil_suction/provenance/03-normalized-vfx-to-babylon-report.json +0 -200
- package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-overrides.json +0 -581
- package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-tuning-report.json +0 -28
- package/packages/resource.particle.viscous_oil_suction/provenance/asset-map.json +0 -111
- package/packages/resource.particle.viscous_oil_suction/provenance/lineage.json +0 -45
- package/packages/types.ts +0 -195
- package/tooling/check-dist-runtime.mjs +0 -166
- package/tooling/generate-index.mjs +0 -55
- package/tooling/test-guardrails.mjs +0 -157
- package/tooling/validate-boundary.mjs +0 -92
- package/tooling/validate-effects.mjs +0 -304
- package/tooling/validate.mjs +0 -53
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
export const runtimeId = "particleEmitter/topDiskSuction/v1";
|
|
2
|
-
|
|
3
|
-
export const runtimeContract = {
|
|
4
|
-
runtimeId,
|
|
5
|
-
kind: "particleEmitter",
|
|
6
|
-
emitterFields: {
|
|
7
|
-
capacity: "Maximum Babylon particle capacity.",
|
|
8
|
-
particleTexturePath: "Package-relative particle texture path used to load the Babylon ParticleSystem.particleTexture.",
|
|
9
|
-
blendMode: "Babylon particle blend mode label: ADD, STANDARD, MULTIPLY, or ONEONE.",
|
|
10
|
-
shape: "Emitter shape definition generated by the Cocos conversion stage.",
|
|
11
|
-
renderColor: "Converted particle color inputs: one base color plus RGB/alpha intensity before writing Babylon color1/color2/colorDead.",
|
|
12
|
-
alphaKeys: "Color alpha gradients sampled over normalized particle lifetime.",
|
|
13
|
-
sizeKeys: "Size gradients sampled over normalized particle lifetime.",
|
|
14
|
-
velocityOverLifetime: "Cocos VelocityOvertimeModule vector velocity sampled over normalized particle lifetime.",
|
|
15
|
-
topDiskSuction: "Reusable behavior config for sampling particles on a top disk and directing them toward a target center.",
|
|
16
|
-
},
|
|
17
|
-
runtimeBindings: {
|
|
18
|
-
"ParticleSystem.particleTexture": "Texture loaded from emitter.particleTexturePath through urlForPackagePath.",
|
|
19
|
-
"ParticleSystem.blendMode": "Mapped from emitter.blendMode.",
|
|
20
|
-
"ParticleSystem.manualEmitCount": "emitter.manualEmitCount when emitRate is 0.",
|
|
21
|
-
"ParticleSystem.emitRate": "emitter.emitRate for sustained emitters.",
|
|
22
|
-
"ParticleSystem.shape": "Mapped from emitter.shape.type and shape parameters.",
|
|
23
|
-
"ParticleSystem.startPositionFunction": "Overridden when shape.emitMode is topDiskSuctionToTarget to sample a top disk.",
|
|
24
|
-
"ParticleSystem.startDirectionFunction": "Overridden when shape.emitMode is topDiskSuctionToTarget to aim particles toward the target center.",
|
|
25
|
-
"ParticleSystem.colorGradient": "emitter.alphaKeys applied to the final ParticleSystem.color1.",
|
|
26
|
-
"ParticleSystem.sizeGradient": "emitter.sizeKeys multiplied by emitter.maxSize.",
|
|
27
|
-
"ParticleSystem.updateFunction": "Wrapped when emitter.velocityOverLifetime exists to add Cocos local/world velocity-over-lifetime displacement.",
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const BABYLON_PARTICLE_UPDATE_SPEED_UNIT = 0.01;
|
|
32
|
-
|
|
33
|
-
function num(value, fallback = 0) {
|
|
34
|
-
const next = Number(value);
|
|
35
|
-
return Number.isFinite(next) ? next : fallback;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function readColor(BABYLON, value, fallback = new BABYLON.Color4(1, 1, 1, 1)) {
|
|
39
|
-
if (!value) return fallback;
|
|
40
|
-
return new BABYLON.Color4(num(value.r, fallback.r), num(value.g, fallback.g), num(value.b, fallback.b), num(value.a, fallback.a));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function applyRenderColorIntensity(BABYLON, color, renderColor = {}) {
|
|
44
|
-
const colorIntensity = Math.max(0, num(renderColor.colorIntensity, 1));
|
|
45
|
-
const alphaIntensity = Math.max(0, num(renderColor.alphaIntensity, colorIntensity));
|
|
46
|
-
return new BABYLON.Color4(
|
|
47
|
-
color.r * colorIntensity,
|
|
48
|
-
color.g * colorIntensity,
|
|
49
|
-
color.b * colorIntensity,
|
|
50
|
-
Math.min(1, color.a * alphaIntensity)
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function particleColors(BABYLON, emitter) {
|
|
55
|
-
const renderColor = emitter.renderColor;
|
|
56
|
-
const baseColor = readColor(BABYLON, renderColor?.color, new BABYLON.Color4(1, 1, 1, 1));
|
|
57
|
-
const color1 = applyRenderColorIntensity(BABYLON, baseColor, renderColor);
|
|
58
|
-
return {
|
|
59
|
-
color1,
|
|
60
|
-
color2: color1,
|
|
61
|
-
colorDead: new BABYLON.Color4(color1.r, color1.g, color1.b, 0),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function readVec(BABYLON, value, fallback = new BABYLON.Vector3(0, 0, 0)) {
|
|
66
|
-
if (!value) return fallback;
|
|
67
|
-
return new BABYLON.Vector3(num(value.x, fallback.x), num(value.y, fallback.y), num(value.z, fallback.z));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function readScaleVec(BABYLON, value, fallback = new BABYLON.Vector3(1, 1, 1)) {
|
|
71
|
-
if (!value) return fallback;
|
|
72
|
-
return new BABYLON.Vector3(num(value.x, fallback.x), num(value.y, fallback.y), num(value.z, fallback.z));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function degreesToRadians(value) {
|
|
76
|
-
return num(value, 0) * Math.PI / 180;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function createEmitterTransform(BABYLON, scene, emitter, index) {
|
|
80
|
-
const transform = emitter.transform || emitter.cocosSource?.transform || {};
|
|
81
|
-
const node = new BABYLON.TransformNode(`particle-emitter-transform-${emitter.name || index}`, scene);
|
|
82
|
-
node.position = readVec(BABYLON, transform.position, BABYLON.Vector3.Zero());
|
|
83
|
-
node.rotation = new BABYLON.Vector3(
|
|
84
|
-
degreesToRadians(transform.rotation?.x),
|
|
85
|
-
degreesToRadians(transform.rotation?.y),
|
|
86
|
-
degreesToRadians(transform.rotation?.z)
|
|
87
|
-
);
|
|
88
|
-
node.scaling = readScaleVec(BABYLON, transform.scale, new BABYLON.Vector3(1, 1, 1));
|
|
89
|
-
return node;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function blendMode(BABYLON, value) {
|
|
93
|
-
if (value === "STANDARD") return BABYLON.ParticleSystem.BLENDMODE_STANDARD;
|
|
94
|
-
if (value === "MULTIPLY") return BABYLON.ParticleSystem.BLENDMODE_MULTIPLY;
|
|
95
|
-
if (value === "ONEONE") return BABYLON.ParticleSystem.BLENDMODE_ONEONE;
|
|
96
|
-
return BABYLON.ParticleSystem.BLENDMODE_ADD;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function billboardMode(BABYLON, value) {
|
|
100
|
-
if (!value || BABYLON.ParticleSystem[value] === undefined) return undefined;
|
|
101
|
-
return BABYLON.ParticleSystem[value];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function coneAxisBasis(BABYLON, axisDirection) {
|
|
105
|
-
const yAxis = readVec(BABYLON, axisDirection, new BABYLON.Vector3(0, 1, 0));
|
|
106
|
-
if (yAxis.lengthSquared() < 1e-6) yAxis.set(0, 1, 0);
|
|
107
|
-
yAxis.normalize();
|
|
108
|
-
const helper = Math.abs(BABYLON.Vector3.Dot(yAxis, new BABYLON.Vector3(0, 1, 0))) > 0.98
|
|
109
|
-
? new BABYLON.Vector3(1, 0, 0)
|
|
110
|
-
: new BABYLON.Vector3(0, 1, 0);
|
|
111
|
-
const xAxis = BABYLON.Vector3.Cross(helper, yAxis).normalize();
|
|
112
|
-
const zAxis = BABYLON.Vector3.Cross(yAxis, xAxis).normalize();
|
|
113
|
-
return { xAxis, yAxis, zAxis };
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function setFromConeBasis(basis, x, y, z, out) {
|
|
117
|
-
out.copyFrom(basis.xAxis).scaleInPlace(x);
|
|
118
|
-
out.addInPlace(basis.yAxis.scale(y));
|
|
119
|
-
out.addInPlace(basis.zAxis.scale(z));
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function applyCocosConeEmitFunctions(BABYLON, system, radius, angle, radiusRange, axisDirection, length, emitFrom, directionScale = 1) {
|
|
123
|
-
const safeRadius = Math.max(0, radius);
|
|
124
|
-
const safeLength = Math.max(0.001, num(length, 1));
|
|
125
|
-
const halfAngle = Math.min(Math.PI, Math.max(0, angle));
|
|
126
|
-
const basis = coneAxisBasis(BABYLON, axisDirection);
|
|
127
|
-
const localPosition = new BABYLON.Vector3();
|
|
128
|
-
const localDirection = new BABYLON.Vector3();
|
|
129
|
-
const radialPoint = new BABYLON.Vector3();
|
|
130
|
-
const emitMode = Number(emitFrom);
|
|
131
|
-
const emitFromMode = Number.isFinite(emitMode) ? emitMode : 0;
|
|
132
|
-
const emitFromShell = emitFromMode === 2;
|
|
133
|
-
const emitFromVolume = emitFromMode === 3;
|
|
134
|
-
const speedDirectionScale = directionScale < 0 ? -1 : 1;
|
|
135
|
-
const innerRadius = safeRadius * Math.max(0, 1 - radiusRange);
|
|
136
|
-
|
|
137
|
-
function sampleRadialPoint(out, forceShell = false) {
|
|
138
|
-
const phi = Math.random() * Math.PI * 2;
|
|
139
|
-
const innerSq = forceShell ? safeRadius * safeRadius : innerRadius * innerRadius;
|
|
140
|
-
const outerSq = safeRadius * safeRadius;
|
|
141
|
-
const r = forceShell
|
|
142
|
-
? safeRadius
|
|
143
|
-
: Math.sqrt(Math.max(0, innerSq + Math.random() * Math.max(0, outerSq - innerSq)));
|
|
144
|
-
setFromConeBasis(
|
|
145
|
-
basis,
|
|
146
|
-
r * Math.cos(phi),
|
|
147
|
-
0,
|
|
148
|
-
r * Math.sin(phi),
|
|
149
|
-
out
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function directionFromRadialPoint(point, out) {
|
|
154
|
-
out.copyFrom(point).scaleInPlace(Math.sin(halfAngle) * speedDirectionScale);
|
|
155
|
-
out.addInPlace(basis.yAxis.scale(Math.cos(halfAngle) * Math.max(0.0001, safeRadius)));
|
|
156
|
-
if (out.lengthSquared() > 1e-6) out.normalize();
|
|
157
|
-
else out.copyFrom(basis.yAxis);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function sampleCocosConePositionAndDirection(positionOut, directionOut) {
|
|
161
|
-
sampleRadialPoint(radialPoint, emitFromShell);
|
|
162
|
-
directionFromRadialPoint(radialPoint, directionOut);
|
|
163
|
-
positionOut.copyFrom(radialPoint);
|
|
164
|
-
if (emitFromVolume) {
|
|
165
|
-
const axisComponent = Math.max(0.0001, BABYLON.Vector3.Dot(directionOut, basis.yAxis));
|
|
166
|
-
positionOut.addInPlace(directionOut.scale(speedDirectionScale * safeLength * Math.random() / axisComponent));
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
system.startPositionFunction = (worldMatrix, positionToUpdate, particle, isLocal) => {
|
|
171
|
-
sampleCocosConePositionAndDirection(localPosition, localDirection);
|
|
172
|
-
particle._cocosConeLocalDirection = particle._cocosConeLocalDirection || new BABYLON.Vector3();
|
|
173
|
-
particle._cocosConeLocalDirection.copyFrom(localDirection);
|
|
174
|
-
if (isLocal) positionToUpdate.copyFrom(localPosition);
|
|
175
|
-
else BABYLON.Vector3.TransformCoordinatesToRef(localPosition, worldMatrix, positionToUpdate);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
system.startDirectionFunction = (worldMatrix, directionToUpdate, particle, isLocal) => {
|
|
179
|
-
if (particle._cocosConeLocalDirection) localDirection.copyFrom(particle._cocosConeLocalDirection);
|
|
180
|
-
else {
|
|
181
|
-
sampleRadialPoint(radialPoint, emitFromShell);
|
|
182
|
-
directionFromRadialPoint(radialPoint, localDirection);
|
|
183
|
-
}
|
|
184
|
-
if (isLocal) directionToUpdate.copyFrom(localDirection);
|
|
185
|
-
else BABYLON.Vector3.TransformNormalToRef(localDirection, worldMatrix, directionToUpdate);
|
|
186
|
-
if (directionToUpdate.lengthSquared() > 1e-6) directionToUpdate.normalize();
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function applyTopDiskSuctionEmitFunctions(BABYLON, system, radius, radiusRange, axisDirection, length, transformScale, preserveWorldShapeSize = false) {
|
|
191
|
-
const safeRadius = Math.max(0, radius);
|
|
192
|
-
const safeLength = Math.max(0.001, num(length, 1));
|
|
193
|
-
const basis = coneAxisBasis(BABYLON, axisDirection);
|
|
194
|
-
const innerRadius = safeRadius * Math.max(0, 1 - radiusRange);
|
|
195
|
-
const localPosition = new BABYLON.Vector3();
|
|
196
|
-
const localDirection = new BABYLON.Vector3();
|
|
197
|
-
const scaledPosition = new BABYLON.Vector3();
|
|
198
|
-
const targetCenter = BABYLON.Vector3.Zero();
|
|
199
|
-
const safeScale = new BABYLON.Vector3(
|
|
200
|
-
Math.max(0.0001, Math.abs(num(transformScale?.x, 1))),
|
|
201
|
-
Math.max(0.0001, Math.abs(num(transformScale?.y, 1))),
|
|
202
|
-
Math.max(0.0001, Math.abs(num(transformScale?.z, 1)))
|
|
203
|
-
);
|
|
204
|
-
const inverseScale = new BABYLON.Vector3(
|
|
205
|
-
1 / safeScale.x,
|
|
206
|
-
1 / safeScale.y,
|
|
207
|
-
1 / safeScale.z
|
|
208
|
-
);
|
|
209
|
-
|
|
210
|
-
function sampleTopDiskPosition(out) {
|
|
211
|
-
const phi = Math.random() * Math.PI * 2;
|
|
212
|
-
const innerSq = innerRadius * innerRadius;
|
|
213
|
-
const outerSq = safeRadius * safeRadius;
|
|
214
|
-
const r = Math.sqrt(Math.max(0, innerSq + Math.random() * Math.max(0, outerSq - innerSq)));
|
|
215
|
-
setFromConeBasis(
|
|
216
|
-
basis,
|
|
217
|
-
r * Math.cos(phi),
|
|
218
|
-
-safeLength,
|
|
219
|
-
r * Math.sin(phi),
|
|
220
|
-
out
|
|
221
|
-
);
|
|
222
|
-
if (preserveWorldShapeSize) out.multiplyInPlace(inverseScale);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function directionToTargetCenter(position, out) {
|
|
226
|
-
if (preserveWorldShapeSize) {
|
|
227
|
-
scaledPosition.copyFrom(position).multiplyInPlace(safeScale);
|
|
228
|
-
targetCenter.subtractToRef(scaledPosition, out);
|
|
229
|
-
} else {
|
|
230
|
-
targetCenter.subtractToRef(position, out);
|
|
231
|
-
}
|
|
232
|
-
if (out.lengthSquared() > 1e-6) out.normalize();
|
|
233
|
-
else out.copyFrom(basis.yAxis);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
system.startPositionFunction = (worldMatrix, positionToUpdate, particle, isLocal) => {
|
|
237
|
-
sampleTopDiskPosition(localPosition);
|
|
238
|
-
particle._cocosConeLocalDirection = particle._cocosConeLocalDirection || new BABYLON.Vector3();
|
|
239
|
-
directionToTargetCenter(localPosition, particle._cocosConeLocalDirection);
|
|
240
|
-
if (isLocal) positionToUpdate.copyFrom(localPosition);
|
|
241
|
-
else BABYLON.Vector3.TransformCoordinatesToRef(localPosition, worldMatrix, positionToUpdate);
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
system.startDirectionFunction = (worldMatrix, directionToUpdate, particle, isLocal) => {
|
|
245
|
-
if (particle._cocosConeLocalDirection) localDirection.copyFrom(particle._cocosConeLocalDirection);
|
|
246
|
-
else {
|
|
247
|
-
sampleTopDiskPosition(localPosition);
|
|
248
|
-
directionToTargetCenter(localPosition, localDirection);
|
|
249
|
-
}
|
|
250
|
-
if (isLocal) directionToUpdate.copyFrom(localDirection);
|
|
251
|
-
else BABYLON.Vector3.TransformNormalToRef(localDirection, worldMatrix, directionToUpdate);
|
|
252
|
-
if (directionToUpdate.lengthSquared() > 1e-6) directionToUpdate.normalize();
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
function applyEmitterShape(BABYLON, system, emitter) {
|
|
257
|
-
const shape = emitter.shape || {};
|
|
258
|
-
const type = shape.type;
|
|
259
|
-
const radius = num(shape.radius, 1);
|
|
260
|
-
const radiusRange = Math.min(1, Math.max(0, num(shape.radiusRange, 1)));
|
|
261
|
-
const angle = num(shape.angle, Math.PI / 4);
|
|
262
|
-
const length = num(shape.length, 1);
|
|
263
|
-
const topDiskSuction = emitter.topDiskSuction || {};
|
|
264
|
-
const topDiskRadius = num(topDiskSuction.topDiskRadius, radius);
|
|
265
|
-
const topDiskRadiusRange = Math.min(1, Math.max(0, num(topDiskSuction.topDiskRadiusRange, radiusRange)));
|
|
266
|
-
const suctionLength = num(topDiskSuction.suctionLength, length);
|
|
267
|
-
const direction1 = readVec(BABYLON, shape.direction1, new BABYLON.Vector3(0, 1, 0));
|
|
268
|
-
const direction2 = readVec(BABYLON, shape.direction2, new BABYLON.Vector3(0, 1, 0));
|
|
269
|
-
const boxMin = readVec(BABYLON, shape.minEmitBox, new BABYLON.Vector3(-radius * 0.5, -radius * 0.5, -radius * 0.5));
|
|
270
|
-
const boxMax = readVec(BABYLON, shape.maxEmitBox, new BABYLON.Vector3(radius * 0.5, radius * 0.5, radius * 0.5));
|
|
271
|
-
|
|
272
|
-
if (type === "Box") {
|
|
273
|
-
system.createBoxEmitter(direction1, direction2, boxMin, boxMax);
|
|
274
|
-
} else if (type === "SphereDirected") {
|
|
275
|
-
system.createDirectedSphereEmitter(radius, direction1, direction2);
|
|
276
|
-
} else if (type === "Sphere") {
|
|
277
|
-
system.createSphereEmitter(radius, radiusRange);
|
|
278
|
-
} else if (type === "Hemisphere") {
|
|
279
|
-
system.createHemisphericEmitter(radius, radiusRange);
|
|
280
|
-
} else if (type === "Cone") {
|
|
281
|
-
const dirSpread = direction1.subtract(direction2).lengthSquared();
|
|
282
|
-
if (dirSpread < 1e-4) {
|
|
283
|
-
system.createConeEmitter(Math.max(0.001, radius), angle);
|
|
284
|
-
if (shape.emitMode === "topDiskSuctionToTarget") {
|
|
285
|
-
applyTopDiskSuctionEmitFunctions(BABYLON, system, topDiskRadius, topDiskRadiusRange, direction1, suctionLength, emitter.transform?.scale, shape.preserveWorldShapeSize === true);
|
|
286
|
-
} else {
|
|
287
|
-
applyCocosConeEmitFunctions(BABYLON, system, radius, angle, radiusRange, direction1, length, shape.emitFrom, shape.directionScale);
|
|
288
|
-
}
|
|
289
|
-
} else {
|
|
290
|
-
system.createDirectedConeEmitter(Math.max(0.001, radius), angle, direction1, direction2);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
function addGradients(BABYLON, system, emitter, color1) {
|
|
296
|
-
for (const key of emitter.alphaKeys || []) {
|
|
297
|
-
const time = Math.min(1, Math.max(0, num(key.time, 0)));
|
|
298
|
-
const alpha = Math.min(1, Math.max(0, num(key.alpha, 1)));
|
|
299
|
-
system.addColorGradient?.(time, new BABYLON.Color4(color1.r, color1.g, color1.b, Math.min(1, color1.a * alpha)));
|
|
300
|
-
}
|
|
301
|
-
for (const key of emitter.sizeKeys || []) {
|
|
302
|
-
const time = Math.min(1, Math.max(0, num(key.time, 0)));
|
|
303
|
-
const size = Math.max(0.001, num(key.size, 1) * num(emitter.maxSize, 1));
|
|
304
|
-
system.addSizeGradient?.(time, size);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
function sampleValueKeys(keys, time, fallback = 0) {
|
|
309
|
-
if (!Array.isArray(keys) || keys.length === 0) return fallback;
|
|
310
|
-
const sorted = [...keys].sort((a, b) => num(a.time, 0) - num(b.time, 0));
|
|
311
|
-
if (time <= num(sorted[0].time, 0)) return num(sorted[0].value, fallback);
|
|
312
|
-
for (let index = 1; index < sorted.length; index += 1) {
|
|
313
|
-
const prev = sorted[index - 1];
|
|
314
|
-
const next = sorted[index];
|
|
315
|
-
const prevTime = num(prev.time, 0);
|
|
316
|
-
const nextTime = num(next.time, 1);
|
|
317
|
-
if (time <= nextTime) {
|
|
318
|
-
const span = Math.max(0.0001, nextTime - prevTime);
|
|
319
|
-
const ratio = (time - prevTime) / span;
|
|
320
|
-
return num(prev.value, fallback) + (num(next.value, fallback) - num(prev.value, fallback)) * ratio;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
return num(sorted[sorted.length - 1].value, fallback);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
function rangeAverage(range, fallback = 1) {
|
|
327
|
-
if (!range) return fallback;
|
|
328
|
-
return (num(range.min, fallback) + num(range.max, fallback)) * 0.5;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function applyVelocityOverLifetime(BABYLON, system, emitterTransform, emitter) {
|
|
332
|
-
const config = emitter.velocityOverLifetime;
|
|
333
|
-
if (!config?.axes || typeof system.updateFunction !== "function") return;
|
|
334
|
-
const baseUpdate = system.updateFunction.bind(system);
|
|
335
|
-
const localVelocity = new BABYLON.Vector3();
|
|
336
|
-
const worldVelocity = new BABYLON.Vector3();
|
|
337
|
-
const speedModifier = rangeAverage(config.speedModifier, 1);
|
|
338
|
-
const isLocalSpace = config.space === 0 || config.space === "local";
|
|
339
|
-
|
|
340
|
-
system.updateFunction = (particles) => {
|
|
341
|
-
baseUpdate(particles);
|
|
342
|
-
const worldMatrix = emitterTransform.getWorldMatrix();
|
|
343
|
-
for (const particle of particles) {
|
|
344
|
-
const lifeRatio = particle.lifeTime > 0 ? Math.min(1, Math.max(0, particle.age / particle.lifeTime)) : 0;
|
|
345
|
-
localVelocity.set(
|
|
346
|
-
sampleValueKeys(config.axes.x, lifeRatio, 0),
|
|
347
|
-
sampleValueKeys(config.axes.y, lifeRatio, 0),
|
|
348
|
-
sampleValueKeys(config.axes.z, lifeRatio, 0)
|
|
349
|
-
);
|
|
350
|
-
localVelocity.scaleInPlace(speedModifier * system.updateSpeed);
|
|
351
|
-
if (isLocalSpace) BABYLON.Vector3.TransformNormalToRef(localVelocity, worldMatrix, worldVelocity);
|
|
352
|
-
else worldVelocity.copyFrom(localVelocity);
|
|
353
|
-
particle.position.addInPlace(worldVelocity);
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
function playbackSpeed(emitter) {
|
|
359
|
-
return Math.max(0.001, num(emitter.updateSpeed, BABYLON_PARTICLE_UPDATE_SPEED_UNIT) / BABYLON_PARTICLE_UPDATE_SPEED_UNIT);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function runtimeDuration(emitter) {
|
|
363
|
-
return Math.max(0.1, num(emitter.runtime?.stopAfterSeconds, 3) / playbackSpeed(emitter));
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export async function createParticleEmitterRuntime({ BABYLON, scene, emitter, index = 0, urlForPackagePath, shouldStart = false }) {
|
|
367
|
-
if (!BABYLON) throw new Error("createParticleEmitterRuntime requires BABYLON.");
|
|
368
|
-
if (!scene) throw new Error("createParticleEmitterRuntime requires scene.");
|
|
369
|
-
if (!emitter) throw new Error("createParticleEmitterRuntime requires emitter.");
|
|
370
|
-
|
|
371
|
-
const capacity = Math.max(1, Math.round(num(emitter.capacity, 100)));
|
|
372
|
-
const system = new BABYLON.ParticleSystem(`particle-emitter-${emitter.name || index}`, capacity, scene);
|
|
373
|
-
const textureUrl = urlForPackagePath ? urlForPackagePath(emitter.particleTexturePath) : emitter.particleTexturePath;
|
|
374
|
-
system.particleTexture = new BABYLON.Texture(textureUrl, scene);
|
|
375
|
-
system.particleTexture.hasAlpha = true;
|
|
376
|
-
const emitterTransform = createEmitterTransform(BABYLON, scene, emitter, index);
|
|
377
|
-
system.emitter = emitterTransform;
|
|
378
|
-
system.blendMode = blendMode(BABYLON, emitter.blendMode);
|
|
379
|
-
system.isLocal = emitter.isLocal === true;
|
|
380
|
-
system.minSize = Math.max(0.001, num(emitter.minSize, 1));
|
|
381
|
-
system.maxSize = Math.max(system.minSize, num(emitter.maxSize, system.minSize));
|
|
382
|
-
system.minScaleX = Math.max(0.001, num(emitter.minScaleX, 1));
|
|
383
|
-
system.maxScaleX = Math.max(system.minScaleX, num(emitter.maxScaleX, system.minScaleX));
|
|
384
|
-
system.minScaleY = Math.max(0.001, num(emitter.minScaleY, 1));
|
|
385
|
-
system.maxScaleY = Math.max(system.minScaleY, num(emitter.maxScaleY, system.minScaleY));
|
|
386
|
-
system.minLifeTime = Math.max(0.02, num(emitter.minLifeTime, 0.55));
|
|
387
|
-
system.maxLifeTime = Math.max(system.minLifeTime, num(emitter.maxLifeTime, system.minLifeTime));
|
|
388
|
-
system.minEmitPower = Math.max(0, num(emitter.minEmitPower, 1));
|
|
389
|
-
system.maxEmitPower = Math.max(system.minEmitPower, num(emitter.maxEmitPower, system.minEmitPower));
|
|
390
|
-
system.updateSpeed = Math.max(0.00001, num(emitter.updateSpeed, BABYLON_PARTICLE_UPDATE_SPEED_UNIT));
|
|
391
|
-
system.gravity = readVec(BABYLON, emitter.gravity, new BABYLON.Vector3(0, -6, 0));
|
|
392
|
-
system.emitRate = Math.max(0, num(emitter.emitRate, 0));
|
|
393
|
-
if (system.emitRate <= 0) system.manualEmitCount = Math.max(0, Math.round(num(emitter.manualEmitCount, 0)));
|
|
394
|
-
|
|
395
|
-
const colors = particleColors(BABYLON, emitter);
|
|
396
|
-
system.color1 = colors.color1;
|
|
397
|
-
system.color2 = colors.color2;
|
|
398
|
-
system.colorDead = colors.colorDead;
|
|
399
|
-
system.minInitialRotation = num(emitter.minInitialRotation, 0);
|
|
400
|
-
system.maxInitialRotation = num(emitter.maxInitialRotation, system.minInitialRotation);
|
|
401
|
-
system.minAngularSpeed = num(emitter.minAngularSpeed, 0);
|
|
402
|
-
system.maxAngularSpeed = num(emitter.maxAngularSpeed, system.minAngularSpeed);
|
|
403
|
-
|
|
404
|
-
const nextBillboardMode = billboardMode(BABYLON, emitter.billboardMode);
|
|
405
|
-
if (nextBillboardMode !== undefined) system.billboardMode = nextBillboardMode;
|
|
406
|
-
|
|
407
|
-
applyEmitterShape(BABYLON, system, emitter);
|
|
408
|
-
addGradients(BABYLON, system, emitter, system.color1);
|
|
409
|
-
applyVelocityOverLifetime(BABYLON, system, emitterTransform, emitter);
|
|
410
|
-
|
|
411
|
-
const preview = {
|
|
412
|
-
start: () => system.start(),
|
|
413
|
-
stop: () => system.stop(),
|
|
414
|
-
dispose: () => {
|
|
415
|
-
system.dispose();
|
|
416
|
-
emitterTransform.dispose();
|
|
417
|
-
},
|
|
418
|
-
isStarted: () => system.isStarted(),
|
|
419
|
-
duration: runtimeDuration(emitter),
|
|
420
|
-
system,
|
|
421
|
-
};
|
|
422
|
-
if (shouldStart) preview.start();
|
|
423
|
-
return preview;
|
|
424
|
-
}
|