This PR documents the particle system library used by the game.
Here is a quick breakdown of how the library works/how to use it:
1. Creating a Manager
To do anything with the library an instance of SPLManager must first be created. When creating one you specify a maximum number of simultaneous emitters and particles that the manager is able to create, as well as a range of polygon IDs to use:
SPLManager *mgr = SPLManager_New(
MyAllocFunc, // Memory allocation function that the manager will use
10, // Maximum 10 emitters
100, // Maximum 100 particles simultaneously
5, // Fixed polygon ID
6, // Mininum polygon ID
63 // Maximum polygon ID
)
2. Loading Resources
Next the manager must be provided with data that defines what particles look like and how they behave. Usually this data comes from a file, but technically it can come from anywhere. The files are a custom binary format with the .spa extension. One such file can contain multiple resources. A resource defines parameters for an emitter, which then passes those parameters to particles it creates.
void *data = NARC_AllocAndReadWholeMemberByIndexPair(...);
SPLManager_LoadResources(mgr, data);
// Both of these functions also have an Ex variant which allows you to specify a custom VRAM allocator
SPLManager_UploadTextures(mgr); // Uploads the textures to VRAM
SPLManager_UploadPalettes(mgr); // Uploads the palettes to VRAM
// Note that the data must be kept alive until the manager is destroyed
3. Creating Emitters
Now that the resources are loaded, emitters can be created. Each emitter is associated with a resource.
VecFx32 pos = {0, 0, 0}; // Initial position of the emitter
SPLEmitter *emitter = SPLManager_CreateEmitter(mgr, 0, &pos);
Note that some emitters are self-maintaining, meaning they will automatically destroy themselves when they are done. Others are not and must be manually destroyed. In the case of the former, SPLManager_CreateEmitter (and similar functions) will return NULL.
If you still want to obtain a reference to a self-maintaining emitter, you can use SPLManager_CreateEmitterWithCallback[Ex] instead. This function will call a callback function after the emitter has been initialized, passing the emitter as an argument.
4. Updating Emitters
To update the emitters, call SPLManager_Update:
SPLManager_Update(mgr);
This function should be called every frame. Also note that typically drawing is done before updating.
5. Drawing
To draw the particles, call SPLManager_Draw:
NNS_G3dGlbFlush(); // Flush the 3D pipeline
const MtxFx43 *view = NNS_G3dGlbGetCameraMtx();
SPLManager_Draw(mgr, view);
Of course, you can pass any view matrix you want.
6. Destroying Emitters
For emitters that are not self-maintaining, you must manually destroy them when they are no longer needed:
SPLManager_DeleteEmitter(mgr, emitter);
Manually Emitting Particles
Normally, emitters will emit particles automatically. However, you can manually make an emitter emit particles:
SPLManager_Emit(mgr, emitter);
// Or you can specify a position
VecFx32 pos = {0, 0, 0}; // Position of the emitter
SPLManager_EmitAt(mgr, emitter, &pos);
Particle Capabilities
All particles have a set of common parameters:
Position (relative to the emitter)
Velocity
Rotation
Angular velocity
Age
Scale
Color
Texture ID
Alpha
These should be self explanatory. However, there are additional behaviors that can be added to particles. Or rather, these behaviors can be added to emitters, which then pass them to particles. These behaviors include:
Gravity: A constant acceleration in a given direction
Random acceleration: A random acceleration, applied in a configurable interval
Magnetic force: A force that attracts particles to a point
Spin: A gradual revolution around the emitter
Collision Plane: A plane that particles will either bounce off of or die when they collide with it
Convergence: Particles will converge to a point, this acts directly on the position of the particles
Without any of these behaviors, particles will simply move in a straight line until they die. Their velocity is based on their initialization parameters. Behaviors are specified in the resource file.
Additionally, particles can also have the following parameters animated:
Scale
Color
Alpha
Texture ID
Emitter Capabilities
Emitters are also not just static entities. They can move around and keep that of their own velocity. However, the velocity must be set manually. Emitter velocity directly affects the velocity of the particles it emits.
Emitters can also have a wide range of emission types:
Point: Particles are emitted from a single point
Sphere Surface: Particles are emitted on the surface of a sphere around the emitter
Circle Border: Particles are emitted randomly on the border of a circle around the emitter
Circle Border Uniform: Particles are emitted uniformly on the border of a circle around the emitter
Sphere: Particles are emitted within a sphere around the emitter
Circle: Particles are emitted within a circle around the emitter
Cylinder Surface: Particles are emitted on the surface of a cylinder around the emitter
Cylinder: Particles are emitted within a cylinder around the emitter
Hemisphere Surface: Particles are emitted on the surface of a hemisphere around the emitter
Hemisphere: Particles are emitted within a hemisphere around the emitter
Child Particles
Particles can also spawn child particles. This behavior is restricted to a single level of recursion. Child particles also have less functionality than their parents. They are limited to Scale and Alpha animations, and they cannot have their own behaviors. Though they can optionally inherit the parent's behaviors.
To make a particle spawn child particles, the resource it stems from must have a Child resource defined.
This PR documents the particle system library used by the game.
Here is a quick breakdown of how the library works/how to use it:
1. Creating a Manager
To do anything with the library an instance of
SPLManager
must first be created. When creating one you specify a maximum number of simultaneous emitters and particles that the manager is able to create, as well as a range of polygon IDs to use:2. Loading Resources
Next the manager must be provided with data that defines what particles look like and how they behave. Usually this data comes from a file, but technically it can come from anywhere. The files are a custom binary format with the
.spa
extension. One such file can contain multiple resources. A resource defines parameters for an emitter, which then passes those parameters to particles it creates.3. Creating Emitters
Now that the resources are loaded, emitters can be created. Each emitter is associated with a resource.
Note that some emitters are self-maintaining, meaning they will automatically destroy themselves when they are done. Others are not and must be manually destroyed. In the case of the former,
SPLManager_CreateEmitter
(and similar functions) will returnNULL
.If you still want to obtain a reference to a self-maintaining emitter, you can use
SPLManager_CreateEmitterWithCallback[Ex]
instead. This function will call a callback function after the emitter has been initialized, passing the emitter as an argument.4. Updating Emitters
To update the emitters, call
SPLManager_Update
:This function should be called every frame. Also note that typically drawing is done before updating.
5. Drawing
To draw the particles, call
SPLManager_Draw
:Of course, you can pass any view matrix you want.
6. Destroying Emitters
For emitters that are not self-maintaining, you must manually destroy them when they are no longer needed:
Manually Emitting Particles
Normally, emitters will emit particles automatically. However, you can manually make an emitter emit particles:
Particle Capabilities
All particles have a set of common parameters:
These should be self explanatory. However, there are additional behaviors that can be added to particles. Or rather, these behaviors can be added to emitters, which then pass them to particles. These behaviors include:
Without any of these behaviors, particles will simply move in a straight line until they die. Their velocity is based on their initialization parameters. Behaviors are specified in the resource file.
Additionally, particles can also have the following parameters animated:
Emitter Capabilities
Emitters are also not just static entities. They can move around and keep that of their own velocity. However, the velocity must be set manually. Emitter velocity directly affects the velocity of the particles it emits.
Emitters can also have a wide range of emission types:
Child Particles
Particles can also spawn child particles. This behavior is restricted to a single level of recursion. Child particles also have less functionality than their parents. They are limited to Scale and Alpha animations, and they cannot have their own behaviors. Though they can optionally inherit the parent's behaviors.
To make a particle spawn child particles, the resource it stems from must have a Child resource defined.