Managing A Point Cloud System

As you can see above the setParticles() function is used in theBabylon.js render loop to provide behavior to the PCS.

Available custom functions of PCS are:

FunctionUsage
Function
initParticles()
Usage
sets the initial particle properties.
Function
updateParticle(particle)
Usage
sets the particle properties. This function is called per particle by PCS.setParticles()
Function
recycleParticle(particle)
Usage
re-sets the particle properties. This function is called conditionally per particle by PCS.updateParticles()
Function
beforeUpdateParticles()
Usage
lets you do things within the call to PCS.setParticles() just before iterating over all the particles.
Function
afterUpdateParticles()
Usage
lets you do things within the call to PCS.setParticles() just after the iteration over all the particles is done.

The pseudo-code for setParticles is

function setParticles() {
beforeUpdateParticles();
for (let p = 0; p < nbParticles; p++) {
updateParticles(particles[p]);
}
afterUpdateParticles();
}

The particle properties that can be set are :

Available properties of PCS are

PropertyUsageDefault
Property
particles
Usage
An array containing all the particles. You iterate over this array in initParticles() function for instance.
Default
 
Property
nbParticles
Usage
The number of particles in the PCS.
Default
 
Property
counter
Usage
A counter for your own usage
Default
0
Property
computeParticleRotation
Usage
Allows ( default) or prevents setParticle computing particle.rotation
Default
true
Property
computeParticleTexture
Usage
Allows ( default) or prevents setParticle computing particle.uvs
Default
true
Property
computeParticleColor
Usage
Allows ( default) or prevents setParticle computing particle.color
Default
true
Property
computeBoundingBox
Usage
Allows or prevents (default) setParticle computing the PCS mesh bounding box
Default
false

The particle properties of color, uvs and rotation are set either during the addition phase or by using initParticles and then setParticles. Updating particle properties requires the use of updateParticle which is called by setParticles. Setting the compute properties to false prevents setParticles() from updating the value of the relevant particle property when it is called. Setting one or more of these to false can increase fps, especially with repeated call to setParticles within the render loop.

If you don't need your PCS any longer, you can dispose it to free the memory

PCS.dispose();
PCS = null; // tells the garbage collector the reference can be also cleaned up

Start and End Indexes for setParticles()

For performance reasons you may not want to compute the properties of all the particles each frame. There are three optional parameters for setParticles() that you can use to choose a range of particles to compute or not : start, end, update

ParameterDefinitionDefault
Parameter
start
Definition
(number) the index from where to start to iterate in the particles array
Default
0
Parameter
stop
Definition
(number) the index (included) where to stop to iterate in the
particles array
Default
nbParticles - 1
Parameter
update
Definition
(boolean) to force the PCS mesh vertex buffer to be updated
Default
true

If you pass a end value greater than nbParticles - 1, the iteration will stop at nbParticles - 1 to prevent you from trying to access to undefined elements.

Example 1 : to only update 10000 particles mesh every three frames

  • frame 1 : setParticles(0, 3300, false) computes everything for particles from 0 to 3300 and doesn't update the mesh.
  • frame 2 : setParticles(3301, 6600, false) computes everything for particles from 3301 to 6600 and doesn't update the mesh.
  • frame 3 : setParticles(6601, 9999, true) computes everything for particles from 6601 to 9999 and finally updates the mesh.

In this playground change invSpeed (line 29) to change speed.

Example 2 : you could keep, say, the first 5000 particles as unused ones and compute the particle behavior only for the last 5000 in your global pool - setParticles(5000, 9999, true) computes everything for particles from 5000 to 9999 and updates the mesh.

Hints and Tips

A PCS can iterate over a very large number of particles during a call to updateParticle and it would be nice to avoid any apparent pauses in scene generation. The JavaScript Garbage Collector can start its cleaning in the middle of what you want to be a very smooth animation and produce lags. One possibility of lessening these is avoid creating new objects in the loops that execute often, where particles are created or updated.

For example, consider a PCS with, say, 30000 particles where you change their velocities

pcs.updateParticle = function (particle) {
var accel = new BABYLON.Vector3(0, 0.5, 0);
particle.velocity = particle.velocity.add(accel);
// ...
};

will create two new Vector3 objects each call, or 60 000 new objects over the course of the update.

Instead, make your update loops reuse variables that are declared outside the loop, and don't call any methods inside the loop that create new objects, for example

var accel = new BABYLON.Vector3(0, 0.5, 0);
pcs.updateParticle = function (particle) {
particle.velocity.addInPlace(accel);
// ...
};

A PCS also has a vars property, which is an object that you can use to store any variables you want to reuse. Any variables you store there will share the PCS lifecycle, and get cleaned up when you dispose it:

pcs.vars.tempVector = new BABYLON.Vector3(0, 0, 0);
// ...
pcs.dispose(); // cleans explicitly all your PCS.vars !