[SESI logo]

Houdini Development Toolkit - Version 6.5

Side Effects Software Inc. 2004

Particle Operators

Creating a custom generator POP

Introduction

Generator POPs are similar to modifier POPs. Most of the concepts introduced in writing a modifier POP apply here with a few differences.

Differences from modifier POPs

An example of a generator POP can be found in the POP toolkit examples. Only the important differences will be examined.

PRM_Template POP_RadialBirth::myTemplateList[] = { PRM_Template(PRM_FLT_J, 1, &POPactivateName, PRMoneDefaults, 0, &PRMunitRange), PRM_Template(PRM_XYZ_J, 3, &names[0]), PRM_Template(PRM_FLT_J, 2, &names[1], distanceDefaults), PRM_Template(PRM_FLT_J, 2, &names[2], speedDefaults), PRM_Template(PRM_INT_J, 1, &names[3], PRMfourDefaults, 0, &birthRange), PRM_Template(PRM_STRING, 1, &names[4]), PRM_Template(PRM_FLT_J, 1, &POPlifeName, &POPlifeDefault), PRM_Template(PRM_FLT_J, 1, &POPlifevarName), PRM_Template(PRM_INT_J, 1, &POPoriginindexName), PRM_Template() }; The source group used in modifier POPs represents a subset of particles to apply the operation on. This concept doesn't really apply when birthing particles, so generator POPs don't require a source group. The activation field still applies. void newPopOperator (OP_OperatorTable* table) { table->addOperator( new OP_Operator("radialbirth", // Name "Radial Birth", // English POP_RadialBirth::myConstructor, // "Constructor" POP_RadialBirth::myTemplateList, // simple parms 0, // MinSources 0, // MaxSources 0, // variable pair OP_FLAG_GENERATOR)); // op flags } Note that the OP_FLAG_GENERATOR flag must be set to tell the operator table that this POP is a generator. POP_RadialBirth::POP_RadialBirth (OP_Network* net, const char* name, OP_Operator* entry) :POP_Node (net, name, entry) When birthing new particles, it doesn't make sense to have local variables that represent the particle's attributes. It's the classic chicken and the egg problem. It's not possible to define particle attributes based on local variables because the attributes have no value yet. So, it makes no sense to inherit from the POP_LocalVar class. Generator POPs should inherit from POP_Node. part = data->getPrimPart(this); initParticleList(context, part); Each generator creates a new particle system, or in Houdini geometry terms, its own particle primitive. The POP_Node variable, myParticleList should contain a list of particle primitives that the POP processes. For modifier POPs, this list is generated from the input wires using the method buildParticleList(). Generator POPs will want to initialize the list with the primitive is creates. The getPrimPart() method of the POP_ContextData returns the primitive associated with this generator. The call will create a new primitive if one doesn't exist yet. The method initParticleList() initializes the list with the newly created primitive. birthParticle(data, part, birthpos, NULL, NULL, NULL, (POP_IntFunc) getOriginIndex, 0, POP_ORIGIN_INDEX, (POP_FloatFunc) getLifetime, (POP_BirthAttribFunc) setAttrib); The POP_Node method birthParticle() is used to birth particles into the particle primitive. This method will birth a particle at a specific location, allow the new particle to inherit attributes, and set some of the particle's initial attributes like the origin and lifetime. A detailed description of the method can be found in the section on POP classes.

Summary

This example demonstrated the general structure of a generator POP. It covered the following topics:
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