# Managing Point Cloud Particles

> Learn all point cloud particle management in Babylon.js.

Source: https://doc.babylonjs.com/features/featuresDeepDive/particles/point_cloud_system/pcs_manage_particles

## Particle Properties

Once the PCS mesh is built, unless immutable, it can respond to changes in the properties of each particle. Existing properties are shown in the table below.

| Property | Type | Default |
| ---- | ---- | ----|
| position | Vector3 | (0, 0, 0) |
| rotation | Vector3 | (0, 0, 0) |
| rotationQuaternion | Vector3 | undefined |
| velocity | Vector3 | (0, 0, 0) |
| color | Vector4 | (1, 1, 1, 1) |
| pivot | Vector3  | (0, 0, 0) |
| uvs | Vector2  | (0,0) |
| translateFromPivot | boolean |false |
| parentId | integer | null |
| idx | integer (read only) | index of particle |
| groupId | integer (read only) | group number for a particle |


If you set a particle rotation quaternion, its rotation property will then be ignored.

New properties can be initialized.

**Note:** Since point particles **_always_** face the camera, setting the rotation of a particle only has any effect in two cases:

1. The rotation of a particle parent will rotate its children about itself;
2. A pivot is set for the particle.



### Initialising Particles

When using `addPoints`, particle properties can be set in the passed function. The `addSurfacePoints` and `addVolumePoints` methods obviously set the position and color properties of the particles, but you may still want to set the initial values of other particle properties.

This can be done using `initParticles`. To do this, iterate over all the particles by using the `nbParticles` property, and follow the call to this function with a call to `setParticles()`. For example:

```javascript
pcs.initParticles = function() {
   for (let p = 0; p < pcs.nbParticles; p++) {
       pcs.particles[p].velocity = BABYLON.Vector3.Zero();
       pcs.particles[p].acceleration = pcs.particles[p].position.scale(0.01);
   }
}

pcs.addSurfacePoints(model, 10000, BABYLON.PointColor.Color);
pcs.buildMeshAsync().then(() => {
  model.dispose()
  pcs.initParticles();
  pcs.setParticles();
});
```

### Updating Particles

Once the appropriate particle properties are initialized, the `updateParticles` method can be used. Unlike `initParticles`, this function is called by `setParticles` and already receives a particle as an argument. The `setParticles` method will execute only after the PCS mesh has been built, so it can safely be placed inside a render loop to produce an animation. For example:

```javascript
pcs.updateParticle = function(particle) {
  particle.velocity.addInPlace(particle.acceleration);
  particle.position.addInPlace(particle.velocity);
}

scene.registerBeforeRender(() => {
  pcs.setParticles();
});
```

**Note:** All particle positions are expressed in the *local space* of the PCS mesh. 

The particle `pivot` vector is also in the *local space* of the PCS mesh. By default, rotations around a pivot are calculated by translating the particle to the pivot point, then rotating it, and then applying the inverse translation. By setting the particle property `translateFromPivot` to `true` (default `false`), rotations are calculated using only the initial translation followed by the rotation, leaving the particle at the translated location.  

