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
68 write(std::ostream &out,
int indent_level)
const {
70 <<
"VrpnClient, server " << _server_name <<
"\n";
73 indent(out, indent_level + 2)
76 indent(out, indent_level + 2)
77 <<
"(no connection)\n";
80 if (!_trackers.empty()) {
81 indent(out, indent_level + 2)
82 << _trackers.size() <<
" trackers:\n";
83 Trackers::const_iterator ti;
84 for (ti = _trackers.begin(); ti != _trackers.end(); ++ti) {
86 vrpn_tracker->write(out, indent_level + 4);
90 if (!_buttons.empty()) {
91 indent(out, indent_level + 2)
92 << _buttons.size() <<
" buttons:\n";
93 Buttons::const_iterator bi;
94 for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
96 vrpn_button->write(out, indent_level + 4);
100 if (!_analogs.empty()) {
101 indent(out, indent_level + 2)
102 << _analogs.size() <<
" analogs:\n";
103 Analogs::const_iterator ai;
104 for (ai = _analogs.begin(); ai != _analogs.end(); ++ai) {
106 vrpn_analog->write(out, indent_level + 4);
110 if (!_dials.empty()) {
111 indent(out, indent_level + 2)
112 << _dials.size() <<
" dials:\n";
113 Dials::const_iterator di;
114 for (di = _dials.begin(); di != _dials.end(); ++di) {
116 vrpn_dial->write(out, indent_level + 4);
131 make_device(
TypeHandle device_type,
const string &device_name) {
132 if (device_type == ClientTrackerDevice::get_class_type()) {
133 return make_tracker_device(device_name);
135 }
else if (device_type == ClientButtonDevice::get_class_type()) {
136 return make_button_device(device_name);
138 }
else if (device_type == ClientAnalogDevice::get_class_type()) {
139 return make_analog_device(device_name);
141 }
else if (device_type == ClientDialDevice::get_class_type()) {
142 return make_dial_device(device_name);
158 disconnect_device(
TypeHandle device_type,
const string &device_name,
160 if (vrpn_cat.is_debug()) {
162 <<
"Disconnecting device " << *device <<
"\n";
165 if (ClientBase::disconnect_device(device_type, device_name, device)) {
166 if (device->
is_of_type(VrpnTrackerDevice::get_class_type())) {
169 }
else if (device->
is_of_type(VrpnButtonDevice::get_class_type())) {
172 }
else if (device->
is_of_type(VrpnAnalogDevice::get_class_type())) {
175 }
else if (device->
is_of_type(VrpnDialDevice::get_class_type())) {
193 ClientBase::do_poll();
195 if (vrpn_cat.is_spam()) {
197 <<
"VrpnClient " << _server_name <<
" polling "
198 << _trackers.size() + _buttons.size() + _analogs.size() + _dials.size()
202 Trackers::iterator ti;
203 for (ti = _trackers.begin(); ti != _trackers.end(); ++ti) {
205 vrpn_tracker->
poll();
208 Buttons::iterator bi;
209 for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
214 Analogs::iterator ai;
215 for (ai = _analogs.begin(); ai != _analogs.end(); ++ai) {
221 for (di = _dials.begin(); di != _dials.end(); ++di) {
249 make_tracker_device(
const string &device_name) {
250 if (vrpn_cat.is_debug()) {
252 <<
"Making tracker device for " << device_name <<
"\n";
255 string tracker_name = device_name;
257 VrpnTrackerDevice::DataType data_type = VrpnTrackerDevice::DT_position;
259 size_t colon = device_name.rfind(
':');
260 if (colon != string::npos && colon + 1 < device_name.length()) {
261 size_t begin = colon + 1;
262 size_t end = device_name.length();
263 VrpnTrackerDevice::DataType maybe_data_type = data_type;
265 switch (device_name[end - 1]) {
267 maybe_data_type = VrpnTrackerDevice::DT_position;
272 maybe_data_type = VrpnTrackerDevice::DT_velocity;
277 maybe_data_type = VrpnTrackerDevice::DT_acceleration;
282 if (
string_to_int(device_name.substr(begin, end - begin), maybe_sensor)) {
284 sensor = maybe_sensor;
285 data_type = maybe_data_type;
286 tracker_name = device_name.substr(0, colon);
295 if (vrpn_cat.is_debug()) {
297 <<
"Creating " << *device <<
"\n";
300 tracker->
mark(device);
309 make_button_device(
const string &device_name) {
310 if (vrpn_cat.is_debug()) {
312 <<
"Making button device for " << device_name <<
"\n";
320 if (vrpn_cat.is_debug()) {
322 <<
"Creating " << *device <<
"\n";
325 button->
mark(device);
334 make_analog_device(
const string &device_name) {
335 if (vrpn_cat.is_debug()) {
337 <<
"Making analog device for " << device_name <<
"\n";
345 if (vrpn_cat.is_debug()) {
347 <<
"Creating " << *device <<
"\n";
350 analog->
mark(device);
359 make_dial_device(
const string &device_name) {
360 if (vrpn_cat.is_debug()) {
362 <<
"Making dial device for " << device_name <<
"\n";
365 VrpnDial *dial = get_dial(device_name);
370 if (vrpn_cat.is_debug()) {
372 <<
"Creating " << *device <<
"\n";
385 vrpn_tracker->
unmark(device);
387 free_tracker(vrpn_tracker);
397 vrpn_button->
unmark(device);
399 free_button(vrpn_button);
409 vrpn_analog->
unmark(device);
411 free_analog(vrpn_analog);
421 vrpn_dial->
unmark(device);
423 free_dial(vrpn_dial);
432 get_tracker(
const string &tracker_name) {
433 Trackers::iterator ti;
434 ti = _trackers.find(tracker_name);
436 if (ti != _trackers.end()) {
441 _trackers.insert(Trackers::value_type(tracker_name, vrpn_tracker));
443 if (vrpn_cat.is_debug()) {
445 <<
"Creating tracker " << *vrpn_tracker <<
"\n";
459 if (vrpn_cat.is_debug()) {
461 <<
"Deleting tracker " << *vrpn_tracker <<
"\n";
464 Trackers::iterator ti;
466 nassertv(ti != _trackers.end());
467 nassertv((*ti).second == vrpn_tracker);
478 get_button(
const string &button_name) {
479 Buttons::iterator bi;
480 bi = _buttons.find(button_name);
482 if (bi != _buttons.end()) {
487 _buttons.insert(Buttons::value_type(button_name, vrpn_button));
489 if (vrpn_cat.is_debug()) {
491 <<
"Creating button " << *vrpn_button <<
"\n";
505 if (vrpn_cat.is_debug()) {
507 <<
"Deleting button " << *vrpn_button <<
"\n";
510 Buttons::iterator bi;
512 nassertv(bi != _buttons.end());
513 nassertv((*bi).second == vrpn_button);
524 get_analog(
const string &analog_name) {
525 Analogs::iterator ai;
526 ai = _analogs.find(analog_name);
528 if (ai != _analogs.end()) {
533 _analogs.insert(Analogs::value_type(analog_name, vrpn_analog));
535 if (vrpn_cat.is_debug()) {
537 <<
"Creating analog " << *vrpn_analog <<
"\n";
551 if (vrpn_cat.is_debug()) {
553 <<
"Deleting analog " << *vrpn_analog <<
"\n";
556 Analogs::iterator ai;
558 nassertv(ai != _analogs.end());
559 nassertv((*ai).second == vrpn_analog);
570 get_dial(
const string &dial_name) {
572 di = _dials.find(dial_name);
574 if (di != _dials.end()) {
579 _dials.insert(Dials::value_type(dial_name, vrpn_dial));
581 if (vrpn_cat.is_debug()) {
583 <<
"Creating dial " << *vrpn_dial <<
"\n";
597 if (vrpn_cat.is_debug()) {
599 <<
"Deleting dial " << *vrpn_dial <<
"\n";
604 nassertv(di != _dials.end());
605 nassertv((*di).second == vrpn_dial);
627 add_remote_tracker(
const string &tracker,
int sensor) {
629 vrpn_Tracker_Remote *vrpn_tracker =
new vrpn_Tracker_Remote(tracker.c_str(), _connection);
630 if (vrpn_tracker ==
nullptr) {
637 VrpnClientInfo *data =
new VrpnClientInfo;
638 data->device_name = tracker;
641 vrpn_tracker->register_change_handler((
void*)data, st_tracker_position);
642 vrpn_tracker->register_change_handler((
void*)data, st_tracker_velocity);
643 vrpn_tracker->register_change_handler((
void*)data, st_tracker_acceleration);
645 _vrpn_trackers[tracker] = vrpn_tracker;
646 _trackers.push_back(tracker);
647 _sensors[tracker].push_back(sensor);
656 add_remote_analog(
const string &analog) {
658 vrpn_Analog_Remote *vrpn_analog =
new vrpn_Analog_Remote(analog.c_str(), _connection);
659 if (vrpn_analog ==
nullptr) {
666 VrpnClientInfo *data =
new VrpnClientInfo;
667 data->device_name = analog;
670 vrpn_analog->register_change_handler((
void*)data, st_analog);
672 _vrpn_analogs[analog] = vrpn_analog;
673 _analogs.push_back(analog);
682 add_remote_button(
const string &button) {
684 vrpn_Button_Remote *vrpn_button =
new vrpn_Button_Remote(button.c_str(), _connection);
685 if (vrpn_button ==
nullptr) {
692 VrpnClientInfo *data =
new VrpnClientInfo;
693 data->device_name = button;
696 vrpn_button->register_change_handler((
void*)data, st_button);
698 _vrpn_buttons[button] = vrpn_button;
699 _buttons.push_back(button);
708 add_remote_dial(
const string &dial) {
710 vrpn_Dial_Remote *vrpn_dial =
new vrpn_Dial_Remote(dial.c_str(), _connection);
711 if (vrpn_dial ==
nullptr) {
718 VrpnClientInfo *data =
new VrpnClientInfo;
719 data->device_name = dial;
722 vrpn_dial->register_change_handler((
void*)data, st_dial);
724 _vrpn_dials[dial] = vrpn_dial;
725 _dials.push_back(dial);
734 max_analog_channels() {
735 return vrpn_CHANNEL_MAX;
747 poll_tracker(
const string &tracker) {
748 _vrpn_trackers[tracker]->mainloop();
755 poll_analog(
const string &analog) {
756 _vrpn_analogs[analog]->mainloop();
763 poll_button(
const string &button) {
764 _vrpn_buttons[button]->mainloop();
771 poll_dial(
const string &dial) {
772 _vrpn_dials[dial]->mainloop();
779 void VRPN_CALLBACK VrpnClient::
780 st_tracker_position(
void *userdata,
const vrpn_TRACKERCB info) {
781 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
782 ((
VrpnClient *)data->self)->tracker_position(data->device_name, info);
789 void VRPN_CALLBACK VrpnClient::
790 st_tracker_velocity(
void *userdata,
const vrpn_TRACKERVELCB info) {
791 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
792 ((
VrpnClient *)data->self)->tracker_velocity(data->device_name, info);
798 void VRPN_CALLBACK VrpnClient::
799 st_tracker_acceleration(
void *userdata,
const vrpn_TRACKERACCCB info) {
800 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
801 ((
VrpnClient *)data->self)->tracker_acceleration(data->device_name, info);
809 st_analog(
void *userdata,
const vrpn_ANALOGCB info) {
810 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
811 ((
VrpnClient *)data->self)->analog(data->device_name, info);
819 st_button(
void *userdata,
const vrpn_BUTTONCB info) {
820 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
821 ((
VrpnClient *)data->self)->button(data->device_name, info);
829 st_dial(
void *userdata,
const vrpn_DIALCB info) {
830 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
831 ((
VrpnClient *)data->self)->dial(data->device_name, info);