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);
VrpnDial * get_vrpn_dial() const
Returns a pointer to the particular VrpnDial this device gets its data from.
int string_to_int(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
VrpnTracker * get_vrpn_tracker() const
Returns a pointer to the particular VrpnTracker this device gets its data from.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_connected() const
Returns true if the connection is established successfully, false otherwise.
A specific ClientBase that connects to a VRPN server and records information on the connected VRPN de...
void unmark(VrpnAnalogDevice *device)
Removes the indicated VrpnAnalogDevice from the list of devices that are sharing this VrpnAnalog.
void poll()
Polls the connected device.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void unmark(VrpnTrackerDevice *device)
Removes the indicated VrpnTrackerDevice from the list of devices that are sharing this VrpnTracker.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The Panda interface to a VRPN analog device.
This is the actual interface to a particular VRPN tracker object, and all of its sensors.
const std::string & get_tracker_name() const
Returns the name of the tracker device that was used to create this VrpnTracker.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The Panda interface to a VRPN tracker.
The Panda interface to a VRPN dial device.
const std::string & get_analog_name() const
Returns the name of the analog device that was used to create this VrpnAnalog.
bool is_valid() const
Returns true if everything seems to be kosher with the server (even if there is no connection),...
PT(ClientDevice) VrpnClient
Creates and returns a new ClientDevice of the appropriate type, according to the requested device_typ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
VrpnAnalog * get_vrpn_analog() const
Returns a pointer to the particular VrpnAnalog this device gets its data from.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void mark(VrpnTrackerDevice *device)
Adds the indicated VrpnTrackerDevice to the list of devices that are sharing this VrpnTracker.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
void mark(VrpnDialDevice *device)
Adds the indicated VrpnDialDevice to the list of devices that are sharing this VrpnDial.
void poll()
Polls the connected device.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_empty() const
Returns true if no VrpnDialDevices reference this VrpnDial, or false otherwise.
void poll()
Polls the connected device.
const std::string & get_dial_name() const
Returns the name of the dial device that was used to create this VrpnDial.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_empty() const
Returns true if no VrpnTrackerDevices reference this VrpnTracker, or false otherwise.
bool is_empty() const
Returns true if no VrpnAnalogDevices reference this VrpnAnalog, or false otherwise.
This is the actual interface to a particular VRPN dial device, and all of its numbered dials.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
void unmark(VrpnDialDevice *device)
Removes the indicated VrpnDialDevice from the list of devices that are sharing this VrpnDial.
void mark(VrpnAnalogDevice *device)
Adds the indicated VrpnAnalogDevice to the list of devices that are sharing this VrpnAnalog.
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the actual interface to a particular VRPN analog device, and all of its numbered controls.
Any of a number of different devices that might be attached to a ClientBase, including trackers,...