rev |
line source |
nuclear@1
|
1 /************************************************************************************
|
nuclear@1
|
2
|
nuclear@1
|
3 Filename : OVR_Win32_HMDDevice.cpp
|
nuclear@1
|
4 Content : Win32 Interface to HMD - detects HMD display
|
nuclear@1
|
5 Created : September 21, 2012
|
nuclear@1
|
6 Authors : Michael Antonov
|
nuclear@1
|
7
|
nuclear@1
|
8 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
|
nuclear@1
|
9
|
nuclear@1
|
10 Use of this software is subject to the terms of the Oculus license
|
nuclear@1
|
11 agreement provided at the time of installation or download, or which
|
nuclear@1
|
12 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@1
|
13
|
nuclear@1
|
14 *************************************************************************************/
|
nuclear@1
|
15
|
nuclear@1
|
16 #include "OVR_Win32_HMDDevice.h"
|
nuclear@1
|
17
|
nuclear@1
|
18 #include "OVR_Win32_DeviceManager.h"
|
nuclear@1
|
19
|
nuclear@1
|
20 #include <tchar.h>
|
nuclear@1
|
21
|
nuclear@1
|
22 namespace OVR { namespace Win32 {
|
nuclear@1
|
23
|
nuclear@1
|
24 //-------------------------------------------------------------------------------------
|
nuclear@1
|
25
|
nuclear@1
|
26 HMDDeviceCreateDesc::HMDDeviceCreateDesc(DeviceFactory* factory,
|
nuclear@1
|
27 const String& deviceId, const String& displayDeviceName)
|
nuclear@1
|
28 : DeviceCreateDesc(factory, Device_HMD),
|
nuclear@1
|
29 DeviceId(deviceId), DisplayDeviceName(displayDeviceName),
|
nuclear@1
|
30 DesktopX(0), DesktopY(0), Contents(0),
|
nuclear@1
|
31 HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0)
|
nuclear@1
|
32 {
|
nuclear@1
|
33 }
|
nuclear@1
|
34 HMDDeviceCreateDesc::HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other)
|
nuclear@1
|
35 : DeviceCreateDesc(other.pFactory, Device_HMD),
|
nuclear@1
|
36 DeviceId(other.DeviceId), DisplayDeviceName(other.DisplayDeviceName),
|
nuclear@1
|
37 DesktopX(other.DesktopX), DesktopY(other.DesktopY), Contents(other.Contents),
|
nuclear@1
|
38 HResolution(other.HResolution), VResolution(other.VResolution),
|
nuclear@1
|
39 HScreenSize(other.HScreenSize), VScreenSize(other.VScreenSize)
|
nuclear@1
|
40 {
|
nuclear@1
|
41 }
|
nuclear@1
|
42
|
nuclear@1
|
43 HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCreateDesc& other,
|
nuclear@1
|
44 DeviceCreateDesc** pcandidate) const
|
nuclear@1
|
45 {
|
nuclear@1
|
46 if ((other.Type != Device_HMD) || (other.pFactory != pFactory))
|
nuclear@1
|
47 return Match_None;
|
nuclear@1
|
48
|
nuclear@1
|
49 // There are several reasons we can come in here:
|
nuclear@1
|
50 // a) Matching this HMD Monitor created desc to OTHER HMD Monitor desc
|
nuclear@1
|
51 // - Require exact device DeviceId/DeviceName match
|
nuclear@1
|
52 // b) Matching SensorDisplayInfo created desc to OTHER HMD Monitor desc
|
nuclear@1
|
53 // - This DeviceId is empty; becomes candidate
|
nuclear@1
|
54 // c) Matching this HMD Monitor created desc to SensorDisplayInfo desc
|
nuclear@1
|
55 // - This other.DeviceId is empty; becomes candidate
|
nuclear@1
|
56
|
nuclear@1
|
57 const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other;
|
nuclear@1
|
58
|
nuclear@1
|
59 if ((DeviceId == s2.DeviceId) &&
|
nuclear@1
|
60 (DisplayDeviceName == s2.DisplayDeviceName))
|
nuclear@1
|
61 {
|
nuclear@1
|
62 // Non-null DeviceId may match while size is different if screen size was overwritten
|
nuclear@1
|
63 // by SensorDisplayInfo in prior iteration.
|
nuclear@1
|
64 if (!DeviceId.IsEmpty() ||
|
nuclear@1
|
65 ((HScreenSize == s2.HScreenSize) &&
|
nuclear@1
|
66 (VScreenSize == s2.VScreenSize)) )
|
nuclear@1
|
67 {
|
nuclear@1
|
68 *pcandidate = 0;
|
nuclear@1
|
69 return Match_Found;
|
nuclear@1
|
70 }
|
nuclear@1
|
71 }
|
nuclear@1
|
72
|
nuclear@1
|
73
|
nuclear@1
|
74 // DisplayInfo takes precedence, although we try to match it first.
|
nuclear@1
|
75 if ((HResolution == s2.HResolution) &&
|
nuclear@1
|
76 (VResolution == s2.VResolution) &&
|
nuclear@1
|
77 (HScreenSize == s2.HScreenSize) &&
|
nuclear@1
|
78 (VScreenSize == s2.VScreenSize))
|
nuclear@1
|
79 {
|
nuclear@1
|
80 if (DeviceId.IsEmpty() && !s2.DeviceId.IsEmpty())
|
nuclear@1
|
81 {
|
nuclear@1
|
82 *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
|
nuclear@1
|
83 return Match_Candidate;
|
nuclear@1
|
84 }
|
nuclear@1
|
85
|
nuclear@1
|
86 *pcandidate = 0;
|
nuclear@1
|
87 return Match_Found;
|
nuclear@1
|
88 }
|
nuclear@1
|
89
|
nuclear@1
|
90 // SensorDisplayInfo may override resolution settings, so store as candidate.
|
nuclear@1
|
91 if (s2.DeviceId.IsEmpty())
|
nuclear@1
|
92 {
|
nuclear@1
|
93 *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
|
nuclear@1
|
94 return Match_Candidate;
|
nuclear@1
|
95 }
|
nuclear@1
|
96 // OTHER HMD Monitor desc may initialize DeviceName/Id
|
nuclear@1
|
97 else if (DeviceId.IsEmpty())
|
nuclear@1
|
98 {
|
nuclear@1
|
99 *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
|
nuclear@1
|
100 return Match_Candidate;
|
nuclear@1
|
101 }
|
nuclear@1
|
102
|
nuclear@1
|
103 return Match_None;
|
nuclear@1
|
104 }
|
nuclear@1
|
105
|
nuclear@1
|
106
|
nuclear@1
|
107 bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other,
|
nuclear@1
|
108 bool* newDeviceFlag)
|
nuclear@1
|
109 {
|
nuclear@1
|
110 // This candidate was the the "best fit" to apply sensor DisplayInfo to.
|
nuclear@1
|
111 OVR_ASSERT(other.Type == Device_HMD);
|
nuclear@1
|
112
|
nuclear@1
|
113 const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other;
|
nuclear@1
|
114
|
nuclear@1
|
115 // Force screen size on resolution from SensorDisplayInfo.
|
nuclear@1
|
116 // We do this because USB detection is more reliable as compared to HDMI EDID,
|
nuclear@1
|
117 // which may be corrupted by splitter reporting wrong monitor
|
nuclear@1
|
118 if (s2.DeviceId.IsEmpty())
|
nuclear@1
|
119 {
|
nuclear@1
|
120 HScreenSize = s2.HScreenSize;
|
nuclear@1
|
121 VScreenSize = s2.VScreenSize;
|
nuclear@1
|
122 Contents |= Contents_Screen;
|
nuclear@1
|
123
|
nuclear@1
|
124 if (s2.Contents & HMDDeviceCreateDesc::Contents_Distortion)
|
nuclear@1
|
125 {
|
nuclear@1
|
126 memcpy(DistortionK, s2.DistortionK, sizeof(float)*4);
|
nuclear@1
|
127 Contents |= Contents_Distortion;
|
nuclear@1
|
128 }
|
nuclear@1
|
129 DeviceId = s2.DeviceId;
|
nuclear@1
|
130 DisplayDeviceName = s2.DisplayDeviceName;
|
nuclear@1
|
131 DesktopX = s2.DesktopX;
|
nuclear@1
|
132 DesktopY = s2.DesktopY;
|
nuclear@1
|
133 if (newDeviceFlag) *newDeviceFlag = true;
|
nuclear@1
|
134 }
|
nuclear@1
|
135 else if (DeviceId.IsEmpty())
|
nuclear@1
|
136 {
|
nuclear@1
|
137 DeviceId = s2.DeviceId;
|
nuclear@1
|
138 DisplayDeviceName = s2.DisplayDeviceName;
|
nuclear@1
|
139 DesktopX = s2.DesktopX;
|
nuclear@1
|
140 DesktopY = s2.DesktopY;
|
nuclear@1
|
141
|
nuclear@1
|
142 // ScreenSize and Resolution are NOT assigned here, since they may have
|
nuclear@1
|
143 // come from a sensor DisplayInfo (which has precedence over HDMI).
|
nuclear@1
|
144
|
nuclear@1
|
145 if (newDeviceFlag) *newDeviceFlag = true;
|
nuclear@1
|
146 }
|
nuclear@1
|
147 else
|
nuclear@1
|
148 {
|
nuclear@1
|
149 if (newDeviceFlag) *newDeviceFlag = false;
|
nuclear@1
|
150 }
|
nuclear@1
|
151
|
nuclear@1
|
152 return true;
|
nuclear@1
|
153 }
|
nuclear@1
|
154
|
nuclear@1
|
155 bool HMDDeviceCreateDesc::MatchDevice(const String& path)
|
nuclear@1
|
156 {
|
nuclear@1
|
157 return DeviceId.CompareNoCase(path) == 0;
|
nuclear@1
|
158 }
|
nuclear@1
|
159
|
nuclear@1
|
160 //-------------------------------------------------------------------------------------
|
nuclear@1
|
161
|
nuclear@1
|
162
|
nuclear@1
|
163 const wchar_t* FormatDisplayStateFlags(wchar_t* buff, int length, DWORD flags)
|
nuclear@1
|
164 {
|
nuclear@1
|
165 buff[0] = 0;
|
nuclear@1
|
166 if (flags & DISPLAY_DEVICE_ACTIVE)
|
nuclear@1
|
167 wcscat_s(buff, length, L"Active ");
|
nuclear@1
|
168 if (flags & DISPLAY_DEVICE_MIRRORING_DRIVER)
|
nuclear@1
|
169 wcscat_s(buff, length, L"Mirroring_Driver ");
|
nuclear@1
|
170 if (flags & DISPLAY_DEVICE_MODESPRUNED)
|
nuclear@1
|
171 wcscat_s(buff, length, L"ModesPruned ");
|
nuclear@1
|
172 if (flags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
nuclear@1
|
173 wcscat_s(buff, length, L"Primary ");
|
nuclear@1
|
174 if (flags & DISPLAY_DEVICE_REMOVABLE)
|
nuclear@1
|
175 wcscat_s(buff, length, L"Removable ");
|
nuclear@1
|
176 if (flags & DISPLAY_DEVICE_VGA_COMPATIBLE)
|
nuclear@1
|
177 wcscat_s(buff, length, L"VGA_Compatible ");
|
nuclear@1
|
178 return buff;
|
nuclear@1
|
179 }
|
nuclear@1
|
180
|
nuclear@1
|
181
|
nuclear@1
|
182 //-------------------------------------------------------------------------------------
|
nuclear@1
|
183 // Callback for monitor enumeration to store all the monitor handles
|
nuclear@1
|
184
|
nuclear@1
|
185 // Used to capture all the active monitor handles
|
nuclear@1
|
186 struct MonitorSet
|
nuclear@1
|
187 {
|
nuclear@1
|
188 enum { MaxMonitors = 8 };
|
nuclear@1
|
189 HMONITOR Monitors[MaxMonitors];
|
nuclear@1
|
190 int MonitorCount;
|
nuclear@1
|
191 };
|
nuclear@1
|
192
|
nuclear@1
|
193 BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
|
nuclear@1
|
194 {
|
nuclear@1
|
195 MonitorSet* monitorSet = (MonitorSet*)dwData;
|
nuclear@1
|
196 if (monitorSet->MonitorCount > MonitorSet::MaxMonitors)
|
nuclear@1
|
197 return FALSE;
|
nuclear@1
|
198
|
nuclear@1
|
199 monitorSet->Monitors[monitorSet->MonitorCount] = hMonitor;
|
nuclear@1
|
200 monitorSet->MonitorCount++;
|
nuclear@1
|
201 return TRUE;
|
nuclear@1
|
202 };
|
nuclear@1
|
203
|
nuclear@1
|
204 //-------------------------------------------------------------------------------------
|
nuclear@1
|
205 // ***** HMDDeviceFactory
|
nuclear@1
|
206
|
nuclear@1
|
207 HMDDeviceFactory HMDDeviceFactory::Instance;
|
nuclear@1
|
208
|
nuclear@1
|
209 void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
|
nuclear@1
|
210 {
|
nuclear@1
|
211 MonitorSet monitors;
|
nuclear@1
|
212 monitors.MonitorCount = 0;
|
nuclear@1
|
213 // Get all the monitor handles
|
nuclear@1
|
214 EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors);
|
nuclear@1
|
215
|
nuclear@1
|
216 bool foundHMD = false;
|
nuclear@1
|
217
|
nuclear@1
|
218 // DeviceManager* manager = getManager();
|
nuclear@1
|
219 DISPLAY_DEVICE dd, ddm;
|
nuclear@1
|
220 UINT i, j;
|
nuclear@1
|
221
|
nuclear@1
|
222 for (i = 0;
|
nuclear@1
|
223 (ZeroMemory(&dd, sizeof(dd)), dd.cb = sizeof(dd),
|
nuclear@1
|
224 EnumDisplayDevices(0, i, &dd, 0)) != 0; i++)
|
nuclear@1
|
225 {
|
nuclear@1
|
226
|
nuclear@1
|
227 /*
|
nuclear@1
|
228 wchar_t buff[500], flagsBuff[200];
|
nuclear@1
|
229
|
nuclear@1
|
230 swprintf_s(buff, 500, L"\nDEV: \"%s\" \"%s\" 0x%08x=%s\n \"%s\" \"%s\"\n",
|
nuclear@1
|
231 dd.DeviceName, dd.DeviceString,
|
nuclear@1
|
232 dd.StateFlags, FormatDisplayStateFlags(flagsBuff, 200, dd.StateFlags),
|
nuclear@1
|
233 dd.DeviceID, dd.DeviceKey);
|
nuclear@1
|
234 ::OutputDebugString(buff);
|
nuclear@1
|
235 */
|
nuclear@1
|
236
|
nuclear@1
|
237 for (j = 0;
|
nuclear@1
|
238 (ZeroMemory(&ddm, sizeof(ddm)), ddm.cb = sizeof(ddm),
|
nuclear@1
|
239 EnumDisplayDevices(dd.DeviceName, j, &ddm, 0)) != 0; j++)
|
nuclear@1
|
240 {
|
nuclear@1
|
241 /*
|
nuclear@1
|
242 wchar_t mbuff[500];
|
nuclear@1
|
243 swprintf_s(mbuff, 500, L"MON: \"%s\" \"%s\" 0x%08x=%s\n \"%s\" \"%s\"\n",
|
nuclear@1
|
244 ddm.DeviceName, ddm.DeviceString,
|
nuclear@1
|
245 ddm.StateFlags, FormatDisplayStateFlags(flagsBuff, 200, ddm.StateFlags),
|
nuclear@1
|
246 ddm.DeviceID, ddm.DeviceKey);
|
nuclear@1
|
247 ::OutputDebugString(mbuff);
|
nuclear@1
|
248 */
|
nuclear@1
|
249
|
nuclear@1
|
250 // Our monitor hardware has string "RTD2205" in it
|
nuclear@1
|
251 // Nate's device "CVT0003"
|
nuclear@1
|
252 if (wcsstr(ddm.DeviceID, L"RTD2205") ||
|
nuclear@1
|
253 wcsstr(ddm.DeviceID, L"CVT0003") ||
|
nuclear@1
|
254 wcsstr(ddm.DeviceID, L"MST0030") ||
|
nuclear@1
|
255 wcsstr(ddm.DeviceID, L"OVR00") ) // Part of Oculus EDID.
|
nuclear@1
|
256 {
|
nuclear@1
|
257 String deviceId(ddm.DeviceID);
|
nuclear@1
|
258 String displayDeviceName(ddm.DeviceName);
|
nuclear@1
|
259
|
nuclear@1
|
260 // The default monitor coordinates
|
nuclear@1
|
261 int mx = 0;
|
nuclear@1
|
262 int my = 0;
|
nuclear@1
|
263 int mwidth = 1280;
|
nuclear@1
|
264 int mheight = 800;
|
nuclear@1
|
265
|
nuclear@1
|
266 // Find the matching MONITORINFOEX for this device so we can get the
|
nuclear@1
|
267 // screen coordinates
|
nuclear@1
|
268 MONITORINFOEX info;
|
nuclear@1
|
269 for (int m=0; m < monitors.MonitorCount; m++)
|
nuclear@1
|
270 {
|
nuclear@1
|
271 info.cbSize = sizeof(MONITORINFOEX);
|
nuclear@1
|
272 GetMonitorInfo(monitors.Monitors[m], &info);
|
nuclear@1
|
273 if (_tcsstr(ddm.DeviceName, info.szDevice) == ddm.DeviceName)
|
nuclear@1
|
274 { // If the device name starts with the monitor name
|
nuclear@1
|
275 // then we found the matching DISPLAY_DEVICE and MONITORINFO
|
nuclear@1
|
276 // so we can gather the monitor coordinates
|
nuclear@1
|
277 mx = info.rcMonitor.left;
|
nuclear@1
|
278 my = info.rcMonitor.top;
|
nuclear@1
|
279 //mwidth = info.rcMonitor.right - info.rcMonitor.left;
|
nuclear@1
|
280 //mheight = info.rcMonitor.bottom - info.rcMonitor.top;
|
nuclear@1
|
281 break;
|
nuclear@1
|
282 }
|
nuclear@1
|
283 }
|
nuclear@1
|
284
|
nuclear@1
|
285 HMDDeviceCreateDesc hmdCreateDesc(this, deviceId, displayDeviceName);
|
nuclear@1
|
286
|
nuclear@1
|
287 if (wcsstr(ddm.DeviceID, L"OVR0002"))
|
nuclear@1
|
288 {
|
nuclear@1
|
289 hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12096f, 0.06804f);
|
nuclear@1
|
290 }
|
nuclear@1
|
291 else
|
nuclear@1
|
292 {
|
nuclear@1
|
293 if (hmdCreateDesc.Is7Inch())
|
nuclear@1
|
294 {
|
nuclear@1
|
295 // Physical dimension of SLA screen.
|
nuclear@1
|
296 hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f);
|
nuclear@1
|
297 }
|
nuclear@1
|
298 else
|
nuclear@1
|
299 {
|
nuclear@1
|
300 hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.12096f, 0.0756f);
|
nuclear@1
|
301 }
|
nuclear@1
|
302 }
|
nuclear@1
|
303
|
nuclear@1
|
304
|
nuclear@1
|
305 OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %s\n",
|
nuclear@1
|
306 deviceId.ToCStr(), displayDeviceName.ToCStr()));
|
nuclear@1
|
307
|
nuclear@1
|
308 // Notify caller about detected device. This will call EnumerateAddDevice
|
nuclear@1
|
309 // if the this is the first time device was detected.
|
nuclear@1
|
310 visitor.Visit(hmdCreateDesc);
|
nuclear@1
|
311 foundHMD = true;
|
nuclear@1
|
312 break;
|
nuclear@1
|
313 }
|
nuclear@1
|
314 }
|
nuclear@1
|
315 }
|
nuclear@1
|
316
|
nuclear@1
|
317 // Real HMD device is not found; however, we still may have a 'fake' HMD
|
nuclear@1
|
318 // device created via SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo.
|
nuclear@1
|
319 // Need to find it and set 'Enumerated' to true to avoid Removal notification.
|
nuclear@1
|
320 if (!foundHMD)
|
nuclear@1
|
321 {
|
nuclear@1
|
322 Ptr<DeviceCreateDesc> hmdDevDesc = getManager()->FindDevice("", Device_HMD);
|
nuclear@1
|
323 if (hmdDevDesc)
|
nuclear@1
|
324 hmdDevDesc->Enumerated = true;
|
nuclear@1
|
325 }
|
nuclear@1
|
326 }
|
nuclear@1
|
327
|
nuclear@1
|
328 DeviceBase* HMDDeviceCreateDesc::NewDeviceInstance()
|
nuclear@1
|
329 {
|
nuclear@1
|
330 return new HMDDevice(this);
|
nuclear@1
|
331 }
|
nuclear@1
|
332
|
nuclear@1
|
333 bool HMDDeviceCreateDesc::Is7Inch() const
|
nuclear@1
|
334 {
|
nuclear@1
|
335 return (strstr(DeviceId.ToCStr(), "OVR0001") != 0) || (Contents & Contents_7Inch);
|
nuclear@1
|
336 }
|
nuclear@1
|
337
|
nuclear@1
|
338 Profile* HMDDeviceCreateDesc::GetProfileAddRef() const
|
nuclear@1
|
339 {
|
nuclear@1
|
340 // Create device may override profile name, so get it from there is possible.
|
nuclear@1
|
341 ProfileManager* profileManager = GetManagerImpl()->GetProfileManager();
|
nuclear@1
|
342 ProfileType profileType = GetProfileType();
|
nuclear@1
|
343 const char * profileName = pDevice ?
|
nuclear@1
|
344 ((HMDDevice*)pDevice)->GetProfileName() :
|
nuclear@1
|
345 profileManager->GetDefaultProfileName(profileType);
|
nuclear@1
|
346
|
nuclear@1
|
347 return profileName ?
|
nuclear@1
|
348 profileManager->LoadProfile(profileType, profileName) :
|
nuclear@1
|
349 profileManager->GetDeviceDefaultProfile(profileType);
|
nuclear@1
|
350 }
|
nuclear@1
|
351
|
nuclear@1
|
352
|
nuclear@1
|
353 bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
|
nuclear@1
|
354 {
|
nuclear@1
|
355 if ((info->InfoClassType != Device_HMD) &&
|
nuclear@1
|
356 (info->InfoClassType != Device_None))
|
nuclear@1
|
357 return false;
|
nuclear@1
|
358
|
nuclear@1
|
359 bool is7Inch = Is7Inch();
|
nuclear@1
|
360
|
nuclear@1
|
361 OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength,
|
nuclear@1
|
362 is7Inch ? "Oculus Rift DK1" :
|
nuclear@1
|
363 ((HResolution >= 1920) ? "Oculus Rift DK HD" : "Oculus Rift DK1-Prototype") );
|
nuclear@1
|
364 OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, "Oculus VR");
|
nuclear@1
|
365 info->Type = Device_HMD;
|
nuclear@1
|
366 info->Version = 0;
|
nuclear@1
|
367
|
nuclear@1
|
368 // Display detection.
|
nuclear@1
|
369 if (info->InfoClassType == Device_HMD)
|
nuclear@1
|
370 {
|
nuclear@1
|
371 HMDInfo* hmdInfo = static_cast<HMDInfo*>(info);
|
nuclear@1
|
372
|
nuclear@1
|
373 hmdInfo->DesktopX = DesktopX;
|
nuclear@1
|
374 hmdInfo->DesktopY = DesktopY;
|
nuclear@1
|
375 hmdInfo->HResolution = HResolution;
|
nuclear@1
|
376 hmdInfo->VResolution = VResolution;
|
nuclear@1
|
377 hmdInfo->HScreenSize = HScreenSize;
|
nuclear@1
|
378 hmdInfo->VScreenSize = VScreenSize;
|
nuclear@1
|
379 hmdInfo->VScreenCenter = VScreenSize * 0.5f;
|
nuclear@1
|
380 hmdInfo->InterpupillaryDistance = 0.064f; // Default IPD; should be configurable.
|
nuclear@1
|
381 hmdInfo->LensSeparationDistance = 0.0635f;
|
nuclear@1
|
382
|
nuclear@1
|
383 // Obtain IPD from profile.
|
nuclear@1
|
384 Ptr<Profile> profile = *GetProfileAddRef();
|
nuclear@1
|
385
|
nuclear@1
|
386 if (profile)
|
nuclear@1
|
387 {
|
nuclear@1
|
388 hmdInfo->InterpupillaryDistance = profile->GetIPD();
|
nuclear@1
|
389 // TBD: Switch on EyeCup type.
|
nuclear@1
|
390 }
|
nuclear@1
|
391
|
nuclear@1
|
392 if (Contents & Contents_Distortion)
|
nuclear@1
|
393 {
|
nuclear@1
|
394 memcpy(hmdInfo->DistortionK, DistortionK, sizeof(float)*4);
|
nuclear@1
|
395 }
|
nuclear@1
|
396 else
|
nuclear@1
|
397 {
|
nuclear@1
|
398 if (is7Inch)
|
nuclear@1
|
399 {
|
nuclear@1
|
400 // 7" screen.
|
nuclear@1
|
401 hmdInfo->DistortionK[0] = 1.0f;
|
nuclear@1
|
402 hmdInfo->DistortionK[1] = 0.22f;
|
nuclear@1
|
403 hmdInfo->DistortionK[2] = 0.24f;
|
nuclear@1
|
404 hmdInfo->EyeToScreenDistance = 0.041f;
|
nuclear@1
|
405 }
|
nuclear@1
|
406 else
|
nuclear@1
|
407 {
|
nuclear@1
|
408 hmdInfo->DistortionK[0] = 1.0f;
|
nuclear@1
|
409 hmdInfo->DistortionK[1] = 0.18f;
|
nuclear@1
|
410 hmdInfo->DistortionK[2] = 0.115f;
|
nuclear@1
|
411
|
nuclear@1
|
412 if (HResolution == 1920)
|
nuclear@1
|
413 hmdInfo->EyeToScreenDistance = 0.040f;
|
nuclear@1
|
414 else
|
nuclear@1
|
415 hmdInfo->EyeToScreenDistance = 0.0387f;
|
nuclear@1
|
416 }
|
nuclear@1
|
417
|
nuclear@1
|
418 hmdInfo->ChromaAbCorrection[0] = 0.996f;
|
nuclear@1
|
419 hmdInfo->ChromaAbCorrection[1] = -0.004f;
|
nuclear@1
|
420 hmdInfo->ChromaAbCorrection[2] = 1.014f;
|
nuclear@1
|
421 hmdInfo->ChromaAbCorrection[3] = 0.0f;
|
nuclear@1
|
422 }
|
nuclear@1
|
423
|
nuclear@1
|
424 OVR_strcpy(hmdInfo->DisplayDeviceName, sizeof(hmdInfo->DisplayDeviceName),
|
nuclear@1
|
425 DisplayDeviceName.ToCStr());
|
nuclear@1
|
426 }
|
nuclear@1
|
427
|
nuclear@1
|
428 return true;
|
nuclear@1
|
429 }
|
nuclear@1
|
430
|
nuclear@1
|
431 //-------------------------------------------------------------------------------------
|
nuclear@1
|
432 // ***** HMDDevice
|
nuclear@1
|
433
|
nuclear@1
|
434 HMDDevice::HMDDevice(HMDDeviceCreateDesc* createDesc)
|
nuclear@1
|
435 : OVR::DeviceImpl<OVR::HMDDevice>(createDesc, 0)
|
nuclear@1
|
436 {
|
nuclear@1
|
437 }
|
nuclear@1
|
438 HMDDevice::~HMDDevice()
|
nuclear@1
|
439 {
|
nuclear@1
|
440 }
|
nuclear@1
|
441
|
nuclear@1
|
442 bool HMDDevice::Initialize(DeviceBase* parent)
|
nuclear@1
|
443 {
|
nuclear@1
|
444 pParent = parent;
|
nuclear@1
|
445
|
nuclear@1
|
446 // Initialize user profile to default for device.
|
nuclear@1
|
447 ProfileManager* profileManager = GetManager()->GetProfileManager();
|
nuclear@1
|
448 ProfileName = profileManager->GetDefaultProfileName(getDesc()->GetProfileType());
|
nuclear@1
|
449
|
nuclear@1
|
450 return true;
|
nuclear@1
|
451 }
|
nuclear@1
|
452 void HMDDevice::Shutdown()
|
nuclear@1
|
453 {
|
nuclear@1
|
454 ProfileName.Clear();
|
nuclear@1
|
455 pCachedProfile.Clear();
|
nuclear@1
|
456 pParent.Clear();
|
nuclear@1
|
457 }
|
nuclear@1
|
458
|
nuclear@1
|
459 Profile* HMDDevice::GetProfile() const
|
nuclear@1
|
460 {
|
nuclear@1
|
461 if (!pCachedProfile)
|
nuclear@1
|
462 pCachedProfile = *getDesc()->GetProfileAddRef();
|
nuclear@1
|
463 return pCachedProfile.GetPtr();
|
nuclear@1
|
464 }
|
nuclear@1
|
465
|
nuclear@1
|
466 const char* HMDDevice::GetProfileName() const
|
nuclear@1
|
467 {
|
nuclear@1
|
468 return ProfileName.ToCStr();
|
nuclear@1
|
469 }
|
nuclear@1
|
470
|
nuclear@1
|
471 bool HMDDevice::SetProfileName(const char* name)
|
nuclear@1
|
472 {
|
nuclear@1
|
473 pCachedProfile.Clear();
|
nuclear@1
|
474 if (!name)
|
nuclear@1
|
475 {
|
nuclear@1
|
476 ProfileName.Clear();
|
nuclear@1
|
477 return 0;
|
nuclear@1
|
478 }
|
nuclear@1
|
479 if (GetManager()->GetProfileManager()->HasProfile(getDesc()->GetProfileType(), name))
|
nuclear@1
|
480 {
|
nuclear@1
|
481 ProfileName = name;
|
nuclear@1
|
482 return true;
|
nuclear@1
|
483 }
|
nuclear@1
|
484 return false;
|
nuclear@1
|
485 }
|
nuclear@1
|
486
|
nuclear@1
|
487 OVR::SensorDevice* HMDDevice::GetSensor()
|
nuclear@1
|
488 {
|
nuclear@1
|
489 // Just return first sensor found since we have no way to match it yet.
|
nuclear@1
|
490 OVR::SensorDevice* sensor = GetManager()->EnumerateDevices<SensorDevice>().CreateDevice();
|
nuclear@1
|
491 if (sensor)
|
nuclear@1
|
492 sensor->SetCoordinateFrame(SensorDevice::Coord_HMD);
|
nuclear@1
|
493 return sensor;
|
nuclear@1
|
494 }
|
nuclear@1
|
495
|
nuclear@1
|
496 }} // namespace OVR::Win32
|
nuclear@1
|
497
|
nuclear@1
|
498
|