HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Adding guide geometry

A POP can export guide geometry that can be displayed in a viewer. An example (.h / .C) of a POP with guide geometry can be found in the toolkit samples.

This section will explain the parts of the code pertaining to guide geometry.

setTemplate(1);

The template flag on a POP is used to specify whether or not to show that node's guide geometry. For the user's convenience, the template flag can be turned on by default. This can also be done in the shelf tool for the node instead.

myGuide = new POP_Guide;
myGuideHandle.allocateAndSet(myGuide);

Guide geometry is implemented by the POP_Guide class. Currently POP_Guide is merely an alias for GOP_Guide. GOP_Guide inherits from GU_Detail, meaning that geometry can be constructed the usual way. GOP_Guide also contains additional methods to determine how the guide geometry should be drawn. The POP will need to create a new POP_Guide. Note that ownership of myGuide is immediately passed to myGuideHandle. External code will always refer to the guide geometry via this handle to avoid the possibility of following an obsolete pointer.

if (doUpdateViewport(data))
{
data->appendGuide(this, myGuideHandle);
}

Guide geometry is updated when the POP is cooked. However, it is not necessary to update the guide geometry on every cook. Call POP_Node::doUpdateViewport(POP_ContextData *) to determine whether to worry about guide geometry during this cook. This call will consider the template flag on the node along with other factors. POP_ContextData maintains a list of guides to show in the viewport, so we need to register our guide.

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 POP_Guide to give it something to show.

The next code fragment is not found in this particular example, but is nonetheless pretty common.

if (data->isGuideOnly())
goto done;

POP_Node::cookPop(OP_Context &) is sometimes called because the viewer needs to update the guide geometry. When this is the case, POP_ContextData::isGuideOnly() will return true, and only the guide should be updated. The particle system should not be altered. The code fragment above can typically be found after the code updating the guide geometry to jump over the rest of the cook code.

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. POP_Node::addAccelGuide() is provided to make this easier.

In these types of POPs, as in this example, don't check POP_ContextData::isGuideOnly() at the beginning of cookPop(). Instead, use code similar to the following where the acceleration is being set.

if (!data->isGuideOnly())
{
ppt->setValue<UT_Vector3>(data->getAccelOffset(), UT_Vector3(x, y, z));
}
if (doUpdateViewport(data))
addAccelGuide(ppt, x, y, z, data->getTimeInc());

In short, if we aren't cooking for guide only, update the particle's acceleration. Then add this acceleration as guide geometry is an update of the guide geometry is appropriate.

Note
Note that myGuide is not explicitly cleared or reallocated by cookPop() in this example. This is handled automatically by the base class.

Guide Geometry for Instancing

The guide geometry that displays the effect of the instance attribute is a special case. A POP wishing to export this guide geometry does not populate myGuide in its cookPop() method. Instead, it merely needs to initialize myGuide as above:

myGuide = new POP_Guide;
myGuideHandle.allocateAndSet(myGuide);

and replace:

if (doUpdateViewport(data))
data->appendGuide(this, myGuideHandle);

with:

if (doUpdateViewport(data))
data->setInstanceGuide(this, myGuideHandle);
Note
More than one POP can call POP_ContextData::setInstanceGuide(). All that matters is that at least one POP does so, and the particle system has the instance attribute.