|
Houdini Development Toolkit - Version 6.5
Side Effects Software Inc. 2004
|
Particle Operators
Other Topics
Generating Events
Events are generated using the addEvent()
method in the POP_ContextData.
Once an event has been added, it remains active. To signal that an event
has ended, the method removeEvent() should be used. The event
should occur for at least one full frame so it is the POP's responsibility
to clear the event, usually before the activation check.
Here is an example of how to generate events. Note that the eventName
is a UT_String.
data->removeEvent(eventName);
// check activation event
if (!checkActivation(data, (POP_FParam) ACTIVATE))
goto done;
if (eventoccurred)
data->addEvent(eventName);
Parameter Evaluation Caching
Some parameter fields apply to every particle being processed. For example,
POPs that apply forces have a mass parameter for setting the mass to use
if the attribute doesn't exist. This parameter could be set to a constant
value or can be different for every particle if an expression like $ID is
used.
For efficiency, when the value is constant, the parameter shouldn't be
continually re-evaluated for every particle. Only when the expression is
variable dependent should the parameter be re-evaluated.
There are some built-in macros and typedefs that help in achieving this.
Here are the steps on how to use them.
- In the header file, make sure there is a way to evaluate the parameter
using the regular OP methods. For example,
float SCALE (float t) { FLOAT_PARM("scale", 0, 0, t) };
int ID (float t) { INT_PARM("id", 1, 0, t) };
- Also define a cache variable and a method to retrieve the cache value.
For example,
POP_FPARM(myScale, getScale);
POP_IPARM(myID, getID);
Note that there are different macros for float and integer types.
- Add a function pointer variable. This function pointer will be used
to evaluate the parameter. The cookPop() method is an ideal place to
define these variables.
POP_FParam scale;
POP_IParam id;
- Before the processing of the particles, cache the parameter value.
POP_FCACHE(scale, SCALE, getScale, myScale);
POP_ICACHE(id, ID, getID, myID);
The macro is used as follows:
POP_FCACHE(function pointer, regular evaluation method,
cache evaluation method, cache value).
The macro will evaluate the parameter once to determine if it is
dependent on local variables or not. If it is, it sets the function
pointer to use the regular OP evalation method. If it isn't, it stores
the value in the cache variable and sets the function pointer to the
method that just returns the cache value.
- To actually evalute the parameter, use the POP_PEVAL macro.
setScale(POP_PEVAL(scale));
setID(POP_PEVAL(id));
Make sure that the current time exists in the scope where the evaluation is
taking place. The time should be stored in the variable t.
Guide Geometry
There is support to show guide geometry with a POP. There is an
example in the POP toolkit
samples.
Here is an explanation of the parts pertaining to guide geometry.
setTemplate(1);
Just for the user's convenience, the template flag can be turned on by
default.
myGuide = new OP_Guide;
Guide geometry is implemented in the OP_Guide class. An OP_Guide inherits
from a GU_Detail meaning that geometry can be constructed the usual way.
The OP_Guide contains additional methods to determine how the geometry
should be drawn. The POP will need to create a new OP_Guide.
data->myOPGuides.append(myGuide);
data->myGuidePOPs.append(this);
Every time the POP is cooked, it will need to update the guide geometry.
The POP_ContextData contains a list of guides to show in the viewport as
well as which POPs own them. Add the guide and the POP to the list.
At this point, the guide will be shown in the viewport, it just has no
geometry. The usual geometry building
methods can be used on the OP_Guide to give it something to show.
if (data->isGuideOnly())
goto done;
A POP is sometimes called to recook because the viewer thinks the guide
geometry needs updating. When this is the case, the call to
isGuideOnly() will be true. This means that the particle system
shouldn't be altered, but the guide should be made up to date.
Simply make sure the guide is updated before this check.
Guide geometry can be used to show the acceleration applied to a particle.
This can be useful for modifier POPs to show how that POP is altering
the acceleration. The method addAccelGuide() is provided to
make doing this easier.
In these types of POPs, don't check isGuideOnly() at the
beginning of the POP's cook method. Instead, where the acceleration is
being set, use the following:
UT_Vector3* vecval;
if (!data->isGuideOnly())
{
vecval = (UT_Vector3*) ppt->getAttribData(data->getAccelOffset());
vecval->assign(x, y, z);
}
if (getTemplate())
addAccelGuide(ppt, x, y, z, data->myTimeInc);
In short, if we aren't cooking for guide only, set the acceleration in
the particle. Then, if the template flag is on, also add this
acceleration as guide geometry.
Transform Spaces
One of the pieces of data that is passed with the
POP_ContextData is
the transform space from which this POP is being cooked. If this POP
deals with coordinates in another frame of reference and it needs to
transform these positions to local space, the transform object is used.
For example, suppose the POP references a SOP named geo1. Yet, the
POP is being cooked from a POP Sop in geo2. Then, the POP wants to know
where geo1 is located relative to geo2. That way, the particles interact
with the geometry in the correct space.
xform = obj->getWorldTransform(context);
if (data->myXformObj)
xform *= data->myXformObj->getIWorldTransform(context);
The particle positions in the geometry are always in local space. The POP
just wants them to interact with geometry that is positioned relative
to the local space. The above example builds a transform to convert from
the obj's space to local space so the particles can interact with
the SOP properly. Following the previous example, obj would be geo1 while
myXformObj would be geo2.
This is a very advanced topic and usually won't be required for most
general purpose POPs. It is only needed if the POP deals with referenced
SOPs.
State Attribute
The state attribute is an integer that represents the state of the
particle. It is a bitwise or of the following flags (which are found
in GEO_PrimPart.h:
PART_STATE_DYING | Particle is about to die |
PART_STATE_STOPPED | Particle is stopped |
PART_STATE_COLLIDE | Particle has collided |
PART_STATE_SUPPPOS | Do not apply default position rule |
PART_STATE_SUPPVEL | Do not apply default velocity rule |
PART_STATE_SUPPUP | Do not apply default up vector rule |
PART_STATE_SUPPAGE | Do not apply default aging rule |
Instance Attribute
The instance attribute is an index into a list of strings. The string
represents the object to instance on the particle. Here is how it should be
accessed.
GB_Attribute* instanceAttr;
instanceAttr =
gdp->pointAttribs().find("instance", sizeof(int), GB_ATTRIB_INDEX);
First, the GB_Attribute* needs to be retrieved. The attribute holds
the table of strings.
int nameindex;
char name[256];
nameIndex = instanceAttr->addIndex(name);
*((int*) ppt->getAttribData(data->getInstanceOffset())) = nameIndex;
Adding the string to the table will give an index into the table. This
is the value that the actual instance attribute is set to.
Rotation Attribute
The rotation attribute is a set of four floats representing a
quaternion. For more information, refer to the UT_Quaternion class.
Speed Limit Attribute
The speed limit attribute is a set of two floats represnting the
minimum and maximum speed that this particle should not exceed.
Table of Contents
Operators |
Surface Operations |
Particle Operations |
Composite Operators |
Channel Operators
Material & Texture |
Objects |
Command and Expression |
Render Output |
Mantra Shaders |
Utility Classes |
Geometry Library |
Image Library |
Clip Library
Customizing UI |
Questions & Answers
Copyright © 2004 Side Effects Software Inc.
477 Richmond Street West, Toronto, Ontario, Canada M5V 3E7