Re: 3d-rotation arround an object

New Message Reply Date view Thread view Subject view Author view

Rob Jenkins (robj++at++barney.reading.sgi.com)
Tue, 4 Jul 1995 10:05:21 +0100


Dietmar

find attached some example code form the Performer course labs - it includes a
'solar system' using DCSs which should point you in the right direction.

Cheers
Rob

-- 
________________________________________________________________
Rob Jenkins, Software Support Group, Silicon Graphics UK Ltd.       
1530 Arlington Business Park, Theale, Reading, UK, RG7 4SB. 
tel 01734 257736, fax 01734 257553, email robj++at++reading.sgi.com,

/* * Module 2, Lab 1, Part 3: * Add lighting to sim.c * Note: formatted with pp, // comments for new code. * Module 2, Lab 1, Part 5: * Add texture and prebinding using pfUtil utilities * Note: need to make scene global, ie shared->scene. * Module 2, Lab 2, Part 1 & 2: * Add an earth/sky model. * Module 3, Lab 1, Part 1: * Add DCS above main model, make it spin. (Stop viewpoint rotation). * Module 3, Lab 1, Part 2: * Add another model in fixed location under DCS, spinning. * Note: changed view to be down -y axis. * Module 3, Lab 1, Part 3: * Add an array of objects under SCS modes. * Added myLoadFile to simplify file loading. * Module 3, Lab 1, Part 4: * Make the cow stand up. Just add 90 degrees of pitch to its DCS. * Module 3, Lab 2, Part 1: * Add a "solar system" of orbiting models. * * G Edwards, SG UK, Nov 94 * */

#include <X11/Xlib.h>

#include <math.h> #include <stdlib.h>

#include "pf.h" #include "pfsgi.h" #include "pfutil.h"

/* function prototypes */ void initialize(int argc, char *argv[]); pfNode *buildScene(int argc, char * argv[]); static void openPipeline(pfPipe *p); void printHelp(char *programName); pfNode *myLoadFile(char * filename);

typedef struct SharedData { pfChannel *chan; pfCoord view; float eyeRadius; pfScene *scene; pfDCS *mainDCS, *dcs2, *planetDCS, *moonDCS; } SharedData;

/* Global Variables */ SharedData *shared;

/* * Main program */

int main(int argc, char *argv[]) { pfCoord view; float time; float maxTime = 20.0; float eyeAngle, spinAngle;

initialize(argc, argv);

pfInitClock(0.0f);

/* Simulate for maxTime seconds. */ /* main loop */ while (time < maxTime) { float sin, cos;

/* Go to sleep until next frame time. */ pfSync();

time = pfGetTime();

// View position and direction now static, down -y axis

pfSinCos(eyeAngle, &sin, &cos); pfSetVec3(view.xyz, 0.0f, -shared->eyeRadius * 1.5, shared->eyeRadius * 0.4f); pfSetVec3(view.hpr, 0.0f, -10.0f, 0.0f); pfChanView(shared->chan, view.xyz, view.hpr);

// // Spin main DCS // spinAngle = 45.0f * time; pfDCSRot(shared->mainDCS, spinAngle, spinAngle / 2.0, 0.0f);

// // Spin 2nd DCS // pfDCSRot(shared->dcs2, 0.0f, 90.0f, spinAngle / 4.0f);

// // Spin earth and moon DCS's for solar system // Note: pfDCSRot uses heading, pitch, roll. //

pfDCSRot(shared->planetDCS, spinAngle/2.0, 0.0, 0.0 ); pfDCSRot(shared->moonDCS, spinAngle, 0.0, 0.0);

/* Initiate cull/draw for this frame. */ pfFrame(); } pfuExitUtil(); pfExit(); exit(0); }

/* * intialize() initializes and configures Performer, * creates a graphics pipe and a channel, and calls * buildScene() to load a scene */

