Larry Lachman (larry++at++spiffy.paradigmsim.com)
Wed, 03 Nov 1999 17:20:10 -0500
I am using Performer 2.2.5, and want to report an anomaly with pfLOD nodes and
the intersection traversal. I discovered that if range 0 of a pfLOD is set to
anything greater than 0.0f, then the intersection traversal stops at the pfLOD
and does not visit any of the pfLOD's children. According to the man page for
pfNodeIsectSegs:
"For pfLODs, the default is to traverse only the child that would be active
at range 0."
But this is not the case given the scenario described above. This anomaly
occurs regardless of the hardware the program is run on. This is either a
Performer bug, or behavior that you will probably want to document in the
pfNodeIsectSegs and pfLOD man pages.
For your convenience, I have enclosed a succinct Performer program that
reproduces this anomaly.
-- _______________________________________________________________Larry Lachman WWW: http://www.multigen-paradigm.com MultiGen-Paradigm, Inc. larry++at++paradigmsim.com 14900 Landmark, Suite 400 (972) 960-2301 ext 287 voice Dallas, Texas 75240 USA (972) 960-2303 fax
--#include <stdlib.h> #include <Performer/pf.h> #include <Performer/pfdu.h>
int main( int argc, char *argv[] ) { void *arena; pfScene *scene; pfPipe *pipe; pfChannel *chan; pfGeoState *gstate; pfCoord view; pfPipeWindow *pwin; pfNode *esprit, *egg; pfLOD *lod; pfSegSet segset; float yval = -20.0;
fprintf( stderr,"\n\n\nPerformer %d.%d\n\n\n", PF_MAJOR_VERSION, PF_MINOR_VERSION );
pfInit(); /* Initialize Performer */ arena = pfGetSharedArena(); /* Get shared memory arena */ pfMultiprocess( PFMP_APPCULLDRAW | PFMP_FORK_DBASE ); pfConfig();
if ( ! getenv( "PFPATH" ) ) pfFilePath( "." );
scene = pfNewScene();
esprit = pfdLoadFile( "esprit.flt" ); egg = pfdLoadFile( "egg.flt" );
if ( esprit && egg ) { lod = pfNewLOD();
pfAddChild( lod, esprit ); pfAddChild( lod, egg );
#ifdef DISABLE_INTERSECTION pfLODRange( lod, 0, 1.0f ); #else pfLODRange( lod, 0, 0.0f ); #endif
pfLODRange( lod, 1, 60.0f ); pfLODRange( lod, 2, 999000.0f );
pfNodeTravMask( lod, PFTRAV_ISECT, 0xFF, PFTRAV_SELF | PFTRAV_DESCEND | PFTRAV_IS_CACHE, PF_SET );
pfAddChild( scene, lod ); } else { printf( "esprit == 0x%x and egg == 0x%x\n", esprit, egg ); exit( -1 ); }
/* Create a scene pfGeoState with lighting enabled */ gstate = pfNewGState( arena ); pfGStateMode( gstate, PFSTATE_ENLIGHTING, PF_ON ); pfSceneGState( scene, gstate); pfAddChild( scene, pfNewLSource() );
/* Create and configure a pfChannel */ pipe = pfGetPipe( 0 ); pwin = pfNewPWin( pipe ); pfPWinOriginSize( pwin, 0, 0, 400, 400 ); pfOpenPWin( pwin ); chan = pfNewChan( pipe ); pfChanScene( chan, scene ); pfChanFOV( chan, 45.0f, -1.0f );
/* Set up intersection segment, pointing out for line of sight */ segset.activeMask = 1; segset.isectMask = 0xFF; segset.discFunc = NULL; segset.bound = NULL; segset.mode = PFTRAV_IS_PRIM | PFTRAV_IS_NORM | PFTRAV_IS_CULL_BACK | PFTRAV_LOD_RANGE0; /* Point the segment straight along Y body axis */ pfSetVec3 (segset.segs[0].dir, 0.0f, 1.0f, 0.0f); segset.segs[0].length = 50000.0f;
while ( 1 ) { pfHit **hits[32]; int isect;
pfSetVec3( view.xyz, 0.0f, yval, 0.5f ); pfSetVec3( view.hpr, 0.0f, 0.0f, 0.0f ); pfChanView( chan, view.xyz, view.hpr );
pfSync(); pfFrame();
/* decrement view position; if too far, reset */ yval -= 0.01f; if ( yval < -60.0f ) yval = -20.0f;
/* update location of intersection segment */ pfSetVec3 (segset.segs[0].pos, 0.0f, yval, 0.5f);
/* do an intersection test against the scene graph */ isect = pfNodeIsectSegs( scene, &segset, hits );
if ( isect ) { pfVec3 pnt, xpnt; pfMatrix xmat; pfQueryHit( *hits[0], PFQHIT_POINT, &pnt ); /* transform object point into scene coordinates */ pfQueryHit( *hits[0], PFQHIT_XFORM, xmat ); pfXformPt3( xpnt, pnt, xmat ); printf( "Intersection at %.3f %.3f %.3f\n", xpnt[PF_X], xpnt[PF_Y], xpnt[PF_Z] ); } }
pfExit(); }
Attention: Performer Team
I am using Performer 2.2.5, and want to report an anomaly with pfLOD nodes and the intersection traversal. I discovered that if range 0 of a pfLOD is set to anything greater than 0.0f, then the intersection traversal stops at the pfLOD and does not visit any of the pfLOD's children. According to the man page for pfNodeIsectSegs:
"For pfLODs, the default is to traverse only the child that would be active at range 0."
But this is not the case given the scenario described above. This anomaly occurs regardless of the hardware the program is run on. This is either a Performer bug, or behavior that you will probably want to document in the pfNodeIsectSegs and pfLOD man pages.
For your convenience, I have enclosed a succinct Performer program that reproduces this anomaly.
-- _______________________________________________________________ Larry Lachman WWW: http://www.multigen-paradigm.com MultiGen-Paradigm, Inc. larry++at++paradigmsim.com 14900 Landmark, Suite 400 (972) 960-2301 ext 287 voice Dallas, Texas 75240 USA (972) 960-2303 fax--#include <stdlib.h>
#include <Performer/pf.h>
#include <Performer/pfdu.h>int main( int argc, char *argv[] )
{
void *arena;
pfScene *scene;
pfPipe *pipe;
pfChannel *chan;
pfGeoState *gstate;
pfCoord view;
pfPipeWindow *pwin;
pfNode *esprit, *egg;
pfLOD *lod;
pfSegSet segset;
float yval = -20.0;fprintf( stderr,"\n\n\nPerformer %d.%d\n\n\n",
PF_MAJOR_VERSION, PF_MINOR_VERSION );pfInit(); /* Initialize Performer */
arena = pfGetSharedArena(); /* Get shared memory arena */
pfMultiprocess( PFMP_APPCULLDRAW | PFMP_FORK_DBASE );
pfConfig();if ( ! getenv( "PFPATH" ) ) pfFilePath( "." );
scene = pfNewScene();
esprit = pfdLoadFile( "esprit.flt" );
egg = pfdLoadFile( "egg.flt" );
if ( esprit && egg )
{
lod = pfNewLOD();pfAddChild( lod, esprit );
pfAddChild( lod, egg );#ifdef DISABLE_INTERSECTION
pfLODRange( lod, 0, 1.0f );
#else
pfLODRange( lod, 0, 0.0f );
#endif
pfLODRange( lod, 1, 60.0f );
pfLODRange( lod, 2, 999000.0f );pfNodeTravMask( lod, PFTRAV_ISECT, 0xFF,
PFTRAV_SELF | PFTRAV_DESCEND | PFTRAV_IS_CACHE, PF_SET );pfAddChild( scene, lod );
}
else
{
printf( "esprit == 0x%x and egg == 0x%x\n", esprit, egg );
exit( -1 );
}
/* Create a scene pfGeoState with lighting enabled */
gstate = pfNewGState( arena );
pfGStateMode( gstate, PFSTATE_ENLIGHTING, PF_ON );
pfSceneGState( scene, gstate);
pfAddChild( scene, pfNewLSource() );/* Create and configure a pfChannel */
pipe = pfGetPipe( 0 );
pwin = pfNewPWin( pipe );
pfPWinOriginSize( pwin, 0, 0, 400, 400 );
pfOpenPWin( pwin );
chan = pfNewChan( pipe );
pfChanScene( chan, scene );
pfChanFOV( chan, 45.0f, -1.0f );/* Set up intersection segment, pointing out for line of sight */
segset.activeMask = 1;
segset.isectMask = 0xFF;
segset.discFunc = NULL;
segset.bound = NULL;
segset.mode = PFTRAV_IS_PRIM | PFTRAV_IS_NORM |
PFTRAV_IS_CULL_BACK | PFTRAV_LOD_RANGE0;
/* Point the segment straight along Y body axis */
pfSetVec3 (segset.segs[0].dir, 0.0f, 1.0f, 0.0f);
segset.segs[0].length = 50000.0f;while ( 1 )
{
pfHit **hits[32];
int isect;pfSetVec3( view.xyz, 0.0f, yval, 0.5f );
pfSetVec3( view.hpr, 0.0f, 0.0f, 0.0f );
pfChanView( chan, view.xyz, view.hpr );
pfSync();
pfFrame();/* decrement view position; if too far, reset */
yval -= 0.01f;
if ( yval < -60.0f ) yval = -20.0f;
/* update location of intersection segment */
pfSetVec3 (segset.segs[0].pos, 0.0f, yval, 0.5f);/* do an intersection test against the scene graph */
isect = pfNodeIsectSegs( scene, &segset, hits );if ( isect )
{
pfVec3 pnt, xpnt;
pfMatrix xmat;
pfQueryHit( *hits[0], PFQHIT_POINT, &pnt );
/* transform object point into scene coordinates */
pfQueryHit( *hits[0], PFQHIT_XFORM, xmat );
pfXformPt3( xpnt, pnt, xmat );
printf( "Intersection at %.3f %.3f %.3f\n",
xpnt[PF_X], xpnt[PF_Y], xpnt[PF_Z] );
}
}
pfExit();
}
This archive was generated by hypermail 2.0b2 on Wed Nov 03 1999 - 13:13:28 PST