ParticleAPI 3.0.0 Performant particle system API in C++ for interactive graphics

pAPI.h
Go to the documentation of this file.
1// PAPI.h
2//
3// Copyright 1997-2007, 2022 by David K. McAllister
4//
5// Include this file in all applications that use the Particle System API.
6
7/*!
8\mainpage The Particle System API
9
10\section intro Introduction
11The Particle System API (Application Programmer Interface) allows C++ programs to simulate the dynamics of particles. It is intended for special effects in
12interactive and non-interactive graphics applications, not for scientific simulation, although principles of Newtonian physics have been used to implement the
13particle dynamics where applicable.
14
15The API consists of four sets of functions:
16- <b>Particle Group Calls</b> - A particle group is a system of particles that are all acted on together. It can be considered a dynamic geometric
17object. From the point of view of the graphics system, a particle group is often treated as just another model to be drawn. These calls create and destroy
18particle groups, etc. Details are in PAPI::PContextParticleGroup_t.
19- <b>Source State Calls</b> - As in OpenGL, some calls actually do something and some calls modify the behavior of the subsequent calls that do something.
20The source state setting calls set the attributes of particles that will be created with the PAPI::PContextActions_t::Source or PAPI::PContextActions_t::Vertex
21calls. The source state calls are in PAPI::pSourceState.
22- <b>Actions</b> - These implement the particle dynamics. Bounce and Gravity are examples of actions. The Actions are in the class PAPI::PContextActions_t.
23- <b>Action List Calls</b> - These create and operate on lists of actions. These are not needed by the new \ref inline_actions API.
24
25Following are several basic concepts central to the Particle System API.
26
27\subsection particles Particles
28
29For the purposes of the Particle System API, a particle is not just a very tiny speck. Particles can be drawn as anything - water droplets, birds,
30tumbleweeds, boulders, etc.. The Particle System API is generally useful for operating on many similar objects that all move and change according to the same
31basic rules, no matter what the objects and rules are.
32
33A particle in the abstract sense used by the API is merely an entity with a small set of
34attributes such as position and color that ultimately dictate the particle's behavior and appearance. Particles are declared in pParticle.h or \ref
35PAPI::Particle_t. Here are the particle attributes:
36
37<table border="1"><tr><td>Position </td><td>location of the particle center </td><td>3 floats</td></tr><tr><td>Color
38</td><td>color (in any color space) </td><td>3 floats </td></tr><tr><td>Velocity </td><td>velocity vector (direction and speed) </td><td>3 floats
39</td></tr><tr><td>Up </td><td>up vector (together with velocity vector, yields an orientation frame) </td><td>3 floats </td></tr><tr><td>Rotational Velocity
40</td><td>direction of rotation of the up vector </td><td>3 floats </td></tr><tr><td>Size </td><td>how large the particle is for rendering (doesn't affect
41particle dynamics or collision) </td><td>3 floats </td></tr><tr><td>PositionB </td><td>initial or target position for returning to (see Restore()) </td><td>3
42floats </td></tr><tr><td>UpB </td><td>initial or target orientation for returning to (see Restore()) </td><td>3 floats </td></tr><tr><td>VelocityB </td><td>can
43be used as velocity from last frame for computing a side vector </td><td>3 floats </td></tr><tr><td>Mass </td><td>how large the particle is for dynamics
44computations (doesn't affect collision location) </td><td>1 float </td></tr><tr><td>Age </td><td>time since the particle's creation </td><td>1 float
45</td></tr><tr><td>Alpha </td><td>opacity, or a fourth color channel </td><td>1 float </td></tr><tr><td>Tmp </td><td>for a sorting key or for tagging particles
46to kill by setting to P_MAXFLOAT </td><td>1 float </td></tr><tr><td>Data </td><td>user data to be passed back to user callbacks </td><td>1 uint32
47</td></tr></table>
48
49\subsection actions Actions
50
51Actions are the core of the Particle System API. They are the functions in the API that directly manipulate particles in particle groups. They perform
52effects such as gravity, explosions, bouncing, etc. to all particles in the current particle group. Actions modify the position, color, velocity, size, age, and
53other attributes of particles. A program typically creates and initializes one or more particle groups, then during each frame it calls particle actions to
54animate the particles then gets the particle data and draws the group of particles onto the screen.
55
56All actions apply to the current particle group, as set by
57CurrentGroup. Some actions will add particles to or delete them from the particle group, and others will modify the particles in other ways. Typically, a series
58of actions will be applied to each particle group once (or more) per rendered frame.
59
60The Particle System API uses a discrete time approximation to all actions. The amount of effect of an action call depends on the
61time step size, dt, as set by \ref PAPI::PContextActionList_t::TimeStep. A smaller time step improves simulation quality.
62
63Some functions have parameters with a default value of P_EPS. P_EPS is a very small floating point constant
64that is most often used as the default value of the epsilon parameter to actions whose influence on a particle is relative to the inverse square of its distance
65from something. If that distance is very small, the amount of influence approaches infinity. Since all actions are computed using Euler's method, this can cause
66unsatisfying results in which particles are accelerated way too much. So this epsilon parameter is added to the distance before taking its inverse square, thus
67keeping the acceleration within reasonable limits. By varying epsilon, you specify what is reasonable. Larger epsilon make particles accelerate less.
68
69The Actions are in the class PAPI::PContextActions_t.
70
71\subsection domains Domains
72A Domain is a representation of a region of 3D space. For example, the Source action uses a domain to describe the volume in which a particle's random
73initial position will be. The Avoid(), Sink() and Bounce() actions use domains to describe a volume in space for particles to steer to avoid, die when they
74enter, or to bounce off, respectively. Domains are used as parameters to many functions within the API.
75
76See PAPI::pDomain and pDomain.h for more.
77
78\subsection sourcestate Source State Setting Calls
79These calls dictate the properties of particles to be created by Source or Vertex. When particles are created within a NewActionList / EndActionList block,
80they will receive attributes from the state that was current when the action list was created. When in immediate mode (not creating or calling an action list),
81particles are created with attributes from the current state.
82
83See the Source State Setting Calls in the class PAPI::pSourceState.
84
85\subsection pgroup Particle Group Calls
86
87A particle group is first created using PAPI::PContextParticleGroup_t::GenParticleGroups, which will create a sequentially-numbered set of particle groups and
88return the identifying number of the first generated particle group. You specify which group is current using PAPI::PContextParticleGroup_t::CurrentGroup.
89Unless otherwise stated, all other commands operate on the current particle group. The maximum number of particles in the group is specified using
90PAPI::PContextParticleGroup_t::SetMaxParticles. The particle group is then acted upon using the Actions (PAPI::PContextActions_t).
91
92After the actions have been applied, the particles are rendered. This is done at the same stage of the application's execution as drawing other geometry. To
93draw a particle group in a graphics API, the application calls PAPI::PContextParticleGroup_t::GetParticles or PAPI::PContextParticleGroup_t::GetParticlePointer
94functions to get the vertex data, then sends it to the graphics API. When a particle group is no longer needed, it is deleted using
95PAPI::PContextParticleGroup_t::DeleteParticleGroups.
96
97See the particle group calls in PAPI::PContextParticleGroup_t.
98
99\subsection alists Action Lists
100Action lists are blocks of actions that are applied together to a particle group. An action list is conceptually similar to a script or procedure. Action
101lists are implemented and expressed similarly to display lists in OpenGL. An action list encapsulates the specifics of a particular effect and allows complex
102effects to be treated as primitives like actions. An action list can be called from within another action list.
103
104When using the \ref legacy_actions API, rather than the more performant \ref inline_actions API, action lists also allow effects to be simulated
105much more efficiently. This is because the entire set of actions is known at the start, and this knowledge can be used by the implementation of the Particle
106System API. For example, several actions can be applied to one set of particles before moving to the next set of particles, yielding better memory access
107patterns. Also, in future versions common sequences of actions might be detected and replaced by efficient code that handles all those actions in one pass.
108
109To take advantage of the up to 50% performance increase of action lists, you need to order your actions carefully. The performance advantage is achieved when
110two or more actions that can be combined are ordered next to each other in the list. Actions that create (Vertex(), Source()) or delete (Sink*(), and
111KillOld()) particles, and actions that reorder particles (Sort()) cannot be combined. All other actions can be combined to yield the performance advantage. See
112Effects.cpp for several examples of efficient ordering.
113
114Action List Calls create and operate on action lists. An empty
115action list is first created using PAPI::PContextActionList_t::GenActionLists, and is then filled or compiled by calling
116PAPI::PContextActionList_t::NewActionList, then calling Actions, then calling PAPI::PContextActionList_t::EndActionList. Once the action list is filled, it is
117run via PAPI::PContextActionList_t::CallActionList. Thus, an action list is sort of a higher-level action. Complex behaviors can be stored in an action list and
118then called later, even as part of another action list. Action lists cannot be edited. They can only be created or destroyed. To destroy an action list, call
119PAPI::PContextActionList_t::DeleteActionLists. When particles are created within a NewActionList / EndActionList block, they will receive attributes from the
120state that was current when the action list was created.
121
122When in immediate mode (not creating or calling an action list), particles are created with attributes
123from the current state. However, the time step length, dt, uses the value that is current when CallActionList is executed, not the value of dt when the action
124list was created. This allows dt to be modified without recompiling action lists.
125
126See the Action List Calls in the class PAPI::PContextActionList_t.
127
128\subsection defparams Default Parameters
129Many functions in the Particle System API take arguments with default values. This is a feature of C++. For example, in \code
130Color(float r, float g, float b, float alpha = 1.0f) \endcode,
131the parameter alpha has a default value of 1.0. This means that Color can be called with either three parameters or four. When
132called with three parameters, they are the values of r, g, and b; and alpha receives the default value, 1.0. Only parameters at the end of the parameter list
133can have default values. Likewise, when calling functions that have default values for parameters, all values specified will be applied to parameters starting
134with the left. This means that there is no way to specify a value for a parameter at the end of the list without specifying values for all parameters to its
135left.
136
137\subsection except Exception Handling
138See pError.h for the list of exceptions thrown by the API.
139
140\section other Other Stuff
141- Change log is <a href="../../ChangeLog.html">[here]</a>.
142- Future work is <a href="../../ToDo.html">[here]</a>.
143- Project is hosted <a href="https://github.com/davemc0/Particle">[here]</a>.
144
145\subsection acks Acknowledgements
146- Code for some of the particle actions and several concepts regarding the structure of the API are thanks to Jonathan P. Leech. See also:
147Jonathan Leech and Russell M. Taylor II, "Interactive Modeling Using Particle Systems", Proceedings of the 2nd Conference on Discrete Element Methods,
148MIT, spring 1993, pp. 105-116.
149- Thanks to Mark B. Allen of NASA Ames Research Center for finding bugs, making suggestions and implementing the particle
150length attribute.
151- Thanks to Jason Pratt of CMU Stage 3 research group (makers of ALICE) for adding the PDTriangle domain. This is a powerful feature
152that should have been there the whole time.
153*/
154
155#ifndef particle_api_h
156#define particle_api_h
157
158#include "Particle/pAPIContext.h"
159
160// Only application code should include this. It contains the definitions of the inline action API functions.
161#include "Particle/pInlineActionsAPI.h"
162
163#endif