- [Playground: Simple Animation](https://playground.babylonjs.com/#UI95UC#12) - Simple example of animating a point cloud system.

In the following playground, the particle pivots in the top PCS are set relative to the particle position, and in the lower one they are set in the same place.
- [Playground: Pivot Animation Example 1](https://playground.babylonjs.com/#UI95UC#14) - Simple example of animating the pivot point of a point cloud system.

In this playground, the only difference is that the lower PCS has `translateFromPivot` set to `true`.
- [Playground: Pivot Animation Example 2](https://playground.babylonjs.com/#UI95UC#15) - Simple example of animating the pivot point of a point cloud system.

This playground animates the mesh, not the particles.
- [Playground: Immutable Animation](https://playground.babylonjs.com/#UI95UC#16) - Simple example of point cloud system immutable animation.

This playground loads meshes from a file, converts them to particles, and animates them.
- [Playground: Loaded Mesh Animation](https://playground.babylonjs.com/#UI95UC#17) - Simple example of point cloud system animation based on loaded mesh animation.

### UVs

While setting and changing particle colors is straightforward, doing the same for UVs is a little more complex. Using `BABYLON.PointColor.UV` as a parameter within `addSurfacepoints` or `addVolumePoints` will set the UVs automatically based on the passed mesh.

You can also set the UV value for each particle using the function passed to `addPoints`. To make the texture map correctly, the UV values should relate in some way to the positional values for each particle. To apply the texture with these UVs, both the `emissiveColor` and `emissiveTexture` for the PCS mesh material must be set after the mesh is built.

**Note:** Only use emissive.

For example

```javascript
var myfunc = function(particle) { 
    var x = Math.random();
    var y = Math.random();
    var z = 0;
    particle.position = new BABYLON.Vector3(x, y, z);
    //Relate uv values to positional values
    particle.uv.x = x;
    particle.uv.y = y; 
    }
    pcs.addPoints(5000, myfunc);

    pcs.buildMeshAsync().then(() => {
      pcs.mesh.material.emissiveColor = new BABYLON.Color3(0, 0, 0);
      pcs.mesh.material.emissiveTexture = myTexture;
    });
```

It is possible to use a texture atlas, but you need to customize and calculate the more complex relationship between positional and UV values.

- [Playground: UV With Added Points](https://playground.babylonjs.com/#UI95UC#23) - Simple example of updating the UVs and adding points of a point cloud system.
- [Playground: UV With Texture Atlas](https://playground.babylonjs.com/#UI95UC#24) - Simple example of updating the UVs of a point cloud system with textured atlas.

### Recycling Particles

You can write your own code to recycle particles using `recycleParticle`, which can be called from within `updateParticle`. For example:

```javascript
pcs.recycleParticle = function(particle) {
    particle.position = BABYLON.Vector3.Zero();
    particle.velocity = BABYLON.Vector3.Zero();
    particle.heightLim = 4 + 0.5 * Math.random();
}

pcs.updateParticle = function(particle) {
    if (particle.position.y > particle.heightLim) {
      this.recycleParticle(particle);
    }
    particle.velocity.addInPlace(particle.acceleration);
    particle.position.addInPlace(particle.velocity);
}
```

- [Playground: Recycling Animations](https://playground.babylonjs.com/#UI95UC#19) - Simple example of recycling animations of a point cloud system.

### Particle Parenting  

Each particle can be given another particle as a parent.  
The parent must be created before the child particle. This means the parent must have a lower index ID (`particle.idx`) than the current particle. So the first particle in the pool (`idx = 0`) cannot have a parent. To give a parent to a particle, just set its property `parentId` to the parent index ID value. 

```javascript
if (particle.idx > 0) {
    particle.parentId = particle.idx - 1; // the previous particle becomes the parent of the current one
}
```
To un-parent a particle, just set `.parentId` back to `null` which is the default value.  

When a particle has a parent, its position and rotation are then expressed in its parent's local space.  
```javascript
if (particle.idx > 0) {
    particle.parentId = particle.idx - 1; // the previous particle becomes the parent of the current one
    // the particle position and rotation are expressed in the previous particle space, this one being already 
    // rotated and translated from the yet previous particle. Etc.
    particle.rotation.z = 0.01;
    particle.position.x = 1.0;
}
```
 - [Playground: Parent Animation](https://playground.babylonjs.com/#UI95UC#18) - Simple example of animating a point cloud system parent.

### Particle Intersections
     
The PCS provides a simple way to deal with intersections between a particle and other meshes. As this feature consumes more memory and CPU, do not include it unless necessary.

To use it, call the method `intersectsMesh(target)` (`target` is a mesh) for any particle to check whether it intersects the _target_.  
It will simply return `true` or `false` depending on whether the particle intersects the target.    
  
```javascript
if (particle.intersectsMesh(anyMesh)) { 
  // change properties of particle
}
```
By default, the check is carried out on the mesh's (AABB) bounding box. If you want to use the mesh's bounding sphere, add the parameter `true`.
```javascript
if (particle.intersectsMesh(mesh, true) {
    // change properties of particle
}; 
```

- [Playground: Recycling Particle Collisions](https://playground.babylonjs.com/#UI95UC#20) - Simple example of recycling particle collisions of a point cloud system.
- [Playground: Mesh Colliding With Point Cloud](https://playground.babylonjs.com/#UI95UC#21) - Simple example of a mesh colliding with a point cloud.
