[SESI logo]

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.

  1. 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) };
  2. 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.

  3. 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;
  4. 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.

  5. 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_DYINGParticle is about to die
PART_STATE_STOPPEDParticle is stopped
PART_STATE_COLLIDEParticle has collided
PART_STATE_SUPPPOSDo not apply default position rule
PART_STATE_SUPPVELDo not apply default velocity rule
PART_STATE_SUPPUPDo not apply default up vector rule
PART_STATE_SUPPAGEDo 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