void initialize(int argc, char *argv[]) { int i; pfPipe *pipe; pfNode *root; pfScene *scene; pfSphere sceneBSphere; pfEarthSky *eSky; void *arena;

printHelp(argv[0]);

pfInit(); /* initialize Performer */

arena = pfGetSharedArena();

/* Malloc storage in shared memory region for shared data, * must be done between pfInit() and pfConfig(), since pfConfig() * may fork processes for cull and draw */ shared = (SharedData *) pfMalloc(sizeof(SharedData), arena);

/* If debugging, force multiprocessing mode */ /* even if on single processor */

pfConfig(); /* configure */

/* Initialize IRIS Performer utility library. */ pfuInitUtil();

pipe = pfGetPipe(0); /* create graphics pipeline */ shared->chan = pfNewChan(pipe); /* create a view into the pipe */

/* Create a scene! */ shared->scene = scene = pfNewScene(); root = buildScene(argc, argv); pfAddChild(scene, root);

/* initialize graphics pipeline and call openPipeline when ready */ pfInitPipe(pipe, openPipeline);

/* specify scene to be viewed by channel */ pfChanScene(shared->chan, scene);

/* Get the scene's extents. */ pfGetNodeBSphere(scene, &sceneBSphere); printf("Scene bounds - center: %f %f %f, radius: %f\n", sceneBSphere. center[0], sceneBSphere.center[1], sceneBSphere.center[2], sceneBSphere.radius); shared->eyeRadius = 1.5f * sceneBSphere.radius;

// // Add an earth/sky model //

eSky = pfNewESky(); // Specify what gets cleared & drawn pfESkyMode(eSky, PFES_BUFFER_CLEAR, PFES_SKY_GRND); // Ground height, a little below most models pfESkyAttr(eSky, PFES_GRND_HT, -1.0f); // Horizon glow band width & colour pfESkyAttr(eSky, PFES_HORIZ_ANGLE, 5.0f); pfESkyColor(eSky, PFES_HORIZ, 0.5f, 0.1f, 0.0f, 1.0f); // Top/bottom sky colours pfESkyColor(eSky, PFES_SKY_TOP, 0.0f, 0.0f, 0.0f, 1.0f); pfESkyColor(eSky, PFES_SKY_BOT, 0.05f, 0.0f, 0.6f, 1.0f); // Near/far ground colours pfESkyColor(eSky, PFES_GRND_NEAR, 0.0f, 0.3f, 0.0f, 1.0f); pfESkyColor(eSky, PFES_GRND_FAR, 0.0f, 0.0f, 0.0f, 1.0f); // Tell chan to draw this each frame pfChanESky(shared->chan, eSky); }

/* * buildScene() loads model file specified in command line * args (or a default) and returns a node containing the model */

pfNode *buildScene(int argc, char * argv[]) { pfNode *model1, *model2, *model3; pfGroup *group; pfMatrix matrix; pfSCS *scs[4][4], *planetSCS, *moonSCS; char *file1, *file2, *file3; char *default1 = "esprit.flt", *default2 = "cow.obj", *default3 = "icosahedron.ascii"; int i, j;

file1 = (argc < 2)? default1: argv[1]; file2 = (argc < 3)? default2: argv[2]; file3 = (argc < 4)? default3: argv[3];

// // Read in model files //

model1 = myLoadFile(file1); model2 = myLoadFile(file2); model3 = myLoadFile(file3);

// // Add a DCS above the main model. Needs to be global to update it from // APP process in main. //

shared->mainDCS = pfNewDCS(); pfAddChild(shared->mainDCS, model1);

// // Add another DCS above a 2nd model. DCS has fixed translation to // position model, and variable rotation to spin it. // And some scaling to get model right size. //

shared->dcs2 = pfNewDCS(); pfDCSTrans(shared->dcs2, 4.0, 0.0, 0.0); pfDCSScale(shared->dcs2, 0.20); pfAddChild(shared->dcs2, model2);

// // Add an array of models under SCS nodes. //

group = pfNewGroup();

for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { pfMakeTransMat(matrix, -(float) i - 1, -(float) j - 1, 0.0); pfPreScaleMat(matrix, 0.4, 0.4, 0.4, matrix); scs[i][j] = pfNewSCS(matrix); pfAddChild(scs[i][j], model3); pfAddChild(group, scs[i][j]); } }

// // Add a "solar system" of orbiting models. //

shared->planetDCS = pfNewDCS(); // earth orbit rot shared->moonDCS = pfNewDCS(); // moon orbit rot pfMakeTransMat(matrix, 5.0, 0.0, 2.0); // earth orbit trans planetSCS = pfNewSCS(matrix); pfMakeTransMat(matrix, 2.0, 0.0, 0.0); // moon orbit trans pfPreScaleMat(matrix, 0.5, 0.5, 0.5, matrix); moonSCS = pfNewSCS(matrix); // Compose the hierarchy pfAddChild(shared->planetDCS, planetSCS); pfAddChild(planetSCS, model3); // just instance model3 some more pfAddChild(planetSCS, shared->moonDCS); pfAddChild(shared->moonDCS, moonSCS); pfAddChild(moonSCS, model3);

// // Put all top level nodes under a group and return it. //

pfAddChild(group, shared->mainDCS); pfAddChild(group, shared->dcs2); pfAddChild(group, shared->planetDCS); return((pfNode *) group); }

