cardemo.c

( Supplemental Files )


/* 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 */