{"_id":"5a8356d8d3dc0f008636c6ef","category":{"_id":"5a8356d8d3dc0f008636c6d6","version":"5a8356d8d3dc0f008636c6d4","project":"5a065a6134873d0010b396ab","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-07-18T21:08:45.730Z","from_sync":false,"order":1,"slug":"develop","title":"Develop"},"project":"5a065a6134873d0010b396ab","user":"57bb7defafc18c0e00529cf1","parentDoc":null,"version":{"_id":"5a8356d8d3dc0f008636c6d4","project":"5a065a6134873d0010b396ab","__v":1,"createdAt":"2018-02-13T21:21:28.228Z","releaseDate":"2018-02-13T21:21:28.228Z","categories":["5a8356d8d3dc0f008636c6d5","5a8356d8d3dc0f008636c6d6","5a8356d8d3dc0f008636c6d7","5a8356d8d3dc0f008636c6d8"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.3.0","version":"1.3.0"},"__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2017-09-16T01:55:33.000Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":11,"body":"Viro's particle system enables developers to create and configure quad emitters for building complex and intricate particle effects. Some examples are smoke, rain, confetti, and fireworks. This development guide will go through several examples of effects that can be created. \n\n[ParticleEmitter](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.html) is a particle factory that creates, contains, and recycles a pool of particles. Groups of particle emitters can be used in conjunction with one another to create a composite effect. For example, a campfire may include a flame emitter, a smoke emitter, and an ember or sparks emitter.\n\nBelow is a code snippet of a basic ParticleEmitter, one that creates a simple 'Fountain' like effect. \n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"Material snowMaterial = new Material();\\nsnowMaterial.setTexture(snowTexture);\\n\\nSurface particle = new Surface(0.1f, 0.1f);\\nparticle.setMaterials(Arrays.asList(snowMaterial));\\n\\nParticleEmitter emitter = new ParticleEmitter(context, particle);\\nemitter.setDuration(2000);\\nemitter.run();\\n\\nNode node = new Node();\\nnode.setPosition(new Vector(0, 4.5f, 0));\\nnode.setParticleEmitter(emitter);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nAs shown above, there are three steps to creating a particle effect:\n\n1. Provide a Surface representing the particles to emit.\n2. Configure a ParticleEmitter.\n3. Attach the ParticleEmitter to a Node and start the emitter.\n[block:api-header]\n{\n  \"title\": \"Basic Emitter Properties\"\n}\n[/block]\nThere are several ways to configure a ParticleEmitter. First, shown below are basic properties of the emitter itself. These include what image to emit, when to emit, and how long to emit for.\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Property\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"surface\",\n    \"1-0\": \"delay / duration / loop / run\",\n    \"0-1\": \"Passed in through the constructor. The Surface is the visual representation of a single quad particle. You can configure this Surface with any Material and Texture.\",\n    \"1-1\": \"These parameters control how long to wait before starting an emission cycle, how long the emission cycle should run for, and if the cycle should be repeated continually.\"\n  },\n  \"cols\": 2,\n  \"rows\": 2\n}\n[/block]\nThe second set of configuration attributes have have to do with spawn behavior: the spawn rate, spawn volume, and burst intervals, if any. \n\n##Spawn Rates \nHow fast an emitter produces particles is determined by either **emissionRatePerSecond** or **emissionRatePerMeter** (in which the particle output is proportional to how fast the emitter itself is moving). Depending on the effect you wish to create, you may decide to one or both properties. For example, in a situation where steam particles are emitted from a train upon movement, emissionRatePerMeter is the sensible choice. This is also true if you, say, have a spaceship that emits more smoke as it accelerates. \n\nHow long a particle lives for (or how fast a particle dies) is defined by **particleLifetime**, in milliseconds. Specifying particleLifeTime and particleEmissionRate determines an eventual steady state. In this steady state, there will be a roughly constant number of existing, spawned particles for the emitter. \n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Emission Rate\",\n    \"h-1\": \"Particle LifeTime\",\n    \"h-2\": \"Max Particles\",\n    \"h-3\": \"Steady State Outcome\",\n    \"0-0\": \"High\",\n    \"1-0\": \"Low\",\n    \"2-0\": \"High\",\n    \"3-0\": \"High\",\n    \"4-0\": \"Low\",\n    \"5-0\": \"High\",\n    \"0-1\": \"Low\",\n    \"3-1\": \"Low\",\n    \"5-2\": \"High\",\n    \"4-2\": \"High\",\n    \"3-2\": \"High\",\n    \"2-2\": \"Low\",\n    \"1-2\": \"Low\",\n    \"0-2\": \"Low\",\n    \"5-1\": \"High\",\n    \"4-1\": \"High\",\n    \"2-1\": \"High\",\n    \"1-1\": \"High\",\n    \"0-3\": \"A quick \\\"jet of particles\\\" that die quickly, possibly resulting in emitter starvation.\",\n    \"1-3\": \"Particles are produced slowly, but are long-lived, eventually resulting in emitter starvation.\",\n    \"2-3\": \"A quick \\\"jet of particles\\\" that are long-lived. Quickly results in emitter starvation.\",\n    \"3-3\": \"Particles are produced quickly and die quickly.\",\n    \"4-3\": \"Particles are produced slowly, and live for a long time. (Possible performance cost)\",\n    \"5-3\": \"Lots of particles, produced quickly, that live for along time. (High performance cost)\"\n  },\n  \"cols\": 4,\n  \"rows\": 6\n}\n[/block]\nTo prevent an unbounded number of particles, the ViroParticleEmitter also provides a ```maxParticles``` property. \n\n```maxParticles = emittedParticlesPerSecond + emittedParticlesPerMeter + emissionBurst```\n\nThis number caps the number of live particles per emitter at any point in time. It is important to note that the more particles your scene has, the higher the performance cost. It is recommended to keep ```maxParticles``` low when possible.\n\n##Spawn Burst\nIn addition to emitting particles at a constant rate, certain particle effects may require the ability to instantaneously spawn *n* number of particles all at once in a single burst. Fireworks, sparks, and explosions are some examples. To specify a burst use the ```setEmissionBursts(List<EmissionBurst>)``` method. Here you can specify a time (or distance traveled) at which to burst a number of particles, in repetition if needed. These bursts are done in conjunction with emission rates, and are also subjected to the same ```maxParticles``` constraint.\n\n##Spawn Volumes\nBy default, an emitter spawns particles at the location of the emitter. This is useful for effects tied to a single source, like smoke rising from a chimney. However, other effects may require more complex spawn volumes; for example, spawning snow or rain over an area of land. \n\nWith the ```setSpawnVolume(SpawnVolume, boolean)``` method, can specify the shape within which to spawn particles. Supported shapes are [SpawnVolumeBox](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.SpawnVolumeBox.html) with width, height, and length, [SpawnVolumeSphere](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.SpawnVolumeSphere.html) with radius, [SpawnVolumeEllipsoid](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.SpawnVolumeEllipsoid.html) with an x,y,z ellipsoid length, and [SpawnVolumePoint](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.SpawnVolumePoint.html). All particles will spawn in a uniformly distributed pattern within the shape.\n\nFinally, there may be effects that require particles to spawn on the surface of a shape, rather than within it. For example, fireworks require particles to be spawned on the surface of a sphere. To achieve this effect, set the ```spawnOnSurface``` boolean to true. Particles will be spawned in a uniformly distributed fashion on the surface of the specified shape. \n[block:api-header]\n{\n  \"title\": \"Particle Appearance Attributes\"\n}\n[/block]\nThe visual traits of particles may change over time. For example, firework particles may change in color, while smoke particles may grow in size before disappearing into the sky. These visual behaviors can be created through various particle visual properties.\n\nThere are four types of particle visual properties: `setOpacityModifier`, `setScaleModifier`, `setRotationModifier`, and setColorModifier`. Each of these methods takes a ParticleModifier as its sole argument. To configure a ParticleModifier:\n\n1. Provide an **initial range** of values. For each particle a value will be chosen from a uniform distribution across this range. If the range consists of two identical values, there will be no randomization. The initial range is set in the constructor of the ParticleModifier.\n\n2. If the property is dynamic (meaning it changes over the course of the particle's lifetime), then it needs a **factor** against which to interpolate the change. This can be either `ParticleEmitter.Factor.TIME` (e.g. making a particle scale down over time) or `ParticleEmitter.Factor.DISTANCE` (e.g. making a particle scale down as it moves away).\n\n3. Finally, again only if the property is dynamic, provide a list of **interpolation** data to describe the change over time. Each item in the interpolation list consists of the **endValue** you wish to interpolate toward, and the **interval** within which to interpolate. Interval values can start and end at any point in the particle's lifecycle, as long as they do not overlap each other.\n\nAn interpolation example is provided below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"Material snowMaterial = new Material();\\nsnowMaterial.setTexture(snowTexture);\\n\\nSurface particle = new Surface(0.1f, 0.1f);\\nparticle.setMaterials(Arrays.asList(snowMaterial));\\n\\nParticleEmitter emitter = new ParticleEmitter(context, particle);\\nemitter.setDuration(2000);\\nemitter.run();\\n\\n// Initial range [1.0, 1.0], so all particles will have opacity 1.0 initially\\nParticleModifierFloat opacityModifier = new ParticleModifierFloat(1.0f, 1.0f);\\nopacityModifier.setFactor(ParticleEmitter.Factor.TIME);\\nopacityModifier.addInterval(500, 0.8f);  // Drop opacity to 0.8 after 500 ms\\nopacityModifier.addInterval(1000, 0.0f); // Drop opacity to 0.0 after 1 second\\nemitter.setOpacityModifier(opacityModifier);\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nIn the snippet above, we are manipulating the opacity of our particles by slowly fading them out to 0.8 over the first 500 milliseconds, and then we fade them completely to 0.0 at 1000 milliseconds.\n[block:api-header]\n{\n  \"title\": \"Particle Physics Attributes\"\n}\n[/block]\nBy default, particle emitters radiate particles in a fountain-like fashion. This movement behavior is also configurable. Whether it be falling snow, rising smoke, or exploding fireworks, these physics-specific attributes describe how a particle moves over the course of its lifetime.\n\nThe first two properties -- `setVelocityModifier` and `setAccelerationModifier` -- are straightforward: they define each particle's initial velocity or constantly applied acceleration. Setting these values will override the emitter's \"fountain-like\" default behavior. As before, you can provide a range of two identical values to eliminate randomization. Or you can provide a lower and upper bound.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/b2ebd69-ezgif.com-video-to-gif.gif\",\n        \"ezgif.com-video-to-gif.gif\",\n        600,\n        337,\n        \"#040404\"\n      ],\n      \"caption\": \"Falling snow with velocity and acceleration\"\n    }\n  ]\n}\n[/block]\nA variety of affects can be produced with these two properties. For example, falling, swaying snow can be achieved with a fixed acceleration of -9.81 and a randomized initial horizontal velocity. A similar configuration can be used to make steam particles emanate from a kettle. Note also that these physics properties can be used in conjunction with the animation system. For example, to make a tornado, radiate particles upward in a fountain-like fashion with fixed velocity, then rotate the node clockwise about the Y axis with an animation.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/42936e8-ezgif.com-crop.gif\",\n        \"ezgif.com-crop.gif\",\n        291,\n        291,\n        \"#040404\"\n      ],\n      \"caption\": \"Sharknado anyone?\"\n    }\n  ]\n}\n[/block]\nWhen moving particles, the ```fixedToEmitter``` property controls the reference point to use when computing the particle's appearance and movement. When true, Viro uses the emitter's current position; when false, Viro uses each particle's individual spawn location. Under ```fixedToEmitter = false```, particles are not \"locked\" to the emitter; they can float away. For example, smoke particles from a moving train would continue floating upward from the location they were spawned. Under ```fixedToEmitter = true```, the smoke particles would be \"locked\" to the train's emitter: they would always move with the train in reference to the emitter's location.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/264c1c3-ezgif.com-crop_1.gif\",\n        \"ezgif.com-crop (1).gif\",\n        295,\n        165,\n        \"#040404\"\n      ],\n      \"caption\": \"A moving \\\"train\\\" with smoke particles (fixedToEmitter: false)\"\n    }\n  ]\n}\n[/block]\nImpulsive forces, to create effects like explosions, are also possible. For example, fireworks require an initial impulse on every particle, each in a different direction from the detonation point. This behavior can be achieved with the `setExplosiveImpulse(float impulse, Vector position, float decelerationPeriod)` method. This impulse is specified in newton seconds. The position parameter (relative to the particle emitter) indicates the center of the detonation: the closer particles are to the detonation point, the greater their explosive force. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/7e2b641-ezgif.com-resize_1.gif\",\n        \"ezgif.com-resize (1).gif\",\n        400,\n        400,\n        \"#2a2c24\"\n      ],\n      \"caption\": \"Fireworks in NYC!\"\n    }\n  ]\n}\n[/block]\nFinally, the behavior of an explosion may also be tuned with the ```decelerationPeriod``` parameter. This effectively enables developers to apply a \"dampening deceleration effect\" against the explosive impulse force, in order to slow down the explosion. The ```decelerationPeriod``` defines the timeframe within which the particles will decelerate from their initial velocity to 0.0 m/s. This is particularly useful for fireworks, which explode outward then slow down / are dampened after a specific length of time or spherical size. An interesting side effect of this property is that the deceleration dampener effect is still applied even after the ```decelerationPeriod```, if the particle is still alive. That is to say, the particle would continue to decelerate in the opposite direction of the explosion, creating a \"gravitational attraction\" effect.\n\nIt is also important to note that invoking `setExplosiveImpulse` automatically invalidates any initial velocity setting, as an explosion directly manipulates an object's velocity. Likewise, the ```decelerationPeriod``` will override any acceleration setting.","excerpt":"","slug":"particle-effects","type":"basic","title":"Particle Effects"}
Viro's particle system enables developers to create and configure quad emitters for building complex and intricate particle effects. Some examples are smoke, rain, confetti, and fireworks. This development guide will go through several examples of effects that can be created. [ParticleEmitter](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.html) is a particle factory that creates, contains, and recycles a pool of particles. Groups of particle emitters can be used in conjunction with one another to create a composite effect. For example, a campfire may include a flame emitter, a smoke emitter, and an ember or sparks emitter. Below is a code snippet of a basic ParticleEmitter, one that creates a simple 'Fountain' like effect. [block:code] { "codes": [ { "code": "Material snowMaterial = new Material();\nsnowMaterial.setTexture(snowTexture);\n\nSurface particle = new Surface(0.1f, 0.1f);\nparticle.setMaterials(Arrays.asList(snowMaterial));\n\nParticleEmitter emitter = new ParticleEmitter(context, particle);\nemitter.setDuration(2000);\nemitter.run();\n\nNode node = new Node();\nnode.setPosition(new Vector(0, 4.5f, 0));\nnode.setParticleEmitter(emitter);", "language": "java" } ] } [/block] As shown above, there are three steps to creating a particle effect: 1. Provide a Surface representing the particles to emit. 2. Configure a ParticleEmitter. 3. Attach the ParticleEmitter to a Node and start the emitter. [block:api-header] { "title": "Basic Emitter Properties" } [/block] There are several ways to configure a ParticleEmitter. First, shown below are basic properties of the emitter itself. These include what image to emit, when to emit, and how long to emit for. [block:parameters] { "data": { "h-0": "Property", "h-1": "Description", "0-0": "surface", "1-0": "delay / duration / loop / run", "0-1": "Passed in through the constructor. The Surface is the visual representation of a single quad particle. You can configure this Surface with any Material and Texture.", "1-1": "These parameters control how long to wait before starting an emission cycle, how long the emission cycle should run for, and if the cycle should be repeated continually." }, "cols": 2, "rows": 2 } [/block] The second set of configuration attributes have have to do with spawn behavior: the spawn rate, spawn volume, and burst intervals, if any. ##Spawn Rates How fast an emitter produces particles is determined by either **emissionRatePerSecond** or **emissionRatePerMeter** (in which the particle output is proportional to how fast the emitter itself is moving). Depending on the effect you wish to create, you may decide to one or both properties. For example, in a situation where steam particles are emitted from a train upon movement, emissionRatePerMeter is the sensible choice. This is also true if you, say, have a spaceship that emits more smoke as it accelerates. How long a particle lives for (or how fast a particle dies) is defined by **particleLifetime**, in milliseconds. Specifying particleLifeTime and particleEmissionRate determines an eventual steady state. In this steady state, there will be a roughly constant number of existing, spawned particles for the emitter. [block:parameters] { "data": { "h-0": "Emission Rate", "h-1": "Particle LifeTime", "h-2": "Max Particles", "h-3": "Steady State Outcome", "0-0": "High", "1-0": "Low", "2-0": "High", "3-0": "High", "4-0": "Low", "5-0": "High", "0-1": "Low", "3-1": "Low", "5-2": "High", "4-2": "High", "3-2": "High", "2-2": "Low", "1-2": "Low", "0-2": "Low", "5-1": "High", "4-1": "High", "2-1": "High", "1-1": "High", "0-3": "A quick \"jet of particles\" that die quickly, possibly resulting in emitter starvation.", "1-3": "Particles are produced slowly, but are long-lived, eventually resulting in emitter starvation.", "2-3": "A quick \"jet of particles\" that are long-lived. Quickly results in emitter starvation.", "3-3": "Particles are produced quickly and die quickly.", "4-3": "Particles are produced slowly, and live for a long time. (Possible performance cost)", "5-3": "Lots of particles, produced quickly, that live for along time. (High performance cost)" }, "cols": 4, "rows": 6 } [/block] To prevent an unbounded number of particles, the ViroParticleEmitter also provides a ```maxParticles``` property. ```maxParticles = emittedParticlesPerSecond + emittedParticlesPerMeter + emissionBurst``` This number caps the number of live particles per emitter at any point in time. It is important to note that the more particles your scene has, the higher the performance cost. It is recommended to keep ```maxParticles``` low when possible. ##Spawn Burst In addition to emitting particles at a constant rate, certain particle effects may require the ability to instantaneously spawn *n* number of particles all at once in a single burst. Fireworks, sparks, and explosions are some examples. To specify a burst use the ```setEmissionBursts(List<EmissionBurst>)``` method. Here you can specify a time (or distance traveled) at which to burst a number of particles, in repetition if needed. These bursts are done in conjunction with emission rates, and are also subjected to the same ```maxParticles``` constraint. ##Spawn Volumes By default, an emitter spawns particles at the location of the emitter. This is useful for effects tied to a single source, like smoke rising from a chimney. However, other effects may require more complex spawn volumes; for example, spawning snow or rain over an area of land. With the ```setSpawnVolume(SpawnVolume, boolean)``` method, can specify the shape within which to spawn particles. Supported shapes are [SpawnVolumeBox](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.SpawnVolumeBox.html) with width, height, and length, [SpawnVolumeSphere](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.SpawnVolumeSphere.html) with radius, [SpawnVolumeEllipsoid](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.SpawnVolumeEllipsoid.html) with an x,y,z ellipsoid length, and [SpawnVolumePoint](https://developer.viromedia.com/virocore/reference/com/viro/core/ParticleEmitter.SpawnVolumePoint.html). All particles will spawn in a uniformly distributed pattern within the shape. Finally, there may be effects that require particles to spawn on the surface of a shape, rather than within it. For example, fireworks require particles to be spawned on the surface of a sphere. To achieve this effect, set the ```spawnOnSurface``` boolean to true. Particles will be spawned in a uniformly distributed fashion on the surface of the specified shape. [block:api-header] { "title": "Particle Appearance Attributes" } [/block] The visual traits of particles may change over time. For example, firework particles may change in color, while smoke particles may grow in size before disappearing into the sky. These visual behaviors can be created through various particle visual properties. There are four types of particle visual properties: `setOpacityModifier`, `setScaleModifier`, `setRotationModifier`, and setColorModifier`. Each of these methods takes a ParticleModifier as its sole argument. To configure a ParticleModifier: 1. Provide an **initial range** of values. For each particle a value will be chosen from a uniform distribution across this range. If the range consists of two identical values, there will be no randomization. The initial range is set in the constructor of the ParticleModifier. 2. If the property is dynamic (meaning it changes over the course of the particle's lifetime), then it needs a **factor** against which to interpolate the change. This can be either `ParticleEmitter.Factor.TIME` (e.g. making a particle scale down over time) or `ParticleEmitter.Factor.DISTANCE` (e.g. making a particle scale down as it moves away). 3. Finally, again only if the property is dynamic, provide a list of **interpolation** data to describe the change over time. Each item in the interpolation list consists of the **endValue** you wish to interpolate toward, and the **interval** within which to interpolate. Interval values can start and end at any point in the particle's lifecycle, as long as they do not overlap each other. An interpolation example is provided below: [block:code] { "codes": [ { "code": "Material snowMaterial = new Material();\nsnowMaterial.setTexture(snowTexture);\n\nSurface particle = new Surface(0.1f, 0.1f);\nparticle.setMaterials(Arrays.asList(snowMaterial));\n\nParticleEmitter emitter = new ParticleEmitter(context, particle);\nemitter.setDuration(2000);\nemitter.run();\n\n// Initial range [1.0, 1.0], so all particles will have opacity 1.0 initially\nParticleModifierFloat opacityModifier = new ParticleModifierFloat(1.0f, 1.0f);\nopacityModifier.setFactor(ParticleEmitter.Factor.TIME);\nopacityModifier.addInterval(500, 0.8f); // Drop opacity to 0.8 after 500 ms\nopacityModifier.addInterval(1000, 0.0f); // Drop opacity to 0.0 after 1 second\nemitter.setOpacityModifier(opacityModifier);", "language": "json" } ] } [/block] In the snippet above, we are manipulating the opacity of our particles by slowly fading them out to 0.8 over the first 500 milliseconds, and then we fade them completely to 0.0 at 1000 milliseconds. [block:api-header] { "title": "Particle Physics Attributes" } [/block] By default, particle emitters radiate particles in a fountain-like fashion. This movement behavior is also configurable. Whether it be falling snow, rising smoke, or exploding fireworks, these physics-specific attributes describe how a particle moves over the course of its lifetime. The first two properties -- `setVelocityModifier` and `setAccelerationModifier` -- are straightforward: they define each particle's initial velocity or constantly applied acceleration. Setting these values will override the emitter's "fountain-like" default behavior. As before, you can provide a range of two identical values to eliminate randomization. Or you can provide a lower and upper bound. [block:image] { "images": [ { "image": [ "https://files.readme.io/b2ebd69-ezgif.com-video-to-gif.gif", "ezgif.com-video-to-gif.gif", 600, 337, "#040404" ], "caption": "Falling snow with velocity and acceleration" } ] } [/block] A variety of affects can be produced with these two properties. For example, falling, swaying snow can be achieved with a fixed acceleration of -9.81 and a randomized initial horizontal velocity. A similar configuration can be used to make steam particles emanate from a kettle. Note also that these physics properties can be used in conjunction with the animation system. For example, to make a tornado, radiate particles upward in a fountain-like fashion with fixed velocity, then rotate the node clockwise about the Y axis with an animation. [block:image] { "images": [ { "image": [ "https://files.readme.io/42936e8-ezgif.com-crop.gif", "ezgif.com-crop.gif", 291, 291, "#040404" ], "caption": "Sharknado anyone?" } ] } [/block] When moving particles, the ```fixedToEmitter``` property controls the reference point to use when computing the particle's appearance and movement. When true, Viro uses the emitter's current position; when false, Viro uses each particle's individual spawn location. Under ```fixedToEmitter = false```, particles are not "locked" to the emitter; they can float away. For example, smoke particles from a moving train would continue floating upward from the location they were spawned. Under ```fixedToEmitter = true```, the smoke particles would be "locked" to the train's emitter: they would always move with the train in reference to the emitter's location. [block:image] { "images": [ { "image": [ "https://files.readme.io/264c1c3-ezgif.com-crop_1.gif", "ezgif.com-crop (1).gif", 295, 165, "#040404" ], "caption": "A moving \"train\" with smoke particles (fixedToEmitter: false)" } ] } [/block] Impulsive forces, to create effects like explosions, are also possible. For example, fireworks require an initial impulse on every particle, each in a different direction from the detonation point. This behavior can be achieved with the `setExplosiveImpulse(float impulse, Vector position, float decelerationPeriod)` method. This impulse is specified in newton seconds. The position parameter (relative to the particle emitter) indicates the center of the detonation: the closer particles are to the detonation point, the greater their explosive force. [block:image] { "images": [ { "image": [ "https://files.readme.io/7e2b641-ezgif.com-resize_1.gif", "ezgif.com-resize (1).gif", 400, 400, "#2a2c24" ], "caption": "Fireworks in NYC!" } ] } [/block] Finally, the behavior of an explosion may also be tuned with the ```decelerationPeriod``` parameter. This effectively enables developers to apply a "dampening deceleration effect" against the explosive impulse force, in order to slow down the explosion. The ```decelerationPeriod``` defines the timeframe within which the particles will decelerate from their initial velocity to 0.0 m/s. This is particularly useful for fireworks, which explode outward then slow down / are dampened after a specific length of time or spherical size. An interesting side effect of this property is that the deceleration dampener effect is still applied even after the ```decelerationPeriod```, if the particle is still alive. That is to say, the particle would continue to decelerate in the opposite direction of the explosion, creating a "gravitational attraction" effect. It is also important to note that invoking `setExplosiveImpulse` automatically invalidates any initial velocity setting, as an explosion directly manipulates an object's velocity. Likewise, the ```decelerationPeriod``` will override any acceleration setting.