pfIBRnode(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfIBRnode(3pf)NAME
pfNewIBRnode, pfIBRnodeIBRtexture, pfGetIBRnodeIBRtexture,
pfIBRnodeFlags, pfGetIBRnodeFlags, pfIBRnodeAngles, pfGetIBRnodeAngles,
pfGetIBRnodeNumAngles, pfIBRnodeProxyTexCoords,
pfGetIBRnodeProxyTexCoords - Represents an object by an precomputed image
from a close view.
FUNCTION SPECIFICATION
#include <Performer/pf.h>
pfIBRnode * pfNewIBRnode(void);
void pfIBRnodeIBRtexture(pfIBRnode* ibrnode,
pfIBRtexture *tex);
pfIBRtexture * pfGetIBRnodeIBRtexture(pfIBRnode* ibrnode);
void pfIBRnodeFlags(pfIBRnode* ibrnode, int which,
int value);
int pfGetIBRnodeFlags(const pfIBRnode* ibrnode, int which);
void pfIBRnodeAngles(pfIBRnode* ibrnode, int i,
float horAngle, float verAngle);
void pfGetIBRnodeAngles(pfIBRnode* ibrnode, int i,
float & horAngle, float & verAngle);
int pfGetIBRnodeNumAngles(pfIBRnode* ibrnode);
void pfIBRnodeProxyTexCoords(pfIBRnode* ibrnode,
pfVec2 ***texCoords);
pfVec2*** pfGetIBRnodeProxyTexCoords(pfIBRnode* ibrnode);
PARENT CLASS FUNCTIONS
The OpenGL Performer class pfIBRnode is derived from the parent class
pfBillboard, so each of these member functions of class pfBillboard are
also directly usable with objects of class pfIBRnode. Casting an object
of class pfIBRnode to an object of class pfBillboard is taken care of
automatically. This is also true for casts to objects of ancestor
classes of class pfBillboard.
void pfBboardPos(pfBillboard* bill, int i, const pfVec3 xyzOrigin);
void pfGetBboardPos(pfBillboard* bill, int i, pfVec3 xyzOrigin);
void pfBboardPosFlux(pfBillboard* bill, pfFlux *flux);
pfFlux * pfGetBboardPosFlux(pfBillboard* bill);
void pfBboardMode(pfBillboard* bill, int mode, int val);
int pfGetBboardMode(pfBillboard* bill, int mode);
void pfBboardAxis(pfBillboard* bill, const pfVec3 axis);
Page 1
pfIBRnode(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfIBRnode(3pf)
void pfGetBboardAxis(pfBillboard* bill, pfVec3 axis);
Since the class pfBillboard is itself derived from the parent class
pfGeode, objects of class pfIBRnode can also be used with these functions
designed for objects of class pfGeode.
int pfAddGSet(pfGeode* geode, pfGeoSet* gset);
int pfRemoveGSet(pfGeode* geode, pfGeoSet* gset);
int pfInsertGSet(pfGeode* geode, int index, pfGeoSet* gset);
int pfReplaceGSet(pfGeode* geode, pfGeoSet* old, pfGeoSet* new);
pfGeoSet * pfGetGSet(const pfGeode* geode, int index);
int pfGetNumGSets(const pfGeode* geode);
Since the class pfGeode is itself derived from the parent class pfNode,
objects of class pfIBRnode can also be used with these functions designed
for objects of class pfNode.
pfGroup * pfGetParent(const pfNode *node, int i);
int pfGetNumParents(const pfNode *node);
void pfNodeBSphere(pfNode *node, pfSphere *bsph, int mode);
int pfGetNodeBSphere(pfNode *node, pfSphere *bsph);
pfNode* pfClone(pfNode *node, int mode);
pfNode* pfBufferClone(pfNode *node, int mode, pfBuffer *buf);
int pfFlatten(pfNode *node, int mode);
int pfNodeName(pfNode *node, const char *name);
const char * pfGetNodeName(const pfNode *node);
pfNode* pfFindNode(pfNode *node, const char *pathName,
pfType *type);
pfNode* pfLookupNode(const char *name, pfType* type);
int pfNodeIsectSegs(pfNode *node, pfSegSet *segSet,
pfHit **hits[]);
void pfNodeTravMask(pfNode *node, int which, uint mask,
int setMode, int bitOp);
uint pfGetNodeTravMask(const pfNode *node, int which);
void pfNodeTravFuncs(pfNode* node, int which,
pfNodeTravFuncType pre, pfNodeTravFuncType post);
void pfGetNodeTravFuncs(const pfNode* node, int which,
pfNodeTravFuncType *pre, pfNodeTravFuncType *post);
void pfNodeTravData(pfNode *node, int which, void *data);
void * pfGetNodeTravData(const pfNode *node, int which);
void pfNodeTravMode(pfNode* node, int which, int mode,
int val);
int pfGetNodeTravMode(const pfNode* node, int which,
int mode);
Since the class pfNode is itself derived from the parent class pfObject,
objects of class pfIBRnode can also be used with these functions designed
for objects of class pfObject.
Page 2
pfIBRnode(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfIBRnode(3pf)
void pfUserDataSlot(pfObject *obj, int slot, void *data);
void pfUserData(pfObject *obj, void *data);
void* pfGetUserDataSlot(pfObject *obj, int slot);
void* pfGetUserData(pfObject *obj);
int pfGetNumUserData(pfObject *obj);
int pfGetNamedUserDataSlot(const char *name);
const char* pfGetUserDataSlotName(int slot);
int pfGetNumNamedUserDataSlots(void);
int pfDeleteGLHandle(pfObject *obj);
Since the class pfObject is itself derived from the parent class
pfMemory, objects of class pfIBRnode can also be used with these
functions designed for objects of class pfMemory.
pfType * pfGetType(const void *ptr);
int pfIsOfType(const void *ptr, pfType *type);
int pfIsExactType(const void *ptr, pfType *type);
const char * pfGetTypeName(const void *ptr);
int pfRef(void *ptr);
int pfUnref(void *ptr);
int pfUnrefDelete(void *ptr);
int pfUnrefGetRef(void *ptr);
int pfGetRef(const void *ptr);
int pfCopy(void *dst, void *src);
int pfDelete(void *ptr);
int pfIsFluxed(void *ptr);
int pfCompare(const void *ptr1, const void *ptr2);
void pfPrint(const void *ptr, uint which, uint verbose,
FILE *file);
void * pfGetArena(void *ptr);
DESCRIPTION
A pfIBRnode is used for very complex objects. Unlike a pfBillboard, a
parent class of pfIBRnode, the texture on pfGeoSets of a pfIBRnode is not
static, but it changes based on the view direction for each pfGeoSet.
This is a basic technique used in image based rendering where a complex
object is represented by a set of images taken from many directions
around the object. When the object is rendered for each view direction
several closest views are blended together.
pfNewIBRnode creates and returns a handle to a pfIBRnode. Like other
pfNodes, pfIBRnodes are always allocated from shared memory and can be
deleted using pfDelete.
Each pfIBRnode has associated a single pfIBRtexture with it that stores a
set of images of the complex object as viewed from different directions.
Each pfGeoSet is then rendered with a texture representing the view of
the object from the given direction. A pfIBRtexture is specified using
pfIBRnodeIBRtexture.
The initial orientation of the complex object can be controlled by
Page 3
pfIBRnode(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfIBRnode(3pf)
specifying the rotation from horizontal plane and from vertical plane for
each pfGeoSet, using pfIBRnodeAngles. These angles are very useful in
case of trees, for example, because you can use different angles for each
instance of the tree. The trees then appear different although they all
use the same pfIBRtexture. The first value is ignored in case only one
ring of views around the object is used.
An pfIBRnode has to be set up so that the pfIBRtexture applied to it can
modify properly the image at each frame. For this purpose, the user has
to set the texture of the pfGeoState associated with each pfGeoSet of the
pfIBRnode to the texture returned by pfGetIBRtextureDefaultTexture. If
the pfIBRtexture has the flag PFIBR_USE_REG_COMBINERS set multitexturing
should be enabled and texture coordinates for additional texture units
have to be specified. See file sample/pguide/C++/IBRnode.C for an
example. If the pfIBRtexture has the flag PFIBR_3D_VIEWS enabled, set
the billboard rotation (PFBB_ROT) to PFBB_AXIAL_ROT.
pfGetIBRnodeClassType returns the pfType* for the class pfIBRnode. The
pfType* returned by pfGetIBRnodeClassType is the same as the pfType*
returned by invoking pfGetType on any instance of class pfIBRnode.
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 pfIsOfType 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.
LIMITATIONS
Currently, a pfIBRtexture applied to a pfIBRnode is not properly rotated
when the pfIBRnode is viewed from the top. This may result in visible
rotation of the texture with respect to the ground.
PFIBRNODE WITH PROXY
By default it is assumed that the geosets of the pfIBRnode specify
rectangles that are always facing the viewer (like billboards). This
approach is very fast but it requires a large number of views to limit
the artifacts due to the differences between the neighboring views.
To reduce the number of views required to obtain a reasonable image of
the complex object from any direction we can use an a shape that
approximates the surface of the complex object instead of a billboard.
This shape is called a proxy. The closer the proxy is to the original
surface the fewer views of the objects are required. Optimally one
creates a proxy that contains a relatively small number of primitives and
that is very close to the original surface. The proxy can be created
using a new tool makeIBRproxy (see below).
Compared to default mapping of views on a billboard there are only minor
changes. Instead of billboard the node's geosets contain the proxy
geometry. The pfIBRtexture associated with the node has set flag
PFIBR_USE_PROXY. There is an array of texture coordinates, indexed by the
view index and the geoset index. These texture coordinates can be
Page 4
pfIBRnode(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfIBRnode(3pf)
defined and queried by pfIBRnodeProxyTexCoords and
pfGetIBRnodeProxyTexCoords Note: it is is more efficient to store the
proxy in one geoset.
Optionally, it is possible to specify different geosets for each view (if
PFIBR_NEAREST flag is set in the pfIBRtexture assigned to the pfIBRnode)
or for each group of views if the views are blended. In this case the
flag PFIBRN_VARY_PROXY_GEOSETS has to be set using pfIBRnodeFlags This
can be useful for removing the invisible parts of the proxy (invisible
from the range of views in the group) or for sorting of the proxy
triangles to avoid artifacts when edges of the proxy textures are
transparent. The array of texture coordinates is then organized as
follows: the first index is the view index or the group index (if the
views are blended) and the second index is the geoset index times the
number of views in a group (1 for nearest view) - grouped by geosets,
thus there are texture coordinates for the geoset 0 for all views in the
group then geoset 1, etc. The geosets are organized as follows: if the
proxy has n geosets and there are v views or groups of views the
pfIBRnode has n*v geosets, and each group of n geosets belongs to one
view.
To create views of a complex object from various directions and to
compute the texture coordinates of its proxy you can use tool
makeProxyImages described below.
MAKEIBRPROXY
makeIBRproxy takes a complex object and creates a simplified surface
around the object so that the object is fully inside the surface.
Currently, the user specifies a maximum allowed distance between the
proxy and the original surface and the initial distance of the first
proxy iteration (usually around the half of the maximum distance). In the
final version the distances will be automatically relaxed to be able to
specify desired number of triangles.
As an additional input the user may control the resolution of a grid used
for determining the initial surface and to speed up the computations.
Optionally the initial surface may be supplied by the user (sometimes it
could be a scaled-up version of the complex object if the scale-up
version fully contains the original object). Do not select too coarse
grid because you can miss some important features of the object, for
example, cow's legs may become connected. On the other hand, too fine
grid results in having too fine initial mesh which considerably slows
down the algorithm.
Run makeIBRproxy without any parameter to get the list of all command
line options.
MAKEPROXYIMAGES
Page 5
pfIBRnode(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfIBRnode(3pf)
makeProxyImages creates textures for the proxy. makeProxyImages works
similarly as makeIBRimages but it addresses issues with mapping the views
(textures) on the proxy. The problem is that there may be surfaces
(backfacing surfaces or surfaces obstructed by another surface) that
become visible when the proxy is rotated away from the direction of the
view. The projection of the object from the given view does not contain
information for these surfaces.
To eliminate this problem makeProxyImages renders the complex object
several times for each view direction, each time removing parts that
obstruct some front facing triangles of the proxy. The textures assigned
to these triangles are added to the regular view (view of the object with
no parts removed) using texture palettizing algorithm. This algorithm
deals with triangular texture patches to reduce the required space. The
texture for backfacing polygons can be taken from the nearest view and
also added to the texture (optionally). At the end each view has
associated a single texture with it that contains texture patches for all
front-facing triangles of the proxy and those backfacing triangles that
can be visible from neighboring views.
It is possible that all the texture patches will not fit around the
original view. Right now those texture patches that do not fit are
ignored. In the final version they will be iteratively scaled untill
they fit.
Run makeProxyImages without any parameter to get the list of all command
line options.
SEE ALSO
pfBillboard, pfIBRtexture, pfAddGSet, pfRemoveGSet, pfChanTravMode,
pfFlatten, pfLookupNode, pfNodeTravFuncs, pfFlux, pfScene,
pfTransparency, pfDelete
Page 6