37VrpnClient(
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);
86write(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);
149make_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);
176disconnect_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) {
267make_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);
327make_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);
352make_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);
377make_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);
450get_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);
496get_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);
542get_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);
588get_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);
645add_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);
674add_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);
700add_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);
726add_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);
752max_analog_channels() {
753 return vrpn_CHANNEL_MAX;
765poll_tracker(
const string &tracker) {
766 _vrpn_trackers[tracker]->mainloop();
773poll_analog(
const string &analog) {
774 _vrpn_analogs[analog]->mainloop();
781poll_button(
const string &button) {
782 _vrpn_buttons[button]->mainloop();
789poll_dial(
const string &dial) {
790 _vrpn_dials[dial]->mainloop();
797void VRPN_CALLBACK VrpnClient::
798st_tracker_position(
void *userdata,
const vrpn_TRACKERCB info) {
799 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
800 ((
VrpnClient *)data->self)->tracker_position(data->device_name, info);
807void VRPN_CALLBACK VrpnClient::
808st_tracker_velocity(
void *userdata,
const vrpn_TRACKERVELCB info) {
809 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
810 ((
VrpnClient *)data->self)->tracker_velocity(data->device_name, info);
816void VRPN_CALLBACK VrpnClient::
817st_tracker_acceleration(
void *userdata,
const vrpn_TRACKERACCCB info) {
818 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
819 ((
VrpnClient *)data->self)->tracker_acceleration(data->device_name, info);
827st_analog(
void *userdata,
const vrpn_ANALOGCB info) {
828 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
829 ((
VrpnClient *)data->self)->analog(data->device_name, info);
837st_button(
void *userdata,
const vrpn_BUTTONCB info) {
838 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
839 ((
VrpnClient *)data->self)->button(data->device_name, info);
847st_dial(
void *userdata,
const vrpn_DIALCB info) {
848 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
849 ((
VrpnClient *)data->self)->dial(data->device_name, info);
Any of a number of different devices that might be attached to a ClientBase, including trackers,...
TypeHandle is the identifier used to differentiate C++ class types.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
The Panda interface to a VRPN analog device.
VrpnAnalog * get_vrpn_analog() const
Returns a pointer to the particular VrpnAnalog this device gets its data from.
This is the actual interface to a particular VRPN analog device, and all of its numbered controls.
const std::string & get_analog_name() const
Returns the name of the analog device that was used to create this VrpnAnalog.
bool is_empty() const
Returns true if no VrpnAnalogDevices reference this VrpnAnalog, or false otherwise.
void unmark(VrpnAnalogDevice *device)
Removes the indicated VrpnAnalogDevice from the list of devices that are sharing this VrpnAnalog.
void mark(VrpnAnalogDevice *device)
Adds the indicated VrpnAnalogDevice to the list of devices that are sharing this VrpnAnalog.
void poll()
Polls the connected device.
A specific ClientBase that connects to a VRPN server and records information on the connected VRPN de...
void write(std::ostream &out, int indent_level=0) const
Writes a list of the active devices that the VrpnClient is currently polling each frame.
bool is_valid() const
Returns true if everything seems to be kosher with the server (even if there is no connection),...
bool is_connected() const
Returns true if the connection is established successfully, false otherwise.
The Panda interface to a VRPN dial device.
VrpnDial * get_vrpn_dial() const
Returns a pointer to the particular VrpnDial this device gets its data from.
This is the actual interface to a particular VRPN dial device, and all of its numbered dials.
void mark(VrpnDialDevice *device)
Adds the indicated VrpnDialDevice to the list of devices that are sharing this VrpnDial.
void poll()
Polls the connected device.
void unmark(VrpnDialDevice *device)
Removes the indicated VrpnDialDevice from the list of devices that are sharing this VrpnDial.
const std::string & get_dial_name() const
Returns the name of the dial device that was used to create this VrpnDial.
bool is_empty() const
Returns true if no VrpnDialDevices reference this VrpnDial, or false otherwise.
The Panda interface to a VRPN tracker.
VrpnTracker * get_vrpn_tracker() const
Returns a pointer to the particular VrpnTracker this device gets its data from.
This is the actual interface to a particular VRPN tracker object, and all of its sensors.
bool is_empty() const
Returns true if no VrpnTrackerDevices reference this VrpnTracker, or false otherwise.
void mark(VrpnTrackerDevice *device)
Adds the indicated VrpnTrackerDevice to the list of devices that are sharing this VrpnTracker.
const std::string & get_tracker_name() const
Returns the name of the tracker device that was used to create this VrpnTracker.
void unmark(VrpnTrackerDevice *device)
Removes the indicated VrpnTrackerDevice from the list of devices that are sharing this VrpnTracker.
void poll()
Polls the connected device.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int string_to_int(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.