37 VrpnClient(
const string &server_name) :
38 _server_name(server_name)
40 if (vrpn_cat.is_debug()) {
42 <<
"Attempting to connect to VRPN server " << _server_name
45 _connection = vrpn_get_connection_by_name(_server_name.c_str());
46 nassertv(_connection !=
nullptr);
50 <<
"Unable to establish connection to VRPN server " << _server_name
69 return (_connection->doing_okay() != 0);
78 return (_connection->connected() != 0);
86 write(std::ostream &out,
int indent_level)
const {
88 <<
"VrpnClient, server " << _server_name <<
"\n";
91 indent(out, indent_level + 2)
94 indent(out, indent_level + 2)
95 <<
"(no connection)\n";
98 if (!_trackers.empty()) {
99 indent(out, indent_level + 2)
100 << _trackers.size() <<
" trackers:\n";
101 Trackers::const_iterator ti;
102 for (ti = _trackers.begin(); ti != _trackers.end(); ++ti) {
104 vrpn_tracker->write(out, indent_level + 4);
108 if (!_buttons.empty()) {
109 indent(out, indent_level + 2)
110 << _buttons.size() <<
" buttons:\n";
111 Buttons::const_iterator bi;
112 for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
114 vrpn_button->write(out, indent_level + 4);
118 if (!_analogs.empty()) {
119 indent(out, indent_level + 2)
120 << _analogs.size() <<
" analogs:\n";
121 Analogs::const_iterator ai;
122 for (ai = _analogs.begin(); ai != _analogs.end(); ++ai) {
124 vrpn_analog->write(out, indent_level + 4);
128 if (!_dials.empty()) {
129 indent(out, indent_level + 2)
130 << _dials.size() <<
" dials:\n";
131 Dials::const_iterator di;
132 for (di = _dials.begin(); di != _dials.end(); ++di) {
134 vrpn_dial->write(out, indent_level + 4);
149 make_device(
TypeHandle device_type,
const string &device_name) {
150 if (device_type == ClientTrackerDevice::get_class_type()) {
151 return make_tracker_device(device_name);
153 }
else if (device_type == ClientButtonDevice::get_class_type()) {
154 return make_button_device(device_name);
156 }
else if (device_type == ClientAnalogDevice::get_class_type()) {
157 return make_analog_device(device_name);
159 }
else if (device_type == ClientDialDevice::get_class_type()) {
160 return make_dial_device(device_name);
176 disconnect_device(
TypeHandle device_type,
const string &device_name,
178 if (vrpn_cat.is_debug()) {
180 <<
"Disconnecting device " << *device <<
"\n";
183 if (ClientBase::disconnect_device(device_type, device_name, device)) {
184 if (device->
is_of_type(VrpnTrackerDevice::get_class_type())) {
187 }
else if (device->
is_of_type(VrpnButtonDevice::get_class_type())) {
190 }
else if (device->
is_of_type(VrpnAnalogDevice::get_class_type())) {
193 }
else if (device->
is_of_type(VrpnDialDevice::get_class_type())) {
211 ClientBase::do_poll();
213 if (vrpn_cat.is_spam()) {
215 <<
"VrpnClient " << _server_name <<
" polling "
216 << _trackers.size() + _buttons.size() + _analogs.size() + _dials.size()
220 Trackers::iterator ti;
221 for (ti = _trackers.begin(); ti != _trackers.end(); ++ti) {
223 vrpn_tracker->
poll();
226 Buttons::iterator bi;
227 for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
232 Analogs::iterator ai;
233 for (ai = _analogs.begin(); ai != _analogs.end(); ++ai) {
239 for (di = _dials.begin(); di != _dials.end(); ++di) {
267 make_tracker_device(
const string &device_name) {
268 if (vrpn_cat.is_debug()) {
270 <<
"Making tracker device for " << device_name <<
"\n";
273 string tracker_name = device_name;
275 VrpnTrackerDevice::DataType data_type = VrpnTrackerDevice::DT_position;
277 size_t colon = device_name.rfind(
':');
278 if (colon != string::npos && colon + 1 < device_name.length()) {
279 size_t begin = colon + 1;
280 size_t end = device_name.length();
281 VrpnTrackerDevice::DataType maybe_data_type = data_type;
283 switch (device_name[end - 1]) {
285 maybe_data_type = VrpnTrackerDevice::DT_position;
290 maybe_data_type = VrpnTrackerDevice::DT_velocity;
295 maybe_data_type = VrpnTrackerDevice::DT_acceleration;
300 if (
string_to_int(device_name.substr(begin, end - begin), maybe_sensor)) {
302 sensor = maybe_sensor;
303 data_type = maybe_data_type;
304 tracker_name = device_name.substr(0, colon);
313 if (vrpn_cat.is_debug()) {
315 <<
"Creating " << *device <<
"\n";
318 tracker->
mark(device);
327 make_button_device(
const string &device_name) {
328 if (vrpn_cat.is_debug()) {
330 <<
"Making button device for " << device_name <<
"\n";
338 if (vrpn_cat.is_debug()) {
340 <<
"Creating " << *device <<
"\n";
343 button->
mark(device);
352 make_analog_device(
const string &device_name) {
353 if (vrpn_cat.is_debug()) {
355 <<
"Making analog device for " << device_name <<
"\n";
363 if (vrpn_cat.is_debug()) {
365 <<
"Creating " << *device <<
"\n";
368 analog->
mark(device);
377 make_dial_device(
const string &device_name) {
378 if (vrpn_cat.is_debug()) {
380 <<
"Making dial device for " << device_name <<
"\n";
383 VrpnDial *dial = get_dial(device_name);
388 if (vrpn_cat.is_debug()) {
390 <<
"Creating " << *device <<
"\n";
403 vrpn_tracker->
unmark(device);
405 free_tracker(vrpn_tracker);
415 vrpn_button->
unmark(device);
417 free_button(vrpn_button);
427 vrpn_analog->
unmark(device);
429 free_analog(vrpn_analog);
439 vrpn_dial->
unmark(device);
441 free_dial(vrpn_dial);
450 get_tracker(
const string &tracker_name) {
451 Trackers::iterator ti;
452 ti = _trackers.find(tracker_name);
454 if (ti != _trackers.end()) {
459 _trackers.insert(Trackers::value_type(tracker_name, vrpn_tracker));
461 if (vrpn_cat.is_debug()) {
463 <<
"Creating tracker " << *vrpn_tracker <<
"\n";
477 if (vrpn_cat.is_debug()) {
479 <<
"Deleting tracker " << *vrpn_tracker <<
"\n";
482 Trackers::iterator ti;
484 nassertv(ti != _trackers.end());
485 nassertv((*ti).second == vrpn_tracker);
496 get_button(
const string &button_name) {
497 Buttons::iterator bi;
498 bi = _buttons.find(button_name);
500 if (bi != _buttons.end()) {
505 _buttons.insert(Buttons::value_type(button_name, vrpn_button));
507 if (vrpn_cat.is_debug()) {
509 <<
"Creating button " << *vrpn_button <<
"\n";
523 if (vrpn_cat.is_debug()) {
525 <<
"Deleting button " << *vrpn_button <<
"\n";
528 Buttons::iterator bi;
530 nassertv(bi != _buttons.end());
531 nassertv((*bi).second == vrpn_button);
542 get_analog(
const string &analog_name) {
543 Analogs::iterator ai;
544 ai = _analogs.find(analog_name);
546 if (ai != _analogs.end()) {
551 _analogs.insert(Analogs::value_type(analog_name, vrpn_analog));
553 if (vrpn_cat.is_debug()) {
555 <<
"Creating analog " << *vrpn_analog <<
"\n";
569 if (vrpn_cat.is_debug()) {
571 <<
"Deleting analog " << *vrpn_analog <<
"\n";
574 Analogs::iterator ai;
576 nassertv(ai != _analogs.end());
577 nassertv((*ai).second == vrpn_analog);
588 get_dial(
const string &dial_name) {
590 di = _dials.find(dial_name);
592 if (di != _dials.end()) {
597 _dials.insert(Dials::value_type(dial_name, vrpn_dial));
599 if (vrpn_cat.is_debug()) {
601 <<
"Creating dial " << *vrpn_dial <<
"\n";
615 if (vrpn_cat.is_debug()) {
617 <<
"Deleting dial " << *vrpn_dial <<
"\n";
622 nassertv(di != _dials.end());
623 nassertv((*di).second == vrpn_dial);
645 add_remote_tracker(
const string &tracker,
int sensor) {
647 vrpn_Tracker_Remote *vrpn_tracker =
new vrpn_Tracker_Remote(tracker.c_str(), _connection);
648 if (vrpn_tracker ==
nullptr) {
655 VrpnClientInfo *data =
new VrpnClientInfo;
656 data->device_name = tracker;
659 vrpn_tracker->register_change_handler((
void*)data, st_tracker_position);
660 vrpn_tracker->register_change_handler((
void*)data, st_tracker_velocity);
661 vrpn_tracker->register_change_handler((
void*)data, st_tracker_acceleration);
663 _vrpn_trackers[tracker] = vrpn_tracker;
664 _trackers.push_back(tracker);
665 _sensors[tracker].push_back(sensor);
674 add_remote_analog(
const string &analog) {
676 vrpn_Analog_Remote *vrpn_analog =
new vrpn_Analog_Remote(analog.c_str(), _connection);
677 if (vrpn_analog ==
nullptr) {
684 VrpnClientInfo *data =
new VrpnClientInfo;
685 data->device_name = analog;
688 vrpn_analog->register_change_handler((
void*)data, st_analog);
690 _vrpn_analogs[analog] = vrpn_analog;
691 _analogs.push_back(analog);
700 add_remote_button(
const string &button) {
702 vrpn_Button_Remote *vrpn_button =
new vrpn_Button_Remote(button.c_str(), _connection);
703 if (vrpn_button ==
nullptr) {
710 VrpnClientInfo *data =
new VrpnClientInfo;
711 data->device_name = button;
714 vrpn_button->register_change_handler((
void*)data, st_button);
716 _vrpn_buttons[button] = vrpn_button;
717 _buttons.push_back(button);
726 add_remote_dial(
const string &dial) {
728 vrpn_Dial_Remote *vrpn_dial =
new vrpn_Dial_Remote(dial.c_str(), _connection);
729 if (vrpn_dial ==
nullptr) {
736 VrpnClientInfo *data =
new VrpnClientInfo;
737 data->device_name = dial;
740 vrpn_dial->register_change_handler((
void*)data, st_dial);
742 _vrpn_dials[dial] = vrpn_dial;
743 _dials.push_back(dial);
752 max_analog_channels() {
753 return vrpn_CHANNEL_MAX;
765 poll_tracker(
const string &tracker) {
766 _vrpn_trackers[tracker]->mainloop();
773 poll_analog(
const string &analog) {
774 _vrpn_analogs[analog]->mainloop();
781 poll_button(
const string &button) {
782 _vrpn_buttons[button]->mainloop();
789 poll_dial(
const string &dial) {
790 _vrpn_dials[dial]->mainloop();
797 void VRPN_CALLBACK VrpnClient::
798 st_tracker_position(
void *userdata,
const vrpn_TRACKERCB info) {
799 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
800 ((
VrpnClient *)data->self)->tracker_position(data->device_name, info);
807 void VRPN_CALLBACK VrpnClient::
808 st_tracker_velocity(
void *userdata,
const vrpn_TRACKERVELCB info) {
809 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
810 ((
VrpnClient *)data->self)->tracker_velocity(data->device_name, info);
816 void VRPN_CALLBACK VrpnClient::
817 st_tracker_acceleration(
void *userdata,
const vrpn_TRACKERACCCB info) {
818 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
819 ((
VrpnClient *)data->self)->tracker_acceleration(data->device_name, info);
827 st_analog(
void *userdata,
const vrpn_ANALOGCB info) {
828 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
829 ((
VrpnClient *)data->self)->analog(data->device_name, info);
837 st_button(
void *userdata,
const vrpn_BUTTONCB info) {
838 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
839 ((
VrpnClient *)data->self)->button(data->device_name, info);
847 st_dial(
void *userdata,
const vrpn_DIALCB info) {
848 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
849 ((
VrpnClient *)data->self)->dial(data->device_name, info);