pfMorph OBSOLETED by pfEngine and pfFlux(3pf)NAMEpfMorph - Create, modify, and query a pfMorph node.
FUNCTION SPECIFICATION
#include <Performer/pf/pfMorph.h>
pfMorph::pfMorph();
static pfType * pfMorph::getClassType(void);
int pfMorph::setAttr(int index, int floatsPerElt,
int nelts, void *dst, int nsrcs, float *alist[],
ushort *ilist[], int nlist[]);
int pfMorph::setWeights(int index, float *weights);
int pfMorph::getWeights(int index, float *weights);
int pfMorph::getNumAttrs(void);
int pfMorph::getSrc(int index, int src, float **alist,
ushort **ilist, int *nlist);
int pfMorph::getNumSrcs(int index);
void * pfMorph::getDst(int index);
void pfMorph::evaluate(void);
PARENT CLASS FUNCTIONS
The OpenGL Performer class pfMorph is derived from the parent class
pfGroup, so each of these member functions of class pfGroup are also
directly usable with objects of class pfMorph. This is also true for
ancestor classes of class pfGroup.
int pfGroup::addChild(pfNode *child);
int pfGroup::insertChild(int index, pfNode *child);
int pfGroup::replaceChild(pfNode *old, pfNode *new);
int pfGroup::removeChild(pfNode* child);
int pfGroup::searchChild(pfNode* child);
pfNode * pfGroup::getChild(int index);
int pfGroup::getNumChildren(void);
int pfGroup::bufferAddChild(pfNode *child);
int pfGroup::bufferRemoveChild(pfNode *child);
Since the class pfGroup is itself derived from the parent class pfNode,
objects of class pfMorph can also be used with these functions designed
for objects of class pfNode.
Page 1
pfMorph OBSOLETED by pfEngine and pfFlux(3pf)
pfGroup * pfNode::getParent(int i);
int pfNode::getNumParents(void);
void pfNode::setBound(pfSphere *bsph, int mode);
int pfNode::getBound(pfSphere *bsph);
pfNode* pfNode::clone(int mode);
pfNode* pfNode::bufferClone(int mode, pfBuffer *buf);
int pfNode::flatten(int mode);
int pfNode::setName(const char *name);
const char * pfNode::getName(void);
pfNode* pfNode::find(const char *pathName, pfType *type);
pfNode* pfNode::lookup(const char *name, pfType* type);
int pfNode::isect(pfSegSet *segSet, pfHit **hits[]);
void pfNode::setTravMask(int which, uint mask, int setMode,
int bitOp);
uint pfNode::getTravMask(int which);
void pfNode::setTravFuncs(int which, pfNodeTravFuncType pre,
pfNodeTravFuncType post);
void pfNode::getTravFuncs(int which, pfNodeTravFuncType *pre,
pfNodeTravFuncType *post);
void pfNode::setTravData(int which, void *data);
void * pfNode::getTravData(int which);
void pfNode::setTravMode(int which, int mode, int val);
int pfNode::getTravMode(int which, int mode) const;
Since the class pfNode is itself derived from the parent class pfObject,
objects of class pfMorph can also be used with these functions designed
for objects of class pfObject.
void* pfObject::operator new(size_t);
void* pfObject::operator new(size_t, pfFluxMemory *fmem);
void pfObject::setUserData(void *data);
void pfObject::setUserData(int slot, void *data);
void* pfObject::getUserData(pfObject *obj);
void* pfObject::getUserData(pfObject *obj, int slot);
int pfObject::getNumUserData();
Since the class pfObject is itself derived from the parent class
pfMemory, objects of class pfMorph can also be used with these functions
designed for objects of class pfMemory.
void* pfMemory::getData(const void *ptr);
pfType * pfMemory::getType();
int pfMemory::isOfType(pfType *type);
int pfMemory::isExactType(pfType *type);
const char * pfMemory::getTypeName();
int pfMemory::copy(pfMemory *src);
int pfMemory::compare(const pfMemory *mem);
void pfMemory::print(uint which, uint verbose, char *prefix,
FILE *file);
Page 2
pfMorph OBSOLETED by pfEngine and pfFlux(3pf)
int pfMemory::getArena(void *ptr);
void* pfMemory::getArena();
int pfMemory::ref();
int pfMemory::unref();
int pfMemory::unrefDelete();
int pfMemory::unrefGetRef();
int pfMemory::getRef();
int pfMemory::checkDelete();
int pfMemory::isFluxed();
void * pfMemory::getArena();
int pfMemory::getSize();
DESCRIPTION
A pfMorph node does not define geometry; rather, it manipulates geometric
attributes of pfGeoSets and other geometric primitives. While pfMorph is
very general, its primary use is for geometric morphing where the colors,
normals, texture coordinates and coordinates of geometry are smoothly
changed over time to simulate actions such as facial and skeletal
animation, ocean waves, continuous level-of-detail, and advanced special
effects. In these situations, the rigid body transformations provided by
matrices do not suffice - instead, efficient per-vertex manipulations are
required.
A pfMorph consists of one or more "sources" and a single "destination"
which together are termed an "attribute". Both sources and destination
are arrays of "elements" where each element consists of 1 or more
floating point numbers, e.g., an array of pfVec3 coordinates. The
pfMorph node produces the destination by computing a weighted sum of the
sources. By varying the source weights and using the morph destination as
a pfGeoSet attribute array, the application can achieve smooth, geometric
animation. A pfMorph can "morph" multiple attributes.
new pfMorph creates and returns a handle to a pfMorph. Like other
pfNodes, pfMorphs are always allocated from shared memory and cannot be
created statically, on the stack or in arrays. pfMorphs should be
deleted using pfDelete rather than the delete operator.
pfMorph::getClassType returns the pfType* for the class pfMorph. The
pfType* returned by pfMorph::getClassType is the same as the pfType*
returned by invoking the virtual function getType on any instance of
class pfMorph. Because OpenGL Performer allows subclassing of built-in
types, when decisions are made based on the type of an object, it is
usually better to use the member function isOfType to test if an object
is of a type derived from a Performer type rather than to test for strict
equality of the pfType*'s.
pfMorph::setAttr configures the indexth attribute of the pfMorph.
floatsPerElt specifies how many floating point numbers comprise a single
attribute element. For example, when morphing pfGeoSet coordinate and
texture coordinate arrays (PFGS_COORD3, PFGS_TEXCOORD2), floatsPerElt
would be 3 and 2 respectively. nelts specifies how many attribute
elements are in the destination array. If the required number of
Page 3
pfMorph OBSOLETED by pfEngine and pfFlux(3pf)
pfGeoSet coordinates is 33, then nelts would be 33, not 33 * 3 = 99. dst
is a pointer to the destination array which should be at least of size
floatsPerElt * nelts * sizeof(float). If dst is NULL, then the pfMorph
will automatically create and use a pfCycleBuffer of appropriate size.
(pfCycleBuffers are useful when OpenGL Performer is configured to
multiprocess.)
There are 2 distinct methods of accessing the source arrays of a pfMorph
attribute: non-indexed and indexed. Indexing provides a means of
efficiently applying sparse changes to the destination array. The nsrcs
argument to pfMorph::setAttr specifies how many source arrays are
provided in alist, i.e., alist[i] is the i'th source and is treated as an
array of elements where each element consists of floatsPerElt floating
point numbers. Index arrays and their lengths are provided in ilist and
nlist respectively. If ilist is NULL then all sources are non-indexed. If
ilist is non-NULL, it contains a list of index lists corresponding to the
source lists in alist. If nlist is NULL, then the index lists are assumed
to be nelts long and if non-NULL, the length of each index list is
specified in nlist. ilist may contain NULL pointers to mix indexed and
non-indexed source arrays.
All source arrays referenced in alist and ilist are reference counted by
pfMorph::setAttr.
pfMorph::setWeights specifies the source weights of the indexth attribute
of the pfMorph in the array weights. weights should consist of nsrcs
floating point numbers where nsrcs is the number of attribute sources
specified in pfMorph::setAttr. If index is < 0, then weights is used for
all attributes of the pfMorph. pfMorph::getWeights copies the weights of
the indexth attribute of the pfMorph into weights. weights should be an
array of at least nsrcs floats.
A pfMorph node is evaluated, i.e., its destination array is computed,
during the APP traversal which is triggered directly by the application
through pfAppFrame (see pfAppFrame) or indirectly by pfSync.
Alternately, the pfMorph node may be explicitly evaluated by calling the
function pfMorph::evaluate. In all cases, destination elements are
computed as in the following pseudocode:
zero destination array;
for (s=0; s<nsrcs; s++)
{
if (ilist == NULL || ilist[s] == NULL)
{
/* Source is non-indexed */
for (i=0; i<nelts; i++)
for (e=0; e<floatsPerElt; e++)
dst[i][e] += weights[s] * alist[s][i][e];
}
else
{
Page 4
pfMorph OBSOLETED by pfEngine and pfFlux(3pf)
/* Source is indexed */
int nindex;
if (nlist == NULL)
nindex = nelts;
else
nindex = nlist[s];
for (i=0; i<nindex; i++)
for (e=0; e<floatsPerElt; e++)
dst[ilist[s][i]][e] += weights[s] * alist[s][i][e];
}
}
Note that the actual implementation is much more efficient than above,
particularly for the special weights of 0 and 1.
Since pfMorph is a pfGroup, it is guaranteed to be evaluated before its
children in the APP traversal. The pfMorph is only evaluated by the APP
traversal when its weights change.
pfMorph::getNumAttrs returns the number of the pfMorph's attributes.
pfMorph::getSrc returns the srcth source parameters of the indexth
attribute of the pfMorph. The source attribute array and index array
pointers are copied into alist and ilist respectively. The size of the
srcth index array is copied into nlist and the number of floats per
element is returned by pfMorph::getSrc.
pfMorph::getNumSrcs returns the number of sources of the indexth
attribute of the pfMorph.
pfMorph::getDst returns the indexth destination array of morph. The
destination array is either that provided earlier by pfMorph::setAttr or
the pfCycleBuffer automatically created when NULL was passed as the dst
argument to pfMorph::setAttr.
OBSOLETEpfMorph has been obsoleted by pfEngine and pfFlux. pfFluxes are
multibuffered data objects for asyncrhonous evaluation, such as by
pfEngines, that can be directly used as vertex attribute arrays, full
pfGeoSets, matrices for pfFSC tranformation nodes, and other special
asynchronous values for pfLOD and pfSwitch. See these man pages for more
information.
Page 5
pfMorph OBSOLETED by pfEngine and pfFlux(3pf)SEE ALSO
pfAppFrame, pfCycleBuffer, pfGroup, pfDelete, pfEngine, pfFlux, pfNode
Page 6