API

Expanding Solid Particle Systems

Create an expandable SPS

Until now, the SPS you created has had a fixed number of particles once and for all because that is the most performant way to use it.
In some cases, it may be useful to add or remove particles from the SPS after it is created, because they are newly needed or no longer needed.
In this case, you can create an expandable SPS with the optional parameter expandable: true (default false).

import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem";
var sps = new SolidParticleSystem("sps", scene, { expandable: true });

Adding particles

If you want to add more particles to the existing ones, just use the addShape() method again as many times as necessary. Then call buildMesh() to rebuild the SPS geometry with the newly added particles.

import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem";
var sps = new SolidParticleSystem("sps", scene, { expandable: true });
sps.addShape(model1, 100); // adds 100 particles from model1
sps.buildMesh();
// ... further in the code, when needed
sps.addShape(model2, 100); // adds 100 new particles from model2
sps.addShape(model3, 200); // and 200 particles from model3
sps.buildMesh(); // update the SPS mesh geometry from the last particle additions
sps.setParticles();

Example: Adding Particles To A Solid Particle System Each mouse click adds 20 new depth sorted particles.

Removing particles

If you want to remove particles from the SPS, use the method removeParticles(start, end), where start and end are the starting and ending indexes of the particles.
This method returns an array populated with the removed particles.

import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem";
var sps = new SolidParticleSystem("sps", scene, { expandable: true });
sps.addShape(model1, 1000); // adds 1000 particles from model1
sps.buildMesh();
// ... further in the code, when needed
var removed1 = sps.removeParticles(700, 999); // removes the last 300 particles
var removed2 = sps.removeParticles(0, 9); // removes the first 10
sps.buildMesh(); // updates the SPS mesh geometry from the last particle additions
sps.setParticles();

Example: Removing Particles From A Solid Particle System Each click removes the first 2 particles and the last 100 particles.
Important note: The SPS must contain at least one particle to work, so never empty it completely!

Storable particles

You may want to create new particles without inserting them into the SPS at creation time, but later. You may also want to keep removed particles aside so you can put them back in the system later.
So when creating new particles, you can specify that they should be stored aside from the SPS with the optional parameter storage: [] of the method addShape().

import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem";
var stock = []; // the array to store the particles
var sps = new SolidParticleSystem("sps", scene, { expandable: true });
sps.addShape(model1, 1); // the SPS needs at least one particle
sps.addShape(model1, 100, { storage: stock }); // stores 100 particles from model1 in the stock array
sps.buildMesh();

This SPS contains only one particle. The 100 others are stored in an external array.

If you want now to restore these particles, or some previously removed ones, just use the method insertParticlesFromArray(array).

import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem";
var stock = []; // the array to store the particles in
var sps = new SolidParticleSystem("sps", scene, { expandable: true });
sps.addShape(model1, 1000); // the SPS contains 1000 particles
sps.addShape(model1, 100, { storage: stock }); // 100 others are stored aside
sps.buildMesh();
// ... later in the code
var removed = sps.removeParticles(0, 99); // the 100 first particles are removed and stored in another array
sps.buildMesh();
// ... later again in the code : let's restore the misssing particles
sps.insertParticlesFromArray(removed); // restores the previously removed particles
sps.insertParticlesFromArray(stock); // restores the previously created particles
sps.buildMesh();
sps.setParticles();

Each time you call insertParticlesFromArray(), the stored particle objects are not just referenced in the SPS; they are cloned, and the clones are reindexed and given a new identifier.
This means that you can modify or get rid of the storage array or its contained particle objects with no effect on the SPS.
Example: Storable Particles Example Each click removes 100 particles of a given shape and restores 100 particles of another shape in turn.
100 particles are stored aside at the SPS creation.

Notes:

  • When you remove particles, the remaining ones are reindexed, meaning that their particle.idx value can change. The particle identifier particle.id keeps unchanged. If a particle is given a parent and if this parent is removed, then the particle parent property value is set to null.

  • Adding or removing particles will create a new VertexData object, and therefore a new VBO buffer, each time buildMesh() is called.
    This can trigger Garbage Collector activity at an unwanted moment, so it is not a good idea to add or remove particles on each frame.
    Moreover, an expandable SPS uses more memory than a fixed one because all the dynamic extensible arrays are kept under the hood throughout the SPS lifecycle.

    In a standard SPS, the particle index particle.idx and the particle identifier particle.id have the same value.
    In an expandable SPS (see below), when particles are removed, only the particle identifier particle.id remains unchanged, whereas the particle index may change.
    So, when using an expandable SPS, make sure to set a particle parent with the parent identifier and make sure that this parent still exists.

if (otherParticle) {
particle.parentId = otherParticle.id; // not otherParticle.idx
}