NS/main/source/particles/PS Docs.htm

2066 lines
128 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0056)http://www.cs.unc.edu/~davemc/Particle/ParticleHelp.html -->
<HTML xmlns="http://www.w3.org/TR/REC-html40" xmlns:o =
"urn:schemas-microsoft-com:office:office" xmlns:w =
"urn:schemas-microsoft-com:office:word"><HEAD><TITLE>To do:</TITLE>
<META content="text/html; charset=windows-1252" http-equiv=Content-Type>
<META content=Word.Document name=ProgId>
<META content="MSHTML 5.00.2920.0" name=GENERATOR>
<META content="Microsoft Word 9" name=Originator><LINK
href="./ParticleHelp_files/filelist.xml" rel=File-List><!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Author>davemc</o:Author>
<o:LastAuthor>David K. McAllister</o:LastAuthor>
<o:Revision>2</o:Revision>
<o:TotalTime>1054</o:TotalTime>
<o:Created>2000-02-18T18:32:00Z</o:Created>
<o:LastSaved>2000-02-18T18:32:00Z</o:LastSaved>
<o:Pages>64</o:Pages>
<o:Words>8724</o:Words>
<o:Characters>49728</o:Characters>
<o:Company>UNC-CH</o:Company>
<o:Lines>414</o:Lines>
<o:Paragraphs>99</o:Paragraphs>
<o:CharactersWithSpaces>61069</o:CharactersWithSpaces>
<o:Version>9.2720</o:Version>
</o:DocumentProperties>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:TargetScreenSize>720x512</o:TargetScreenSize>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Print</w:View>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>0</w:DisplayVerticalDrawingGridEvery>
<w:UseMarginsForDrawingGridOrigin/>
<w:Compatibility>
<w:FootnoteLayoutLikeWW8/>
<w:ShapeLayoutLikeWW8/>
<w:AlignTablesRowByRow/>
<w:ForgetLastTabAlignment/>
<w:LayoutRawTableWidth/>
<w:LayoutTableRowsApart/>
</w:Compatibility>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml><![endif]-->
<STYLE>P.MsoNormal {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt; mso-style-update: auto; mso-style-parent: ""; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
LI.MsoNormal {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt; mso-style-update: auto; mso-style-parent: ""; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
DIV.MsoNormal {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt; mso-style-update: auto; mso-style-parent: ""; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
H1 {
FONT-FAMILY: Arial; FONT-SIZE: 14pt; MARGIN: 12pt 0in 3pt; PAGE-BREAK-BEFORE: always; mso-bidi-font-weight: normal; mso-style-update: auto; mso-pagination: widow-orphan; mso-style-next: Normal; mso-outline-level: 1; mso-bidi-font-size: 10.0pt; mso-bidi-font-family: "Times New Roman"; mso-font-kerning: 14.0pt
}
H2 {
FONT-FAMILY: Arial; FONT-SIZE: 12pt; FONT-STYLE: italic; MARGIN: 12pt 0in 3pt; mso-bidi-font-weight: normal; mso-bidi-font-style: normal; mso-pagination: widow-orphan; mso-style-next: Normal; mso-outline-level: 2; mso-bidi-font-size: 10.0pt; mso-bidi-font-family: "Times New Roman"
}
H3 {
FONT-FAMILY: Arial; FONT-SIZE: 12pt; FONT-WEIGHT: normal; MARGIN: 12pt 0in 3pt; mso-pagination: widow-orphan; mso-style-next: Normal; mso-outline-level: 3; mso-bidi-font-size: 10.0pt; mso-bidi-font-family: "Times New Roman"
}
P.MsoList {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 0.25in; TEXT-INDENT: -0.25in; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
LI.MsoList {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 0.25in; TEXT-INDENT: -0.25in; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
DIV.MsoList {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 0.25in; TEXT-INDENT: -0.25in; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
P.MsoBodyText {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 6pt; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
LI.MsoBodyText {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 6pt; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
DIV.MsoBodyText {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 6pt; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
P.MsoNoteHeading {
FONT-FAMILY: Arial; FONT-SIZE: 10pt; FONT-WEIGHT: bold; MARGIN: 0in 0in 10pt; TEXT-TRANSFORM: uppercase; mso-bidi-font-weight: normal; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Note; mso-bidi-font-family: "Times New Roman"
}
LI.MsoNoteHeading {
FONT-FAMILY: Arial; FONT-SIZE: 10pt; FONT-WEIGHT: bold; MARGIN: 0in 0in 10pt; TEXT-TRANSFORM: uppercase; mso-bidi-font-weight: normal; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Note; mso-bidi-font-family: "Times New Roman"
}
DIV.MsoNoteHeading {
FONT-FAMILY: Arial; FONT-SIZE: 10pt; FONT-WEIGHT: bold; MARGIN: 0in 0in 10pt; TEXT-TRANSFORM: uppercase; mso-bidi-font-weight: normal; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Note; mso-bidi-font-family: "Times New Roman"
}
P.MsoBodyText2 {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; FONT-STYLE: italic; MARGIN: 0in 0in 10pt; TEXT-ALIGN: center; mso-bidi-font-style: normal; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
LI.MsoBodyText2 {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; FONT-STYLE: italic; MARGIN: 0in 0in 10pt; TEXT-ALIGN: center; mso-bidi-font-style: normal; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
DIV.MsoBodyText2 {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; FONT-STYLE: italic; MARGIN: 0in 0in 10pt; TEXT-ALIGN: center; mso-bidi-font-style: normal; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"
}
A:link {
COLOR: blue; TEXT-DECORATION: underline; text-underline: single
}
SPAN.MsoHyperlink {
COLOR: blue; TEXT-DECORATION: underline; text-underline: single
}
A:visited {
COLOR: purple; TEXT-DECORATION: underline; text-underline: single
}
SPAN.MsoHyperlinkFollowed {
COLOR: purple; TEXT-DECORATION: underline; text-underline: single
}
P.MsoPlainText {
FONT-FAMILY: "Courier New"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family: "Times New Roman"
}
LI.MsoPlainText {
FONT-FAMILY: "Courier New"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family: "Times New Roman"
}
DIV.MsoPlainText {
FONT-FAMILY: "Courier New"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-bidi-font-family: "Times New Roman"
}
P.FuncProto {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 1in; PAGE-BREAK-BEFORE: always; TEXT-INDENT: -1in; mso-style-update: auto; mso-style-parent: "Plain Text"; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Description; mso-outline-level: 1; mso-style-name: FuncProto
}
LI.FuncProto {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 1in; PAGE-BREAK-BEFORE: always; TEXT-INDENT: -1in; mso-style-update: auto; mso-style-parent: "Plain Text"; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Description; mso-outline-level: 1; mso-style-name: FuncProto
}
DIV.FuncProto {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 1in; PAGE-BREAK-BEFORE: always; TEXT-INDENT: -1in; mso-style-update: auto; mso-style-parent: "Plain Text"; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Description; mso-outline-level: 1; mso-style-name: FuncProto
}
P.Description {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; FONT-WEIGHT: bold; MARGIN: 0in 0in 10pt; mso-bidi-font-weight: normal; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Normal; mso-style-name: Description
}
LI.Description {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; FONT-WEIGHT: bold; MARGIN: 0in 0in 10pt; mso-bidi-font-weight: normal; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Normal; mso-style-name: Description
}
DIV.Description {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; FONT-WEIGHT: bold; MARGIN: 0in 0in 10pt; mso-bidi-font-weight: normal; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-next: Normal; mso-style-name: Description
}
P.Note {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 0.25in; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-name: Note
}
LI.Note {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 0.25in; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-name: Note
}
DIV.Note {
FONT-FAMILY: "Times New Roman"; FONT-SIZE: 10pt; MARGIN: 0in 0in 10pt 0.25in; mso-style-update: auto; mso-pagination: widow-orphan; mso-fareast-font-family: "Times New Roman"; mso-style-name: Note
}
DIV.Section1 {
page: Section1
}
OL {
MARGIN-BOTTOM: 0in
}
UL {
MARGIN-BOTTOM: 0in
}
</STYLE>
</HEAD>
<BODY lang=EN-US link=blue style="tab-interval: .5in" vLink=purple>
<DIV class=Section1>
<H1 align=center style="TEXT-ALIGN: center">Documentation for the Particle
System API</H1>
<P align=center class=MsoNormal style="TEXT-ALIGN: center">By David K.
McAllister</P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><A
href="mailto:davemc@cs.unc.edu">davemc@cs.un<SPAN
style="mso-bookmark: _Hlt423319854">c</SPAN>.edu</A><![if !supportNestedAnchors]><A
name=_Hlt423319854></A><![endif]></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center">Version 1.20</P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center">November 12, 1999</P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><![if !supportEmptyParas]><![endif]>&nbsp;<o:p></o:p></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal">The home page of the Particle System API is
<A href="http://www.cs.unc.edu/~davemc/Particle"><SPAN
style="FONT-WEIGHT: normal">http://www.cs.unc.edu/~davemc/Particle</SPAN></A><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal">Check back occasionally for new versions
and other new developments.<o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P align=center class=MsoNormal style="TEXT-ALIGN: center"><B
style="mso-bidi-font-weight: normal"><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></B></P>
<P class=MsoBodyText2>The Particle System API may be freely distributed in its
original distribution form and used for non-commercial purposes. For commercial
licensing, please contact <A
href="mailto:davemc@cs.unc.edu">davemc@cs.unc.edu</A> .</P>
<H1>Introduction</H1>
<P class=MsoNormal>The Particle System Application Programmer Interface (API) is
a set of functions that allow C++ programs to simulate the dynamics of
particles. The Particle System API is intended for special effects in
interactive and non-interactive graphics applications, not for scientific
simulation, although principles of Newtonian physics have been used to implement
the particle dynamics where applicable. The style of the API is intended to be
similar to that of OpenGL (from Silicon Graphics, Inc. and the OpenGL
Architecture Review Board). OpenGL is currently the standard 3D graphics API
because of its cleanness, clarity, and ability to represent a variety of
graphics hardware while completely abstracting the hardware away from the
application programmer.</P>
<P class=MsoNormal>This API consists of four sets of functions. These are calls
that set the current state of the library, calls that act on groups of particles
(these functions are called Actions), calls that operate on and manage particle
groups, and calls that create and operate on action lists. The documentation is
divided into four sections for the four kinds of functions.</P>
<H3>Particles</H3>
<P class=MsoNormal>For 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, tumbleweeds, even people. The Particle System API is generally useful for
operating on many similar objects that all move and change according to the same
basic rules, no matter what the objects and rules are.</P>
<P class=MsoNormal>A particle in the abstract sense used by the API is merely an
entity with a small set of attributes such as position and color that ultimately
dictate the particle's behavior and appearance. Here are the particle
attributes: The position, represented as three floats, tells where the particle
is. The color is represented as three floats. The velocity consists of three
floats telling the direction and speed (velocity vector) of the particle's
movement. The size is three floats representing how large the particle is for
purposes of drawing. At present, the size attribute does not affect the
particle's behavior (under gravity, for example), and should not be interpreted
as mass in particle physics equations. The size also does not indicate how close
the particle is to other particles or surfaces. It is only a drawing attribute.
The age attribute is one float representing the amount of time since the
particle's creation. The secondary position, or <I
style="mso-bidi-font-style: normal">positionB</I> attribute, specifies another
position in space for this particle. It usually represents the particle's
initial position, or the particle's destination. See <B
style="mso-bidi-font-weight: normal">pRestore</B> for a use of <I
style="mso-bidi-font-style: normal">positionB</I>. </P>
<H3>Particle Groups</H3>
<P class=MsoNormal>A particle group is a system of particles that are all acted
on together. </P>
<P class=MsoNormal>It can be considered a dynamic geometric object. </P>
<P class=MsoNormal>The dynamics are provided by the particle actions. From the
point of view of the graphics system, a particle group is just another model to
be drawn. The Particle Groups section of the documentation explains the
functions that create and deal with particle groups.</P>
<H3>State</H3>
<P class=MsoNormal>As in OpenGL, some calls actually do something and some calls
modify the current settings (the current state) that describe the behavior of
the calls that do something. Each of the following calls modifies the current
state of the Particle System API. Most elements of the current state are used to
specify attributes of particles to be created. </P>
<H3>Actions</H3>
<P class=MsoNormal>Actions are the core of the Particle System API. They are the
functions in the API that directly manipulate particles in particle groups. They
perform effects such as gravity, explosions, bouncing, etc. to all particles in
the current particle group. A program typically creates and initializes one or
more particle groups, then at run time it calls particle actions to animate the
particles and finally calls a <B
style="mso-bidi-font-weight: normal">pDrawGroup</B> function to draw the group
of particles onto the screen.</P>
<P class=MsoNormal>The Particle System API uses a discrete time approximation to
all actions. See <B style="mso-bidi-font-weight: normal">pTimeStep</B> for
information on improving simulation quality by varying the time step, <I
style="mso-bidi-font-style: normal">dt</I>.</P>
<H3>Action Lists</H3>
<P class=MsoNormal>Action lists are blocks of actions that are applied together
to a particle group. They are conceptually similar to scripts or procedures.
They can also be thought of as similar to display lists in OpenGL. An action
list abstracts the specifics of a particular effect and allows complex effects
to be treated as primitives like actions (except that an action list cannot be
an action within another action list). Action lists also allow effects to be
simulated much more efficiently on certain parallel machines, such as PixelFlow.
Also, action lists can be optimized by a particular implementation of the
Particle System API. For example, common sequences of actions can be detected
and replaced by efficient code that handles all those actions in one pass.</P>
<H3>Domains</H3>
<P class=MsoNormal>A Domain is a representation of a region of space. For
example, the <B style="mso-bidi-font-weight: normal">pSource</B> action uses a
domain to describe the volume in which a particle's random initial position will
be. The <B style="mso-bidi-font-weight: normal">pSink</B> and <B
style="mso-bidi-font-weight: normal">pBounce</B> actions use domains to describe
a volume in space for particles to die when they enter, or to bounce off,
respectively. Domains are used as parameters to many functions within the API.
See the <U>Domains</U> section of this document for more.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>Many functions in the Particle System API take arguments with
default values. This is a feature of C++ that may be new to many people. For
example, in <B style="mso-bidi-font-weight: normal">pColor</B>(float <I
style="mso-bidi-font-style: normal">r</I>, float <I
style="mso-bidi-font-style: normal">g</I>, float <I
style="mso-bidi-font-style: normal">b</I>, float <I
style="mso-bidi-font-style: normal">alpha</I> = 1.0f), the parameter <I
style="mso-bidi-font-style: normal">alpha </I>has a default value of 1.0. This
means that <B style="mso-bidi-font-weight: normal">pColor</B> can be called with
either three parameters or four. When called with four, the parameters are the
values for <I style="mso-bidi-font-style: normal">r, g, b</I> and <I
style="mso-bidi-font-style: normal">alpha</I>. When called with three
parameters, they are the values of <I style="mso-bidi-font-style: normal">r, g,
</I>and<I style="mso-bidi-font-style: normal"> b</I>. The value of <I
style="mso-bidi-font-style: normal">alpha </I>in such a function call is the
default value, 1.0. Only parameters starting with the right-hand end of the
parameter list can have default values specified. Likewise, when calling
functions that have default values for parameters at the end of the list, all
values specified will be applied to parameters starting with 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 left.</P>
<H1>State Setting Calls</H1>
<P class=MsoNormal>This is a description of all calls that set the current state
of the Particle System API. With the exception of <B
style="mso-bidi-font-weight: normal">pTimeStep </B>these state values dictate
the properties of particles to be created by <B
style="mso-bidi-font-weight: normal">pSource</B> or <B
style="mso-bidi-font-weight: normal">pVertex</B>.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>When particles are created within a <B
style="mso-bidi-font-weight: normal">pNewActionList</B> / <B
style="mso-bidi-font-weight: normal">pEndActionList</B> block, they 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), particles are
created with attributes from the current state.</P>
<P class=Note>The initial color domain, modifiable by <B
style="mso-bidi-font-weight: normal">pColor</B>, is: <B
style="mso-bidi-font-weight: normal">PDPoint</B>, 1.0, 1.0, 1.0, that is, white.
The initial alpha value is 1.0.</P>
<P class=Note>The initial velocity domain, modifiable by <B
style="mso-bidi-font-weight: normal">pVelocity</B>, is: <B
style="mso-bidi-font-weight: normal">PDPoint</B>, 0.0, 0.0, 0.0, or no
velocity.</P>
<P class=Note>The initial positionB domain, modifiable by <B
style="mso-bidi-font-weight: normal">pVertexB</B>, is: <B
style="mso-bidi-font-weight: normal">PDPoint</B>, 0.0, 0.0, 0.0.</P>
<P class=Note>However positionB is initially set to track particle position.</P>
<P class=Note>The initial size domain, modifiable by <B
style="mso-bidi-font-weight: normal">pSize</B>, is: <B
style="mso-bidi-font-weight: normal">PDPoint</B>, 1.0, 1.0, 1.0, or a unit
cube.</P>
<P class=Note>The initial starting age, modifiable by <B
style="mso-bidi-font-weight: normal">pStartingAge</B>, is 0.0 with standard
deviation 0.0.</P>
<P class=FuncProto>void <B style="mso-bidi-font-weight: normal">pColor</B>(float
<I style="mso-bidi-font-style: normal">red</I>, float <I
style="mso-bidi-font-style: normal">green</I>, float <I
style="mso-bidi-font-style: normal">blue</I>, float <I
style="mso-bidi-font-style: normal">alpha</I> = 1.0f)</P>
<P class=Description>Specify the color of new particles.</P>
<P class=MsoNormal>All new particles will have the color <I
style="mso-bidi-font-style: normal">red, green, blue, alpha</I>. This is a
special case of <B style="mso-bidi-font-weight: normal">pColorD</B>.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>See the documentation of Domains for a discussion of color spaces
in the Particle System API.</P>
<P class=Note>If rendering is to be done by a method other than the <B
style="mso-bidi-font-weight: normal">pDrawGroup</B> calls, the particle color
does not necessarily need to be used to represent color. It can be interpreted
as an arbitrary three-vector.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pColorD</B>(float <I
style="mso-bidi-font-style: normal">alpha</I>, <B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Specify the color domain of new particles.</P>
<P class=MsoNormal>All new particles will have a color chosen randomly from
within the specified domain and will have an alpha value (usually used for
transparency) of <I style="mso-bidi-font-style: normal">alpha</I>.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B style="mso-bidi-font-weight: normal">pSize</B>(float
<I style="mso-bidi-font-style: normal">size_x</I>, float <I
style="mso-bidi-font-style: normal">size_y</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">size_z</I> = 0.0f)</P>
<P class=Description>Specify the size of new particles.</P>
<P class=MsoNormal>All new particles will have a size of <I
style="mso-bidi-font-style: normal">size</I>. The size values may be negative.
This is a special case of <B
style="mso-bidi-font-weight: normal">pSizeD</B>.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>The size does not affect any particle dynamics, including
acceleration and bouncing. It is merely a triple of rendering attributes, like
color, and can be interpreted at the whim of the application programmer (that<61>s
you). In particular, the three components do not need to be used together as
three dimensions of the particle<6C>s size. For example, one could be interpreted
as radius, another as length, and another as density.</P>
<P class=Note>The definition of this call has changed because it is now a
special case of <B style="mso-bidi-font-weight: normal">pSizeD</B>.</P>
<P class=FuncProto style="MARGIN-LEFT: 0in; TEXT-INDENT: 0in">void <B
style="mso-bidi-font-weight: normal">pSizeD</B>(<B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Specify the size domain of new particles.</P>
<P class=MsoNormal>All new particles will have a size chosen randomly from
within the specified domain. The size values may be negative.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>The size does not affect any particle dynamics, including
acceleration and bouncing. It is merely a triple of rendering attributes, like
color, and can be interpreted at the whim of the application programmer (that<61>s
you). In particular, the three components do not need to be used together as
three dimensions of the particle<6C>s size. For example, one could be interpreted
as radius, another as length, and another as density.</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pStartingAge</B>(float <I
style="mso-bidi-font-style: normal">age</I>, float <I
style="mso-bidi-font-style: normal">stdev</I> = 0.0f)</P>
<P class=Description>Specify the initial age of new particles.</P>
<P class=MsoNormal>The value <I style="mso-bidi-font-style: normal">age</I> can
be positive, zero, or negative. Giving particles different starting ages allows
<B style="mso-bidi-font-weight: normal">pKillOld</B> to distinguish between
which to kill in interesting ways. Setting <I
style="mso-bidi-font-style: normal">stdev</I> to a non-zero value will give the
particles an initial age with a normal distribution with mean <I
style="mso-bidi-font-style: normal">age</I> and standard deviation <I
style="mso-bidi-font-style: normal">stdev</I>. When many particles are created
at once this allows a few particles to die at each time step, yielding a more
natural effect.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pTimeStep</B>(float <I
style="mso-bidi-font-style: normal">newDT</I>)</P>
<P class=Description>Specify the time step length.</P>
<P class=MsoNormal>The Particle System API uses a discrete time approximation to
all actions. This means that actions are applied to the particles at a
particular instant in time as if the action's effect accumulated over a small
time interval, <I style="mso-bidi-font-style: normal">dt</I>, with the world
being constant over the interval. The clock is then "ticked" by the length of
the interval and the actions can then be reapplied with the particles having
their updated values. This is the standard method of doing almost all
time-varying simulations in computer science.</P>
<P class=MsoNormal>How does the time step, <I
style="mso-bidi-font-style: normal">dt</I>, relate to the application's frame
rate? The easiest method is to apply the actions once per frame. If the
application prefers to keep time in terms of seconds, <I
style="mso-bidi-font-style: normal">dt</I> can be set to (1 /
frames_per_second). But more often, it is easier for a time unit to be one frame
instead of one second. In this case, <I
style="mso-bidi-font-style: normal">dt</I> should be 1.0, which is the
default.</P>
<P class=MsoNormal>For higher quality, the application can apply particle
actions more than once per frame. This provides smoother, more realistic results
in many subtle ways. Suppose the application wanted to compute three animation
steps for each rendered frame. Set <I style="mso-bidi-font-style: normal">dt</I>
to 1/3 its previous value using <B
style="mso-bidi-font-weight: normal">pTimeStep</B>, then loop three times over
all the action code that gets executed per frame, including the calls to <B
style="mso-bidi-font-weight: normal">pMove</B>. If using action lists, this can
be simply a loop over the <B
style="mso-bidi-font-weight: normal">pCallActionList</B> call. The run-time
results should be about the same, but with fewer discrete approximation
artifacts. Surprisingly enough, the actions themselves usually take a small
percentage of the CPU time, so using a finer step size usually does not impact
frame rate very much.</P>
<P class=MsoNormal>In terms of numerical integration, particle actions can be
thought of as the first derivative of unknown functions dictating the particle
attributes (such as position) over time. In order to compute the particle
attributes these derivative functions must be integrated. Since closed form
integration doesn't make sense for most actions, Euler's method is used instead.
Euler's method is simply the method just described <20> the evaluation of the
derivative functions at a particular time and then incrementing the current
particle values by these derivative results times <I
style="mso-bidi-font-style: normal">dt</I>. In Euler's method, the smaller the
<I style="mso-bidi-font-style: normal">dt</I>, the more accurate the
results.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>Unlike with other state setting calls, action lists execute using
the current <I style="mso-bidi-font-style: normal">dt</I> value set by <B
style="mso-bidi-font-weight: normal">pTimeStep</B>, rather than the time step
value that was current when the action list was created. Making action lists
independent of time step size allows the time step to be changed without
recompiling the action list.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pVelocity</B>(float <I
style="mso-bidi-font-style: normal">x</I>, float <I
style="mso-bidi-font-style: normal">y</I>, float <I
style="mso-bidi-font-style: normal">z</I>)</P>
<P class=Description>Specify the initial velocity of new particles.</P>
<P class=MsoNormal>This is shorthand for <B
style="mso-bidi-font-weight: normal">pVelocityD</B>(<B
style="mso-bidi-font-weight: normal">PDPoint, </B><I
style="mso-bidi-font-style: normal">x</I>, <I
style="mso-bidi-font-style: normal">y</I>, <I
style="mso-bidi-font-style: normal">z</I>).</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pVelocityD</B>(<B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Specify the initial velocity domain of new particles.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pVertexB</B>(float <I
style="mso-bidi-font-style: normal">x</I>, float <I
style="mso-bidi-font-style: normal">y</I>, float <I
style="mso-bidi-font-style: normal">z</I>)</P>
<P class=Description>Specify the secondary position of new particles.</P>
<P class=MsoNormal>This is shorthand for <B
style="mso-bidi-font-weight: normal">pVertexBD</B>(<B
style="mso-bidi-font-weight: normal">PDPoint</B>, <I
style="mso-bidi-font-style: normal">x</I>, <I
style="mso-bidi-font-style: normal">y</I>, <I
style="mso-bidi-font-style: normal">z</I>).</P>
<P class=FuncProto>void <B style="mso-bidi-font-weight: normal">pVertexBD</B>(<B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Specify the secondary position domain of new particles.</P>
<P class=MsoNormal>Set the domain from which the <I
style="mso-bidi-font-style: normal">positionB</I> of each particle will be
randomly chosen when it is created. But if <B
style="mso-bidi-font-weight: normal">pVertexBTracks</B> is set to true (the
default), then the <I style="mso-bidi-font-style: normal">positionB</I> will
instead be the same as the initial particle position.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pVertexBTracks</B>(bool <I
style="mso-bidi-font-style: normal">doCopy</I>)</P>
<P class=Description>Specify how the secondary position of each new particle is
chosen.</P>
<P class=MsoNormal>Specify how the <I
style="mso-bidi-font-style: normal">positionB</I> of each new particle emitted
will be chosen. The positionB is the destination position or initial position of
particles. See <B style="mso-bidi-font-weight: normal">pRestore</B> for a use of
positionB.</P>
<P class=MsoNormal>If <I style="mso-bidi-font-style: normal">doCopy</I> is true
then when a particle is created its <I
style="mso-bidi-font-style: normal">positionB</I> will be the same as its
initial particle position (the default).</P>
<P class=MsoNormal>If <I style="mso-bidi-font-style: normal">doCopy</I> is false
then when a particle is created its <I
style="mso-bidi-font-style: normal">positionB</I> will be chosen from the <I
style="mso-bidi-font-style: normal">VertexB</I> domain.</P>
<H1>Actions</H1>
<P class=MsoPlainText><SPAN style="FONT-FAMILY: 'Times New Roman'">Actions
modify the position, color, velocity, size, age, and secondary position and
velocity of particles. All actions apply to the current particle group, as set
by <B
style="mso-bidi-font-weight: normal">pCurrentGroup</B>.<o:p></o:p></SPAN></P>
<P class=MsoPlainText><SPAN style="FONT-FAMILY: 'Times New Roman'">Remember that
the amount of effect of an action call depends on the time step size, <I
style="mso-bidi-font-style: normal">dt</I>, as set by <B
style="mso-bidi-font-weight: normal">pTimeStep</B>. See <B
style="mso-bidi-font-weight: normal">pTimeStep</B> for an explanation of time
steps.<o:p></o:p></SPAN></P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>Some functions have parameters with a default value of P_EPS.
P_EPS is a very small floating point constant that is most often used as the
default value of the <I style="mso-bidi-font-style: normal">epsilon</I>
parameter to actions whose influence on a particle is relative to the inverse
square of its distance from 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 unsatisfying results in which particles are
accelerated way too much. So this <I
style="mso-bidi-font-style: normal">epsilon</I> parameter is added to the
distance before taking its inverse square, thus keeping the acceleration within
reasonable limits. By varying <I
style="mso-bidi-font-style: normal">epsilon</I>, you specify what is reasonable.
Larger <I style="mso-bidi-font-style: normal">epsilon</I> make particles
accelerate less.</P>
<P class=FuncProto>void <B style="mso-bidi-font-weight: normal">pAvoid</B>(float
<I style="mso-bidi-font-style: normal">magnitude</I>, float <I
style="mso-bidi-font-style: normal">epsilon</I>, float <I
style="mso-bidi-font-style: normal">look_ahead</I>, <B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Steer particles away from a domain of space.</P>
<P class=MsoNormal>Particles are tested to see whether they will pass from being
outside the specified domain to being inside it within <I
style="mso-bidi-font-style: normal">look_ahead</I> time units from now if the
next <B style="mso-bidi-font-weight: normal">pMove</B> action were to occur now.
<I style="mso-bidi-font-style: normal">magnitude</I> tells how drastically the
particle velocities are modified to avoid the obstacle at each time step. As
with most acceleration actions, the amount of acceleration falls off inversely
with <I style="mso-bidi-font-style: normal">r<SUP>2</SUP></I>. But when <I
style="mso-bidi-font-style: normal">r</I> is small, the acceleration would be
infinite, so <I style="mso-bidi-font-style: normal">epsilon</I> is always added
to <I style="mso-bidi-font-style: normal">r</I>.</P>
<P class=MsoNormal>The specific direction and amount of turn is dependent on the
kind of domain being avoided.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>At present the only domains for which <B
style="mso-bidi-font-weight: normal">pAvoid</B> is implemented are <B
style="mso-bidi-font-weight: normal">PDSphere</B>,<B
style="mso-bidi-font-weight: normal"> PDRectangle, PDTriangle, PDDisc</B> and <B
style="mso-bidi-font-weight: normal">PDPlane</B>.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pBounce</B>(float <I
style="mso-bidi-font-style: normal">friction</I>, float <I
style="mso-bidi-font-style: normal">resilience</I>, float <I
style="mso-bidi-font-style: normal">cutoff</I>, <B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Bounce particles off a domain of space.</P>
<P class=MsoNormal>Particles are tested to see whether they will pass from being
outside the specified domain to being inside it if the next <B
style="mso-bidi-font-weight: normal">pMove</B> action were to occur now. If they
would pass through the surface of the domain, they are instead bounced off it.
That is, their velocity vector is decomposed into components normal to the
surface and tangent to the surface. The direction of the normal component is
reversed, and the components are recomposed into a new velocity heading away
from the surface.</P>
<P class=MsoNormal>The normal component is multiplied by the <I
style="mso-bidi-font-style: normal">resilience</I> parameter and the tangential
component, if its magnitude is greater than <I
style="mso-bidi-font-style: normal">cutoff</I>, is multiplied by (1 - the <I
style="mso-bidi-font-style: normal">friction</I> parameter) when being composed
into the new velocity vector.</P>
<P class=MsoNormal>The <I style="mso-bidi-font-style: normal">cutoff</I>
parameter can allow particles to glide smoothly along a surface without
sticking.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>Since particles are tested to see whether they would pass through
the domain if <B style="mso-bidi-font-weight: normal">pMove</B> were called now,
it is best to have <B style="mso-bidi-font-weight: normal">pBounce</B> be the
last action that modifies a particle's velocity before calling <B
style="mso-bidi-font-weight: normal">pMove</B>. Also, actions such as <B
style="mso-bidi-font-weight: normal">pRandomDisplace</B> and <B
style="mso-bidi-font-weight: normal">pVortex</B> that modify a particle's
position directly, rather than modifying its velocity vector, may yield
unsatisfying results when used with <B
style="mso-bidi-font-weight: normal">pBounce</B>.</P>
<P class=Note>At present the only domains for which <B
style="mso-bidi-font-weight: normal">pBounce</B> is implemented are <B
style="mso-bidi-font-weight: normal">PDSphere</B>,<B
style="mso-bidi-font-weight: normal"> PDRectangle, DTriangle, PDDisc</B> and <B
style="mso-bidi-font-weight: normal">PDPlane</B>. For spheres, the particle is
always forced out of the sphere. For planes, triangles and discs, the particles
bounce off either side of the surface. For rectangles, particles bounce off
either side of the diamond-shaped patch whose corners are <I
style="mso-bidi-font-style: normal">o</I>, <I
style="mso-bidi-font-style: normal">o</I>+<I
style="mso-bidi-font-style: normal">u</I>, <I
style="mso-bidi-font-style: normal">o</I>+<I
style="mso-bidi-font-style: normal">u</I>+<I
style="mso-bidi-font-style: normal">v</I>, and <I
style="mso-bidi-font-style: normal">o</I>+<I
style="mso-bidi-font-style: normal">v</I>. See the documentation on domains for
an explanation.</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=Note><B style="mso-bidi-font-weight: normal">pBounce</B> doesn't work
correctly with small time step sizes for particle sliding along a surface. The
<I style="mso-bidi-font-style: normal">friction</I> and <I
style="mso-bidi-font-style: normal">resilience</I> parameters should not be
scaled by <I style="mso-bidi-font-style: normal">dt</I>, since a bounce happens
instantaneously. On the other hand, they should be scaled by <I
style="mso-bidi-font-style: normal">dt</I> because particles sliding along a
surface will hit more often if <I style="mso-bidi-font-style: normal">dt</I> is
smaller. If you have any suggestions, let me know.</P>
<P class=MsoNormal><![if !supportEmptyParas]><![endif]>&nbsp;<o:p></o:p></P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pCopyVertexB</B>(bool <I
style="mso-bidi-font-style: normal">copy_pos</I> = true, bool <I
style="mso-bidi-font-style: normal">copy_vel</I> = false)</P>
<P class=Description>Set the secondary position from current position.</P>
<P class=MsoNormal>If <I style="mso-bidi-font-style: normal">copy_pos</I> is
true, sets the <I style="mso-bidi-font-style: normal">positionB</I> of each
particle in the current particle group to be equal to the current position of
that particle. This makes each particle "remember" this position so it can later
return to it using <B style="mso-bidi-font-weight: normal">pRestore</B>. If <I
style="mso-bidi-font-style: normal">copy_vel</I> is true, sets the <I
style="mso-bidi-font-style: normal">velocityB</I> of each particle in the
current particle group to be equal to the current velocity of that particle.
This is useful for computing the orientation of the particle when rendering it
using <B style="mso-bidi-font-weight: normal">pDrawGroupl</B>.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pDamping</B>(float <I
style="mso-bidi-font-style: normal">damping_x</I>, float <I
style="mso-bidi-font-style: normal">damping_y</I>, float <I
style="mso-bidi-font-style: normal">damping_z</I>, float <I
style="mso-bidi-font-style: normal">vlow</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">vhigh</I> = P_MAXFLOAT)</P>
<P class=Description>Simulate air by slowing down particle velocities.</P>
<P class=MsoNormal>If a particle's velocity magnitude is within <I
style="mso-bidi-font-style: normal">vlow</I> and <I
style="mso-bidi-font-style: normal">vhigh</I>, then multiply each component of
the velocity by the respective damping constant. Typically, the three components
of <I style="mso-bidi-font-style: normal">damping</I> will have the same
value.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>There are no bounds on the damping constants. Thus, by giving
values greater than 1.0 they may be used to speed up particles in stead of slow
them down.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pExplosion</B>(float <I
style="mso-bidi-font-style: normal">center_x</I>, float <I
style="mso-bidi-font-style: normal">center_y</I>, float <I
style="mso-bidi-font-style: normal">center_z</I>, float <I
style="mso-bidi-font-style: normal">velocity</I>, float <I
style="mso-bidi-font-style: normal">magnitude</I>, float <I
style="mso-bidi-font-style: normal">stdev</I>, float <I
style="mso-bidi-font-style: normal">epsilon</I> = P_EPS, float <I
style="mso-bidi-font-style: normal">age</I> = 0.0f)</P>
<P class=Description>An Explosion.</P>
<P class=MsoNormal>Causes an explosion by accelerating all particles away from
the <I style="mso-bidi-font-style: normal">center</I>. Particles are accelerated
away from the <I style="mso-bidi-font-style: normal">center</I> by an amount
proportional to <I style="mso-bidi-font-style: normal">magnitude</I>. As with
most acceleration actions, the amount of acceleration falls off inversely with
<I style="mso-bidi-font-style: normal">r</I><SUP>2</SUP>. But when <I
style="mso-bidi-font-style: normal">r</I> is small, the acceleration would be
infinite, so <I style="mso-bidi-font-style: normal">epsilon</I> is always added
to <I style="mso-bidi-font-style: normal">r</I>.</P>
<P class=MsoNormal>The shock wave of the explosion has a gaussian magnitude. The
center of the gaussian travels outward from the <I
style="mso-bidi-font-style: normal">center</I> at the specified <I
style="mso-bidi-font-style: normal">velocity</I>. So at a given time step,
particles at a distance <I style="mso-bidi-font-style: normal">(velocity *
age)</I> from <I style="mso-bidi-font-style: normal">center</I> will receive the
most acceleration, and particles not at the peak of the shock wave will receive
a lesser acceleration.</P>
<P class=MsoNormal><SPAN style="mso-spacerun: yes">&nbsp;</SPAN>The shock wave
has a standard deviation of <I style="mso-bidi-font-style: normal">stdev</I>,
which is the sharpness or broadness of the strength of the wave.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">age</I> is used to
calculate the radius of the shock wave. For <B
style="mso-bidi-font-weight: normal">pExplosion</B> calls in action lists, <I
style="mso-bidi-font-style: normal">age</I> is the initial age of the explosion.
It is incremented by <I style="mso-bidi-font-style: normal">dt</I> after each
call. For immediate mode, <I style="mso-bidi-font-style: normal">age</I> is the
current age of the explosion, and it is up to the application to increment the
<I style="mso-bidi-font-style: normal">age</I> parameter for each call to <B
style="mso-bidi-font-weight: normal">pExlosion.<o:p></o:p></B></P>
<P class=MsoNoteHeading>NOTE</P>
<P class=Note>Since the current radius of the shock wave is given by <I
style="mso-bidi-font-style: normal">(velocity * age)</I> you can set up a
standing wave by setting <I style="mso-bidi-font-style: normal">velocity</I> to
the desired radius of the wave and <I
style="mso-bidi-font-style: normal">age</I> to 1.0. This only works in immediate
mode.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pFollow</B>(float <I
style="mso-bidi-font-style: normal">magnitude</I> = 1.0f, float <I
style="mso-bidi-font-style: normal">epsilon</I> = P_EPS, float <I
style="mso-bidi-font-style: normal">max_radius</I> = P_MAXFLOAT)</P>
<P class=Description>Accelerate toward the next particle in the group.</P>
<P class=MsoNormal>This allows snaky effects where the particles follow each
other. Each particle is accelerated toward the next particle in the group by an
amount proportional to <I style="mso-bidi-font-style: normal">magnitude</I>. As
with most acceleration actions, the amount of acceleration falls off inversely
with <I style="mso-bidi-font-style: normal">r</I><SUP>2</SUP>. But when <I
style="mso-bidi-font-style: normal">r</I> is small, the acceleration would be
infinite, so <I style="mso-bidi-font-style: normal">epsilon</I> is always added
to <I style="mso-bidi-font-style: normal">r</I>.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">max_radius</I> defines
the sphere of influence of this action. No particle further than <I
style="mso-bidi-font-style: normal">max_radius</I> from its predecessor is
affected.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>The <B style="mso-bidi-font-weight: normal">pFollow</B> action
does not affect the last particle in the group. This allows controlled effects
where the last particle in the group is killed after each time step and replaced
by a new particle at a slightly different position. See <B
style="mso-bidi-font-weight: normal">pKillOld</B> to learn how to kill the last
particle in the group after each step.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pGravitate</B>(float <I
style="mso-bidi-font-style: normal">magnitude</I> = 1.0f, float <I
style="mso-bidi-font-style: normal">epsilon</I> = P_EPS, float <I
style="mso-bidi-font-style: normal">max_radius</I> = P_MAXFLOAT)</P>
<P class=Description>Accelerate each particle toward each other particle.</P>
<P class=MsoNormal>Each particle is accelerated toward each other particle in
the group by an amount proportional to <I
style="mso-bidi-font-style: normal">magnitude</I>. As with most acceleration
actions, the amount of acceleration falls off inversely with <I
style="mso-bidi-font-style: normal">r</I><SUP>2</SUP>. But when r is small, the
acceleration would be infinite, so <I
style="mso-bidi-font-style: normal">epsilon</I> is always added to <I
style="mso-bidi-font-style: normal">r</I>.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">max_radius</I> defines
the sphere of influence of this action. No particle further than <I
style="mso-bidi-font-style: normal">max_radius</I> from another particle is
affected.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>This action is more computationally intensive than the others are
because each particle is affected by each other particle.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pGravity</B>(float <I
style="mso-bidi-font-style: normal">dir_x</I>, float <I
style="mso-bidi-font-style: normal">dir_y</I>, float <I
style="mso-bidi-font-style: normal">dir_z</I>)</P>
<P class=Description>Accelerate particles in the given direction.</P>
<P class=MsoNormal>The gravity acceleration vector is simply added to the
velocity vector of each particle at each time step. The magnitude of the gravity
vector is the acceleration due to gravity. For example, <B
style="mso-bidi-font-weight: normal">pGravity</B>(0, 0, -9.8) specifies gravity
in the negative Z direction.</P>
<P class=FuncProto>void <B style="mso-bidi-font-weight: normal">pJet</B>(float
<I style="mso-bidi-font-style: normal">center_x</I>, float <I
style="mso-bidi-font-style: normal">center_y</I>, float <I
style="mso-bidi-font-style: normal">center_z</I>, float <I
style="mso-bidi-font-style: normal">magnitude</I> = 1.0f, float <I
style="mso-bidi-font-style: normal">epsilon</I> = P_EPS, float <I
style="mso-bidi-font-style: normal">max_radius</I> = P_MAXFLOAT)</P>
<P class=Description>Accelerate particles that are near the center of the
jet.</P>
<P class=MsoNormal>For each particle, chooses an acceleration vector from the
domain and applies it to the particle's velocity. The amount of acceleration
applied is directly proportional to <I
style="mso-bidi-font-style: normal">magnitude</I>. As with most acceleration
actions, the amount of acceleration falls off inversely with <I
style="mso-bidi-font-style: normal">r<SUP>2</SUP></I>. But when <I
style="mso-bidi-font-style: normal">r</I> is small, the acceleration would be
infinite, so <I style="mso-bidi-font-style: normal">epsilon</I> is always added
to <I style="mso-bidi-font-style: normal">r</I>.</P>
<P class=MsoNormal>The domain from which acceleration vectors are chosen is the
current velocity domain.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">max_radius</I> defines
the sphere of influence of this action. No particle further than <I
style="mso-bidi-font-style: normal">max_radius</I> from the center is
affected.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pKillOld</B>(float <I
style="mso-bidi-font-style: normal">age_limit</I>, bool <I
style="mso-bidi-font-style: normal">kill_less_than</I> = false)</P>
<P class=Description>Remove old particles.</P>
<P class=MsoNormal>Removes all particles older than <I
style="mso-bidi-font-style: normal">age_limit</I>. But if <I
style="mso-bidi-font-style: normal">kill_less_than</I> is true, it instead
removes all particles newer than <I
style="mso-bidi-font-style: normal">age_limit</I>. <I
style="mso-bidi-font-style: normal">age_limit</I> is not clamped, so negative
values are ok. This can be used in conjunction with <B
style="mso-bidi-font-weight: normal">pStartingAge</B>(-n) to create and then
kill a particular set of particles.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>In order to kill a particular particle, set <B
style="mso-bidi-font-weight: normal">pStartingAge</B> to a number that will
never be a typical age for any other particle in the group, for example -10.0.
Then emit the particle using <B style="mso-bidi-font-weight: normal">pSource</B>
or <B style="mso-bidi-font-weight: normal">pVertex</B>. Then do the rest of the
particle actions and finally call <B
style="mso-bidi-font-weight: normal">pKillOld</B>(-8.0, true) to kill the
special particle because it is the only one with an age less than -8.0.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pMatchVelocity</B>(float <I
style="mso-bidi-font-style: normal">magnitude</I> = 1.0f, float <I
style="mso-bidi-font-style: normal">epsilon</I> = P_EPS, float <I
style="mso-bidi-font-style: normal">max_radius</I> = P_MAXFLOAT)</P>
<P class=Description>Modify each particle<6C>s velocity to be similar to that of
its neighbors.</P>
<P class=MsoNormal>Each particle is accelerated toward the weighted mean of the
velocities of other particles in the group by an amount proportional to <I
style="mso-bidi-font-style: normal">magnitude</I>. As with most acceleration
actions, the amount of acceleration falls off inversely with <I
style="mso-bidi-font-style: normal">r</I><SUP>2</SUP> to the other particles.
But when <I style="mso-bidi-font-style: normal">r</I> is small, the acceleration
would be infinite, so <I style="mso-bidi-font-style: normal">epsilon</I> is
always added to <I style="mso-bidi-font-style: normal">r</I>. Using an epsilon
similar in magnitude to <I style="mso-bidi-font-style: normal">magnitude</I> can
increase the range of influence of nearby particles on this particle.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=MsoNormal>This action is more computationally intensive than the others
are because each particle is affected by each other particle.</P>
<P class=FuncProto>void <B style="mso-bidi-font-weight: normal">pMove</B>()</P>
<P class=Description>Move particle positions based on velocities.</P>
<P class=MsoNormal>This action actually updates the particle positions by adding
the current velocity to the current position. This is typically the last
particle action performed in an iteration of a particle simulation, and
typically only occurs once per action list.</P>
<P class=MsoNormal>The velocity is multiplied by the time step length, <I
style="mso-bidi-font-style: normal">dt</I>, before being added to the position.
This implements Euler's method of numerical integration with a constant, but
specifiable step size. See <B style="mso-bidi-font-weight: normal">pTimeStep</B>
for more on varying the step size.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pOrbitLine</B>(float <I
style="mso-bidi-font-style: normal">p_x</I>, float <I
style="mso-bidi-font-style: normal">p_y</I>, float <I
style="mso-bidi-font-style: normal">p_z</I>, float <I
style="mso-bidi-font-style: normal">axis_x</I>, float <I
style="mso-bidi-font-style: normal">axis_y</I>, float <I
style="mso-bidi-font-style: normal">axis_z</I>, float <I
style="mso-bidi-font-style: normal">magnitude</I> = 1.0f, float <I
style="mso-bidi-font-style: normal">epsilon</I> = P_EPS, float <I
style="mso-bidi-font-style: normal">max_radius</I> = P_MAXFLOAT)</P>
<P class=Description>Accelerate toward the closest point on the given line.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">p</I> and <I
style="mso-bidi-font-style: normal">axis</I> define an infinite line, where <I
style="mso-bidi-font-style: normal">p</I> can be any point on the line and <I
style="mso-bidi-font-style: normal">axis</I> is any vector parallel to the line.
For each particle, this action computes the vector to the closest point on the
line, and accelerates the particle in the vector direction. The amount of
acceleration applied is directly proportional to <I
style="mso-bidi-font-style: normal">magnitude</I>. As with most acceleration
actions, the amount of acceleration falls off inversely with <I
style="mso-bidi-font-style: normal">r</I><SUP>2</SUP>. But when <I
style="mso-bidi-font-style: normal">r</I> is small, the acceleration would be
infinite, so <I style="mso-bidi-font-style: normal">epsilon</I> is always added
to <I style="mso-bidi-font-style: normal">r</I>.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">max_radius</I> defines
the infinite cylinder of influence of this action. No particle further than <I
style="mso-bidi-font-style: normal">max_radius</I> from the line is
affected.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pOrbitPoint</B>(float <I
style="mso-bidi-font-style: normal">center_x</I>, float <I
style="mso-bidi-font-style: normal">center_y</I>, float <I
style="mso-bidi-font-style: normal">center_z</I>, float <I
style="mso-bidi-font-style: normal">magnitude</I> = 1.0f, float <I
style="mso-bidi-font-style: normal">epsilon</I> = P_EPS, float <I
style="mso-bidi-font-style: normal">max_radius</I> = P_MAXFLOAT)</P>
<P class=Description>Accelerate toward the given center point.</P>
<P class=MsoNormal>For each particle, this action computes the vector to the
center point, and accelerates the particle in the vector direction. The amount
of acceleration applied is directly proportional to <I
style="mso-bidi-font-style: normal">magnitude</I>. As with most acceleration
actions, the amount of acceleration falls off inversely with <I
style="mso-bidi-font-style: normal">r</I><SUP>2</SUP>. But when <I
style="mso-bidi-font-style: normal">r</I> is small, the acceleration would be
infinite, so <I style="mso-bidi-font-style: normal">epsilon</I> is always added
to <I style="mso-bidi-font-style: normal">r</I>.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">max_radius</I> defines
the sphere of influence of this action. No particle further than <I
style="mso-bidi-font-style: normal">max_radius</I> from the <I
style="mso-bidi-font-style: normal">center</I> is affected.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pRandomAccel</B>(<B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Accelerate particles in random directions.</P>
<P class=MsoNormal>For each particle, chooses an acceleration vector from the
specified domain and adds it to the particle's velocity.</P>
<P class=MsoNormal>Reducing the time step, <I
style="mso-bidi-font-style: normal">dt</I>, will make a higher probability of
being near the original velocity after unit time. Smaller <I
style="mso-bidi-font-style: normal">dt</I> approach a normal distribution of
velocity vectors instead of a square wave distribution.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pRandomDisplace</B>(<B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Immediately replace position with a position from the
domain.</P>
<P class=MsoNormal>For each particle, chooses a displacement vector from the
specified domain and adds it to the particle's position.</P>
<P class=MsoNormal>Reducing the time step, <I
style="mso-bidi-font-style: normal">dt</I>, will make a higher probability of
being near the original position after unit time. Smaller <I
style="mso-bidi-font-style: normal">dt</I> approach a normal distribution of
particle positions instead of a square wave distribution.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>Since this action moves particle positions, unsatisfying results
may occur when used with the <B style="mso-bidi-font-weight: normal">pAvoid
</B>or <B style="mso-bidi-font-weight: normal">pBounce</B> actions. In
particular, particles may be displaced to the opposite side of the surface
without bouncing off it.</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pRandomVelocity</B>(<B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Immediately replace velocity with a velocity from the
domain.</P>
<P class=MsoNormal>For each particle, sets the particle's velocity vector to a
random vector in the specified domain.</P>
<P class=MsoNormal>This function is not affected by <I
style="mso-bidi-font-style: normal">dt</I>. If you can think of an appropriate
way for this to vary with <I style="mso-bidi-font-style: normal">dt</I>, let me
know.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pRestore</B>(float <I
style="mso-bidi-font-style: normal">time_left</I>)</P>
<P class=Description>Over time, restore particles to their secondary
positions.</P>
<P class=MsoNormal>Computes a new velocity for each particle that will make the
particle arrive at its <I style="mso-bidi-font-style: normal">positionB</I> at
the specified amount of time in the future. The curved path that the particles
take is a parametric quadratic. Once the specified amount of time has passed,
the particles are clamped to their <I
style="mso-bidi-font-style: normal">positionB</I> and their velocities are set
to 0 to freeze them in place.</P>
<P class=MsoNormal>If <B style="mso-bidi-font-weight: normal">pRestore</B> is
called in immediate mode, it is the application's responsibility to decrease <I
style="mso-bidi-font-style: normal">time_left</I> by <I
style="mso-bidi-font-style: normal">dt</I> on each call. When in an action list,
<I style="mso-bidi-font-style: normal">time_left</I> gets decremented
automatically.</P>
<P class=MsoNormal>The <I style="mso-bidi-font-style: normal">positionB</I>
attribute of each particle is typically the particle's position when it was
created, or it can be specified within a domain. This is controlled by <B
style="mso-bidi-font-weight: normal">pVertexBTracks</B>, <B
style="mso-bidi-font-weight: normal">pVertexB</B>, and <B
style="mso-bidi-font-weight: normal">pVertexBD</B>. The <I
style="mso-bidi-font-style: normal">positionB</I> can be set at any time to the
particle's current position using the <B
style="mso-bidi-font-weight: normal">pCopyVertexB</B> action.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note><B style="mso-bidi-font-weight: normal">pRestore</B>(0) is the
opposite of <B style="mso-bidi-font-weight: normal">pCopyVertexB</B> <20> it sets
each particle's position to be equal to its positionB. However, this has the
side effect of setting each particle's velocity to 0.</P>
<P class=FuncProto>void <B style="mso-bidi-font-weight: normal">pSink</B>(bool
<I style="mso-bidi-font-style: normal">kill_inside</I>, <B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Kill particles with positions on wrong side of the
specified domain.</P>
<P class=MsoNormal>If <I style="mso-bidi-font-style: normal">kill_inside</I> is
true, deletes all particles inside the given domain. If <I
style="mso-bidi-font-style: normal">kill_inside</I> is false, deletes all
particles outside the given domain.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pSinkVelocity</B>(bool <I
style="mso-bidi-font-style: normal">kill_inside</I>, <B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Kill particles with velocities on wrong side of the
specified domain.</P>
<P class=MsoNormal>If <I style="mso-bidi-font-style: normal">kill_inside</I> is
true, deletes all particles whose velocity vectors are inside the given domain.
If <I style="mso-bidi-font-style: normal">kill_inside</I> is false, deletes all
particles whose velocity vectors are outside the given domain. This allows
particles to die when they turn around, get too fast or too slow, etc.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>This action replaces the deprecated <B
style="mso-bidi-font-weight: normal">pKillSlow</B> by using a sphere domain
centered at the origin and a radius equal to the cutoff velocity.</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pSource</B>(float <I
style="mso-bidi-font-style: normal">particle_rate</I>, <B
style="mso-bidi-font-weight: normal">PDomainEnum</B> <I
style="mso-bidi-font-style: normal">dtype</I>, float <I
style="mso-bidi-font-style: normal">a0</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a1</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a2</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a3</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a4</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a5</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a6</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a7</I> = 0.0f, float <I
style="mso-bidi-font-style: normal">a8</I> = 0.0f)</P>
<P class=Description>Add particles in the specified domain.</P>
<P class=MsoNormal>Adds new particles to the current particle group. The
particle positions are chosen from the given domain. The particle colors, sizes,
initial ages, velocities, and secondary positions are chosen according to their
current domains. See <B style="mso-bidi-font-weight: normal">pColor</B>, <B
style="mso-bidi-font-weight: normal">pColorD</B>, <B
style="mso-bidi-font-weight: normal">pSize</B>, <B
style="mso-bidi-font-weight: normal">pStartingAge, pVelocity</B>, <B
style="mso-bidi-font-weight: normal">pVelocityD</B>, <B
style="mso-bidi-font-weight: normal">pVertexB</B>, <B
style="mso-bidi-font-weight: normal">pVertexBD</B>, and <B
style="mso-bidi-font-weight: normal">pVertexBTracks</B>.</P>
<P class=MsoNormal>When <B style="mso-bidi-font-weight: normal">pSource</B> is
called within an action list, the particle attribute domains used are those that
were current when the <B style="mso-bidi-font-weight: normal">pSource</B>
command was called within the <B
style="mso-bidi-font-weight: normal">pNewActionList</B> / <B
style="mso-bidi-font-weight: normal">pEndActionList</B> block instead of when <B
style="mso-bidi-font-weight: normal">pCallActionList</B> is called. Note that
this is unlike OpenGL.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">particle_rate</I> is
the number of particles to add per unit time. If <I
style="mso-bidi-font-style: normal">particle_rate</I> / <I
style="mso-bidi-font-style: normal">dt</I> is a fraction then <B
style="mso-bidi-font-weight: normal">pSource</B> adjusts the number of particles
to add during this time step so that the average number added per unit time is
<I style="mso-bidi-font-style: normal">particle_rate</I>.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>If too few particles seem to be added each frame, it is probably
because the particle group is already full. If this is bad, you can grow the
group using <B style="mso-bidi-font-weight: normal">pSetMaxParticles</B>.</P>
<P class=Note>See the documentation of Domains for an explanation of the other
arguments.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pSpeedLimit</B>(float <I
style="mso-bidi-font-style: normal">min_speed, </I>float<I
style="mso-bidi-font-style: normal"> max_speed = </I>P_MAXFLOAT)</P>
<P class=Description>Clamp each particle<6C>s speed to the given min and max.</P>
<P class=MsoNormal>Computes each particle<6C>s speed (the magnitude of its velocity
vector) and if it is less than <I
style="mso-bidi-font-style: normal">min_speed</I> or greater than <I
style="mso-bidi-font-style: normal">max_speed</I> it is clamped to those bounds,
while preserving the velocity vector<6F>s direction.<I
style="mso-bidi-font-style: normal"><o:p></o:p></I></P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>The vector [0,0,0] is an exception because it has no direction.
Such vectors are not modified by <B
style="mso-bidi-font-weight: normal">pSpeedLimit</B>.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pTargetColor</B>(float <I
style="mso-bidi-font-style: normal">color_x</I>, float <I
style="mso-bidi-font-style: normal">color_y</I>, float <I
style="mso-bidi-font-style: normal">color_z</I>, float <I
style="mso-bidi-font-style: normal">alpha</I>, float <I
style="mso-bidi-font-style: normal">scale</I>)</P>
<P class=Description>Change color of all particles toward the specified
color.</P>
<P class=MsoNormal>Modifies the color and alpha of each particle to be <I
style="mso-bidi-font-style: normal">scale</I> percent of the way closer to the
specified <I style="mso-bidi-font-style: normal">color</I> and <I
style="mso-bidi-font-style: normal">alpha</I>.<I
style="mso-bidi-font-style: normal"> scale</I> is multiplied by <I
style="mso-bidi-font-style: normal">dt</I> before scaling the sizes. Thus, using
smaller <I style="mso-bidi-font-style: normal">dt</I> causes a slightly faster
approach to the target color.<I
style="mso-bidi-font-style: normal"><o:p></o:p></I></P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>This action makes all colors tend toward the specified, uniform
color. Future versions will have more actions that modify color. Please send me
suggestions (perhaps with sample implementations).</P>
<P class=Note>The value of <I style="mso-bidi-font-style: normal">scale</I> will
usually be very small (less than 0.01) to yield a gradual transition.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pTargetSize</B>(float <I
style="mso-bidi-font-style: normal">size_x</I>, float <I
style="mso-bidi-font-style: normal">size_y</I>, float <I
style="mso-bidi-font-style: normal">size_z</I>, float <I
style="mso-bidi-font-style: normal">scale_x</I> = 0.0, float <I
style="mso-bidi-font-style: normal">scale_y</I> = 0.0, float <I
style="mso-bidi-font-style: normal">scale_z</I> = 0.0)</P>
<P class=Description>Change sizes of all particles toward the specified
size.</P>
<P class=MsoNormal>Modifies the size of each particle to be <I
style="mso-bidi-font-style: normal">scale</I> percent of the way closer to the
specified <I style="mso-bidi-font-style: normal">size</I> triple. This makes
sizes grow asymptotically closer to the given size. <I
style="mso-bidi-font-style: normal">scale</I> is multiplied by <I
style="mso-bidi-font-style: normal">dt</I> before scaling the sizes. Thus, using
smaller <I style="mso-bidi-font-style: normal">dt</I> causes a slightly faster
approach to the target size. The separate scales for each component allow only
selected components to be scaled.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>This action makes all sizes tend toward the specified, uniform
size. Future versions will have more actions that modify size. Please send me
suggestions (perhaps with sample implementations).</P>
<P class=Note>The value of <I style="mso-bidi-font-style: normal">scale</I> will
usually be very small (less than 0.01) to yield a gradual transition.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pTargetVelocity</B>(float <I
style="mso-bidi-font-style: normal">vel_x</I>, float <I
style="mso-bidi-font-style: normal">vel_y</I>, float <I
style="mso-bidi-font-style: normal">vel_z</I>, float <I
style="mso-bidi-font-style: normal">scale</I>)</P>
<P class=Description>Change velocity of all particles toward the specified
velocity.</P>
<P class=MsoNormal>Modifies the velocity of each particle to be <I
style="mso-bidi-font-style: normal">scale</I> percent of the way closer to the
specified <I style="mso-bidi-font-style: normal">velocity</I> triple. This makes
velocities grow asymptotically closer to the given velocity. <I
style="mso-bidi-font-style: normal">scale</I> is multiplied by <I
style="mso-bidi-font-style: normal">dt</I> before scaling the velocities. Thus,
using smaller <I style="mso-bidi-font-style: normal">dt</I> causes a slightly
faster approach to the target velocity.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>This action makes all velocities tend toward the specified,
uniform velocity.</P>
<P class=Note>The value of <I style="mso-bidi-font-style: normal">scale</I> will
usually be very small (less than 0.01) to yield a gradual transition.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pVertex</B>(float <I
style="mso-bidi-font-style: normal">x</I>, float <I
style="mso-bidi-font-style: normal">y</I>, float <I
style="mso-bidi-font-style: normal">z</I>)</P>
<P class=Description>Add a single particle at the specified location.</P>
<P class=MsoNormal>When called within a <B
style="mso-bidi-font-weight: normal">pNewActionList</B> / <B
style="mso-bidi-font-weight: normal">pEndActionList</B> block, this action is a
shorthand for:</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">pSource</B>(1, <B
style="mso-bidi-font-weight: normal">PDPoint</B>, <I
style="mso-bidi-font-style: normal">x</I>, <I
style="mso-bidi-font-style: normal">y</I>, <I
style="mso-bidi-font-style: normal">z</I>).</P>
<P class=MsoNormal>However, when called in immediate mode, this action uses a
slightly faster method to add a single particle to the current particle group.
Also, when in immediate mode, exactly one particle will be added per call,
instead of an average of 1 / <I style="mso-bidi-font-style: normal">dt</I>
particles being added. Particle attributes are chosen according to their current
domains, as with <B style="mso-bidi-font-weight: normal">pSource</B>.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>This call is patterned after the <B
style="mso-bidi-font-weight: normal">glVertex</B> calls. It is useful for
creating a particle group with exactly specified initial positions. For example,
you can specify a geometrical model using <B
style="mso-bidi-font-weight: normal">pVertex</B> calls, and then explode or
deform it.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pVortex</B>(float <I
style="mso-bidi-font-style: normal">center_x</I>, float <I
style="mso-bidi-font-style: normal">center_y</I>, float <I
style="mso-bidi-font-style: normal">center_z</I>, float <I
style="mso-bidi-font-style: normal">axis_x</I>, float <I
style="mso-bidi-font-style: normal">axis_y</I>, float <I
style="mso-bidi-font-style: normal">axis_z</I>, float <I
style="mso-bidi-font-style: normal">magnitude</I> = 1.0f, float <I
style="mso-bidi-font-style: normal">epsilion = </I>P_EPS, float <I
style="mso-bidi-font-style: normal">max_radius</I> = P_MAXFLOAT)</P>
<P class=Description>Swirl particles around a vortex.</P>
<P class=MsoNormal><I style="mso-bidi-font-style: normal">center</I> and <I
style="mso-bidi-font-style: normal">axis</I> define an infinite line, where <I
style="mso-bidi-font-style: normal">center</I> represents the tip of the vortex
and <I style="mso-bidi-font-style: normal">axis</I> is a vector along the line,
the length of which is irrelevant. As with most acceleration actions, the amount
of acceleration falls off inversely with <I
style="mso-bidi-font-style: normal">r</I><SUP>2</SUP> to the <I
style="mso-bidi-font-style: normal">center</I>. But when <I
style="mso-bidi-font-style: normal">r</I> is small, the acceleration would be
infinite, so <I style="mso-bidi-font-style: normal">epsilon</I> is always added
to <I style="mso-bidi-font-style: normal">r</I>. Using an epsilon similar in
magnitude to <I style="mso-bidi-font-style: normal">magnitude</I> can increase
the range of influence of the vortex. <I
style="mso-bidi-font-style: normal">max_radius</I> defines the sphere of
influence of this action. No particle further than <I
style="mso-bidi-font-style: normal">max_radius</I> from the vortex center is
affected.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note><SPAN style="mso-spacerun: yes">&nbsp;</SPAN><B
style="mso-bidi-font-weight: normal">pVortex</B> immediately displaces particle
positions, unlike most actions which affect particle velocities, so unsatisfying
results may occur when used with the <B
style="mso-bidi-font-weight: normal">pAvoid </B>or <B
style="mso-bidi-font-weight: normal">pBounce</B> actions. In particular,
particles may be displaced to the opposite side of the surface without bouncing
off it.</P>
<P class=Note><B style="mso-bidi-font-weight: normal">pVortex</B> currently does
not pull the particles up or down along the axis like a tornado. This will be
saved for a future release. If you can suggest an implementation, feel free to
send it to me.</P>
<P class=Note>Particles can be attracted toward the axis of the vortex using <B
style="mso-bidi-font-weight: normal">pOrbitLine</B>.</P>
<H1>Particle Group Calls</H1>
<P class=MsoNormal>A particle group is first created using <B
style="mso-bidi-font-weight: normal">pGenParticleGroups</B>, which will return
the identifying number of the generated particle group. Unless otherwise
specified, all other commands operate on the current particle group. You specify
which group is current using <B
style="mso-bidi-font-weight: normal">pCurrentGroup</B>. The maximum number of
particles in the group is specified using <B
style="mso-bidi-font-weight: normal">pSetMaxParticles</B>. The particle group is
then acted upon using the functions listed in the <B
style="mso-bidi-font-weight: normal">Actions</B>. Some actions will add
particles to the particle group, and others will modify the particles in other
ways. Typically, a series of actions will be applied to each particle group once
(or more) per rendered frame. The particles are then actually drawn. This is
similar to the process of rendering a display list in OpenGL, and should be done
at the same stage of the application's execution as drawing geometry. To draw a
particle group in OpenGL, the application calls one of the <B
style="mso-bidi-font-weight: normal">pDrawGroup</B> functions. Alternatively,
the application can get a copy of the particle data using <B
style="mso-bidi-font-weight: normal">pGetParticles</B> and use it for other
rendering or processing methods. When a particle group is no longer needed, it
is deleted using <B
style="mso-bidi-font-weight: normal">pDeleteParticleGroups</B>.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pCopyGroup</B>(int <I
style="mso-bidi-font-style: normal">p_group_num</I>, int <I
style="mso-bidi-font-style: normal">index</I> = 0, int <I
style="mso-bidi-font-style: normal">copy_count</I> = P_MAXINT)</P>
<P class=Description>Copy particles from the specified group into the current
group.</P>
<P class=MsoNormal>Copy particles from the specified particle group, <I
style="mso-bidi-font-style: normal">p_group_num</I>, to the current particle
group. Only <I style="mso-bidi-font-style: normal">copy_count</I> particles,
starting with number <I style="mso-bidi-font-style: normal">index</I> are
copied. Of course, the number of particles actually copied is bounded by the
available space in the current particle group, and the number of particles
actually in the source particle group. The particles are added in order to the
end of the current group. <I style="mso-bidi-font-style: normal">index</I> is
the index of the first particle in the source particle group to be copied.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pCurrentGroup</B>(int <I
style="mso-bidi-font-style: normal">p_group_num</I>)</P>
<P class=Description>Change which group is current.</P>
<P class=MsoNormal>Makes <I style="mso-bidi-font-style: normal">p_group_num</I>
be the current particle group to which all actions and commands apply.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pDeleteParticleGroups</B>(int <I
style="mso-bidi-font-style: normal">p_group_num</I>, int <I
style="mso-bidi-font-style: normal">p_group_count</I>)</P>
<P class=Description>Delete one or more consecutive particle groups.</P>
<P class=MsoNormal>Deletes <I
style="mso-bidi-font-style: normal">p_group_count</I> particle groups, with <I
style="mso-bidi-font-style: normal">p_group_num</I> being the particle group
number of the first one. The groups must be numbered sequentially, and must all
exist. This removes the specified particle groups from existence. It does not
merely change the number of existing particles or the maximum size of the
group.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pDrawGroupl</B>(int <I
style="mso-bidi-font-style: normal">dlist</I>, bool <I
style="mso-bidi-font-style: normal">const_size</I> = false, bool <I
style="mso-bidi-font-style: normal">const_color</I> = false, bool <I
style="mso-bidi-font-style: normal">const_rotation</I> = false)</P>
<P class=Description>Draw each particle as a model using OpenGL display
lists.</P>
<P class=MsoNormal>Calls the given OpenGL display list, <I
style="mso-bidi-font-style: normal">dlist</I>, once for each particle in the
particle group. The display list typically contains only geometry (<B
style="mso-bidi-font-weight: normal">glBegin</B> / <B
style="mso-bidi-font-weight: normal">glEnd</B> blocks). Before the display list
is drawn for each particle, the OpenGL state is changed. First, the display list
is translated to the particle's position. Next, if <I
style="mso-bidi-font-style: normal">const_size</I> is false, the matrix stack is
modified to scale the display list by the particle's size. Then, if <I
style="mso-bidi-font-style: normal">const_rotation</I> is false, the matrix is
rotated so that the display list's positive X axis points in the direction of
the particle's velocity vector. Finally, if <I
style="mso-bidi-font-style: normal">const_color</I> is false, the OpenGL current
color is set to the particle's color. If <I
style="mso-bidi-font-style: normal">const_color</I> is true, then the OpenGL
current color is set only once before drawing any particles. If <I
style="mso-bidi-font-style: normal">const_size</I> is true, then no scaling is
ever done. If <I style="mso-bidi-font-style: normal">const_rotation</I> is true
then no rotation is ever done. This is useful for symmetrical models such as
spheres.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>The OpenGL current color is left in an undefined state following a
call to <B style="mso-bidi-font-weight: normal">pDrawGroupl</B>.</P>
<P class=Note>This command operates on the OpenGL matrix stack, but does not
change the matrix mode. It is the application's responsibility to ensure that
the matrix mode is correct, usually by calling <B
style="mso-bidi-font-weight: normal">glMatrixMode</B>(GL_MODELVIEW) first.</P>
<P class=Note>Models containing multiple colors can be drawn by constructing a
display list that first draws the geometry that will be in the particle color,
then changes the color (by calling <B
style="mso-bidi-font-weight: normal">glColor</B>), then draws geometry in the
new color. For example, this could be used to draw balloons of many different
colors that each have a white string.</P>
<P class=Note>Another way to draw particles that allows greater flexibility than
<B style="mso-bidi-font-weight: normal">pDrawGroupl</B> is for the application
to get the particle data using <B
style="mso-bidi-font-weight: normal">pGetParticles</B>, and then draw it using
any desired method.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pDrawGroupp</B>(int <I
style="mso-bidi-font-style: normal">primitive</I>, bool <I
style="mso-bidi-font-style: normal">const_size</I> = false, bool <I
style="mso-bidi-font-style: normal">const_color</I> = false)</P>
<P class=Description>Draw a particle group using OpenGL primitives.</P>
<P class=MsoNormal>This is the fastest OpenGL-based method of drawing particles.
The exact results depend on the OpenGL <I
style="mso-bidi-font-style: normal">primitive</I> type specified. When <I
style="mso-bidi-font-style: normal">primitive</I> equals GL_POINTS or any value
other than GL_LINES, each particle becomes a single vertex in an OpenGL <B
style="mso-bidi-font-weight: normal">glBegin</B> / <B
style="mso-bidi-font-weight: normal">glEnd</B> block. For GL_LINES, each
particle becomes a line specified by two vertices - the particle's position and
the particle's position minus velocity, yielding a line in the direction that
the particle is travelling.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>The OpenGL current color is left in an undefined state following a
call to <B style="mso-bidi-font-weight: normal">pDrawGroupp</B>.</P>
<P class=Note>At present, GL_LINES is the only primitive handled as a special
case. If you have suggestions for sensible, general ways to handle other OpenGL
primitives, please tell me.</P>
<P class=Note>See also <B
style="mso-bidi-font-weight: normal">pDrawGroupl</B>.</P>
<P class=FuncProto>int <B
style="mso-bidi-font-weight: normal">pGenParticleGroups</B>(int <I
style="mso-bidi-font-style: normal">p_group_count</I> = 1, int <I
style="mso-bidi-font-style: normal">max_particles</I> = 0)</P>
<P class=Description>Create particle groups, each with max_particles
allocated.</P>
<P class=MsoNormal>Generates <I
style="mso-bidi-font-style: normal">p_group_count</I> new particle groups and
returns the particle group number of the first one. The groups are numbered
sequentially, beginning with the number returned. Each particle group is set to
have at most <I style="mso-bidi-font-style: normal">max_particles</I> particles.
Call <B style="mso-bidi-font-weight: normal">pSetMaxParticles</B> to change
this.</P>
<P class=MsoNormal>Particle group numbers of groups that have been deleted
(using <B style="mso-bidi-font-weight: normal">pDeleteParticleGroups</B>) may be
reused by <B style="mso-bidi-font-weight: normal">pGenParticleGroups</B>.</P>
<P class=FuncProto>int <B
style="mso-bidi-font-weight: normal">pGetGroupCount</B>()</P>
<P class=Description>Returns the number of particles existing in the current
group.</P>
<P class=MsoNormal>What the summary says.</P>
<P class=FuncProto>int <B
style="mso-bidi-font-weight: normal">pGetParticles</B>(int <I
style="mso-bidi-font-style: normal">index</I>, int <I
style="mso-bidi-font-style: normal">count</I>, float *<I
style="mso-bidi-font-style: normal">position</I> = NULL, float *<I
style="mso-bidi-font-style: normal">color</I> = NULL, float *<I
style="mso-bidi-font-style: normal">vel</I> = NULL, float *<I
style="mso-bidi-font-style: normal">size</I> = NULL, float *<I
style="mso-bidi-font-style: normal">age</I> = NULL)</P>
<P class=Description>Copy particles from the current group to application
memory.</P>
<P class=MsoNormal>Copies at most <I
style="mso-bidi-font-style: normal">count</I> particles beginning with the <I
style="mso-bidi-font-style: normal">index</I>-th particle in the current
particle group into memory already allocated by the application. Three floats
are returned for the position of each particle, representing its x,y,z location.
Four floats are returned for the color of each particle, representing its
R,G,B,A color. Three floats are returned for the velocity of each particle,
representing its dx,dy,dz direction vector. Three floats are returned for the
size of each particle, representing whatever the application wants them to. One
float is returned for the age of each particle.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">pGetParticles</B>
returns the number of particles copied to application memory. Of course, the
number of particles actually returned is bounded by <I
style="mso-bidi-font-style: normal">count</I> and by the number of particles
actually in the particle group minus <I
style="mso-bidi-font-style: normal">index</I>. </P>
<P class=MsoNormal>If <I style="mso-bidi-font-style: normal">verts, color</I>,
<I style="mso-bidi-font-style: normal">vel</I>, <I
style="mso-bidi-font-style: normal">size</I> or <I
style="mso-bidi-font-style: normal">age</I> is NULL then no position, color,
velocity, size or age data, respectively, will be returned. <I
style="mso-bidi-font-style: normal">index</I> and <I
style="mso-bidi-font-style: normal">count</I> must be at least 0 and less than
the number of particles. <I style="mso-bidi-font-style: normal">index</I> + <I
style="mso-bidi-font-style: normal">count</I> must be less than the number of
particles.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>The following code gets the position of all particles:</P>
<P class=Note style="TEXT-INDENT: 0.25in">float *ppos = new
float[pGetGroupCount() * 3];</P>
<P class=Note style="TEXT-INDENT: 0.25in">int num_ret = pGetParticles(0, MAXINT,
ppos);</P>
<P class=Note>As with all arrays in C, the index of the first particle is
zero.</P>
<P class=FuncProto>int <B
style="mso-bidi-font-weight: normal">pSetMaxParticles</B>(int <I
style="mso-bidi-font-style: normal">max_count</I>)</P>
<P class=Description>Change the maximum number of particles in the current
group.</P>
<P class=MsoNormal>If necessary, this will delete particles from the end of the
particle group, but no other particles will be deleted.</P>
<H1>Action List Calls</H1>
<P class=MsoNormal>These calls create and operate on action lists, which are
scripts of many actions to be applied together as a block to the current
particle group. An action list is first created using <B
style="mso-bidi-font-weight: normal">pGenActionLists</B>, and is then defined by
calling particle action functions between a call to <B
style="mso-bidi-font-weight: normal">pNewActionList</B> and a call to <B
style="mso-bidi-font-weight: normal">pEndActionList</B>. Once the action list is
created, it is run via <B
style="mso-bidi-font-weight: normal">pCallActionList</B>. Thus, an action list
is sort of a higher-level action. Complex behaviors can be stored in an action
list and then 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 <B style="mso-bidi-font-weight: normal">pDeleteActionLists</B>.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>When particles are created within a <B
style="mso-bidi-font-weight: normal">pNewActionList</B> / <B
style="mso-bidi-font-weight: normal">pEndActionList</B> block, they 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), particles are
created with attributes from the current state.</P>
<P class=Note>The time step length, <I
style="mso-bidi-font-style: normal">dt</I>, uses the value that is current when
<B style="mso-bidi-font-weight: normal">pCallActionList</B> is executed, not the
value of <I style="mso-bidi-font-style: normal">dt</I> when the action list was
created. This allows <I style="mso-bidi-font-style: normal">dt</I> to be
modified without recompiling action lists. Maybe this isn't a good idea. If it
should be the other way in the future, let me know.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pCallActionList</B>(int <I
style="mso-bidi-font-style: normal">action_list_num</I>)</P>
<P class=Description>Apply the specified action list to the current particle
group.</P>
<P class=MsoNormal>Call the action functions as specified when this action list
was created with <B style="mso-bidi-font-weight: normal">pNewActionList</B>. The
actions are executed with the state elements values in effect when the action
list was created, except the current global value of <I
style="mso-bidi-font-style: normal">dt</I> is used, not the value of <I
style="mso-bidi-font-style: normal">dt</I> when the list was created.</P>
<P class=Description>pCallActionList <SPAN style="FONT-WEIGHT: normal">is the
only function other than actions that can be stored in an action list. This
allows action lists to become atomic operations in more complex action lists.
When calling </SPAN>pCallActionList<SPAN style="FONT-WEIGHT: normal"> during the
creation of a new action list, <I
style="mso-bidi-font-style: normal">action_list_num</I> does not need to
indicate an existing action list.<o:p></o:p></SPAN></P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>It is an error for <I
style="mso-bidi-font-style: normal">action_list_num</I> to not indicate an
existing (generated) action list.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pDeleteActionLists</B>(int <I
style="mso-bidi-font-style: normal">action_list_num</I>, int <I
style="mso-bidi-font-style: normal">action_list_count</I> = 1)</P>
<P class=Description>Delete one or more consecutive action lists.</P>
<P class=MsoNormal>Deletes <I
style="mso-bidi-font-style: normal">action_list_count</I> action lists, with <I
style="mso-bidi-font-style: normal">action_list_num</I> being the list number of
the first one. The lists must be numbered sequentially, and must all exist. This
removes the specified action lists from existence.</P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pEndActionList</B>()</P>
<P class=Description>End the creation of a new action list.</P>
<P class=FuncProto>int <B
style="mso-bidi-font-weight: normal">pGenActionLists</B>(int <I
style="mso-bidi-font-style: normal">action_list_count</I> = 1)</P>
<P class=Description>Generate a block of empty action lists.</P>
<P class=MsoNormal>All list numbers are in sequential order starting with the
first list. Returns the action list number of the first allocated list. Valid
action list numbers are non-negative.</P>
<P class=MsoNormal><![if !supportEmptyParas]><![endif]>&nbsp;<o:p></o:p></P>
<P class=FuncProto>void <B
style="mso-bidi-font-weight: normal">pNewActionList</B>(int <I
style="mso-bidi-font-style: normal">action_list_num</I>)</P>
<P class=Description>Begin the creation of the specified action list.</P>
<P class=MsoNormal>The <I
style="mso-bidi-font-style: normal">action_list_num</I> must have already been
generated using <B style="mso-bidi-font-weight: normal">pGenActionLists</B>.
Most calls other than actions cannot be made between a call to <B
style="mso-bidi-font-weight: normal">pNewActionList</B> and the corresponding
call to <B style="mso-bidi-font-weight: normal">pEndActionList</B>.</P>
<P class=MsoNoteHeading>NOTES</P>
<P class=Note>If called on an action list that has previously been defined, the
previous contents of the action list are destroyed and the action list will be
created anew. This is as with <B
style="mso-bidi-font-weight: normal">glNewList</B> in OpenGL.</P>
<H1>Domains</H1>
<P class=MsoNormal>A Domain is a representation of a region of space. For
example, the <B style="mso-bidi-font-weight: normal">pSource</B> action uses a
domain to describe the volume in which a particle will be created. A random
point within the domain is chosen as the initial position of the particle. The
<B style="mso-bidi-font-weight: normal">pAvoid</B>,<B
style="mso-bidi-font-weight: normal"> pSink</B> and <B
style="mso-bidi-font-weight: normal">pBounce</B> actions use domains to describe
a volume in space for particles to steer around, die when they enter, or bounce
off, respectively.</P>
<P class=MsoNormal>Domains are also used to describe velocities. Picture the
velocity vector as having its tail at the origin and its tip being in the
domain.</P>
<P class=MsoNormal>Finally, domains can be used to describe colors. For drawing
with OpenGL, the full color space is 0.0 -&gt; 1.0 in the red, green, and blue
axes. For example, the domain <B
style="mso-bidi-font-weight: normal">PDLine</B>, 1, 0, 0, 1, 1, 0 will choose
points on a line between red and yellow. Points outside the 0.0 -&gt; 1.0 range
will not be clamped, but eventually will be clamped deep within the OpenGL
pipeline.</P>
<P class=MsoNormal>Since data from particle systems can be used by more than
just the OpenGL renderer, the floating point triple used for color can mean
different things to different consumers of the data. For example, if a software
renderer used colors on the range 0 -&gt; 255, the domain used to choose the
colors can be on that range. The color space does not even need to be thought of
as RGB, but will be for use in OpenGL.</P>
<P class=MsoNormal>Several types of domains can be specified. The two basic
abstract operations on a domain are <B
style="mso-bidi-font-weight: normal">Generate</B>, which returns a random point
in the domain, and <B style="mso-bidi-font-weight: normal">Within</B>, which
tells whether a given point is within the domain. Functions such as <B
style="mso-bidi-font-weight: normal">pSource</B> that take a domain as an
argument take it in the form of a <B
style="mso-bidi-font-weight: normal">PDomainEnum</B>, followed by nine floats.
The <B style="mso-bidi-font-weight: normal">PDomainEnum</B> is one of the
symbolic constants listed below, such as <B
style="mso-bidi-font-weight: normal">PDPoint</B>. The nine floats mean different
things for each type of domain, as described below. Not all domains require all
nine floats. You only need to specify the first few values that are relevant to
that domain type. The rest default to 0.0 and will be ignored.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDPoint<SPAN
style="mso-tab-count: 1"> </SPAN></B><I style="mso-bidi-font-style: normal">x,
y, z<o:p></o:p></I></P>
<P class=MsoNormal>This domain is a single point.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> always
returns this point. <B style="mso-bidi-font-weight: normal">Within</B> always
returns false.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDLine<SPAN
style="mso-tab-count: 1">&nbsp; </SPAN></B><I
style="mso-bidi-font-style: normal">x1, y1, z1, x2, y2, z2<o:p></o:p></I></P>
<P class=MsoNormal>These are the endpoints of a line segment.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a random point on this segment. <B
style="mso-bidi-font-weight: normal">Within</B> always returns false.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDTriangle<SPAN
style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></B><I style="mso-bidi-font-style: normal">x0, y0, z0, x1, y1, z1, x2,
y2, z2<o:p></o:p></I></P>
<P class=MsoNormal>These are the vertices of a triangle. The triangle can be
used to define an arbitrary geometrical model for particles to bounce off, or
generate particles on its surface (and explode them), etc.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a random point in the triangle. <B style="mso-bidi-font-weight: normal">Within
</B>always returns false. [This must eventually change so we can sink particles
that enter/exit a model. Suggestions?]</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDPlane<SPAN
style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></B><I style="mso-bidi-font-style: normal">ox, oy, oz, nx, ny,
nz<o:p></o:p></I></P>
<P class=MsoNormal>The point <I style="mso-bidi-font-style: normal">o</I> is a
point on the plane. <I style="mso-bidi-font-style: normal">n</I> is the normal
vector of the plane. It need not be unit length. If you have a plane in <I
style="mso-bidi-font-style: normal">a,b,c,d</I> form remember that <I
style="mso-bidi-font-style: normal">n = [a,b,c] </I>and you can compute a
suitable point <I style="mso-bidi-font-style: normal">o</I> as <I
style="mso-bidi-font-style: normal">o = -n*d.</I> The normal will get
normalized, so it need not already be normalized.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
the point <I style="mso-bidi-font-style: normal">o.<o:p></o:p></I></P>
<P class=MsoNormal><SPAN style="mso-spacerun: yes">&nbsp;</SPAN><B
style="mso-bidi-font-weight: normal">Within</B> returns true if the point is in
the positive half-space of the plane (in the plane or on the side that <I
style="mso-bidi-font-style: normal">n</I> points to).</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDRectangle<SPAN
style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></B><I style="mso-bidi-font-style: normal">ox, oy, oz, ux, uy, uz, vx,
vy, vz<o:p></o:p></I></P>
<P class=MsoNormal>The point <I style="mso-bidi-font-style: normal">o</I> is a
point on the plane. <I style="mso-bidi-font-style: normal">u</I> and <I
style="mso-bidi-font-style: normal">v</I> are (non-parallel) basis vectors in
the plane. They don't need to be normal or orthogonal.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a random point in the diamond-shaped patch whose corners are <I
style="mso-bidi-font-style: normal">o</I>, <I
style="mso-bidi-font-style: normal">o</I>+<I
style="mso-bidi-font-style: normal">u</I>, <I
style="mso-bidi-font-style: normal">o</I>+<I
style="mso-bidi-font-style: normal">u</I>+<I
style="mso-bidi-font-style: normal">v</I>, and <I
style="mso-bidi-font-style: normal">o</I>+<I
style="mso-bidi-font-style: normal">v.</I> <B
style="mso-bidi-font-weight: normal">Within</B> returns true if the point is in
the positive half-space of the plane (in the plane or on the side that the
normal (<I style="mso-bidi-font-style: normal">u</I> cross <I
style="mso-bidi-font-style: normal">v</I>) points to).</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDBox<SPAN
style="mso-tab-count: 1">&nbsp;&nbsp; </SPAN></B><I
style="mso-bidi-font-style: normal">x1, y1, z1, x2, y2, z2<o:p></o:p></I></P>
<P class=MsoNormal>These are the minima and maxima of an axis-aligned box. It
doesn't matter which of each coordinate is min and which is max.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a random point in this box. <B style="mso-bidi-font-weight: normal">Within</B>
returns true if the point is in the box.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDSphere<SPAN
style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></B><I style="mso-bidi-font-style: normal">ox, oy, oz, radius1,
radius2</I> = 0.0</P>
<P class=MsoNormal>The point <I style="mso-bidi-font-style: normal">o</I> is the
center of the sphere. <I style="mso-bidi-font-style: normal">radius1</I> is the
outer radius of the shell and <I style="mso-bidi-font-style: normal">radius2</I>
is the inner radius.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a random point in the thick shell at a distance between <I
style="mso-bidi-font-style: normal">radius1</I> to <I
style="mso-bidi-font-style: normal">radius2</I> from point <I
style="mso-bidi-font-style: normal">o</I>. If <I
style="mso-bidi-font-style: normal">radius2</I> is 0, then it is the whole
sphere. <B style="mso-bidi-font-weight: normal">Within</B> returns true if the
point lies within the thick shell at a distance between <I
style="mso-bidi-font-style: normal">radius1</I> to <I
style="mso-bidi-font-style: normal">radius2</I> from point <I
style="mso-bidi-font-style: normal">o</I>.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDCylinder<SPAN
style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></B><I style="mso-bidi-font-style: normal">x1, y1, z1, x2, y2, z2,
radius1, radius2</I> = 0.0</P>
<P class=MsoNormal>The two points are the endpoints of the axis of the cylinder.
<I style="mso-bidi-font-style: normal">radius1</I> is the outer radius, and <I
style="mso-bidi-font-style: normal">radius2</I> is the inner radius for a
cylindrical shell. <I style="mso-bidi-font-style: normal">radius2</I> = 0 for a
solid cylinder with no empty space in the middle.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a random point in the cylindrical shell. <B
style="mso-bidi-font-weight: normal">Within</B> returns true if the point is
within the cylindrical shell.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDCone<SPAN
style="mso-tab-count: 1"> </SPAN><SPAN
style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></B><I style="mso-bidi-font-style: normal">x1, y1, z1, x2, y2, z2,
radius1, radius2</I> = 0.0</P>
<P class=MsoNormal>The first point is the apex of the cone and the second is the
other endpoint of the axis of the cone. <I
style="mso-bidi-font-style: normal">radius1</I> is the radius of the base of the
cone. <I style="mso-bidi-font-style: normal">radius2</I> is the radius of the
base of a cone to subtract from the first cone to create a conical shell. This
is similar to the cylindrical shell, which can be thought of as a large cylinder
with a smaller cylinder subtracted from the middle. Both cones share the same
apex and axis, which implies that the thickness of the conical shell tapers to 0
at the apex.<I style="mso-bidi-font-style: normal"> radius2</I> = 0 for a solid
cone with no empty space in the middle.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a random point in the conical shell. <B
style="mso-bidi-font-weight: normal">Within</B> returns true if the point is
within the conical shell.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDBlob<SPAN
style="mso-tab-count: 1">&nbsp; </SPAN><SPAN
style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></B><I style="mso-bidi-font-style: normal">x, y, z,
stdev<o:p></o:p></I></P>
<P class=MsoNormal>The point<I style="mso-bidi-font-style: normal"> x, y, z</I>
is the center of a normal probability density of standard deviation <I
style="mso-bidi-font-style: normal">stdev</I>. The density is radially
symmetrical. The blob domain allows for some very natural-looking effects
because there is no sharp, artificial-looking boundary at the edge of the
domain.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a point with normal probability density. <B
style="mso-bidi-font-weight: normal">Within</B> has a probability of returning
true equal to the probability density at the specified point.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">PDDisc<SPAN
style="mso-tab-count: 1">&nbsp; </SPAN><SPAN
style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></B><I style="mso-bidi-font-style: normal">x, y, z, nx, ny, nz, radius1,
radius2</I> = 0.0<I style="mso-bidi-font-style: normal"><o:p></o:p></I></P>
<P class=MsoNormal>The point<I style="mso-bidi-font-style: normal"> x, y, z</I>
is the center of a disc in the plane with normal <I
style="mso-bidi-font-style: normal">nx, ny, nz</I>. The disc has outer radius <I
style="mso-bidi-font-style: normal">radius1</I> and inner radius <I
style="mso-bidi-font-style: normal">radius2</I>. The normal will get normalized,
so it need not already be normalized.</P>
<P class=MsoNormal><B style="mso-bidi-font-weight: normal">Generate</B> returns
a point inside the disc. <B style="mso-bidi-font-weight: normal">Within</B>
returns false.</P>
<H1>Appendix</H1>
<H2>Acknowledgements</H2>
<P class=MsoNormal>Code for some of the particle actions and several concepts
regarding the structure of the API are thanks to Jonathan P. Leech, <A
href="mailto:ljp@sgi.com">ljp@sgi.com</A>. See also:</P>
<P class=MsoNormal>Jonathan Leech and Russell M. Taylor II, "Interactive
Modeling Using Particle Systems", Proceedings of the 2nd Conference on Discrete
Element Methods, MIT, spring 1993, pp. 105-116.</P>
<P class=MsoNormal>Thanks to Mark B. Allen of NASA Ames Research Center for
finding bugs, making suggestions and implementing the particle length
attribute.</P>
<P class=MsoNormal>Thanks to Jason Pratt of CMU Stage 3 research group (makers
of ALICE) for adding the PDTriangle domain. This is a powerful feature that
should have been there the whole time.</P>
<H2>Recent Changes</H2>
<H3>New in version 1.20.</H3>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Added a gaussian splat drawing mode to pspray. You can
draw either as a triangle or a quad with a gaussian alpha texture.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Added a <B
style="mso-bidi-font-weight: normal">PDDisc</B> domain for generating and
bouncing.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Split the <B
style="mso-bidi-font-weight: normal">PDPlane</B> domain into <B
style="mso-bidi-font-weight: normal">PDPlane</B>, for infinite planes and
half-spaces; and <B style="mso-bidi-font-weight: normal">PDRectangle</B>, for
rhombus-shaped planar patches.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Added <B
style="mso-bidi-font-weight: normal">pTargetVelocity</B> to make all particles
tend toward a given velocity. This is a component of Boids.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Added <B
style="mso-bidi-font-weight: normal">pMatchVelocity</B> to match velocity to
near neighbors.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Added <B style="mso-bidi-font-weight: normal">pAvoid</B>
to steer to avoid the given domain.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Added <B
style="mso-bidi-font-weight: normal">pSpeedLimit</B>.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Removed <B
style="mso-bidi-font-weight: normal">pKillSlow</B>. Instead use <B
style="mso-bidi-font-weight: normal">pSinkVelocity</B>.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Fixed a bug in the Within logic for <B
style="mso-bidi-font-weight: normal">PDBlob</B> so now it<69>s right.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Demonstrated flocking behavior using a Boids demo.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Changed <B
style="mso-bidi-font-weight: normal">pGetParticles</B> so that <I
style="mso-bidi-font-style: normal">verts</I> can be NULL. It now returns the
number of particles it<69>s copying. This way you can just tell it the size of your
array instead of having to call <B
style="mso-bidi-font-weight: normal">pGetGroupCount</B>.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Changed the particle size scalar to be a domain. This
will allow greater expression of particle shape. Orientation becomes more
important. Added <B style="mso-bidi-font-weight: normal">pSizeD</B> to specify
it. Changed <B style="mso-bidi-font-weight: normal">pGetParticles</B> so that it
returns three floats per particle for size.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>For Windows, made it a DLL instead of a static
library.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>For Windows, ships with a DLL compiled with the Intel
Vtune compiler (a bit faster).</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Made pspray choose a demo randomly on startup.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Made <B
style="mso-bidi-font-weight: normal">pStartingAge</B> take an optional parameter
for the standard deviation of random starting ages, centered at <I
style="mso-bidi-font-style: normal">age</I>.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Replaced the <I
style="mso-bidi-font-style: normal">lifetime</I> parameter of explosions with <I
style="mso-bidi-font-style: normal">stdev</I> and made the shock wave be
gaussian instead of square. This will fix the ugly stratification effects in
explosions of very dense particle clouds.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Updated the documentation.</P>
<P class=MsoList style="mso-list: l3 level1 lfo3; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Changed <B
style="mso-bidi-font-weight: normal">pCallActionList</B> to be storable in
action lists, as the docs said.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Added a trivial app. for learning the API.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Made a rocket demo. It has the rockets in one particle
group and their sparks in another, generated at the rocket positions.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>When re-using an action list that was already generated,
it now properly deletes the previous actions.</P>
<H2>To Do</H2>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Add a TOC listing all functions.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Change <B
style="mso-bidi-font-weight: normal">pDraw*</B> const_ to apply_, reverse the
sense of it, and make it so if false, color isn<73>t touched.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Compound domains (so you can define a whole model as a
single domain instead of a zillion triangle domains). This may be the answer for
obstacle avoidance.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Const_size isn<73>t used in pDrawGroupp.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>For the pspray demo, have it randomly change modes
occasionally.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Have a secondary color for each particle.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>How can you add user-defined particle attributes? For
now, <B style="mso-bidi-font-weight: normal">pSize</B> is the best we can
do.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Make a screensaver.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Make color and size be generic attributes with generic
attribute operators.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]><B
style="mso-bidi-font-weight: normal">pDensityColor</B> - color is f
(density)</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]><B
style="mso-bidi-font-weight: normal">pPositionColor</B> - color is f
(position)</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]><B style="mso-bidi-font-weight: normal">pRandomColor</B>
- random domain is added to color</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]><B
style="mso-bidi-font-weight: normal">pVelocityColor</B> - color is f(
velocity)</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]><B
style="mso-bidi-font-weight: normal">pVelocitySize</B> - size is f(velocity)</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Test multiple particle groups better.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Think about changing <I
style="mso-bidi-font-style: normal">dt</I> to not be a global value. I don<6F>t
think I<>ll do it.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Think about removing <B
style="mso-bidi-font-weight: normal">pDraw*</B> from the API since they are
OpenGL dependent.</P>
<P class=MsoList style="mso-list: l0 level1 lfo4; tab-stops: list .25in"><![if !supportLists]><SPAN
style="FONT-FAMILY: Symbol"><3E><SPAN
style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</SPAN></SPAN><![endif]>Change <B
style="mso-bidi-font-weight: normal">pVortex</B> to accelerate the particles
instead of displacing them. Tried it. Hard.</P></DIV></BODY></HTML>