pfLOD / Intersection Traversal Anomaly

New Message Reply Date view Thread view Subject view Author view

Larry Lachman (larry++at++spiffy.paradigmsim.com)
Wed, 03 Nov 1999 17:20:10 -0500


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(); }

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();
}
 


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Wed Nov 03 1999 - 13:13:28 PST

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.