From: Brian Furtaw (brian++at++sgi.com)
Date: 11/22/2000 07:35:56
Mark,
I could not get the your callback to work unless I called two different
callbacks. Which is the same result you found. This looks like a
Performer bug. I was able to implement a new class PlanetDCS which
subclassed off the pfDCS and incorporated your method and this code
works fine. I have attached the modified simple.C example for reference.
Brian
Mark Gill wrote:
>
> greetings,
>
> Today's question is about traversal functions. I'm trying to use a single
> traversal function, applying it to several pfDCS's (I want each pfDCS to
> perform a similar task, but with different specific parameters). I'm trying
> to control the performance of each function with setTravData -- passing it a
> struct.
>
> Here's my problem: Both of my objects act the same way. It's as if the
> traversal function is over-writing the parameter structure for the second
> object with that of the first.
>
> Here's some code:
> ++++++++++++++++++
> // structure for the planet data
> /*
> The data in this structure controls how the planets behave,
> their rotation, revolution and distance from the sun.
> if pl_rot and pl_rev are set to the same value, then the planet
> will revolve once for every rotations, keeping the same face toward
> the sun */
>
> struct planet_data {
>
> int pl_id;
> float pl_rot;
> float pl_rot_inc; // rotation inciment in degrees
>
> float pl_rev;
> float pl_rev_inc; // revolution incriment in degrees
>
> float pl_radius; // radius from the sun (origin)
>
> };
>
> typedef struct planet_data planetdata;
>
> *********************Then later on I do this:...
>
> planet_data *earth_data, *moon_data;
>
> earth_data = (planet_data *) pfMalloc (sizeof (planet_data),
> pfGetSharedArena ());
> moon_data = (planet_data *) pfMalloc (sizeof (planet_data), pfGetSharedArena
> ());
>
> // set up the data for the planets
>
> earth_data->pl_id = 3;
> earth_data->pl_radius = 3000.0;
> earth_data->pl_rot = 0.0;
> earth_data->pl_rot_inc = 1.0;
> earth_data->pl_rev = 1.0;
> earth_data->pl_rev_inc = (1.0/365.0);
>
> moon_data->pl_id = 31;
> moon_data->pl_radius = 3000.0;
> moon_data->pl_rot = 0.0;
> moon_data->pl_rot_inc = (1.0/30);
> moon_data->pl_rev = 1.0;
> moon_data->pl_rev =(1.0/365);
>
> pfVec3 earth_origin;
>
> // load the starfield
> pfNode *env = pfdLoadFile ("env2.iv");
>
> // load the sun object
> pfNode *sun = pfdLoadFile ("sun.iv");
> sundcs = new pfDCS;
> sundcs -> addChild (sun);
>
> // load the earth -- 3 levels of detail
> pfLOD *earth_lod = new pfLOD;
>
> pfNode *earth_l = pfdLoadFile ("earth_l.iv"); // low poly count
> pfNode *earth = pfdLoadFile ("earth.iv");
> pfNode *earth_h = pfdLoadFile ("earth_h.iv"); // high poly count
>
> earthdcs = new pfDCS;
>
> //earth_origin.set(0.0,0.0,0.0);
> //earth_lod -> setCenter (earth_origin);
> earth_lod -> addChild (earth_h);
> earth_lod -> setRange (1, 750.0);
>
> earth_lod -> addChild (earth);
> earth_lod -> setRange (2, 3000.0);
>
> earth_lod -> addChild (earth_l);
> earth_lod -> setRange (3, 12000);
>
> //earth_lod -> setRange (-1, 100000.0);
>
> earthdcs -> addChild (earth_lod);
> earthdcs->setTravFuncs(PFTRAV_APP,pl_rotate,NULL);
> earthdcs->setTravData (PFTRAV_APP, (void *) earth_data);
>
> // load the moon
>
> moondcs = new pfDCS;
> pfNode *moon = pfdLoadFile ("moon.iv");
> moondcs -> addChild (moon);
> moondcs -> setTravFuncs (PFTRAV_APP,pl_rotate,NULL);
> moondcs -> setTravData (PFTRAV_APP, (void *) moon_data);
>
> And here's the rotation traversal function:
>
> /*++++++++++++++++++++++++++++ planet_rotate +++++++++++++*/
>
> static int pl_rotate(pfTraverser *trav,void * data)
>
> {
> static planet_data * pl_data = (planet_data *) data;
> static float radians, x, y;
>
> //recylce the rotation and revolution data
>
> if (pl_data -> pl_rot > 359.9)
> pl_data -> pl_rot = 0.0;
>
> if (pl_data -> pl_rev > 359.9)
> pl_data -> pl_rev = 0.0;
>
> radians = 1 * 3.14/180; // leave in formula to let me tweak
>
> x = 0.0 +(pl_data->pl_radius * (cos (radians * pl_data->pl_rev)));
> y = 0.0 + (pl_data->pl_radius * (sin (radians * pl_data->pl_rev)));
>
> pfDCS *rot_dcs = (pfDCS *) trav->getNode();/*get a ptr to the DCS node
> itself */
>
> rot_dcs -> setRot (pl_data -> pl_rot, 0.0, 0.0);
> rot_dcs -> setTrans (x, y, 0.0);
>
> pl_data -> pl_rot = pl_data -> pl_rot + pl_data -> pl_rot_inc;
> pl_data -> pl_rev = pl_data -> pl_rev + pl_data -> pl_rev_inc;
>
> // some debug code
> printf ("planet id: %i ", pl_data->pl_id);
> printf (" -- revolution = %f \n", pl_data->pl_rev);
>
> return PFTRAV_CONT;
>
> }
>
> When I run the program I can tell that both objects are being affected (they
> both move), but they both act the same way, and printing out the debug data
> shows that the same data is passing through the traversal function.
>
> Am I just missing something -- overlooking something simple? I'm trying to
> avoid writing a different traversal function for each object, but I know
> that will work.
>
> thanks in advance...
>
> Mark Gill Visualization Researcher
> CHL Stennis Space Center
> Mark.Gill++at++usm.edu
> ----------------------------------------------
>
> -----------------------------------------------------------------------
> List Archives, FAQ, FTP: http://www.sgi.com/software/performer/
> Submissions: info-performer++at++sgi.com
> Admin. requests: info-performer-request++at++sgi.com
--
----oOOo---- ----oOOo---- ----oOOo---- ----oOOo----
Brian Furtaw (brian++at++sgi.com)
Graphics Guru Office:(301)572-3293 Fax: (603)250-0370
12200-G Plum Orchard Drive OpenGL/Performer/OpenInventor/ImageVision
Silver Spring, Maryland 20904 Volumizer/Optimizer/React/PCI Device
Drivers
#ident "$Revision$" // // Copyright 1995, Silicon Graphics, Inc. // ALL RIGHTS RESERVED // // This source code ("Source Code") was originally derived from a // code base owned by Silicon Graphics, Inc. ("SGI") // // LICENSE: SGI grants the user ("Licensee") permission to reproduce, // distribute, and create derivative works from this Source Code, // provided that: (1) the user reproduces this entire notice within // both source and binary format redistributions and any accompanying // materials such as documentation in printed or electronic format; // (2) the Source Code is not to be used, or ported or modified for // use, except in conjunction with OpenGL Performer; and (3) the // names of Silicon Graphics, Inc. and SGI may not be used in any // advertising or publicity relating to the Source Code without the // prior written permission of SGI. No further license or permission // may be inferred or deemed or construed to exist with regard to the // Source Code or the code base of which it forms a part. All rights // not expressly granted are reserved. // // This Source Code is provided to Licensee AS IS, without any // warranty of any kind, either express, implied, or statutory, // including, but not limited to, any warranty that the Source Code // will conform to specifications, any implied warranties of // merchantability, fitness for a particular purpose, and freedom // from infringement, and any warranty that the documentation will // conform to the program, or any warranty that the Source Code will // be error free. // // IN NO EVENT WILL SGI BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT // LIMITED TO DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, // ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THE // SOURCE CODE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT OR // OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR // PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, // OR AROSE OUT OF USE OR RESULTS FROM USE OF, OR LACK OF ABILITY TO // USE, THE SOURCE CODE. // // Contact information: Silicon Graphics, Inc., // 1600 Amphitheatre Pkwy, Mountain View, CA 94043, // or: http://www.sgi.com // // // simple.C: simple Performer program for programmer's guide // // $Revision: 1.3 $ // $Date: 2000/11/21 22:36:21 $ //
#include <stdlib.h>
#include <Performer/pf/pfChannel.h> #include <Performer/pf/pfLightSource.h> #include <Performer/pf/pfNode.h> #include <Performer/pf/pfScene.h> #include <Performer/pf/pfDCS.h> #include <Performer/pf/pfGroup.h> #include <Performer/pf/pfTraverser.h>
#include <Performer/pfutil.h> #include <Performer/pfdu.h>
struct planet_data {
int pl_id; float pl_rot; float pl_rot_inc; // rotation inciment in degrees
float pl_rev; float pl_rev_inc; // revolution incriment in degrees
float pl_radius; // radius from the sun (origin)
};
typedef struct planet_data planetdata_s;
class PlanetDCS : public pfDCS { public: PlanetDCS(); PlanetDCS(planetdata_s *pd); ~PlanetDCS(); static void init(); static pfType* getClassType(){ return classType; }; static pfType* classType; protected: virtual int app(pfTraverser *trav); int needsApp(); private: planetdata_s *_pd; int place; float radians, x, y; int enable; };
pfType *PlanetDCS::classType = NULL;
PlanetDCS::PlanetDCS() : pfDCS() { setType(classType); // set the type of this instance }
PlanetDCS::PlanetDCS(planetdata_s *pd) : pfDCS(), _pd(pd), place(0), enable(1) { setType(classType); // set the type of this instance }
PlanetDCS::~PlanetDCS() // can't do this : ~pfDCS() { }
void PlanetDCS::init() { if (classType == NULL) { pfDCS::init(); classType = new pfType(pfDCS::getClassType(), "PlanetDCS"); } }
int PlanetDCS::app(pfTraverser *trav) { float s,c; if (enable) {
//recylce the rotation and revolution data
if (_pd->pl_rot > 359.9) _pd->pl_rot = 0.0;
if (_pd ->pl_rev > 359.9) _pd ->pl_rev = 0.0;
#ifdef SLOW_WAY radians = 1 * 3.14/180; // leave in formula to let me tweak
x = 0.0 +(_pd->pl_radius * (cos (radians * _pd->pl_rev))); y = 0.0 + (_pd->pl_radius * (sin (radians * _pd->pl_rev))); #else pfSinCos(_pd->pl_rev, &s, &c); x = 0.0 +(_pd->pl_radius * (c)); y = 0.0 + (_pd->pl_radius * (s)); #endif
setRot (_pd->pl_rot, 0.0, 0.0); setTrans (x, y, 0.0);
_pd->pl_rot = _pd->pl_rot + _pd->pl_rot_inc; _pd->pl_rev = _pd->pl_rev + _pd->pl_rev_inc;
if(place < 10) { // some debug code printf("Node id: 0x%x\n", trav->getNode()); printf("Is of type %s\n", trav->getNode()->getClassType()->getName() ); printf ("planet id: %i ", _pd->pl_id); printf (" -- revolution = %f \n", _pd->pl_rev); place++; }
return PFTRAV_CONT;
}
return pfDCS::app(trav); }
int PlanetDCS::needsApp(void) { return TRUE; }
/*++++++++++++++++++++++++++++ planet_rotate +++++++++++++*/
#if 0
static int pl_rotate(pfTraverser *trav,void * data)
{ static planet_data * pl_data = (planet_data *) data; static float radians, x, y; static int place = 0;
//recylce the rotation and revolution data
if (pl_data -> pl_rot > 359.9) pl_data -> pl_rot = 0.0;
if (pl_data -> pl_rev > 359.9) pl_data -> pl_rev = 0.0;
radians = 1 * 3.14/180; // leave in formula to let me tweak
x = 0.0 +(pl_data->pl_radius * (cos (radians * pl_data->pl_rev))); y = 0.0 + (pl_data->pl_radius * (sin (radians * pl_data->pl_rev)));
pfDCS *rot_dcs = (pfDCS *) trav->getNode();/*get a ptr to the DCS node itself */
rot_dcs -> setRot (pl_data -> pl_rot, 0.0, 0.0); rot_dcs -> setTrans (x, y, 0.0);
pl_data -> pl_rot = pl_data -> pl_rot + pl_data -> pl_rot_inc; pl_data -> pl_rev = pl_data -> pl_rev + pl_data -> pl_rev_inc;
if(place < 10) { // some debug code printf("Node id: 0x%x\n", trav->getNode()); printf ("planet id: %i ", pl_data->pl_id); printf (" -- revolution = %f \n", pl_data->pl_rev); place++; }
return PFTRAV_CONT;
}
static int pl_rotate2(pfTraverser *trav,void * data)
{ static planet_data * pl_data = (planet_data *) data; static float radians, x, y; static int place = 0;
//recylce the rotation and revolution data
if (pl_data -> pl_rot > 359.9) pl_data -> pl_rot = 0.0;
if (pl_data -> pl_rev > 359.9) pl_data -> pl_rev = 0.0;
radians = 1 * 3.14/180; // leave in formula to let me tweak
x = 0.0 +(pl_data->pl_radius * (cos (radians * pl_data->pl_rev))); y = 0.0 + (pl_data->pl_radius * (sin (radians * pl_data->pl_rev)));
pfDCS *rot_dcs = (pfDCS *) trav->getNode();/*get a ptr to the DCS node itself */
rot_dcs -> setRot (pl_data -> pl_rot, 0.0, 0.0); rot_dcs -> setTrans (x, y, 0.0);
pl_data -> pl_rot = pl_data -> pl_rot + pl_data -> pl_rot_inc; pl_data -> pl_rev = pl_data -> pl_rev + pl_data -> pl_rev_inc;
if(place < 10) { // some debug code printf("Node id: 0x%x\n", trav->getNode()); printf ("planet id: %i ", pl_data->pl_id); printf (" -- revolution = %f \n", pl_data->pl_rev); place++; }
return PFTRAV_CONT;
} #endif
// // Usage() -- print usage advice and exit. This // procedure is executed in the application process. // static void Usage (void) { pfNotify(PFNFY_FATAL, PFNFY_USAGE, "Usage: simpleC file.ext ...\n"); exit(1); }
int main (int argc, char *argv[]) { float t = 0.0f; if (argc < 2) Usage(); // Initialize Performer pfInit(); // Use default multiprocessing mode based on number of // processors. // pfMultiprocess( PFMP_DEFAULT ); // Load all loader DSO's before pfConfig() forks pfdInitConverter(argv[1]);
// initiate multi-processing mode set in pfMultiprocess call // FORKs for Performer processes, CULL and DRAW, etc. happen here. // PlanetDCS::init(); pfConfig(); // Append to Performer search path, PFPATH, files in // /usr/share/Performer/data */ pfFilePath(".:/usr/share/Performer/data"); // Attach loaded file to a new pfScene pfScene *scene = new pfScene; pfGroup *scene_group = new pfGroup; PlanetDCS *dcs_p, *dcs_pp; planet_data *earth_data, *moon_data;
earth_data = (planet_data *) pfMalloc(sizeof (planet_data), pfGetSharedArena()); moon_data = (planet_data *) pfMalloc(sizeof (planet_data), pfGetSharedArena());
// set up the data for the planets
earth_data->pl_id = 3; earth_data->pl_radius = 3000.0; earth_data->pl_rot = 0.0; earth_data->pl_rot_inc = 1.0; earth_data->pl_rev = 1.0; earth_data->pl_rev_inc = (1.0/365.0); moon_data->pl_id = 31; moon_data->pl_radius = 3000.0; moon_data->pl_rot = 0.0; moon_data->pl_rot_inc = (1.0/30); moon_data->pl_rev = 1.0; moon_data->pl_rev =(1.0/365); pfNode *root; for(int x = 1; x < 3; x++) { root = pfdLoadFile(argv[x]); if (root == NULL) { pfExit(); exit(-1); } if(x == 1) { dcs_p = dcs_pp = new PlanetDCS(moon_data); //dcs_p->setTravFuncs(PFTRAV_APP, pl_rotate, NULL); //dcs_p->setTravData(PFTRAV_APP, (void *) earth_data); } else { dcs_p = new PlanetDCS(earth_data); //dcs_p->setTravFuncs(PFTRAV_APP, pl_rotate2, NULL); //dcs_p->setTravData(PFTRAV_APP, (void *) moon_data); } dcs_p->addChild(root); scene_group->addChild(dcs_p); printf("dcs_p 0x%x dcs_pp 0x%x\n", dcs_p, dcs_pp); } // Create a pfLightSource and attach it to scene scene->addChild(new pfLightSource); scene->addChild(scene_group); // Configure and open GL window pfPipe *p = pfGetPipe(0); pfPipeWindow *pw = new pfPipeWindow(p); pw->setWinType(PFPWIN_TYPE_X); pw->setName("OpenGL Performer"); pw->setOriginSize(0,0,500,500); pw->open(); // Create and configure a pfChannel. pfChannel *chan = new pfChannel(p); chan->setScene(scene); chan->setFOV(45.0f, 0.0f); // determine extent of scene's geometry pfSphere bsphere; scene_group->getBound(&bsphere); chan->setNearFar(1.0f, 10.0f * bsphere.radius); // Simulate for twenty seconds. while (t < 20.0f) { pfCoord view; float s, c; // Go to sleep until next frame time. pfSync(); // Initiate cull/draw for this frame. pfFrame(); // Compute new view position. t = pfGetTime(); pfSinCos(45.0f*t, &s, &c); view.hpr.set(45.0f*t, -10.0f, 0); view.xyz.set(2.0f * bsphere.radius * s, -2.0f * bsphere.radius *c, 0.5f * bsphere.radius); chan->setView(view.xyz, view.hpr); } // Terminate parallel processes and exit pfExit(); return 0; }
This archive was generated by hypermail 2b29 : Wed Nov 22 2000 - 07:37:47 PST