/* cardemo.c - A simple VR program to illustrate the use of movable nodes in scene graphs, for Eng 591, Virtual Reality Programming. Written September 1999 by John T. Bell Last modified _________ by __________ */ #include #include #include "wt.h" /* Function Prototypes */ void UserActions( void ); /* Global Variables - Use only when NECESSARY */ WTpq InitialView = { { -50.0f, -25.0f, -50.0f }, { 0.0f, -0.3827f, 0.0f, 0.9239f } }; WTnode *Root = NULL; WTviewpoint *Viewpoint = NULL; WTsensor *Mouse = NULL; WTnode *Car = NULL, *Wheels = NULL, *LeftWheel = NULL, *RightWheel = NULL; int main ( int argc, char **argv ) { /* Local Variables */ WTp3 right_rear = { 4.0f, -1.0f, -6.0f }, left_rear = { -4.0f, -1.0f, -6.0f }, right_front = { 4.0f, -1.0f, 5.0f }, left_front = { -4.0f, -1.0f, 5.0f }; WTq left = { 0.0f, 1.0f, 0.0f, 0.0f }; WTp3 lightPosition = { -100.0, -100.0, 0.0 }; WTnode *sep = NULL, *wheel = NULL, *node = NULL; /* Intialize the Universe */ WTuniverse_new( WTDISPLAY_DEFAULT, WTWINDOW_DEFAULT ); /* Set some global variables */ Root = WTuniverse_getrootnodes(); Viewpoint = WTuniverse_getviewpoints(); /* Set up devices */ WTkeyboard_open(); Mouse = WTmouse_new(); if( !Mouse ) WTerror( "Sorry; A mouse is required to run" " this program.\n" ); else { WTmotionlink_new( Mouse, Viewpoint, WTSOURCE_SENSOR, WTTARGET_VIEWPOINT ); } /* Build the scene graph */ WTlightnode_newdirected( Root ); node = WTlightnode_newpoint( Root ); WTlightnode_setposition( node, lightPosition ); WTnode_load( Root, "grounds.nff", 1.0 ); /* First load the separator, the overall car transform, and the car body itelf. Save a pointer to the transform in the global variable "Car". */ sep = WTsepnode_new( Root ); Car = WTxformnode_new( sep ); WTnode_load( sep, "carbody.nff", 1.0 ); /* Now load and locate the rear wheels. Save a local pointer to the first wheel, for instancing. */ wheel = WTmovnode_load( sep, "wheel.nff", 1.0 ); /* Right rear */ WTnode_settranslation( wheel, right_rear ); node = WTmovnode_instance( sep, wheel ); /* Left rear */ WTnode_settranslation( node, left_rear ); WTnode_setorientation( node, left ); /* Next load a transform to be used later to turn the front wheels. Save a global variable "Wheels" to point to this transform. Then load the front wheels themselves. ( Note: The above approach did not work, so separate pointers are also saved to each individual front wheel */ Wheels = WTxformnode_new( sep ); RightWheel = WTmovnode_instance( sep, wheel ); /* Right front */ WTnode_settranslation( RightWheel, right_front ); LeftWheel = WTmovnode_instance( sep, wheel ); /* Left front */ WTnode_settranslation( LeftWheel, left_front ); WTnode_setorientation( LeftWheel, left ); /* Initialize the viewpoint */ /*WTwindow_zoomviewpoint( WTuniverse_getcurrwindow() );*/ WTviewpoint_moveto( Viewpoint, &InitialView ); /* Setup the action function */ WTuniverse_setactions( UserActions ); /* The "go" function runs the simulation. It doesn't return until we quit. */ WTuniverse_ready(); WTuniverse_go(); /* And now to clean up our toys and go home. */ WTuniverse_delete(); return 0; } /* End of Main Routine */ /********************************************************************************/ void UserActions( void ) { short key; WTp3 p3; WTq q; WTp3 step = { 0.0f, 0.0f, 1.0f }; /* Move car 1 step forward */ /* Process Keyboard Input */ key = WTkeyboard_getlastkey(); if( key ) { switch( key ) { case 'f': case 'F': WTnode_translate( Car, step, WTFRAME_LOCAL ); break; case 'R': /* Turn car right PI / 16 degrees */ WTnode_axisrotation( Car, Y, PI/16.0, WTFRAME_LOCAL ); break; case 'L': /* Turn car left PI / 16 degrees */ WTnode_axisrotation( Car, Y, -PI/16.0, WTFRAME_LOCAL ); break; case 'r': /* Turn wheels right PI / 16 degrees */ /*WTnode_axisrotation( Wheels, Y, PI/16.0, WTFRAME_LOCAL );*/ WTnode_axisrotation( LeftWheel, Y, PI/16.0, WTFRAME_LOCAL ); WTnode_axisrotation( RightWheel, Y, PI/16.0, WTFRAME_LOCAL ); break; case 'l': /* Turn wheels left PI / 6 degrees */ /*WTnode_axisrotation( Wheels, Y, -PI/16.0, WTFRAME_LOCAL );*/ WTnode_axisrotation( LeftWheel, Y, -PI/16.0, WTFRAME_LOCAL ); WTnode_axisrotation( RightWheel, Y, -PI/16.0, WTFRAME_LOCAL ); break; case 'i': case 'I': WTviewpoint_getposition( Viewpoint, p3 ); WTviewpoint_getorientation( Viewpoint, q ); WTp3_print( p3, "Current Position: " ); WTq_print( q, "Current Orientation: " ); break; case 'q': case 'Q': WTuniverse_stop(); break; case 'p': case 'P': WTnode_print( Root ); break; case '0': WTviewpoint_moveto( Viewpoint, &InitialView ); break; case 'h': /* Help - Fall through to default */ case 'H': case '?': default: WTmessage( "\nThe following keys are active:\n\n" ); WTmessage( "Q or q: Quit.\n" ); WTmessage( "0 ( zero ): Reset\n" ); WTmessage( "F or f: Move car forward.\n" ); WTmessage( "L: Turn car left.\n" ); WTmessage( "R: Turn car right.\n" ); WTmessage( "l: Turn wheels left.\n" ); WTmessage( "r: Turn wheels right.\n" ); WTmessage( "P or p: Print scene graph.\n" ); break; } } return; } /* End of UserActions */