13. Particle systems

See also GranularBodySystem

13.1. Basic usage

There are two types of particle systems available in AGX: RigidParticleSystem and ConstraintFluid. The RigidParticleSystem simulates a collection of hard spheres that are held apart by contact constraint solved by a Gauss-Seidel solver. The ConstraintFluid simulates a fluid where each particle samples a density field and the particles are held apart by density constraints solved by a conjugate-gradient solver. There are two-way interactions between the rigid particles and other parts of the simulation, but the constraint fluid currently only supports static geometries in the scene.

A particle system can be created either from C++ code or from a Python scene script, but the setup procedure is very similar. Examples in code are given below for everything that is described in the following in both C++ and Python code.

The first step is to create an instance of the particle system class in question, the RigidParticleSystem class for the hard sphere particles and ConstraintFluid for the density constrained fluid. The second step is to create a set of particles to simulate. They can either be allocated and initialized using the particle API, or created in a regular grid using the spawnParticlesInBound method available in the ParticleSystem base class.

Regardless of how the particles were created, individual particles can be accessed and manipulated using ParticlePtrs. A ParticlePtr is an accessor object that gives access to the individual attributes of a particle, stored as elements in the buffers that make up the EntityStorage that the particle in question is part of. The ParticlePtr exposes one accessor method for each attribute of the Particle entity.

  • position

  • velocity

  • force

  • life

13.1.1. Particle systems in C++

The following code snippet demonstrates how to create a simple rigid particle system in C++.

// Create and configure a rigid particle system.
ParticleSystemRef particleSystem = new RigidParticleSystem();
simulation->add( particleSystem );
particleSystem->setParticleMass( Real(10.0) );
agx::Physics::ParticlePtr particle = particleSystem->createParticle();
particle.position() = Vec3(0, 0, 4.5);
// Create a bunch of particles in a bound.
agx::Bound3 spawnBound = agx::Bound3( Vec3(0.0, 0.0, 0), agx::Vec3(4.0, 1.0, 4.0) );
particleSystem->spawnParticlesInBound( spawnBound, agx::Vec3f(0.1) );

13.1.2. Particle systems in Python

The following code snippet demonstrates how to create a simple rigid particle system in Python.

# Create and configure a particle system.
particle_system = agx.RigidParticleSystem()
sim.add( particle_system )
particle_system.setParticleMass( 10 )
# Create a single particle.
particle = particle_system.createParticle()
particle.position().set( agx.Vec3(0, 0, 4.5) )
# Create a bunch of particles in a bound.
spawn_bound = agx.Bound3( agx.Vec3(0, 0, 0), agx.Vec3(4,1,4) )
particle_system.spawnParticlesInBound( spawn_bound, agx.Vec3(0.1) )

13.1.3. Particle emitter

The particle system comes with a collection of tasks designed to be part of a particle system update. One such task is the particle emitter, which creates new particles at a certain rate within a specified spawn volume. This task has an explicit Python binding and can therefore be created directly from Python code. The volume in which particles may be created is defined by a geometry and a method is used to set the volume.

emitter = agx.ParticleEmitter( )
emitter.setGeometry( agxCollide.Geometry( agxCollide.Cylinder(1.6, 10) ) )
simulation.add( emitter );

The emitter contains a parameter to control the rate of the particle creation, in particles per second. This parameter can be set from Python using the following code snippet:

emitter.setRate( 15 )

To set the initial “life” of an emitted particle:

emitter.setLife( 10 );