📄 uinit.c
字号:
/****************************************************************************** ** uinit.c --** OpenGVS user initialization software for the Train demo********************************************************************************/#include <g_sys.h>#include <g_consts.h>#include <g_timer.h>#include <g_math.h>#include <gv_sys.h>#include <gv_user.h>#include <gvu_path.h>#include <tgifts.h>#include "hostdata.h"#include "train.h"/* Globals */Season season = SEASON_SUMMER;#define NRECORDS_OWNTRAIN 106#define NRECORDS_OTHER0 11#define NRECORDS_OTHER1 1#define NRECORDS_OTHER2 55typedef struct { G_Position position; G_Rotation rotation; float elapsed_time;} Path_record;/* Global throughout this module only */static TParse_data *tdata = NULL;static G_Boolean debug = G_FALSE;static Path_record path_data_other0[NRECORDS_OTHER0] = {#include "path_otrain0.h"};static Path_record path_data_other1[NRECORDS_OTHER1] = {#include "path_otrain1.h"};static Path_record path_data_other2[NRECORDS_OTHER2] = {#include "path_otrain2.h"};/* Globals */GVU_Path path_owntrain = NULL;GVU_Path path_other[NUM_VEHICLES];/****************************************************************************** path_train_finished --** Tells us when the OWNTRAIN path has finished******************************************************************************/static int path_train_finished( GVU_Path path, void * data_in ){ static GV_Obi train_town = NULL; static GV_Obi summer_time = NULL; static GV_Obi autumn_time = NULL; static GV_Obi winter_time = NULL; static int * ptr_int = NULL; (void) data_in; (void) path; /* Reset the OWNTRAIN and other paths now */ tkui_event_reset( 0 ); if( !train_town ) { GV_obi_inq_by_name( "TRAIN_TOWN", &train_town ); GV_obi_inq_by_name_relative( train_town, ".../summer", &summer_time); GV_obi_inq_by_name_relative( train_town, ".../autumn", &autumn_time); GV_obi_inq_by_name_relative( train_town, ".../winter", &winter_time); } /* For grins, change the season every time we reset */ season++; if( season > SEASON_WINTER ) season = SEASON_SUMMER; season_change( season ); if( tdata && tdata->network_duties == NETWORK_DUTIES_MASTER ) { Tevent event; event.opcode = APP_EVENT_SEASON_CHANGE; ptr_int = (int *)&event.data[0]; if( ptr_int ) { *ptr_int = (Season)season; host_data.event = event; host_data.discrete_count++; #if DEBUG fprintf( stdout, "path_train_finished: season = %d\n", (int)season); #endif } } return G_SUCCESS;}/***************************************************************************** path_generate_points --** Generate the path based upon data points collected outside of * realtime (we need to compute the estimated arrival times at each* waypoint)*****************************************************************************/static void path_generate_points( GVU_Path path, Path_record data[], int nrecords, float speed ){ float etime = 0.0f; int inx; for( inx = 0; inx<nrecords; inx++ ) { GVU_Path_point point; G_Rotation radians; G_Position last_pos; float distance; float dt; G_Vector3 diff; /* Create a point for each data record */ GVU_path_point_create( &point ); /* Create an artificial speed to move through the path since the original sample data was not time synchronized */ if( inx > 0 ) { last_pos = data[inx-1].position; G_vec_subtract( &data[inx].position, &last_pos, &diff ); G_vec_magnitude( &diff, &distance ); /* Minor smoothing with delta time from last frame */ dt = distance / speed; etime += dt; } radians.x = data[inx].rotation.x * G_DEG_TO_RAD; radians.y = data[inx].rotation.y * G_DEG_TO_RAD; radians.z = data[inx].rotation.z * G_DEG_TO_RAD; GVU_path_point_set_rotation( point, &radians ); GVU_path_point_set_position( point, &data[inx].position ); GVU_path_point_set_time( point, etime ); GVU_path_add_point( path, point ); data[inx].elapsed_time = etime; if( debug ) fprintf( stdout, "path_generate_points: elapsed time %f for " "point #%d at %.2f,%.2f,%.2f\n", etime, inx, data[inx].position.x, data[inx].position.y, data[inx].position.z ); }}/****************************************************************************** path_other_create --** Create a path for the other1 moving train in the scene******************************************************************************/static GVU_Path path_other_create( int tnumber ){ GVU_Path path = NULL; if( (tnumber >= 0 && tnumber < NUM_VEHICLES) && vobi[tnumber] ) { static float speed[NUM_VEHICLES] = {15.0f, 1.0f, 15.0f}; G_Name name; GV_obi_inq_name( vobi[tnumber], name ); GVU_path_create( &path ); GVU_path_set_smoothing( path, GVU_PATH_SMOOTHING_SPLINE ); GVU_path_set_state( path, G_ON ); GVU_path_set_type( path, GVU_PATH_TYPE_OPEN ); GVU_path_set_name( path, name ); if( tnumber == 0 ) path_generate_points( path, path_data_other0, NRECORDS_OTHER0, speed[tnumber] ); else if( tnumber == 1 ) path_generate_points( path, path_data_other1, NRECORDS_OTHER1, speed[tnumber] ); else if( tnumber == 2 ) path_generate_points( path, path_data_other2, NRECORDS_OTHER2, speed[tnumber] ); } else fprintf( stderr, "path_other_create: " "could not setup path for vehicle #%d\n", tnumber ); return path;}/****************************************************************************** path_owntrain_create --** Create a path for the owntrain ******************************************************************************/static GVU_Path path_owntrain_create( void ){ char * filename = "path_owntrain.txt"; GVU_Path lpath = NULL; FILE *stream = NULL; int inx = 0; GVU_Path_point point; G_Position start_position, pos; G_Rotation start_rotation, rot; char header[128], s1[128], s2[128], s3[128], nrecords[24]; float elapsed_time; stream = fopen( filename, "r" ); if( stream == NULL ) { fprintf( stderr, "path_owntrain_create: " "could not open path data file %s\n", filename ); return NULL; } /* Read the initial header record (and ignore it) */ fscanf( stream, "%s%s%s%s%s", header,nrecords,s1,s2,s3); GVU_path_create( &lpath ); GVU_path_set_smoothing( lpath, GVU_PATH_SMOOTHING_SPLINE ); GVU_path_set_state( lpath, G_ON ); GVU_path_set_type( lpath, GVU_PATH_TYPE_OPEN ); GVU_path_set_name( lpath, "OWNTRAIN" ); GVU_path_set_finish_callback( lpath, path_train_finished ); /* Read the PATH file till done */ while( fscanf( stream, "%f,%f,%f,%f,%f,%f,%f,", &pos.x,&pos.y,&pos.z, &rot.x,&rot.y,&rot.z, &elapsed_time)!= EOF) { /* Create a point for each data record */ GVU_path_point_create( &point ); /* Add the point to the path */ GVU_path_point_set_position( point, &pos); GVU_path_point_set_rotation( point, &rot); GVU_path_point_set_time( point, elapsed_time ); /* Now that we've finished defining this point, it is now OK to formally add it to the path */ GVU_path_add_point( lpath, point ); inx++; } /* Finished reading the file... close it now */ fclose( stream ); /* Initialize the object to be in the right place on the first frame */ GVU_path_set_speed_scale( lpath, 1.0 ); GVU_path_point_inq_first( lpath, &point ); GVU_path_point_inq_position( point, &start_position ); GVU_path_point_inq_rotation( point, &start_rotation ); return lpath;}/***************************************************************************** ** GV_user_init --** Callback function from OpenGVS which is called* once during OpenGVS system initialization. ******************************************************************************/int GV_user_init( void ){ int ists; int unit; int nunits; /* Get pointer to parse data */ tparse_inq_data( &tdata ); /* Create graphics resources and then make necessary connections */ gfx_create_resources(); gfx_connect_resources(); if( !pcf_realtime ) { /* Turn off real-time calculations (use steady state dt for demo) */ G_timer_set_realtime_state( G_OFF ); G_timer_set_frame_period_const( 1.0/30.0f ); } if( tdata && tdata->network_duties != NETWORK_DUTIES_SLAVE ) { int inx; path_owntrain = path_owntrain_create(); /* Our train */ for( inx=0; inx<NUM_VEHICLES; inx++ ) path_other[inx] = path_other_create(inx); /* Add external train */ events_init(); /* Event handlers */ } /* Finished with initialization; time to start graphics as required */ nunits = tmultifbf_inq_nunits(); for( unit=0; unit<nunits; unit++) GV_fbf_add_channel(fbf[unit], tchannel[unit] ); if( tdata && tdata->network_duties == NETWORK_DUTIES_MASTER ) { /* Network communications are active; have master setup host data */ static int nslaves = 1; static int extrawait_milliseconds = 500; static GV_Camera cam_engineer = NULL; static GV_Obi owntrain = NULL; if( !cam_engineer ) GV_cam_set_name( cam_engineer, "ENGINEER" ); if( !owntrain ) GV_obi_inq_by_name( "OWNTRAIN", &owntrain ); host_master_init( owntrain, cam_engineer ); /* Establish network communications */ ists = dnet_master_init( tchannel[0] ) ; /* Force a rendezvous with at least ONE of the slaves before we proceed to runtime */ ists = dnet_wait_for_slaves( nslaves, extrawait_milliseconds ); ists = dnet_sync_video() ; fprintf( stdout, "train: Running as a network master.\n" ); } else if( tdata && tdata->network_duties == NETWORK_DUTIES_SLAVE ) { fprintf(stdout, "train: Waiting for network connection to master...\n"); ists = dnet_slave_init( tchannel[0] ) ; ists = dnet_sync_video() ; fprintf( stdout, "train: Running as a network slave.\n" ); } if ( pcf_timing ) ttiming_init( 32000 , tchannel[0] ) ; return G_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -