vrpn 07.35
Virtual Reality Peripheral Network
 
Loading...
Searching...
No Matches
vrpn_Tracker_zSight.C
Go to the documentation of this file.
1
2//
3// Name: vrpn_Tracker_zSight.C
4//
5// Authors: David Borland
6// Josep Maria Tomas Sanahuja
7//
8// EventLab at the University of Barcelona
9//
10// Description: VRPN tracker class for Sensics zSight HMD with built-in tracker. The tracker
11// reports only orientation information, not position. It is interfaced to as
12// a DirectX joystick, so VRPN_USE_DIRECTINPUT must be defined in
13// vrpn_Configure.h to use it.
14//
16
17#include "vrpn_Tracker_zSight.h"
18
19#if defined(_WIN32) && defined(VRPN_USE_DIRECTINPUT) && defined(VRPN_HAVE_ATLBASE)
20
21#include <math.h>
22
23// Convert from 2's complement, as per the Sensics zSight documentation
24short FromTwos(unsigned short x) {
25 if ( x < 0x8000 ) {
26 return (short) x;
27 }
28 else {
29 x = x ^ 0xFFFF;
30 short y = (short) x;
31 if (y != 32767) {
32 y = y + 1;
33 }
34 y = -y;
35 return (short) y;
36 }
37}
38
39vrpn_Tracker_zSight::vrpn_Tracker_zSight(const char* name, vrpn_Connection* c) :
40 vrpn_Tracker(name, c)
41{
42 // Create a window handle
43 hWnd = CreateWindow("STATIC", "zSightWindow", WS_ICONIC, 0, 0, 10, 10, NULL, NULL, NULL, NULL);
44
45 // Initialize DirectInput and acquire the device
46 if (FAILED(InitDevice())) {
47 fprintf(stderr,"vrpn_Tracker_zSight::vrpn_Tracker_zSight(): Failed to open device\n");
48 hWnd = NULL;
49 return;
50 }
51
52 // VRPN stuff
53 register_server_handlers();
54}
55
56vrpn_Tracker_zSight::~vrpn_Tracker_zSight()
57{
58 // Release the Sensics device if necessary
59 if (sensics) {
60 sensics->Unacquire();
61 }
62}
63
64void vrpn_Tracker_zSight::mainloop()
65{
66 // Call the generic server mainloop, since we are a server
67 server_mainloop();
68
69 // Get latest data
70 get_report();
71}
72
73void vrpn_Tracker_zSight::get_report()
74{
75 // Get the current time
76 vrpn_gettimeofday(&timestamp, NULL);
77
78 if (hWnd) {
79 HRESULT hr;
80 DIJOYSTATE2 js;
81 if (FAILED(hr = sensics->GetDeviceState(sizeof(DIJOYSTATE2), &js))) {
82 fprintf(stderr, "vrpn_Tracker_zSight::get_report(): Can't read tracker\n");
83 return;
84 }
85
86 // No need to fill in position, as we donīt get position information
87
88 // Get the orientation, as per the Sensics zSight documentation
89 float w = FromTwos((unsigned short) js.lRx) / 32768.0f;
90 float x = FromTwos((unsigned short) js.lRy) / 32768.0f;
91 float y = FromTwos((unsigned short) js.lX) / 32768.0f;
92 float z = FromTwos((unsigned short) js.lY) / 32768.0f;
93 float mag = sqrt(w*w + x*x + y*y + z*z);
94
95 // Set for internal quat, as per the Sensics zSight documentation
96 d_quat[3] = w / mag;
97 d_quat[0] = x / mag;
98 d_quat[1] = y / mag;
99 d_quat[2] = -z / mag;
100 }
101
102 // Send the data
103 send_report();
104}
105
106void vrpn_Tracker_zSight::send_report()
107{
108 if (d_connection) {
109 char msgbuf[1000];
110 int len = encode_to(msgbuf);
111 if (d_connection->pack_message(len, timestamp, position_m_id, d_sender_id, msgbuf,
113 fprintf(stderr,"vrpn_Tracker_zSight: cannot write message: tossing\n");
114 }
115 }
116}
117
118HRESULT vrpn_Tracker_zSight::InitDevice()
119{
120 HRESULT hr;
121
122 // Register with the DirectInput subsystem and get a pointer to an IDirectInput interface we can use.
123 if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL),
125 IID_IDirectInput8,
126 (void**)&directInput, NULL))) {
127 fprintf(stderr, "vrpn_Tracker_zSight::InitDevice(): Cannot open DirectInput\n");
128 return hr;
129 }
130
131 // Initialize the zSight device, which is implemented as a DirectInput joystick
132 if (FAILED(hr = directInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumSensicsCallback, this, DIEDFL_ATTACHEDONLY))) {
133 fprintf(stderr, "vrpn_Tracker_zSight::InitDevice(): Cannot enumerate device\n");
134 return hr;
135 }
136
137 // Make sure we got the device we wanted
138 if (sensics == NULL) {
139 fprintf(stderr, "vrpn_Tracker_zSight::InitDevice(): No Sensics zSight device found\n");
140 return E_FAIL;
141 }
142
143 // Set the data format
144 if (FAILED(hr = sensics->SetDataFormat(&c_dfDIJoystick2)))
145 {
146 fprintf(stderr, "vrpn_Tracker_zSight::InitDevice(): Cannot set data format\n");
147 sensics->Unacquire();
148 return hr;
149 }
150
151 // Set the cooperative level
152 if (FAILED(hr = sensics->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND))) {
153 fprintf(stderr, "vrpn_Tracker_zSight::InitDevice(): Cannot set cooperative level\n");
154 sensics->Unacquire();
155 return hr;
156 }
157
158 // Get the joystick axis object
159 if (FAILED(hr = sensics->EnumObjects(EnumObjectsCallback, this, DIDFT_AXIS))) {
160 fprintf(stderr, "vrpn_Tracker_zSight::InitDevice(): Cannot enumerate objects\n");
161 sensics->Unacquire();
162 return hr;
163 }
164
165 // Acquire the joystick
166 if (FAILED(hr = sensics->Acquire())) {
167 char *reason;
168
169 switch (hr) {
170
171 case DIERR_INVALIDPARAM:
172 reason = "Invalid parameter";
173 break;
174
175 case DIERR_NOTINITIALIZED:
176 reason = "Not initialized";
177 break;
178
179 case DIERR_OTHERAPPHASPRIO:
180 reason = "Another application has priority";
181 break;
182
183 default:
184 reason = "Unknown";
185 }
186
187 fprintf(stderr, "vrpn_Tracker_zSight::InitDevice(): Cannot acquire device because %s\n", reason);
188 sensics->Unacquire();
189 return hr;
190 }
191
192 return S_OK;
193}
194
195BOOL CALLBACK vrpn_Tracker_zSight::EnumSensicsCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* selfPtr)
196{
197 vrpn_Tracker_zSight* me = (vrpn_Tracker_zSight*)(selfPtr);
198 HRESULT hr;
199
200 // Obtain an interface to the tracker
201 hr = me->directInput->CreateDevice(pdidInstance->guidInstance, &me->sensics, NULL);
202
203 // Make sure it is a Sensics zSight device
204 if (SUCCEEDED(hr) == TRUE) {
205 if (strcmp(pdidInstance->tszProductName, "Sensics zSight HMD") != 0) {
206 me->sensics->Unacquire();
207 }
208 else {
209 return DIENUM_STOP;
210 }
211 }
212
213 return DIENUM_CONTINUE;
214}
215
216BOOL CALLBACK vrpn_Tracker_zSight::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* selfPtr)
217{
218 vrpn_Tracker_zSight* me = (vrpn_Tracker_zSight*)(selfPtr);
219
220 if (pdidoi->dwType & DIDFT_AXIS) {
221 DIPROPRANGE diprg;
222 ::memset(&diprg, 0, sizeof(DIPROPRANGE));
223 diprg.diph.dwSize = sizeof(DIPROPRANGE);
224 diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
225 diprg.diph.dwHow = DIPH_BYID;
226 diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
227 diprg.lMin = 0;
228 diprg.lMax = 65535;
229
230 // Set the range for the axis
231 if (FAILED(me->sensics->SetProperty(DIPROP_RANGE, &diprg.diph))) {
232 fprintf(stderr, "vrpn_Tracker_zSight::vrpn_Tracker_zSight(): Cannot set data range\n");
233 return DIENUM_STOP;
234 }
235 }
236
237 return DIENUM_CONTINUE;
238}
239
240#endif
Generic connection class not specific to the transport mechanism.
#define DIRECTINPUT_VERSION
const vrpn_uint32 vrpn_CONNECTION_LOW_LATENCY
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99