pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)NAMEpfASD - Create pfASD, specify pfASD properties.
FUNCTION SPECIFICATION
#include <Performer/pf/pfASD.h>
pfASD::pfASD();
static pfType * pfASD::getClassType(void);
void pfASD::setAttr(int _which,
int _bind, int _size,
void *_attr);
void pfASD::getAttr(int _which,
int *_bind, int *_size,
void **_attr);
void pfASD::setMorphAttrs(int _mc);
int pfASD::getMorphAttrs(void);
void -
pfASD::getActiveGeode(pfChannel *_chan,
pfList *_geom);
void pfASD::setNumBaseFaces(int num);
int pfASD::getNumBaseFaces(void);
void -
pfASD::setGStates(pfGeoState **gs,
int num);
void -
pfASD::getGStates(pfGeoState ***gs,
int *num);
pfGeoState* pfASD::getGState(int num);
int pfASD::getNumGStates();
void -
pfASD::setLODState(pfLODState *ls);
void pfASD::getLODState(void);
void -
pfASD::setLODStateIndex(int index);
Page 1
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
void pfASD::getLODStateIndex(void);
void -
pfASD::setSyncGroup(uint _syncGroup);
uint pfASD::getSyncGroup();
void pfASD::enableClipRings(void);
void -
pfASD::setNumClipRings(int _numrings);
int pfASD::getNumClipRings(void);
void -
pfASD::setClipRings(float *_rings);
float* pfASD::getClipRings(void);
void -
pfASD::setCalcVirtualClipTexParamsFunc(pfASDCalcVirtualClipTexParamsFuncType _func);
pfASDCalcVirtualClipTexParamsFuncType -
pfASD::getCalcVirtualClipTexParamsFunc(void);
void -
pfASD::setFaceBBoxes(pfBox *_box);
pfBox* pfASD::getFaceBBoxes(void);
void -
pfASD::setFaceBBox(pfBox *_facebbox,
int _faceid);
void -
pfASD::getFaceBBox(pfBox *_facebbox,
int _faceid);
void pfASD::setBBox(pfBox *_box);
void pfASD::getBBox(pfBox *_box);
void pfASD::config();
void pfASD::setMaxMorphDepth(int _m,
float _morphweightconstraint);
void pfASD::getMaxMorphDepth(int *_m,
float *_morphweightconstraint);
Page 2
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
void pfASD::setEvalMethod(int method);
int pfASD::getEvalMethod(void);
void -
pfASD::setEvalFunc(pfTerrainEvalFuncType _eval);
pfTerrainEvalFuncType pfASD::getEvalFunc(void);
void pfASD::setMask(uint _which,
uint _mask, int _id);
void pfASD::setCullEnlarge(float fov,
float near, float far);
void -
pfASD::setMorphWeight(int _vertid,
float _morphweight);
void -
pfASD::unsetMorphWeight(int _vertid);
void pfASD::initMask(uint _which);
void -
pfASD::clearAllMasks(uint _which);
int pfASD::isPaging(void);
int pfASD::isPageMaster(void);
void pfASD::initPaging(void);
void -
pfASD::setTileSize(float **_tsize);
float** pfASD::getTileSize(void);
void pfASD::setPageSize(int **_page);
int** pfASD::getPageSize(void);
void -
pfASD::setTotalTiles(short **_tilenum);
short** pfASD::getTotalTiles(void);
void -
pfASD::setMaxTileMemSize(int _tilefaces,
int _tileverts);
Page 3
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
void -
pfASD::getMaxTileMemSize(int *_tilefaces,
int *_tileverts);
void pfASD::setOrigin(pfVec3 *_min);
pfVec3* pfASD::getOrigin(void);
void -
pfASD::setPageFname(char *_fname);
char* pfASD::getPageFname(void);
virtual int -
pfASD::addQueryArray(float *_vertices,
float *_down,
int nofVertices, uint _mask,
pfFlux *_results);
virtual void -
pfASD::deleteQueryArray(int _index);
virtual void -
pfASD::setQueryArrayElement(int _arrayIndex,
int _elementIndex,
float *_vertex,
float *_down);
virtual void -
pfASD::getQueryArrayPositionSpan(int _index,
pfBox *_box);
unsigned long -
pfASD::ContainsQueryArray(pfASD *_asd,
float *_vertices,
float *_down,
int _nofVertices);
int -
pfASD::addQueryTriangles(float *_v,
float *_t, float *_c,
int _nofTriangles,
float *_base, float *_down,
float *_projection,
float *_azimuth,
unsigned long _opcode,
uint _mask,
pfFlux *_results);
void -
pfASD::deleteQueryGeoSet(int _index);
Page 4
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
int -
pfASD::addQueryGeoSet(pfGeoSet *gset,
float *_down, uint _mask,
pfFlux *_results);
void -
pfASD::replaceQueryGeoSet(int index,
pfGeoSet *gset,
float *_down);
void -
pfASD::projectPointFinestPositionNormal(float *_base,
float *_down,
unsigned long _flags,
float *_base_pos,
float *_base_normal);
void -
pfASD::projectPointFinestPosition(float *_base,
float *_down,
unsigned long _flags,
float *_base_pos);
void -
pfASD::getQueryArrayPositionSpan(int _index,
pfBox *_box);
PARENT CLASS FUNCTIONS
The OpenGL Performer class pfASD is derived from the parent class pfNode,
so each of these member functions of class pfNode are also directly
usable with objects of class pfASD. This is also true for ancestor
classes of class pfNode.
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);
Page 5
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
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 pfASD 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 pfASD 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);
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 pfASD is a pfNode which can handle the dynamic generation and morphing
geometry based on multiple LODs. pfASD contains a small scene graph that
is generated dynamically to reflect the changing geometry being rendered.
Active Surface Definition approach, models terrain as a single connected
Page 6
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
surface rather than using the traditional multiple-patch configuration.
The surface is modeled with several hierarchical level of detail meshes
in the special ASD data structures. In the real-time simulation, an ASD
evaluation process selects polygons from the appropriate LODs and
constructs a valid meshing to best approximate the visible terrain on the
screen based on criteria such as view point, viewing frustum, desired
polygon count, desired terrain fidelity, and similar factors. The
resulting mesh is the "active mesh" for the current evaluation. The
positions of vertices in the active mesh are smoothly morphed between
positions stored in the different LODs. The goal for ASD is to present a
visually realistic terrain with minimum geometry while simultaneously
allowing freedom of motion through the terrain with the maintenance of
visual fidelity. This eliminates artifacts such as instant LOD transition
popping, rigid patch boundaries, and limited size of textures. In
summary, the ASD system takes as input a hierarchical description of LODs
and a collection of predefined evaluation functions and produces active
meshes.
These routines implement the Active Surface Definition (ASD) feature.
ASD defines a hierarchical structure that organizes all the LODs of a
terrain. At run-time, ASD traverses the structure, selecting triangles
from different LODs to render the portion of the terrain that is within a
volume of interest. Triangles are rendered either at their pre-stored
locations, when they are in a particular LOD range, or at computed
morphed locations, when they are between the morphing ranges. There will
be other ways to evaluate the terrain other than purely range based
approach. These are also supported by ASD.
If the application directs Performer to fork a COMPUTE process, pfASD
evaluation runs asynchronously in that process. Otherwise, pfASD
evaluation runs in the APP process each frame. This evaluation can be
slow when using large pfASD models. Therefore, we recommend that
applications fork a COMPUTE process when using pfASD models. In order to
fork a COMPUTE process, the application should include the bit
PFMP_FORK_COMPUTE in the call to pfMultiprocess.
When run asynchronously, pfASD evaluation may take multiple APP/CULL/DRAW
frames. Performer merges the results of a pfASD evaluation frame into the
scene graph on a frame boundary, hence avoiding any visual artifacts.
The asynchronous nature of pfASD evaluation can cause culling artifacts:
pfASD computes the visible geometry for a given camera position. By the
time pfASD finishes evaluating, the camera moves and looks at a culled-
out portion of the pfASD surface. The display shows that a portion of the
pfASD geometry is missing.
In order to overcome this limitation, pfASD uses an enlarged viewing
frustum - larger than the current camera frustum. The larger the frustum,
the less culling artifacts it produces. However, the larger the frustum,
the less efficient pfASD culling is.
Here are the general rules for deciding how large the pfASD culling
Page 7
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
frustum should be: The slower pfASD evaluation is, the larger the
frustum should be. The faster the camera changes its direction, the
larger the frustum should be.
You can monitor the length of the pfASD evaluation process on the
Performer statistics display (look for the duration of the COMPUTE
process).
new pfASD creates and returns a handle to a pfASD. Like other pfNodes,
pfASDs are always allocated from shared memory and cannot be created
statically, on the stack or in arrays. pfASDs should be deleted using
pfDelete rather than the delete operator.
pfASD::getClassType returns the pfType* for the class pfASD. The pfType*
returned by pfASD::getClassType is the same as the pfType* returned by
invoking the virtual function getType on any instance of class pfASD.
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.
pfASD::setAttr sets up the database for terrain. which takes one of the 6
values: PFASD_LODS, PFASD_COORDS, PFASD_FACES, PFASD_PER_VERTEX_ATTR, or
PFASD_OVERALL_ATTR. type is a bit combination of PFASD_NORMALS,
PFASD_COLORS, and PFASD_TCOORDS that defined which attribute is described
in the attr list. size is the number of attributes and attr is the
pointer to the attribte list.
1. ASD face pfASDFace description:
The terrain database consists of several layers of triangle meshes that
are organized as a tree. For detailed explaination of the structure of
the database, please refer to Performer Programmer's Guide. The vertices
in each triangle must be arranged ccw. Let the three vetices be
vertex[0], vertex[1], and vertex[2]. The reference point i locates
between vertex[(i-1)%3] and vertex[i]. If the triangle is part of a
triangle strip, then the vertices should also be arranged such that
vertex[2] is the vertex used in the tstrip.
2. pfASDFace structure
struct pfASDFace
{
int level;
int tsid;
int vert[3];
int attr[3];
int refvert[3];
int sattr[3];
int child[4];
Page 8
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
ushort gstateid;
ushort mask;
} ;
Each face has an unique entry in this array, and the index is the faceID.
The LOD level in which this face is present is defined by level. The
entry tsid is the triangle strip ID of this face. The vertices and
reference points, vert[3] and refvert[3], are indices into the coordinate
array. The attr is the attribute index of the vertex, and sattr is the
attribute index of the reference point. The field child[4] is the 4
indices of the child nodes in the tree. If any of the entries is
missing, enter PFASD_NIL_ID in the field. ASD takes on an array of
geostates. Each face can point to 1 geostate. This is useful when the
terrain has multiple appearances, for example, multiple textures. The
gstateid is the index of the geostate. A face can be rendered as a
"hole", i.e. not drawn. This can be described by setting mask to
PFASD_FACE_NODRAW. Although a face is rendered as a "hole", its virtual
position can still be queried. If the position of the face should not be
used is alignment query, OR the mask with bit value PFASD_FACE_NOQUERY.
If mask is 0, then the face is drawn regularly and queried regularly.
1. When which is PFASD_COORDS, attr is the pointer to the pfASDVert
array.
struct pfASDVert
{
pfVec3 v0, vd;
int neighborid[2];
int vertid;
};
Each vertex i in the database has 2 values associated with it: v0 is the
final position of the vertex, and vd is the vector which is the
difference between the reference and final position. The index i is the
vertex id. Each vertex is a reference point on a unique edge. The edge
has two neighboring faces. The field neighborid[2] holds the indices of
the two neighboring faces.
2. When which is PFASD_PER_VERTEX_ATTR, attr is the pointer to an array
of attributes. Normal, color, and texture coordinates are defined in
this attribute array of interleaved floats. Each attribute has two
values, the final attribute and attribute change. The format of each
unit in this array is : n0(pfVec3, 3 floats), nd(pfVec3, 3 floats),
c0(pfVec4, 4 floats), cd(pfVec4, 4 floats), t0(pfVec2, 2 floats),
td(pfVec2, 2 floats). Any of the attributes can be missing from this
array. The type field defines which attributes are in the array. For
Page 9
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
example, if the array is a list of normal and texture coordinates, but no
color, then unit in the array looks like
n0 (3 floats)
nd (3 floats)
t0 (2 floats)
td (2 floats)
and type is PFASD_NORMALS | PFASD_TCOORDS
If there is only Normals in the attr list, then the unit will look like:
n0 (3 floats)
nd (3 floats)
and type is PFASD_NORMALS.
PFASD_PER_VERTEX_ATTR defines attributes for individual vertices. Each
vertex in ASD can have one attribute per face. For example, to describe a
very sharp edge, a vertex can have more than 1 normals. The attribute is
defined in each pfASDFace structure. The attr and sattr field are
indices into the units in the attribute array. They are morphed based on
the morph weight of the vertex.
3. When which is PFASD_OVERALL_ATTR, attr points to a set of attributes
describing the overall appearance of the terrain. This attribute can be
morphed as well.
Notice, there is only one PFASD_PER_VERTEX_ATTR attribute array for each
ASD, There is also only one OVERALL attribute array. The terrain can not
have both of them at the same time. Whichever is defined last will be
the effective appearance of the terrain. The attributes defined in attr
do not have to be morphing at the same time. User can require ASD to
morph only the color of each vertex but let vertex take on the final
normal value. See pfASDMorphAttrs for details.
4. size is the size of the input arrays.
5. ASD face pfASDFace description:
The terrain database consists of several layers of triangle meshes that
are organized as a tree. For detailed explaination of the structure of
the database, please refer to Performer Programmer's Guide. The vertices
in each triangle must be arranged ccw. Let the three vetices be
vertex[0], vertex[1], and vertex[2]. The reference point i locates
between vertex[(i-1)%3] and vertex[i]. If the triangle is part of a
triangle strip, then the vertices should also be arranged such that
vertex[2] is the vertex used in the tstrip.
6. pfASDFace structure
Page 10
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
struct pfASDFace
{
int level;
int tsid;
int vert[3];
int attr[3];
int refvert[3];
int sattr[3];
int child[4];
ushort gstateid;
ushort mask;
} ;
Each face has an unique entry in this array, and the index is the faceID.
The LOD level in which this face is present is defined by level. The
coarsest LOD is level 0. The entry tsid is the triangle strip ID of this
face. The vertices and reference points, vert[3] and refvert[3], are
indices into the coordinate array. The attr is the attribute index of
the vertex, and sattr is the attribute index of the reference point. The
field child[4] is the 4 indices of the child nodes in the tree. If any
of the entries is missing, enter PFASD_NIL_ID in the field. ASD takes on
an array of geostates. Each face can point to 1 geostate. This is useful
when the terrain has multiple appearances, for example, multiple
textures. The gstateid is the index of the geostate. A face can be
rendered as a "hole", i.e. not drawn. This can be described by setting
mask to PFASD_FACE_NODRAW. Although a face is rendered as a "hole", its
virtual position can still be queried. If the position of the face should
not be used is alignment query, OR the mask with bit value
PFASD_FACE_NOQUERY. If mask is 0, then the face is drawn regularly and
queried regularly.
Notice that although the reference position and the final position can be
different for a vertex, they are all referenced by the same index in the
vertex array. Therefore the reference field in the pfASDFace structure
should be the same as the vert field in another pfASDFace structure if
they all refer to the same vertex. It is very important that each vertex
and face must have an unique vertex ID and face ID.
OpenGL Performer provides a default evaluation function to calculate the
morph weight of each edge in the database. When user chooses to use this
function, a set of LOD switch ranges needs to be entered. When which is
PFASD_LODS, attr is a pointer to the pfASDLODRange lod array. size is the
number of lod levels in the database. The pfASDLODRange structure is
struct pfASDLODRange
{
float switchin;
float morph;
} ;
Page 11
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
Inside a pfASDLODRange structure, switchin is the "far" range. If the
distance from the eyepoint to the final position of a vertex of a face at
level i is less than switchin[i], than the LODi edge associated with this
vertex will be replaced by edges from the next LOD. (See
pfTerrainEvalMethod for more details).
The morphing distance morph decides how close a vertex will morph to its
final position. When the distance is less than switchin[i] - morph[i],
the vertex is completely morphed to its final position.
The LOD range can be adjusted at run time. It could be adjusted based on
channel information, scene information, or stress, to name a few.
Among all the attributes, only LODRange can be changed at run time. The
rest of Attrs are "read-only" data, i.e., there is no internal copies of
the data. LODRange is copied internally, and user can make changes on the
copy of LODRange returned by pfASDGetAttr.
TRIANGLE STRIPS
Mesh triangles in each individual LOD separately. Assign an unique tstrip
ID to each triangle. Make sure triangles in the same tstrip have
contiguous IDs. Tstrip ID ranges between tstrips are not continuous. For
example: tstrip (f1, f2, f3, f4) and tstrip (f6, f7, f8) might have IDs
like f1 = 10, f2 = 11, f3 = 12, f4 = 13; and f6 = 20, f7 = 21, f8 = 22.
but they can't have f1 = 10, f2 = 11, f3 = 12, f4 = 13; and f6 = 14, f7 =
15, f8 = 16;
It is very important to start a tstrip on an even tstrip ID. For
example, triangles in the first tstrip can have IDs 0,1,2...; but they
can't have 1,2,3,...
Triangles will be sorted at run time by their tstrip ID to determine the
meshing. The field tsid in face structure is the tstrip ID.
pfASD::setNumBaseFaces sets the total number of faces on the base (the
coarsest) level of detail. The faces on the first LOD (LOD0) must be
listed at the beginning of face array. Other faces can be listed in any
order. We recommand listing faces that are in the same LOD together.
pfASD::setMorphAttrs sets the attributes to be morphed. _mc is a bit
combination of PFASD_NORMALS, PFASD_COLORS, or PFASD_TCOORDS. The
attributes set by the pattern will be morphed on a per vertex per face
level based on morphing weights. If there is no attributes to be
morphed, set _mc to PFASD_NO_ATTR. If pfASDMorphAttrs is not called, ASD
morphes the PFASD_PER_VERTEX_ATTR attributes.
pfASD::getMorphAttrs returns the bit mask that describes the morphing
attributes.
pfASD::setEvalMethod
Page 12
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
pfASD::getEvalMethod method identifies the morphing weight calculation at
each point. PFASD_DIST makes morphing weight linear to the real
distance.
morphing weight = 1 - (switchin - dist)/morph;
PFASD_DIST2 uses square of distance instead of real distance.
morphing weight = 1 - (switchin - dist_square)/ (morph*morph);
PFASD_DIST is chosen by default. When PFASD_DIST2 is picked, the switchin
and morph on each LOD is sqaured internally. The input array of LODRange
is left untouched.
pfASD::getActiveGeom fills a pointer _geom to a List of pfGroup pointers
which contain the active geometry (active mesh) that is the result of
current ASD evaluation. Since ASD evaluation is done on a per channel
bases, the geometry corresponds to that being displayed in that channel
chan. geom is a user allocated pfList * whose element is a pfGroup
pointer.
pfASD::setGStates defines the pfGeoState list that is associated with
pfASD. Each triangle face in pfASD can take on a separate pfGeoState.
gstateid in the pfASDFace is an index into the pfGeoState list gs. num is
the size of the geostate list. The active geometry generated by ASD
evaluation are sorted into GeoSets based on the GeoStates. The GeoState
list is not copied into pfASD internally.
pfASD::getGStates returns the pointer to pfGeoState list and the size of
the list.
pfASD::getGState returns a particular pfGeoState in the pfGeoState list
indexed by num.
pfASD::getNumGStates returns the size of the pfGeoState list.
pfASD::setLODState associates the given pfASD and pfLODState. This
enables the control of how a particular pfASD LODRange responds to stress
and range. pfASD::getLODState returns the pfLODState associated with
pfASD if there is one or NULL if one does not exist. The LODState
parameters rangeRangeA modifies the channel LODscale and rangeRangeB
offsets the result. If you do not want channel LODscale to affect
LODRange, simple set the parameter[rangeRangeA] to 0 and
parameter[rangeRangeB] to 1.0. Similarly, parameters rangeFOVA and
rangFOVB modefied the channel aspect ratio affects LODRanges. To disable
the FOV influence on LODRange, set parameter[rangeFOVA] to 0 and
parameter[rangeFOVB] to 1.0. Currently, channel stress does not affect
LODRanges.
pfASD::setLODStateIndex allows pfLODStates to be indexed on a per channel
Page 13
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
basis. index is an index into an pfList of pfLODStates specified via
pfChannel::setLODStateList. pfASD::getLODStateIndex returns the index
currently specified for the pfASD or -1 if no index has been specified.
pfASD::enableClipRings turns on the clipring mode in pfASD for virtual
cliptxture. pfASD will sort the active mesh into several groups of
geometry each of which is inside one of the set of concentric bounded
rings around eye point. Currently the concentric rings are bounded by
switchin fields in pfLODRange arrays. As eyepoint moves in application,
the coordinates of the rings change too in real-time. If the smallest
ring is not fine enough for the high resolution cliptexture, more rings
can be specified by enlarge the pfLODRange size. Refer to
pfdASDClipring.c for example. User needs to allocate some additional
LODRanges in order for pfASD to sort things into cliprings. Currently,
this API is all that is needed to make pfASD and virtual cliptexture work
together.
pfASD::setNumClipRings specifies the number of cliprings. This API is not
active.
pfASD::getNumClipRings return the number of cliprings. This API is not
active.
pfASD::setClipRings This API is not active.
pfASD::getClipRings This API is not active.
pfASD::setCalcVirtualClipTexParamsFunc User callback function to define
the virtual cliptexture parameters. The format is the same as the
function in pfutil.
pfASD::getCalcVirtualClipTexParamsFunc returns the user callback function
that defines the virtual cliptexture parameters.
pfASD::setFaceBBoxes ASD keeps a bounding box tree that coresponds to the
pfASDFace tree. The bounding box of a face bounds all of its possible
positions and all the bounding boxes of its children. User can enter a
full bounding box array _box. The box with index i is the bounding box of
pfASDFace i. If _box is NULL, ASD computes the bounding boxes. Since
faces are "read-only", ASD will not allocate internal space if _box is
not NULL.
pfASD::getFaceBBoxes returns the pointer to the bounding box array.
Each bounding box of a particular face can be set or queried by calling
pfASD::setFaceBBox or pfASD::getFaceBBox.
pfASD::config should be called after user has set all the attributes of a
pfASD node, i.e. face, vertices, attributes, and basefaces. The routine
computes the bounding box array for the pfASD node and does other time
consuming data structure changes before the real-time evaluation starts.
The rountine should be called before alignment objects are registered to
Page 14
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
this node.
pfASD::setMaxMorphDepth restricts the ASD evaluation to be carried out to
certain LOD level with morphweight no less than _morphweightconstraint.
_m is the level, with base level at LOD0. Notice that in ASD, morphweight
0 means a vertex is in its fully morphed final position, and 1 means the
vertex is in NO_MORPH, reference position. Therefore a morph weight less
than certain number implies that the vertex is not morphed further than
that constraint. For example: _m is 4, _morphweightconstraint is 0.3
means the finest triangle possible in current active mesh is from LOD 4,
with its vertices at 0.3 away from their final positions. Refer to
asdfly/terrain.c for examples. This API is useful for stress load
control.
The maximum evaluation LOD depth and morphweightconstraint can be queried
using pfASD::getMaxMorphDepth.
pfASD::setEvalFunc pfASD::getEvalFunc
typedef float (*pfTerrainEvalFuncType)(pfTerrain *mesh, int faceid, int refvertid).Ee
The vertex in the database is evaluated by eval. eval is a user
defined callback function that returns a float between 0 and 1. 1
means the edge in the current LOD associated with this vertex is not
replaced. Any number less than 1 means the edge is replaced by 2
edges from the next LOD. 0 means the vertex is at its final
position. A number in (0, 1) is used as the morph weight to
determine the position of the vertex by linearly interpolate using
its final position and its delta vector.
OpenGL Performer provides a default evaluation function which is
purely based on distance from the eyepoint to the final position of
the new vertex associated with the edge. The distance is compared
with the range in pfASDLODRange that is entered in pfASDAttr. The
edge of a face on lod level i is evaluated using range[i+1] in
pfsLODRange. To use the default evaluation function, do not call
pfASDEvalFunc.
pfASDEvalFuncType takes as arguments faceid which identifies the
face of which the edge is evaluated. refvertid is the index of the
vertex whose reference position is on this edge.
pfASD::initMask
pfASD::setMask
pfASD::clearAllMasks A set of routines to override the morphing of
certain vertices or the draw mode of certain faces. pfASDInitMask
indicates whether the user wants to override vertex mode or face
mode. This call should be made once before any override masks are
set. which can be PFASD_TRAV_VERTEX or PFASD_TRAV_FACE. When which
Page 15
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
is PFASD_TRAV_VERTEX, a vertex can be marked completely morphed or
not allowed to morph by setting mask to either PFASD_C_MORPH or
PFASD_NO_MORPH respectively.id is the index of the vertex. If a
vertex is marked PFASD_C_MORPH, then all of vertices in its parent
triangles are marked PFASD_C_MORPH recursively. The result is the
vertex will definitely be rendered at its final position if it is
within the culling polytope. When which is PFASD_TRAV_FACE, a face
can be rendered as a hole by setting mask to PFASD_FACE_NODRAW. id
is the index of the face in the faces array. pfASDClearAllMasks
reset all the masks to 0.
pfASD::setMorphWeight
pfASD::unsetMorphWeight can set the morph weight for any vertex.
Notice that pfASD does not take care of marking the associated
vertices. Users are responsible for setting the correct morphing
weights for all the vertices involved to make sure the vertex will
be rendered. vertid is the index of the vertex, and morphweight is
the morphing weight that is between 0 and 1.
pfASD::setCullEnlarge sets the culling frustum of ASD evaluation.
The FOV of this frutum is fov * FOV of viewing frustum. The near
clipping plane is moved closer the view point by near ratio.
Similarly, the far clipping plane is far * far clipping plane of
viewing frustum. This routine can be called at run time to adjust
the culling in response to load stress.
pfASD supports multi-resolution paging. The format of a paging file
is
int numfaces
int numverts
/* numfaces of the following */
int faceid1
pfASDFace face <--- structure of the face faceid1
int faceid2
pfASDFace face <--- structure of the face faceid2
/* numfaces of the following */
pfBox box <-- face bounding box of faceid1
pfBox box <-- face bounding box of faceid2
/* numverts of the following */
int vertid1
pfASDVert vert <-- structure of vertex vertid1
int vertid2
pfASDVert vert <-- structure of vertex vertid2
pfASD::isPaging returns TRUE is the pfASD node is paging database;
Page 16
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
returns FALSE is all of the data is in memory.
pfASD::isPageMaster Multiple ASD nodes can share paged database
through cloning. The node that initializes paging by calling
pfASDInitPaging is the pageMaster and is responsible for bringing in
data from disk. All other nodes will use the data that is being
paged. This function returns TRUE if the node issues paging
requests.
pfASD::initPaging is called at data loading time to indicate this
node is going to be paging data.
pfASD::setTileSize Every LOD of the database is subdivided into
grided tiles. Each tile is a rectangle in terrain. Tile in
different LOD has different size. This size is measured in object
space. _tsize is an array of 2 floats. The _tsize[i] is the
dimension of tiles in LODi. _tsize[i][0] is the length is x
dimension and _tsize[i][1] is that in y. The size of the array
should be number of LODs in pfASD.
pfASD::getTileSize returns the pointer to the tilesize array.
pfASD::setPageSize A page is a paging unit that contains pfASDFaces
and pfASDVerts that are located inside a tile. The paging is
scheduled according to the paging center, which currently is
eyepoint projected onto x-y plane, and offset defined by _page. In
any LODi, let paging center falls inside tile[x][y], then the tiles
to be resident in memory are
tile[x-_page[i][0]][y-_page[i][1]], tile[x-_page[i][0]+1],[y-_page[i][1]],
tile[x+_page[i][0]][y+_page[i][1]]
This paging is done for every LOD.
In the other words, we page in all tiles centered around the paging
center, with index offset within _page.
pfASD::getPageSize returns the paging offset array.
pfASD::setTotalTiles This function sets the total number of tiles in
the database. _tilenum is an array of 2 shorts. The length of the
array is number of LODs in pfASD. The 2 shorts describe the number
of tiles in x and y dimension in that particular LOD.
pfASD::getTotalTiles returns a pointer to the total tile size.
pfASD::setMaxTileMemSize This function sets the maximum memory for a
tile among all the tiles in all the LODs. _tilefaces is the maximum
faces a tile can possibly contain in the database. _tileverts is the
maximum vertices.
Page 17
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
pfASD::getMaxTileMemSize requires the maximum faces and vertices a
tile could contain in the database.
pfASD::setOrigin This function sets the lower left corner of each
LOD in the database. _min is an array of pfVec3 that describes the
the corner of tile[0][0] in each LOD. This set of numbers is given
in object space.
pfASD::getOrigin queries the corners of each LOD.
pfASD::setPageFname enters the basename of all paging files on disk.
Each file is a paging unit that refers to a tile of a particular LOD
in the database. The filenames are constructed as
"basename%02d%03d%03d.asd". the first 2 digits describes the LOD
level. the next 3 digits describes the tile index in x dimension,
and the last 3 digits describes tile index in y dimension. Notice
the pageName is a simple pointer copy instead of copy-by-value.
pfASD::getPageFname returns the basename of paging files on disk.
pfASD supports queries for point location on the morphing surface.
Given a query point and a vector pointing downwards from that point,
pfASD can calculate the projection of this point in the specified
down direction onto the surface. Note that the projection of the
query point may vary between frames according to the morphing
behavior of the pfASD surface. For each query point, pfASD can
calculate the position and plane normal at the projection point.
Point queries are relevant only in visible parts of the surface.
pfASD does not perform surface morphing evaluation outside of the
culling frustum. pfASD faces with a mask bit PFTERRAIN_FACE_NOQUERY
set do not participate in the query calculation. This way, the
application can switch faces into or out of the query mechanism.
Note that pfASD does not exclude faces with the
PFTERRAIN_FACE_NODRAW bit set from the query calculation, therefore
one can turn a face off for drawing, replace it with some coplanar
geometry, and continue to query the original pfASD face.
pfASD::addQueryArray adds an array of query points to pfASD. It
expects two arrays of 3D vectors: vertices and down containing
nofVertices (x,y,z) triplets each. pfASD calculates the results for
each query point after it pfASD finished its surface evaluation.
Query results are reported by packing them into the supplied pfFlux
_results. mask specifies the type of query results desired. It is a
bitwise OR of the following constants:
PR_QUERY_FRAME
make the first 8 bytes in the returned array contain the
time of the view parameters for this query array result.
Page 18
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
PR_QUERY_RECORD_FRAME
For each query point, store a double word aligned double
precision float containing the time of the view parameters
when the query results for this point were calculated.
Note that the same query result array may contain query
results of different ages because when pfASD can not reply
to a query, we return the most recent query results for
this point. pfASD can not reply to queries about points
outside the viewing frustum.
PR_QUERY_POSITION
- For each query point, store three floats containing
x,y,z coordinates of the projected point.
PR_QUERY_NORMAL
- For each query point, store three floats containing the
surface normal at the projection point.
Query point results are packed into the result array by storing all
the results for each point in the above order, following by all the
result for the next point. For example, for a mask of (-
PR_QUERY_RECORD_FRAME | PR_QUERY_FRAME | PR_QUERY_NORMAL), For a
query array containing three query points, the returned query result
pfFlux shall be packed as follows:
Word Contents
_____________________________________
0 Frame Time (0)
1 Frame Time (1)
2 Record#0 Time(0)
3 Record#0 Time(1)
4 Normal#0 X
5 Normal#0 Y
6 Normal#0 Z
7 Nothing (doubleword alignment)
8 Record#1 Time(0)
9 Record#1 Time(1)
10 Normal#1 X
11 Normal#1 Y
12 Normal#1 Z
13 Nothing (doubleword alignment)
14 Record#2 Time(0)
15 Record#2 Time(1)
16 Normal#2 X
17 Normal#2 Y
18 Normal#2 Z
|
pfASD::addQueryArray returns a unique number identifying the query
array. This number identifies this array for other pfASD routines
such as pfASD::deleteQueryArray.
pfASD::deleteQueryArray deletes a previously added query point
Page 19
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
array. index is the number returned by pfASD::addQueryArray.
pfASD::getQueryArrayPositionSpan returns the maximum bounding box of
all the query points in a query array with the given index. This
bounding box contains all the possible positions of the query points
for all possible surface morphing states.
pfASD::containsQueryArray takes an array of 3D points, and a
corresponding array of down vectors. It checks each point
individually and composes a result. Each point can be one of the
following:
1. Projects on some level-zero face. For each face it
projects onto, if this face has higher level children, it
projects on at least one of them (denote: always
contained).
2. Projects on some level-zero face. There exists a face with
children in the pfASD structure, such that the point
projects on the face but not on any of its children or on
the children of its direct neighbors (denote: maybe
contained).
3. Does not project on any level-zero face (denote: never
contained).
The following table shows the returned values of
pfASD::containsQueryArray. The three leftmost columns describe the
results of the single point queries. If at least one point returned
a given value, its corresponding column is set to 1.
Always Maybe Never Returned
_____________________________________________________________
0 0 0 PFIS_FALSE
0 0 1 PFIS_FALSE
0 1 0 PFIS_MAYBE
0 1 1 PFIS_MAYBE
1 0 0 PFIS_MAYBE | PFIS_TRUE | PFIS_ALL_IN
1 0 1 PFIS_MAYBE | PFIS_TRUE
1 1 0 PFIS_MAYBE | PFIS_TRUE
1 1 1 PFIS_MAYBE | PFIS_TRUE
|
|
|
pfASD supports the projection and tessellation of triangles onto the
currently visible pfASD surface. The results of such queries are
useful for casting the shadow of objects on the pfASD surface, and
for adding surface decals. Similar to query vertices, the
calculation of triangle query results ignores pfASD faces with a
mask bit PFTERRAIN_FACE_NOQUERY set.
pfASD::addQueryGeoSet adds the triangles in a pfGeoSet to pfASD.
_gset is a pfGeoSet containing triangle primitives. The query
Page 20
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
result for each triangle is the projection (in direction _down) of
the triangle onto the current pfASD geometry, tessellated to match
the ASD surface tessellation. pfASD generates query results after
evaluating its own geometry. it stores the results in the pfFlux
_results.
If _results is a fluxed pfGeoset, pfASD::addQueryGeoSet stores
results as pfGeoSet attributes according to _mask (see below). It
takes care of allocating memory for NULL attributes, and
reallocating it if it has too many result triangles. It also sets
the number of primitives in the pfGeoSet to the number of triangle
fragments in the query result. The query mechanism generates
pfGeoSet attributes ready for hooking onto a pfGeode for drawing.
However, the query mechanism does not set any other pfGeoSet
attributes (e.g. Primitive type, Bounding box, pfGeoState, any
overall attributes).
The contents of the query results is determined by the type of
information requested. _mask specifies the type of query results
desired. It is a bitwise OR of the following constants:
PR_QUERY_FRAME
- Store the query frame as a double-word at the head of
the result pfFlux buffer.
PR_QUERY_TRI_COORD
- For each query triangle, store three floats containing
x,y,z coordinates of the projected point.
PR_QUERY_TRI_TEXTURE
- For each vertex in the tessellated projected triangle,
store two floats containing the interpolated texture
coordinates at the projection point.
PR_QUERY_TRI_COLOR
- For each vertex in the tessellated projected triangle,
store four floats containing the interpolated RGBA color
at the projection point.
PR_QUERY_TRI_NORMAL
- For each vertex in the tessellated projected triangle,
store three floats containing the interpolated normal at
the projection point.
If _results is a fluxed pfGeoset, the bit PR_QUERY_FRAME is ignored.
The input pfGeoSet must contain the requested attributes. An input
number of triangles can generates many tessellated triangles, In a
regular result pfFlux, the query mechanism will generate triangles
to fill the input pfFlux without overflow. Any remaining triangles
will be ignored. It is the responsibility of the calling
Page 21
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
application to allocate a large enough pfFlux buffer. Following is
an example of the result flux format for regular pfFlux result
buffer (not a fluxed pfGeoSet): If _mask is (PR_QUERY_FRAME |
PR_QUERY_TRI_COORD | PR_QUERY_TRI_TEXTURE), the format of the output
pfFlux is (assume the query result contains two triangles):
Word Contents
_______________________________________
0 Frame Time (0)
1 Frame Time (1)
2 Number of result triangles (= 2)
3 Vertex (Tri 0, v0, X)
4 Vertex (Tri 0, v0, Y)
5 Vertex (Tri 0, v0, Z)
60 Texture (Tri 0, v0, s)
7 Texture (Tri 0, v0, t)
8 Vertex (Tri 0, v1, X)
9 Vertex (Tri 0, v1, Y)
10 Vertex (Tri 0, v1, Z)
11 Texture (Tri 0, v1, s)
12 Texture (Tri 0, v1, t)
13 Vertex (Tri 0, v2, X)
14 Vertex (Tri 0, v2, Y)
15 Vertex (Tri 0, v2, Z)
16 Texture (Tri 0, v2, s)
17 Texture (Tri 0, v2, t)
18 Vertex (Tri 1, v0, X)
19 Vertex (Tri 1, v0, Y)
20 Vertex (Tri 1, v0, Z)
21 Texture (Tri 1, v0, s)
22 Texture (Tri 1, v0, t)
23 Vertex (Tri 1, v1, X)
24 Vertex (Tri 1, v1, Y)
25 Vertex (Tri 1, v1, Z)
26 Texture (Tri 1, v1, s)
27 Texture (Tri 1, v1, t)
28 Vertex (Tri 1, v2, X)
29 Vertex (Tri 1, v2, Y)
30 Vertex (Tri 1, v2, Z)
31 Texture (Tri 1, v2, s)
32 Texture (Tri 1, v2, t)
|
The current implementation supports queries of tessellated triangle
vertex and texture only. queries of tessellated color and normal
will be added in the future.
pfASD::deleteQueryGeoSet removes the query pfGeoSet with index
_index.
pfASD::replaceQueryGeoSet replaces the query pfGeoSet with index
_index by the input pfGeoset gset. It also sets the down direction
Page 22
pfASD(3pf) OpenGL Performer 3.2.2 libpf C++ Reference Pages pfASD(3pf)
to down.
pfASD::setSyncGroup defines a synchronization group for fluxed query
arrays. Using a syncGroup an application can synchronize the
insertion point of all pfASD related evaluation results: pfASD
geometry and pfASD query arrays. When using a syncGroup, all pfASD
evaluation results become available on the same frame boundary. For
example: A model of a car is attached to a query point on a pfASD
model. As the pfASD geometry morphs, the query point moves and the
car model follows the terrain. Without a syncGroup, the car and
terrain position may be off by a few frames. Such artifacts make the
car float-over or sink-into the terrain surface.
pfASD::getSyncGroup returns the synchronization group that this
pfASD uses.
Notice, pfASD works in multipipe and multichannel environments.
Please refer to pfChannel for details.
SEE ALSO
pfNode, pfGeode, pfFlux, pfGeoState, pfChannel, pfdAlignVerticesToASD,
pfdProjectVerticesOnASD.
Page 23