/* * openPipeline() creates a GL window and sets up the * window system, IRIS GL, and IRIS Performer. This * procedure is executed in the draw process (when * there is a separate draw process). */

static void openPipeline(pfPipe *pipe) { pfuGLXWindow *win; Display *XDpy; void *arena; pfList *texList;

XDpy = (Display *) pfuOpenXDisplay(0); if (!(win = pfuGLXWinopen((pfuXDisplay *) XDpy, pipe, "sim", 100, 900, 100, 900))) { pfNotify(PFNFY_FATAL, PFNFY_RESOURCE, "OpenXPipeline: Could not create GLX Window.\n"); }

/* initialize Performer for GLX rendering */ pfInitGLXGfx(pipe, (void *) XDpy, win->xWin, win->glWin, win->overWin, PFGLX_AUTO_RESIZE);

// // Turn on lighting //

arena = pfGetSharedArena();

// Create and apply default material (light grey) pfApplyMtl(pfNewMtl(arena));

// Create and apply default lighting model pfApplyLModel(pfNewLModel(arena));

// Create and apply one default light (white light looking down -y axis) pfLightOn(pfNewLight(arena));

// Enable lighting (this is defaulted on anyway) pfEnable(PFEN_LIGHTING);

// // Turn on texturing //

// Enable textuuring pfEnable(PFEN_TEXTURE);

// Create default texture environment pfApplyTEnv(pfNewTEnv(arena));

// Prebind (ie. read and download to gfx hardware) textures in scene. // This also gives the nice texture slideshow. pfuInitUtil(); texList = pfuMakeTexList((pfNode *) shared->scene); pfuDownloadTexList(texList, PFUTEX_SHOW); }

/* * Read model file, exit if not found. */

pfNode *myLoadFile(char * filename) { pfNode *model;

fprintf(stdout, "Loading Model file %s\n", filename); if ((model = LoadFile(filename, NULL)) == NULL) { fprintf(stderr, "Model file %s not found, exiting\n", filename); pfuExitUtil(); pfExit(); system("rm /usr/tmp/pfUtil*"); exit(-1); }

return(model); }

/* * Help routine */

void printHelp(char *programName) { fprintf(stdout, "Usage: %s [model1] [model2] [model3]\n\n", programName); fprintf(stdout, // "Loads model file specified (or a default model)\n" // "and loops around model\n" // "and turns on lighting\n" // "and turns on texturing\n" // "and adds an earth/sky model\n" // "and adds a DCS above main model\n" // "and adds another model in fixed location under a DCS, spinning\n" // "\n", // programName); }


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:51:39 PDT

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