pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)NAME
pfNewASD, pfGetASDClassType, pfASDAttr, pfGetASDAttr, pfASDMorphAttrs,
pfGetASDMorphAttrs, pfGetASDActiveGeom, pfASDNumBaseFaces,
pfGetASDNumBaseFaces, pfASDGStates, pfGetASDGStates, pfGetASDGState,
pfGetASDNumGStates, pfASDLODState, pfGetASDLODState, pfASDLODStateIndex,
pfGetASDLODStateIndex, pfASDSyncGroup, pfGetASDSyncGroup,
pfASDEnableClipRings, pfASDNumClipRings, pfASDClipRings,
pfGetASDClipRings, pfGetASDNumClipRings,
pfASDCalcVirtualClipTexParamsFunc, pfGetASDCalcVirtualClipTexParamsFunc,
pfASDFaceBBoxes, pfGetASDFaceBBoxes, pfASDFaceBBox, pfGetASDFaceBBox,
pfASDBBox, pfGetASDBBox, pfASDConfig, pfASDMaxMorphDepth,
pfGetASDMaxMorphDepth, pfASDEvalMethod, pfGetASDEvalMethod,
pfASDEvalFunc, pfGetASDEvalFunc, pfASDMask, pfASDCullEnlarge,
pfASDMorphWeight, pfASDUnsetMorphWeight, pfASDInitMask,
pfASDClearAllMasks, pfASDIsPaging, pfASDIsPageMaster, pfASDInitPaging,
pfASDTileSize, pfGetASDTileSize, pfASDPageSize, pfGetASDPageSize,
pfASDTotalTiles, pfGetASDTotalTiles, pfASDMaxTileMemSize,
pfGetASDMaxTileMemSize, pfASDOrigin, pfGetASDOrigin, pfASDPageFname,
pfGetASDPageFname, pfASDAddQueryArray, pfASDDeleteQueryArray,
pfASDQueryArrayElement, pfASDContainsQueryArray, pfASDAddQueryTriangles,
pfASDDeleteQueryGeoSet, pfASDAddQueryGeoSet, pfASDReplaceQueryGeoSet,
pfASDProjectPointFinestPositionNormal, pfASDProjectPointFinestPosition,
pfASDGetQueryArrayPositionSpan - Create pfASD, specify pfASD properties.
FUNCTION SPECIFICATION
#include <Performer/pf.h>
pfASD* pfNewASD(void);
pfType* pfGetASDClassType(void);
void pfASDAttr(pfASD* _asd,
int _which, int _type,
int _size, void *_attr);
void pfGetASDAttr(pfASD* _asd,
int _which, int *_type,
int *_size, void **_attr);
void pfASDMorphAttrs(pfASD* _asd,
int _mc);
int pfGetASDMorphAttrs(pfASD* _asd);
void pfGetASDActiveGeom(pfASD* _asd,
pfChannel *_chan,
pfList *_geom);
void pfASDNumBaseFaces(pfASD* _asd,
int num);
Page 1
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
int -
pfGetASDNumBaseFaces(pfASD* _asd);
void pfASDGStates(pfASD* _asd,
pfGeoState **gs, int num);
void pfGetASDGStates(pfASD* _asd,
pfGeoState ***gs, int *num);
pfGeoState* pfGetASDGState(pfASD* _asd,
int num);
int pfGetASDNumGStates(pfASD* _asd);
void pfASDLODState(pfASD *_asd,
pfLODState *ls);
void pfGetASDLODState(pfASD *_asd);
void pfASDLODStateIndex(pfASD *_asd,
int index);
void -
pfGetASDLODStateIndex(pfASD *_asd);
void pfASDSyncGroup(pfASD* _asd,
uint _syncGroup);
uint pfGetASDSyncGroup(pfASD* _asd);
void -
pfASDEnableClipRings(pfASD* _asd);
void pfASDNumClipRings(pfASD* _asd,
int _numrings);
void pfASDClipRings(pfASD* _asd,
float *_rings);
float* pfGetASDClipRings(pfASD* _asd);
int -
pfGetASDNumClipRings(pfASD* _asd);
void -
pfASDCalcVirtualClipTexParamsFunc(pfASD* _asd,
pfASDCalcVirtualClipTexParamsFuncType _func);
pfASDCalcVirtualClipTexParamsFuncType -
pfGetASDCalcVirtualClipTexParamsFunc(pfASD* _asd);
Page 2
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
void pfASDFaceBBoxes(pfASD* _asd,
pfBox *_box);
pfBox* pfGetASDFaceBBoxes(pfASD* _asd);
void pfASDFaceBBox(pfASD* _asd,
pfBox *_facebbox,
int _faceid);
void pfGetASDFaceBBox(pfASD* _asd,
pfBox *_facebbox,
int _faceid);
void pfASDBBox(pfASD* _asd,
pfBox *_box);
void pfGetASDBBox(pfASD* _asd,
pfBox *_box);
void pfASDConfig(pfASD* _asd);
void pfASDMaxMorphDepth(pfASD* _asd,
int _m,
float _morphweightconstraint);
void -
pfGetASDMaxMorphDepth(pfASD* _asd,
int *_m,
float *_morphweightconstraint);
void pfASDEvalMethod(pfASD* _asd,
int method);
int pfGetASDEvalMethod(pfASD* _asd);
void pfASDEvalFunc(pfASD* _asd,
pfTerrainEvalFuncType _eval);
pfTerrainEvalFuncType pfGetASDEvalFunc(pfASD* _asd);
void pfASDMask(pfASD* _asd,
uint _which, uint _mask,
int _id);
void pfASDCullEnlarge(pfASD* _asd,
float fov, float near,
float far);
void pfASDMorphWeight(pfASD* _asd,
int _vertid,
float _morphweight);
Page 3
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
void -
pfASDUnsetMorphWeight(pfASD* _asd,
int _vertid);
void pfASDInitMask(pfASD* _asd,
uint _which);
void pfASDClearAllMasks(pfASD* _asd,
uint _which);
int pfASDIsPaging(pfASD* _asd);
int pfASDIsPageMaster(pfASD* _asd);
void pfASDInitPaging(pfASD* _asd);
void pfASDTileSize(pfASD* _asd,
float **_tsize);
float** pfGetASDTileSize(pfASD* _asd);
void pfASDPageSize(pfASD* _asd,
short **_page);
short** pfGetASDPageSize(pfASD* _asd);
void pfASDTotalTiles(pfASD* _asd,
short **_tilenum);
short** pfGetASDTotalTiles(pfASD* _asd);
void pfASDMaxTileMemSize(pfASD* _asd,
int _tilefaces,
int _tileverts);
void -
pfGetASDMaxTileMemSize(pfASD* _asd,
int *_tilefaces,
int *_tileverts);
void pfASDOrigin(pfASD* _asd,
pfVec3 *_min);
pfVec3* pfGetASDOrigin(pfASD* _asd);
void pfASDPageFname(pfASD* _asd,
char *_fname);
char* pfGetASDPageFname(pfASD* _asd);
Page 4
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
int pfASDAddQueryArray(pfASD* _asd,
float *_vertices,
float *_down,
int nofVertices, uint _mask,
pfFlux *_results);
void -
pfASDDeleteQueryArray(pfASD* _asd,
int _index);
void -
pfASDQueryArrayElement(pfASD* _asd,
int _arrayIndex,
int _elementIndex,
float *_vertex,
float *_down);
unsigned long -
pfASDContainsQueryArray(pfASD* _asd,
float *_vertices,
float *_down,
int _nofVertices);
int -
pfASDAddQueryTriangles(pfASD* _asd,
float *_v, float *_t,
float *_c, int _nofTriangles,
float *_base, float *_down,
float *_projection,
float *_azimuth,
unsigned long _opcode,
uint _mask,
pfFlux *_results);
void -
pfASDDeleteQueryGeoSet(pfASD* _asd,
int _index);
int pfASDAddQueryGeoSet(pfASD* _asd,
pfGeoSet *gset, float *_down,
uint _mask,
pfFlux *_results);
void -
pfASDReplaceQueryGeoSet(pfASD* _asd,
int index, pfGeoSet *gset,
float *_down);
void -
pfASDProjectPointFinestPositionNormal(pfASD* _asd,
float *_base, float *_down,
unsigned long _flags,
Page 5
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
float *_base_pos,
float *_base_normal);
void -
pfASDProjectPointFinestPosition(pfASD* _asd,
float *_base, float *_down,
unsigned long _flags,
float *_base_pos);
void -
pfASDGetQueryArrayPositionSpan(pfASD* _asd,
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. Casting an object of class pfASD to
an object of class pfNode is taken care of automatically. This is also
true for casts to objects of ancestor classes 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 pfASD can also be used with these functions designed for
objects of class pfObject.
Page 6
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(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 pfASD 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);
PARAMETERS
asd identifies a pfASD.
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
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
Page 7
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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
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).
pfNewASD creates and returns a handle to a pfASD. Like other pfNodes,
pfASDs are always allocated from shared memory and can be deleted using
pfDelete.
Page 8
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
pfGetASDClassType returns the pfType* for the class pfASD. The pfType*
returned by pfGetASDClassType is the same as the pfType* returned by
invoking pfGetType 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 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.
pfASDAttr 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];
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
Page 9
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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
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:
Page 10
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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
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;
Page 11
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
} ;
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;
} ;
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],
Page 12
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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.
pfASDNumBaseFaces 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.
pfASDMorphAttrs 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.
pfGetASDMorphAttrs returns the bit mask that describes the morphing
attributes.
pfASDEvalMethod
pfGetASDEvalMethod 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.
Page 13
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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.
pfGetASDActiveGeom 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.
pfASDGStates 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.
pfGetGStates returns the pointer to pfGeoState list and the size of the
list.
pfGetASDGState returns a particular pfGeoState in the pfGeoState list
indexed by num.
pfGetASDNumGStates returns the size of the pfGeoState list.
pfASDLODState associates the given pfASD and pfLODState. This enables
the control of how a particular pfASD LODRange responds to stress and
range. pfGetASDLODState 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.
pfASDLODStateIndex allows pfLODStates to be indexed on a per channel
basis. index is an index into an pfList of pfLODStates specified via
pfChanLODStateList. pfGetASDLODStateIndex returns the index currently
specified for asd or -1 if no index has been specified.
pfASDEnableClipRings 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
Page 14
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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.
pfASDNumClipRings specifies the number of cliprings. This API is not
active.
pfGetASDNumClipRings return the number of cliprings. This API is not
active.
pfASDClipRings This API is not active.
pfGetASDClipRings This API is not active.
pfASDCalcVirtualClipTexParamsFunc User callback function to define the
virtual cliptexture parameters. The format is the same as the function in
pfutil.
pfGetASDCalcVirtualClipTexParamsFunc returns the user callback function
that defines the virtual cliptexture parameters.
pfASDFaceBBoxes 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.
pfGetASDFaceBBoxes returns the pointer to the bounding box array.
Each bounding box of a particular face can be set or queried by calling
pfASDFaceBBox or pfGetASDFaceBBox.
pfASDConfig 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
this node.
pfASDMaxMorphDepth 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,
Page 15
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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 pfGetASDMaxMorphDepth.
pfASDEvalFunc pfGetASDEvalFunc
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.
pfASDInitMask
pfASDMask
pfASDClearAllMasks 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
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.
Page 16
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
pfASDMorphWeight
pfASDUnsetMorphWeight 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.
pfASDCullEnlarge 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
pfASDIsPaging returns TRUE is the pfASD node is paging database;
returns FALSE is all of the data is in memory.
pfASDIsPageMaster 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.
pfASDInitPaging is called at data loading time to indicate this node
is going to be paging data.
Page 17
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
pfASDTileSize 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.
pfGetASDTileSize returns the pointer to the tilesize array.
pfASDPageSize 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.
pfGetASDPageSize returns the paging offset array.
pfASDTotalTiles 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.
pfGetASDTotalTiles returns a pointer to the total tile size.
pfASDMaxTileMemSize 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.
pfGetASDMaxTileMemSize requires the maximum faces and vertices a
tile could contain in the database.
pfASDOrigin 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.
pfGetASDOrigin queries the corners of each LOD.
cpfASDPageFname 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
Page 18
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
"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.
pfGetASDPageFname 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.
pfASDAddQueryArray 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.
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.
Page 19
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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
|
pfASDAddQueryArray returns a unique number identifying the query
array. This number identifies this array for other pfASD routines
such as pfASDDeleteQueryArray.
pfASDDeleteQueryArray deletes a previously added query point array.
index is the number returned by pfASDAddQueryArray.
pfASDGetQueryArrayPositionSpan 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.
pfASDContainsQueryArray 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:
Page 20
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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
pfASDContainsQueryArray. 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.
pfASDAddQueryGeoSet adds the triangles in a pfGeoSet to pfASD. _gset
is a pfGeoSet containing triangle primitives. The query 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, pfASDAddQueryGeoSet 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,
Page 21
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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
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)
|
Page 22
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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.
pfASDDeleteQueryGeoSet removes the query pfGeoSet with index _index.
pfASDReplaceQueryGeoSet replaces the query pfGeoSet with index
_index by the input pfGeoset gset. It also sets the down direction
to down.
pfASDSyncGroup 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.
pfGetASDSyncGroup returns the synchronization group that this pfASD
Page 23
pfASD(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfASD(3pf)
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 24