File list   File Members  

papi.h File Reference

Include this file in all applications that use the Particle System API. More...

Enumerations

Functions


Detailed Description

Include this file in all applications that use the Particle System API.

Copyright 1997-1998 by David K. McAllister.
http://www.cs.unc.edu/~davemc/Particle

For more information on concepts of the Particle Systems API, please read this.


Enumeration Type Documentation

enum PDomainEnum

Type codes for domains.

Enumeration values:


Function Documentation

void pColor(float red, float green, float blue, float alpha = 1.0f)

STATE: Specify the color of new particles.

NOTES:

    See the documentation of Domains for a discussion of color spaces in the Particle System API.

    If rendering is to be done by a method other than the pDrawGroup calls, the particle color does not necessarily need to be used to represent color. It can be interpreted as an arbitrary 3 vector.

void pColorD(float alpha, PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

STATE: Specify the color domain of new particles.

NOTES:

    See the documentation of Domains for an explanation of the other arguments.

void pLength(float l1, float l2 = -1.0)

STATE: Set length of particle, if drawn as line/cylinder.

THIS IS NOT CURRENTLY PART OF THE PARTICLE SYSTEMS API.

void pSize(float s1, float s2 = -1.0)

STATE: Specify the size range of new particles.

The special value of s2, -1.0, means to set s2 equal to s1. Since the default value of s2 is -1.0, this makes it possible to set the size of particles to an exact value instead of a range by specifying only a single parameter.

void pStartingAge(float age)

STATE: Specify the initial age of new particles.

This value can be positive, zero, or negative.

void pTimeStep(float newDT)

STATE: Specify the time step length.

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, dt, 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.

How does the time step, dt, 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, dt 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, dt should be 1.0, which is the default.

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 dt to 1/3 its previous value using pTimeStep, then loop three times over all the action code that gets executed per frame, including the calls to pMove. If using action lists, this can be simply a loop over the pCallActionList 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.

In terms of numerical integration, particle actions can be thought of as the first derivative of unknown functions dictating the particle attributes 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 - the evaluation of the derivative functions at a particular time and then incrementing the current particle values by these derivative results times dt. In Euler's method, the smaller the dt, the more accurate the results.

NOTES:

    Unlike with other state setting calls, action lists execute using the current dt value set by pTimeStep, 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.

void pVelocity(float x, float y, float z)

STATE: Specify the initial velocity of new particles.

This is shorthand for pVelocityD(PDPoint, x, y, z).

void pVelocityD(PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

STATE: Specify the initial velocity domain of new particles.

NOTES:

    See the documentation of Domains for an explanation of the other arguments.

void pVertexB(float x, float y, float z)

STATE: Specify the secondary position of new particles.

This is shorthand for pVertexBD(PDPoint, x, y, z).

void pVertexBD(PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

STATE: Specify the secondary position domain of new particles.

Set the domain from which the positionB of each particle will be randomly chosen when it is created. But if pVertexBTracks is set to true (the default), then the positionB will instead be the same as the initial particle position.

NOTES:

    See the documentation of Domains for an explanation of the other arguments.

void pVertexBTracks(bool trackVertex = true)

STATE: Specify how the secondary position of each new particle is chosen.

Specify how the positionB of each new particle emitted will be chosen. The positionB is the destination position or initial position of particles. See pRestore for a use of positionB.

If doCopy is true then when a particle is created its positionB will be the same as its initial particle position (the default).

If doCopy is false then when a particle is created its positionB will be chosen from the VertexB domain.

void pCallActionList(int action_list_num)

ACTION LIST: Apply the specified action list to the current particle group.

void pDeleteActionLists(int action_list_num, int action_list_count = 1)

ACTION LIST: Delete one or more consecutive action lists.

Deletes action_list_count action lists, with action_list_num 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.

void pEndActionList()

ACTION LIST: End the creation of a new action list.

int pGenActionLists(int action_list_count = 1)

ACTION LIST: Generate empty action lists.

void pNewActionList(int action_list_num)

ACTION LIST: Begin the creation of the specified action list.

NOTES:

    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 glNewList in OpenGL.

void pCopyGroup(int p_group_num, int index = 0, int copy_count = P_MAXINT)

PARTICLE GROUP: Copy particles from the specified group into the current group.

Copy particles from the specified particle group, p_group_num, to the current particle group. Only copy_count particles, starting with number index 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. index is the index of the first particle in the source particle group to be copied.

void pCurrentGroup(int p_group_num)

PARTICLE GROUP: Change which group is current.

Makes p_group_num be the current particle group to which all actions and commands apply.

void pDeleteParticleGroups(int p_group_num, int p_group_count = 1)

PARTICLE GROUP: Delete one or more consecutive particle groups.

Deletes p_group_count particle groups, with p_group_num 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.

void pDrawGroupl(int dlist, bool const_size = false, bool const_color = false, bool const_rotation = false)

PARTICLE GROUP: Draw each particle as a model using OpenGL display lists.

Calls the given OpenGL display list, dlist, once for each particle in the particle group. The display list typically contains only geometry (glBegin / glEnd 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 const_size is false, the matrix stack is modified to scale the display list by the particle's size. Then, if const_rotation 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 const_color is false, the OpenGL current color is set to the particle's color. If const_color is true, then the OpenGL current color is set only once before drawing any particles. If const_size is true, then no scaling is ever done. If const_rotation is true then no rotation is ever done. This is useful for symmetrical models such as spheres.

NOTES:

    The OpenGL current color is left in an undefined state following a call to pDrawGroupl.

    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 glMatrixMode(GL_MODELVIEW) first.

    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 glColor), 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.

    Another way to draw particles that allows greater flexibility than pDrawGroupl is for the application to get the particle data using pGetParticles, and then draw it using any desired method.

void pDrawGroupp(int primitive, bool const_size = false, bool const_color = false)

PARTICLE GROUP: Draw a particle group using OpenGL primitives.

This is the fastest OpenGL-based method of drawing particles. The exact results depend on the OpenGL primitive type specified. When primitive equals GL_POINTS or any value other than GL_LINES, each particle becomes a single vertex in an OpenGL glBegin / glEnd 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.

NOTES:

    The OpenGL current color is left in an undefined state following a call to pDrawGroupp.

    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.

    See also pDrawGroupl.

int pGenParticleGroups(int p_group_count = 1, int max_particles = 0)

PARTICLE GROUP: Create particle groups, each with max_particles allocated.

Generates p_group_count 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 max_particles particles. Call pSetMaxParticles to change this.

Particle group numbers of groups that have been deleted (using pDeleteParticleGroups) may be reused by pGenParticleGroups.

int pGetGroupCount()

PARTICLE GROUP: Returns the number of particles existing in the current group.

What the summary says.

void pGetParticles(int index, int count, float *verts, float *color = NULL, float *vel = NULL, float *size = NULL, float *length = NULL)

PARTICLE GROUP: Copy particles from the current group to application memory.

Copies count particles beginning with the index-th particle in the current particle group into application memory.

int pSetMaxParticles(int max_count)

PARTICLE GROUP: Change the maximum number of particles in the current group.

If necessary, this will delete particles from the end of the particle group, but no other particles will be deleted.

void pBounce(float friction, float resilience, float cutoff, PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

ACTION: Bounce particles off a domain of space.

Particles are tested to see whether they will pass from being outside the specified domain to being inside it if the next pMove 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.

The normal component is multiplied by the resilience parameter and the tangential component, if its magnitude is greater than cutoff, is multiplied by (1 - the friction parameter) when being composed into the new velocity vector.

The cutoff parameter can allow particles to glide smoothly along a surface without sticking.

NOTES:

    Since particles are tested to see whether they would pass through the domain if pMove were called now, it is best to have pBounce be the last action that modifies a particle's velocity before calling pMove. Also, actions such as pRandomDisplace and pVortex that modify a particle's position directly, rather than modifying its velocity vector, may yield unsatisfying results when used with pBounce.

    At present the only domains for which pBounce is implemented are PDSphere, PDTriangle and PDPlane. For spheres, the particle is always forced out of the sphere. For triangles, the particles bounce off either side of the triangle. For planes, particles bounce off either side of the diamond-shaped patch whose corners are o, o+u, o+u+v, and o+v. See the documentation on domains for an explanation.

    See the documentation of Domains for an explanation of the other arguments.

    pBounce doesn't work correctly with small time step sizes for particle sliding along a surface. The friction and resilience parameters should not be scaled by dt, since a bounce happens instantaneously. On the other hand, they should be scaled by dt because particles sliding along a surface will hit more often if dt is smaller. If you have any suggestions, let me know.

void pCopyVertexB(bool copy_pos = true, bool copy_vel = false)

ACTION: Set the secondary position from current position.

If copy_pos is true, sets the positionB 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 pRestore. If copy_vel is true, sets the velocityB 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 pDrawGroupl.

void pDamping(float damping_x, float damping_y, float damping_z, float vlow = 0.0f, float vhigh = P_MAXFLOAT)

ACTION: Simulate air by slowing down particle velocities.

If a particle's velocity magnitude is within vlow and vhigh, then multiply each component of the velocity by the respective damping constant. Typically, the three components of damping will have the same value.

NOTES:

    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.

void pExplosion(float center_x, float center_y, float center_z, float velocity, float magnitude, float lifetime, float epsilon = P_EPS, float age = 0.0f)

ACTION: An Explosion.

Causes an explosion by accelerating all particles away from the center. Particles in the shock wave are accelerated away from the center by an amount proportional to magnitude. As with most acceleration actions, the amount of acceleration falls off inversely with (r^2). But when r is small, the acceleration would be infinite, so epsilon is always added to r.

The shock wave of the explosion travels outward from the center at the specified velocity. The shock wave has a thickness of lifetime, which is the amount of time for which the shock wave will affect any piece of space.

age is used to calculate the radius of the shock wave. For pExplosion calls in action lists, age is the initial age of the explosion. It is incremented by dt after each call. For immediate mode, age is the current age of the explosion, and it is up to the application to increment the age parameter for each call to pExlosion.

void pFollow(float grav = 1.0f, float epsilon = P_EPS)

ACTION: Accelerate toward the next particle in the group.

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 grav. As with most acceleration actions, the amount of acceleration falls off inversely with (r^2). But when r is small, the acceleration would be infinite, so epsilon is always added to r.

NOTES:

    The pFollow 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 pKillOld to learn how to kill the last particle in the group after each step.

void pGravitate(float grav = 1.0f, float epsilon = P_EPS)

ACTION: Accelerate each particle toward each other particle.

Each particle is accelerated toward each other particle in the group by an amount proportional to grav. As with most acceleration actions, the amount of acceleration falls off inversely with (r^2). But when r is small, the acceleration would be infinite, so epsilon is always added to r.

NOTES:

    This action is more computationally intensive than the others are because each particle is affected by each other particle.

    This action can cause particles to conform to a certain shape. Define the shape using a few particles as control points. Place them in particular locations and keep them there each frame by killing them with pKillOld and replacing them with pVertex. See pKillOld to learn how to kill the last particles in the group after each step.

void pGravity(float dir_x, float dir_y, float dir_z)

ACTION: Accelerate particles in the given direction.

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, pGravity(0, 0, -9.8) specifies gravity in the negative Z direction.

void pGrowSize(float destSize, float scale)

ACTION:.

void pJet(float center_x, float center_y, float center_z, float grav = 1.0f, float epsilon = P_EPS, float maxRadius = P_MAXFLOAT)

ACTION: Accelerate particles that are near the center of the jet.

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 grav. As with most acceleration actions, the amount of acceleration falls off inversely with (r^2). But when r is small, the acceleration would be infinite, so epsilon is always added to r.

The domain from which acceleration vectors are chosen is the current velocity domain.

maxRadius defines the sphere of influence of this action. No particle further than maxRadius from the center is affected.

void pKillOld(float ageLimit, bool kill_less_than = false)

ACTION: Remove old particles.

Removes all particles older than ageLimit. But if kill_less_than is true, it instead removes all particles newer than ageLimit. ageLimit is not clamped, so negative values are ok. This can be used in conjunction with pStartingAge(-n) to create and then kill a particular set of particles.

NOTES:

    In order to kill a particular particle, set pStartingAge 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 pSource or pVertex. Then do the rest of the particle actions and finally call pKillOld(-8.0, true) to kill the special particle because it is the only one with an age less than -8.0.

void pKillSlow(float speedLimit, bool kill_less_than = true)

ACTION: Remove slow particles.

Removes all particles whose velocity magnitudes are less than speedLimit. But if kill_less_than is false, it instead removes all particles whose velocity magnitudes are faster than speedLimit.

NOTES:

    This action is similar to pSinkVelocity, but it considers the magnitude of the velocity only.

void pMove()

ACTION: Move particle positions based on velocities.

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.

The velocity is multiplied by the time step length, dt, before being added to the position. This implements Euler's method of numerical integration with a constant, but specifiable step size. See pTimeStep for more on varying the step size.

void pOrbitLine(float p_x, float p_y, float p_z, float axis_x, float axis_y, float axis_z, float grav = 1.0f, float epsilon = P_EPS, float maxRadius = P_MAXFLOAT)

ACTION: Accelerate toward the closest point on the given line.

p and axis define an infinite line, where p can be any point on the line and axis 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 grav. As with most acceleration actions, the amount of acceleration falls off inversely with (r^2). But when r is small, the acceleration would be infinite, so epsilon is always added to r.

maxRadius defines the infinite cylinder of influence of this action. No particle further than maxRadius from the line is affected.

void pOrbitPoint(float center_x, float center_y, float center_z, float grav = 1.0f, float epsilon = P_EPS, float maxRadius = P_MAXFLOAT)

ACTION: Accelerate toward the given center point.

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 grav. As with most acceleration actions, the amount of acceleration falls off inversely with (r^2). But when r is small, the acceleration would be infinite, so epsilon is always added to r.

maxRadius defines the sphere of influence of this action. No particle further than maxRadius from the center is affected.

void pRandomAccel(PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

ACTION: Accelerate particles in random directions.

For each particle, chooses an acceleration vector from the specified domain and adds it to the particle's velocity.

Reducing the time step, dt, will make a higher probability of being near the original velocity after unit time. Smaller dt approach a normal distribution of velocity vectors instead of a square wave distribution.

NOTES:

    See the documentation of Domains for an explanation of the other arguments.

void pRandomDisplace(PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

ACTION:.

void pRandomVelocity(PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

ACTION: Immediately assign a random velocity.

For each particle, sets the particle's velocity vector to a random vector in the specified domain.

This function is not affected by dt. If you can think of an appropriate way for this to vary with dt, let me know.

NOTES:

    See the documentation of Domains for an explanation of the other arguments.

void pRestore(float time)

ACTION: Over time, restore particles to their secondary positions.

Computes a new velocity for each particle that will make the particle arrive at its positionB 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 positionB and their velocities are set to 0 to freeze them in place.

If pRestore is called in immediate mode, it is the application's responsibility to decrease timeLeft by dt on each call. When in an action list, timeLeft gets decremented automatically.

The positionB 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 pVertexBTracks, pVertexB, and pVertexBD. The positionB can be set at any time to the particle's current position using the pCopyVertexB action.

NOTES:

    pRestore(0) is the opposite of pCopyVertexB - 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.

void pShade(float color_x, float color_y, float color_z, float alpha, float scale)

ACTION:.

void pSink(bool kill_inside, PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

ACTION: Kill particles with positions on wrong side of the specified domain.

If kill_inside is true, deletes all particles inside the given domain. If kill_inside is false, deletes all particles outside the given domain.

NOTES:

    See the documentation of Domains for an explanation of the other arguments.

void pSinkVelocity(bool kill_inside, PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

ACTION: Kill particles with velocities on wrong side of the specified domain.

If kill_inside is true, deletes all particles whose velocity vectors are inside the given domain. If kill_inside is false, deletes all particles whose velocity vectors are outside the given domain.

NOTES:

    See the documentation of Domains for an explanation of the other arguments.

void pSource(float particleRate, PDomainEnum dtype, float a0=0.0f, float a1=0.0f, float a2=0.0f, float a3=0.0f, float a4=0.0f, float a5=0.0f, float a6=0.0f, float a7=0.0f, float a8=0.0f)

ACTION: Add particles in the specified domain.

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 pColor, pColorD, pSize, pStartingAge, pVelocity, pVelocityD, pVertexB, pVertexBD, and pVertexBTracks.

When pSource is called within an action list, the particle attribute domains used are those that were current when the pSource command was called within the pNewActionList / pEndActionList block instead of when pCallActionList is called. Note that this is unlike OpenGL.

particleRate is the number of particles to add per unit time. If particleRate / dt is a fraction then pSource adjusts the number of particles to add during this time step so that the average number added per unit time is particleRate.

NOTES:

    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 pSetMaxParticles.

    See the documentation of Domains for an explanation of the other arguments.

void pTargetColor(float color_x, float color_y, float color_z, float alpha, float scale)

ACTION: Change color of all particles toward the specified color.

Modifies the color and alpha of each particle to be scale percent of the way closer to the specified color and alpha. scale is multiplied by dt before scaling the sizes. Thus, using smaller dt causes a slightly faster approach to the target color.

NOTES:

    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).

void pTargetSize(float destSize, float scale)

ACTION: Gradually grow particle sizes toward specified size.

Modifies the size of each particle to be scale percent of the way closer to the specified destSize. This makes sizes grow asymptotically closer to the given size. scale is multiplied by dt before scaling the sizes. Thus, using smaller dt causes a slightly faster approach to the target size.

NOTES:

    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).

void pVertex(float x, float y, float z)

ACTION: Add a single particle at the specified location.

When called within a pNewActionList / pEndActionList block, this action is a shorthand for:

pSource(1, PDPoint, x, y, z).

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 / dt particles being added. Particle attributes are chosen according to their current domains, as with pSource.

NOTES:

    This call is patterned after the glVertex calls. It is useful for creating a particle group with exactly specified initial positions. For example, you can specify a geometrical model using pVertex calls, and then explode or deform it.

void pVortex(float center_x, float center_y, float center_z, float axis_x, float axis_y, float axis_z, float magnitude, float tightness=1.0f, float maxRadius = P_MAXFLOAT)

ACTION: Swirl particles around a vortex.

Center and axis define an infinite line, where center represents the tip of the vortex and axis is any vector parallel to the line. All particles are rotated about the line by an amount theta = magnitude / (r^tightness), where r is the distance from the vortex tip to the particle, so particles closer to the tip are rotated faster.

maxRadius defines the sphere of influence of this action. No particle further than maxRadius from the vortex center is affected.

NOTES:

    pVortex immediately displaces particle positions, unlike most actions which affect particle velocities, so unsatisfying results may occur when using the pVortex action with the pBounce action. In particular, particles may be displaced to the opposite side of the bounce surface without bouncing off it.

    pVortex currently does not pull the particles toward the axis or pull them up or down along the axis. This will be saved for a future release. If you write a sample implementation of these features, feel free to send it to me.


Generated at Fri Jul 23 21:22:06 1999 for ParticleSystemsAPI by doxygen  written by Dimitri van Heesch, © 1997-1998