87#ifdef VRPN_USE_WINSOCK_SOCKETS
88 #ifdef VRPN_USE_WINSOCK2
95 #include <netinet/in.h>
96 #include <sys/socket.h>
98 #include <sys/select.h>
109#define DTRACK2VRPN_BUTTONS_PER_FLYSTICK 8
110#define DTRACK2VRPN_ANALOGS_PER_FLYSTICK 2
112#define UDPRECEIVE_BUFSIZE 20000
118#define DTRACK_ERR_NONE 0
119#define DTRACK_ERR_TIMEOUT 1
120#define DTRACK_ERR_UDP 2
121#define DTRACK_ERR_PARSE 3
125static char* string_nextline(
char* str,
char* start,
int len);
126static char* string_get_i(
char* str,
int* i);
127static char* string_get_ui(
char* str,
unsigned int* ui);
128static char* string_get_d(
char* str,
double* d);
129static char* string_get_f(
char* str,
float* f);
130static char* string_get_block(
char* str,
const char* fmt,
int* idat,
float* fdat);
132static unsigned int ip_name2ip(
const char* name );
133static vrpn_SOCKET udp_init(
unsigned short port,
unsigned int multicastIp );
134static int udp_exit(
vrpn_SOCKET sock,
unsigned int multicastIp );
135static int udp_receive(
vrpn_SOCKET sock,
void *buffer,
int maxlen,
int tout_us );
136static int udp_send(
vrpn_SOCKET sock,
const void* buffer,
int len,
unsigned int ip,
unsigned short port,
int toutUs );
152 const char* dtrackHost,
int dtrackPort,
bool doFirewall,
153 float timeToReachJoy,
154 int fixNbody,
int fixNflystick,
int* fixId,
155 bool act3DOFout,
bool actTracing ) :
170 output_3dof_marker = act3DOFout;
171 tracing = actTracing;
174 tim_first.tv_sec = tim_first.tv_usec = 0;
175 tim_last.tv_sec = tim_last.tv_usec = 0;
179 if(fixNbody >= 0 && fixNflystick >= 0){
180 use_fix_numbering =
true;
182 fix_nbody = fixNbody;
183 fix_nflystick = fixNflystick;
185 fix_idbody.resize(fix_nbody + fix_nflystick);
186 fix_idflystick.resize(fix_nflystick);
189 for(i=0; i<fix_nbody + fix_nflystick; i++){
190 fix_idbody[i] = fixId[i];
193 for(i=0; i<fix_nflystick; i++){
194 fix_idflystick[i] = fixId[i + fix_nbody];
197 for(i=0; i<fix_nbody; i++){
198 for(
int j=0; j<fix_nflystick; j++){
199 if(fixId[i] < fixId[j + fix_nbody] && fix_idflystick[j] > 0){
205 for(i=0; i<fix_nbody + fix_nflystick; i++){
208 for(i=0; i<fix_nflystick; i++){
209 fix_idflystick[i] = i;
213 use_fix_numbering =
false;
216 warning_nbodycal =
false;
220 if(timeToReachJoy > 1e-20){
221 joy_incPerSec = 1.f / timeToReachJoy;
223 joy_incPerSec = 1e20f;
229 if ( dtrackHost != NULL )
231 ip = ip_name2ip( dtrackHost );
234 fprintf( stderr,
"vrpn_Tracker_DTrack: Cannot resolve hostname/IP '%s'.\n", dtrackHost );
235 exit( EXIT_FAILURE );
239 if ( ! dtrack_init( ip, dtrackPort, doFirewall ) )
241 exit( EXIT_FAILURE );
266 int nbody, nflystick, i;
275 if(!dtrack_receive()){
277 fprintf(stderr,
"vrpn_Tracker_DTrack: Receive Error from DTrack.\n");
288 if ( act_timestamp_sec > 0 )
290 struct timeval timestamp_dt;
291 timestamp_dt.tv_sec = act_timestamp_sec;
292 timestamp_dt.tv_usec = act_timestamp_usec;
296 if (
timestamp.tv_usec < (
int )act_latency_usec )
298 timestamp.tv_usec += 1000000 - act_latency_usec;
311 else if ( act_timestamp >= 0 )
313 tts = (long )act_timestamp;
314 ttu = (long )((act_timestamp - tts) * 1000000);
317 if(tts >=
timestamp.tv_sec + 43200 - 1800){
319 }
else if(tts <=
timestamp.tv_sec - 43200 - 1800){
327 if(tim_first.tv_sec == 0 && tim_first.tv_usec == 0){
334 if ( tracing && ( ( tracing_frames % 10 ) == 0 ) )
336 printf(
"framenr %u ts %d.%06d dtime %.6lf\n", act_framecounter, (
int )
timestamp.tv_sec, (
int )
timestamp.tv_usec,
346 if(use_fix_numbering){
348 nflystick = fix_nflystick;
349 }
else if(act_has_bodycal_format){
350 nbody = act_num_bodycal;
351 nflystick = act_num_flystick;
353 if(!warning_nbodycal){
354 fprintf(stderr,
"vrpn_Tracker_DTrack warning: no DTrack '6dcal' data available.\n");
355 warning_nbodycal =
true;
358 nbody = act_num_body;
359 nflystick = act_num_flystick;
368 for(i=0; i<act_num_body; i++){
369 if(act_body[i].
id < nbody){
370 if(act_body[i].quality >= 0){
371 if(use_fix_numbering){
372 newid = fix_idbody[act_body[i].id];
374 newid = act_body[i].id;
377 dtrack2vrpn_body(newid,
"", act_body[i].
id, act_body[i].loc, act_body[i].rot,
timestamp);
382 if(
num_channel >=
static_cast<int>(joy_last.size())){
383 size_t j0 = joy_last.size();
388 for(
size_t j=j0; j< static_cast<size_t>(
num_channel); j++){
389 joy_simulate[j] =
false;
394 for(i=0; i<(int)act_num_flystick; i++){
395 if(act_flystick[i].
id < nflystick){
396 if(act_flystick[i].quality >= 0){
397 if(use_fix_numbering){
398 newid = fix_idbody[act_flystick[i].id + nbody];
400 newid = act_flystick[i].id + nbody;
403 dtrack2vrpn_body(newid,
"f", act_flystick[i].
id, act_flystick[i].loc, act_flystick[i].rot,
407 if(use_fix_numbering){
408 newid = fix_idflystick[act_flystick[i].id];
410 newid = act_flystick[i].id;
413 dtrack2vrpn_flystickbuttons(newid, act_flystick[i].
id,
414 act_flystick[i].num_button, act_flystick[i].button,
timestamp);
416 dtrack2vrpn_flystickanalogs(newid, act_flystick[i].
id,
417 act_flystick[i].num_joystick, act_flystick[i].joystick, dt,
timestamp);
421 if (output_3dof_marker) {
424 for(i=0; i<act_num_marker; i++){
425 dtrack2vrpn_marker(offset + i,
"m", act_marker[i].
id, act_marker[i].loc,
timestamp);
453int vrpn_Tracker_DTrack::dtrack2vrpn_marker(
int id,
const char* str_dtrack,
int id_dtrack,
454 const float* loc,
struct timeval timestamp)
461 pos[0] = loc[0] / 1000.;
462 pos[1] = loc[1] / 1000.;
463 pos[2] = loc[2] / 1000.;
467 q_make(
d_quat, 1, 0, 0, 0);
478 fprintf(stderr,
"vrpn_Tracker_DTrack: cannot write message: tossing.\n");
484 if(tracing && ((tracing_frames % 10) == 0)){
486 printf(
"marker id (DTrack vrpn): %s%d %d pos (x y z): %.4f %.4f %.4f\n",
487 str_dtrack, id_dtrack,
id,
pos[0],
pos[1],
pos[2]);
503int vrpn_Tracker_DTrack::dtrack2vrpn_body(
int id,
const char* str_dtrack,
int id_dtrack,
504 const float* loc,
const float* rot,
struct timeval timestamp)
511 pos[0] = loc[0] / 1000.;
512 pos[1] = loc[1] / 1000.;
513 pos[2] = loc[2] / 1000.;
517 q_matrix_type destMatrix;
519 destMatrix[0][0] = rot[0];
520 destMatrix[0][1] = rot[1];
521 destMatrix[0][2] = rot[2];
522 destMatrix[0][3] = 0.0;
524 destMatrix[1][0] = rot[3];
525 destMatrix[1][1] = rot[4];
526 destMatrix[1][2] = rot[5];
527 destMatrix[1][3] = 0.0;
529 destMatrix[2][0] = rot[6];
530 destMatrix[2][1] = rot[7];
531 destMatrix[2][2] = rot[8];
532 destMatrix[2][3] = 0.0;
534 destMatrix[3][0] = 0.0;
535 destMatrix[3][1] = 0.0;
536 destMatrix[3][2] = 0.0;
537 destMatrix[3][3] = 1.0;
539 q_from_row_matrix(
d_quat, destMatrix);
550 fprintf(stderr,
"vrpn_Tracker_DTrack: cannot write message: tossing.\n");
556 if(tracing && ((tracing_frames % 10) == 0)){
557 q_vec_type yawPitchRoll;
559 q_to_euler(yawPitchRoll,
d_quat);
561 printf(
"body id (DTrack vrpn): %s%d %d pos (x y z): %.4f %.4f %.4f euler (y p r): %.3f %.3f %.3f\n",
562 str_dtrack, id_dtrack,
id,
pos[0],
pos[1],
pos[2],
563 Q_RAD_TO_DEG(yawPitchRoll[0]), Q_RAD_TO_DEG(yawPitchRoll[1]), Q_RAD_TO_DEG(yawPitchRoll[2]));
578int vrpn_Tracker_DTrack::dtrack2vrpn_flystickbuttons(
int id,
int id_dtrack,
579 int num_but,
const int* but,
struct timeval timestamp)
600 if(act_has_old_flystick_format){
610 if(tracing && ((tracing_frames % 10) == 0)){
611 printf(
"flystick id (DTrack vrpn): f%d %d but ", id_dtrack,
id);
613 printf(
" %d", but[i]);
631int vrpn_Tracker_DTrack::dtrack2vrpn_flystickanalogs(
int id,
int id_dtrack,
632 int num_ana,
const float* ana,
float dt,
struct timeval timestamp)
652 joy_simulate[ind] =
false;
653 }
else if((f > 0.99 || f < -0.99) && joy_last[ind] == 0){
654 joy_simulate[ind] =
true;
657 if(joy_simulate[ind]){
659 f = joy_last[ind] + joy_incPerSec * dt;
663 joy_simulate[ind] =
false;
666 f = joy_last[ind] - joy_incPerSec * dt;
670 joy_simulate[ind] =
false;
688 if(tracing && ((tracing_frames % 10) == 0)){
689 printf(
"flystick id (DTrack vrpn): f%d %d ana ", id_dtrack,
id);
691 printf(
" %.2f", ana[i]);
713bool vrpn_Tracker_DTrack::dtrack_init(
unsigned int serverIp,
int udpport,
bool doFirewall )
718 if ( ( serverIp & 0xf0000000 ) == 0xe0000000 )
720 d_multicastIp = serverIp;
724 fprintf( stderr,
"vrpn_Tracker_DTrack: Cannot enable UDP traffic through stateful firewall.\n" );
728 else if ( ! doFirewall )
730 fprintf( stderr,
"vrpn_Tracker_DTrack: Cannot connect to DTRACK in communicating mode.\n" );
740 if(udpport <= 0 || udpport > 65535){
741 fprintf(stderr,
"vrpn_Tracker_DTrack: Illegal UDP port %d.\n", udpport);
745 d_udpsock = udp_init( (
unsigned short )udpport, d_multicastIp );
748 fprintf(stderr,
"vrpn_Tracker_DTrack: Cannot Initialize UDP Socket.\n");
758 d_udpbuf = (
char *)malloc(d_udpbufsize);
760 if(d_udpbuf == NULL){
761 udp_exit( d_udpsock, d_multicastIp );
763 fprintf(stderr,
"vrpn_Tracker_DTrack: Cannot Allocate Memory for UDP Buffer.\n");
769 act_framecounter = 0;
771 act_timestamp_sec = 0;
772 act_timestamp_usec = 0;
773 act_latency_usec = 0;
775 act_num_marker = act_num_body = act_num_flystick = 0;
776 act_has_bodycal_format =
false;
777 act_has_old_flystick_format =
false;
783 const char* txt =
"fw4vrpndt";
785 udp_send( d_udpsock, (
void* )txt, (
int )strlen( txt ) + 1, serverIp, 50107, 100000 );
796bool vrpn_Tracker_DTrack::dtrack_exit()
801 if(d_udpbuf != NULL){
808 udp_exit( d_udpsock, d_multicastIp );
819bool vrpn_Tracker_DTrack::dtrack_receive()
822 int i, j, k, l, n, len, id;
826 int loc_num_bodycal, loc_num_flystick1, loc_num_meatool;
835 act_framecounter = 0;
837 act_timestamp_sec = 0;
838 act_timestamp_usec = 0;
839 act_latency_usec = 0;
841 loc_num_bodycal = -1;
842 loc_num_flystick1 = loc_num_meatool = 0;
844 act_has_bodycal_format =
false;
848 len = udp_receive(d_udpsock, d_udpbuf, d_udpbufsize-1, d_udptimeout_us);
869 if(!strncmp(s,
"fr ", 3)){
872 if(!(s = string_get_ui(s, &act_framecounter))){
873 act_framecounter = 0;
882 if(!strncmp(s,
"ts ", 3)){
885 if(!(s = string_get_d(s, &act_timestamp))){
895 if ( strncmp( s,
"ts2 ", 4 ) == 0 )
899 s = string_get_ui( s, &act_timestamp_sec );
902 s = string_get_ui( s, &act_timestamp_usec );
905 s = string_get_ui( s, &act_latency_usec );
909 act_timestamp_sec = 0;
910 act_timestamp_usec = 0;
911 act_latency_usec = 0;
920 if(!strncmp(s,
"6dcal ", 6)){
923 act_has_bodycal_format =
true;
925 if(!(s = string_get_i(s, &loc_num_bodycal))){
934 if(!strncmp(s,
"3d ", 3)){
938 if(!(s = string_get_i(s, &n))){
942 if (
static_cast<unsigned>(n) > act_marker.size()) {
943 act_marker.resize(n);
947 if(!(s = string_get_block(s,
"if", &
id, &f))){
951 act_marker[act_num_marker].id = id;
953 if(!(s = string_get_block(s,
"fff", NULL, act_marker[act_num_marker].loc))){
965 if(!strncmp(s,
"6d ", 3)){
968 for(i=0; i<act_num_body; i++){
969 memset(&act_body[i], 0,
sizeof(vrpn_dtrack_body_type));
971 act_body[i].quality = -1;
974 if(!(s = string_get_i(s, &n))){
979 if(!(s = string_get_block(s,
"if", &
id, &f))){
983 if(
id >= act_num_body){
984 act_body.resize(
id + 1);
986 for(j=act_num_body; j<=id; j++){
987 memset(&act_body[j], 0,
sizeof(vrpn_dtrack_body_type));
989 act_body[j].quality = -1;
992 act_num_body =
id + 1;
995 act_body[id].id = id;
996 act_body[id].quality = f;
998 if(!(s = string_get_block(s,
"fff", NULL, act_body[
id].loc))){
1002 if(!(s = string_get_block(s,
"fffffffff", NULL, act_body[
id].rot))){
1012 if(!strncmp(s,
"6df ", 4)){
1015 act_has_old_flystick_format =
true;
1017 if(!(s = string_get_i(s, &n))){
1021 loc_num_flystick1 = n;
1023 if(n > act_num_flystick){
1024 act_flystick.resize(n);
1026 act_num_flystick = n;
1030 if(!(s = string_get_block(s,
"ifi", iarr, &f))){
1038 act_flystick[i].id = iarr[0];
1039 act_flystick[i].quality = f;
1041 act_flystick[i].num_button = 8;
1044 act_flystick[i].button[j] = k & 0x01;
1048 act_flystick[i].num_joystick = 2;
1050 act_flystick[i].joystick[0] = -1;
1051 }
else if(iarr[1] & 0x80){
1052 act_flystick[i].joystick[0] = 1;
1054 act_flystick[i].joystick[0] = 0;
1057 act_flystick[i].joystick[1] = -1;
1058 }
else if(iarr[1] & 0x40){
1059 act_flystick[i].joystick[1] = 1;
1061 act_flystick[i].joystick[1] = 0;
1064 if(!(s = string_get_block(s,
"fff", NULL, act_flystick[i].loc))){
1068 if(!(s = string_get_block(s,
"fffffffff", NULL, act_flystick[i].rot))){
1078 if(!strncmp(s,
"6df2 ", 5)){
1081 act_has_old_flystick_format =
false;
1083 if(!(s = string_get_i(s, &n))){
1087 if(n > act_num_flystick){
1088 act_flystick.resize(n);
1090 act_num_flystick = n;
1093 if(!(s = string_get_i(s, &n))){
1098 if(!(s = string_get_block(s,
"ifii", iarr, &f))){
1106 act_flystick[i].id = iarr[0];
1107 act_flystick[i].quality = f;
1115 act_flystick[i].num_button = iarr[1];
1116 act_flystick[i].num_joystick = iarr[2];
1118 if(!(s = string_get_block(s,
"fff", NULL, act_flystick[i].loc))){
1122 if(!(s = string_get_block(s,
"fffffffff", NULL, act_flystick[i].rot))){
1128 while(j < act_flystick[i].num_button){
1133 while(j < act_flystick[i].num_joystick){
1138 if(!(s = string_get_block(s, sfmt, iarr, act_flystick[i].joystick))){
1143 for(j=0; j<act_flystick[i].num_button; j++){
1144 act_flystick[i].button[j] = iarr[k] & 0x01;
1160 if(!strncmp(s,
"6dmt ", 5)){
1163 if(!(s = string_get_i(s, &n))){
1167 loc_num_meatool = n;
1174 }
while((s = string_nextline(d_udpbuf, s, d_udpbufsize)) != NULL);
1178 if(loc_num_bodycal >= 0){
1179 act_num_bodycal = loc_num_bodycal - loc_num_flystick1 - loc_num_meatool;
1197static char* string_nextline(
char* str,
char* start,
int len)
1200 char* se = str + len;
1204 if(*s ==
'\r' || *s ==
'\n'){
1208 return (*s) ? s : NULL;
1224static char* string_get_i(
char* str,
int* i)
1228 *i = (int )strtol(str, &s, 0);
1229 return (s == str) ? NULL : s;
1238static char* string_get_ui(
char* str,
unsigned int* ui)
1242 *ui = (
unsigned int )strtoul( str, &s, 10 );
1243 return (s == str) ? NULL : s;
1252static char* string_get_d(
char* str,
double* d)
1256 *d = strtod(str, &s);
1257 return (s == str) ? NULL : s;
1266static char* string_get_f(
char* str,
float* f)
1270 *f = (float )strtod(str, &s);
1271 return (s == str) ? NULL : s;
1282static char* string_get_block(
char* str,
const char* fmt,
int* idat,
float* fdat)
1285 int index_i, index_f;
1287 if((str = strchr(str,
'[')) == NULL){
1290 if((strend = strchr(str,
']')) == NULL){
1297 index_i = index_f = 0;
1302 if((str = string_get_i(str, &idat[index_i++])) == NULL){
1309 if((str = string_get_f(str, &fdat[index_f++])) == NULL){
1336static unsigned int ip_name2ip(
const char* name )
1338#if defined( VRPN_USE_WINSOCK_SOCKETS ) && ! defined( VRPN_USE_WINSOCK2 )
1339 fprintf( stderr,
"vrpn_Tracker_DTrack: This build does not support multicast UDP; needs VRPN_USE_WINSOCK2.\n" );
1343 struct addrinfo hints, *res;
1345 memset( &hints, 0,
sizeof( hints ) );
1346 hints.ai_family = AF_INET;
1347 hints.ai_socktype = SOCK_STREAM;
1350 err = getaddrinfo( name, NULL, &hints, &res );
1351 if ( err != 0 || res == NULL )
1355 struct sockaddr_in sin;
1356 memcpy( &sin, res->ai_addr,
sizeof( sin ) );
1357 ip = ntohl( ( (
struct in_addr )( sin.sin_addr ) ).s_addr );
1359 freeaddrinfo( res );
1370static vrpn_SOCKET udp_init(
unsigned short port,
unsigned int multicastIp )
1373 struct sockaddr_in name;
1377#ifdef VRPN_USE_WINSOCK_SOCKETS
1382 vreq = MAKEWORD(2, 0);
1384 if(WSAStartup(vreq, &wsa) != 0){
1392 sock = socket( AF_INET, SOCK_DGRAM, 0 );
1396#ifdef VRPN_USE_WINSOCK_SOCKETS
1402 if ( multicastIp != 0 )
1406 if ( setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (
char* )&flag_on,
sizeof( flag_on ) ) < 0 )
1408 udp_exit( sock, 0 );
1415 name.sin_family = AF_INET;
1416 name.sin_port = htons(port);
1417 name.sin_addr.s_addr = htonl(INADDR_ANY);
1419 if(bind(sock, (
struct sockaddr *) &name,
sizeof(name)) < 0){
1420 udp_exit( sock, 0 );
1424 if ( multicastIp != 0 )
1427 struct ip_mreq ipmreq;
1428 ipmreq.imr_multiaddr.s_addr = htonl( multicastIp );
1429 ipmreq.imr_interface.s_addr = htonl( INADDR_ANY );
1432 if ( setsockopt( sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
char* )&ipmreq,
sizeof( ipmreq ) ) < 0 )
1434 udp_exit( sock, 0 );
1448static int udp_exit(
vrpn_SOCKET sock,
unsigned int multicastIp )
1452 if ( multicastIp != 0 )
1454 struct ip_mreq ipmreq;
1455 ipmreq.imr_multiaddr.s_addr = htonl( multicastIp );
1456 ipmreq.imr_interface.s_addr = htonl( INADDR_ANY );
1459 setsockopt( sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (
char* )&ipmreq,
sizeof( ipmreq ) );
1462#ifdef VRPN_USE_WINSOCK_SOCKETS
1463 err = closesocket(sock);
1486#ifdef VRPN_USE_WINSOCK_SOCKETS
1487#pragma warning ( disable : 4127 )
1490static int udp_receive(
vrpn_SOCKET sock,
void *buffer,
int maxlen,
int tout_us )
1494 struct timeval tout;
1501 tout.tv_sec = tout_us / 1000000;
1502 tout.tv_usec = tout_us % 1000000;
1504 switch((err = select(FD_SETSIZE, &set, NULL, NULL, &tout))){
1519 nbytes = recv(sock, (
char *)buffer, maxlen, 0);
1533 if(select(FD_SETSIZE, &set, NULL, NULL, &tout) != 1){
1537 if(nbytes >= maxlen){
1555static int udp_send(
vrpn_SOCKET sock,
const void* buffer,
int len,
unsigned int ip,
unsigned short port,
int toutUs )
1558 struct timeval tout;
1560 struct sockaddr_in addr;
1563 addr.sin_family = AF_INET;
1564 addr.sin_addr.s_addr = htonl( ip );
1565 addr.sin_port = htons( port );
1569 FD_SET( sock, &set );
1570 tout.tv_sec = toutUs / 1000000;
1571 tout.tv_usec = toutUs % 1000000;
1573 err = select( FD_SETSIZE, NULL, &set, NULL, &tout );
1585 int nbytes =
static_cast< int >( sendto( sock, (
const char* )buffer, len, 0, (
struct sockaddr* )&addr,
1586 (
size_t )
sizeof(
struct sockaddr_in ) ) );
vrpn_float64 channel[vrpn_CHANNEL_MAX]
vrpn_Analog(const char *name, vrpn_Connection *c=NULL)
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
vrpn_Connection * d_connection
Connection that this object talks to.
vrpn_int32 d_sender_id
Sender ID registered with the connection.
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
vrpn_Tracker_DTrack(const char *name, vrpn_Connection *c, const char *dtrackHost, int dtrackPort, bool doFirewall, float timeToReachJoy=0.f, int fixNbody=-1, int fixNflystick=-1, int *fixId=NULL, bool act3DOFout=false, bool actTracing=false)
virtual void mainloop()
This function should be called each time through the main loop of the server code....
virtual int encode_to(char *buf)
vrpn_Tracker(const char *name, vrpn_Connection *c=NULL, const char *tracker_cfg_file_name=NULL)
const vrpn_uint32 vrpn_CONNECTION_LOW_LATENCY
Header containing macros formerly duplicated in a lot of implementation files.
double vrpn_TimevalDurationSeconds(struct timeval endT, struct timeval startT)
Return the number of seconds between startT and endT as a floating-point value.
void vrpn_strcpy(char(&to)[charCount], const char *pSrc)
Null-terminated-string copy function that both guarantees not to overrun the buffer and guarantees th...
#define vrpn_gettimeofday
#define DTRACK2VRPN_ANALOGS_PER_FLYSTICK
#define DTRACK_ERR_TIMEOUT
#define DTRACK2VRPN_BUTTONS_PER_FLYSTICK
#define UDPRECEIVE_BUFSIZE
#define vrpn_DTRACK_FLYSTICK_MAX_BUTTON
#define vrpn_DTRACK_FLYSTICK_MAX_JOYSTICK
class VRPN_API vrpn_Connection