/* 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 <stdlib.h>
#include <stdio.h>
#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 */