00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "OVR_OSX_HMDDevice.h"
00017 #include <CoreGraphics/CGDirectDisplay.h>
00018 #include <CoreGraphics/CGDisplayConfiguration.h>
00019 #include <CoreFoundation/CoreFoundation.h>
00020 #include <CoreFoundation/CFString.h>
00021 #include <IOKit/graphics/IOGraphicsLib.h>
00022
00023 namespace OVR { namespace OSX {
00024
00025
00026
00027 HMDDeviceCreateDesc::HMDDeviceCreateDesc(DeviceFactory* factory,
00028 UInt32 vend, UInt32 prod, const String& displayDeviceName, long dispId)
00029 : DeviceCreateDesc(factory, Device_HMD),
00030 DisplayDeviceName(displayDeviceName),
00031 DesktopX(0), DesktopY(0), Contents(0),
00032 HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0),
00033 DisplayId(dispId)
00034 {
00035
00036
00037
00038
00039
00040
00041
00042 DeviceId = DisplayDeviceName;
00043 }
00044
00045 HMDDeviceCreateDesc::HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other)
00046 : DeviceCreateDesc(other.pFactory, Device_HMD),
00047 DeviceId(other.DeviceId), DisplayDeviceName(other.DisplayDeviceName),
00048 DesktopX(other.DesktopX), DesktopY(other.DesktopY), Contents(other.Contents),
00049 HResolution(other.HResolution), VResolution(other.VResolution),
00050 HScreenSize(other.HScreenSize), VScreenSize(other.VScreenSize),
00051 DisplayId(other.DisplayId)
00052 {
00053 }
00054
00055 HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCreateDesc& other,
00056 DeviceCreateDesc** pcandidate) const
00057 {
00058 if ((other.Type != Device_HMD) || (other.pFactory != pFactory))
00059 return Match_None;
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other;
00070
00071 if ((DeviceId == s2.DeviceId) &&
00072 (DisplayId == s2.DisplayId))
00073 {
00074
00075
00076 if (!DeviceId.IsEmpty() ||
00077 ((HScreenSize == s2.HScreenSize) &&
00078 (VScreenSize == s2.VScreenSize)) )
00079 {
00080 *pcandidate = 0;
00081 return Match_Found;
00082 }
00083 }
00084
00085
00086
00087 if ((HResolution == s2.HResolution) &&
00088 (VResolution == s2.VResolution) &&
00089 (HScreenSize == s2.HScreenSize) &&
00090 (VScreenSize == s2.VScreenSize))
00091 {
00092 if (DeviceId.IsEmpty() && !s2.DeviceId.IsEmpty())
00093 {
00094 *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
00095 return Match_Candidate;
00096 }
00097
00098 *pcandidate = 0;
00099 return Match_Found;
00100 }
00101
00102
00103 if (s2.DeviceId.IsEmpty() && s2.DisplayId == 0)
00104 {
00105 *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
00106 return Match_Candidate;
00107 }
00108
00109 else if (DeviceId.IsEmpty() && DisplayId == 0)
00110 {
00111 *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
00112 return Match_Candidate;
00113 }
00114
00115 return Match_None;
00116 }
00117
00118
00119 bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other, bool* newDeviceFlag)
00120 {
00121
00122 OVR_ASSERT(other.Type == Device_HMD);
00123
00124 const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other;
00125
00126
00127
00128
00129 if (s2.DeviceId.IsEmpty() && s2.DisplayId == 0)
00130 {
00131
00132 HScreenSize = s2.HScreenSize;
00133 VScreenSize = s2.VScreenSize;
00134 Contents |= Contents_Screen;
00135
00136 if (s2.Contents & HMDDeviceCreateDesc::Contents_Distortion)
00137 {
00138 memcpy(DistortionK, s2.DistortionK, sizeof(float)*4);
00139 Contents |= Contents_Distortion;
00140 }
00141 DeviceId = s2.DeviceId;
00142 DisplayId = s2.DisplayId;
00143 DisplayDeviceName = s2.DisplayDeviceName;
00144 if (newDeviceFlag) *newDeviceFlag = true;
00145 }
00146 else if (DeviceId.IsEmpty())
00147 {
00148
00149
00150 DeviceId = s2.DeviceId;
00151 DisplayId = s2.DisplayId;
00152 DisplayDeviceName = s2.DisplayDeviceName;
00153 if (newDeviceFlag) *newDeviceFlag = true;
00154 }
00155 else
00156 {
00157 if (newDeviceFlag) *newDeviceFlag = false;
00158 }
00159
00160 return true;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 HMDDeviceFactory HMDDeviceFactory::Instance;
00171
00172 void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
00173 {
00174 CGDirectDisplayID Displays[32];
00175 uint32_t NDisplays = 0;
00176 CGGetOnlineDisplayList(32, Displays, &NDisplays);
00177
00178 for (int i = 0; i < NDisplays; i++)
00179 {
00180 io_service_t port = CGDisplayIOServicePort(Displays[i]);
00181 CFDictionaryRef DispInfo = IODisplayCreateInfoDictionary(port, kIODisplayMatchingInfo);
00182
00183 uint32_t vendor = CGDisplayVendorNumber(Displays[i]);
00184 uint32_t product = CGDisplayModelNumber(Displays[i]);
00185 unsigned mwidth = (unsigned)CGDisplayPixelsWide(Displays[i]);
00186 unsigned mheight = (unsigned)CGDisplayPixelsHigh(Displays[i]);
00187 CGRect desktop = CGDisplayBounds(Displays[i]);
00188
00189 if (vendor == 16082 && product == 1)
00190 {
00191 char idstring[9];
00192 idstring[0] = 'A'-1+((vendor>>10) & 31);
00193 idstring[1] = 'A'-1+((vendor>>5) & 31);
00194 idstring[2] = 'A'-1+((vendor>>0) & 31);
00195 snprintf(idstring+3, 5, "%04d", product);
00196
00197 HMDDeviceCreateDesc hmdCreateDesc(this, vendor, product, idstring, Displays[i]);
00198
00199 if (product == 2)
00200 {
00201 hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y,
00202 mwidth, mheight, 0.12096f, 0.06804f);
00203 }
00204 else
00205 {
00206 if (hmdCreateDesc.Is7Inch())
00207 {
00208
00209 hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y,
00210 mwidth, mheight, 0.14976f, 0.0936f);
00211 }
00212 else
00213 {
00214 hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y,
00215 mwidth, mheight, 0.12096f, 0.0756f);
00216 }
00217 }
00218
00219 OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %x:%x\n", vendor, product));
00220
00221
00222
00223 visitor.Visit(hmdCreateDesc);
00224 }
00225 CFRelease(DispInfo);
00226 }
00227 }
00228
00229 DeviceBase* HMDDeviceCreateDesc::NewDeviceInstance()
00230 {
00231 return new HMDDevice(this);
00232 }
00233
00234 bool HMDDeviceCreateDesc::Is7Inch() const
00235 {
00236 return (strstr(DeviceId.ToCStr(), "OVR0001") != 0) || (Contents & Contents_7Inch);
00237 }
00238
00239 Profile* HMDDeviceCreateDesc::GetProfileAddRef() const
00240 {
00241
00242 ProfileManager* profileManager = GetManagerImpl()->GetProfileManager();
00243 ProfileType profileType = GetProfileType();
00244 const char * profileName = pDevice ?
00245 ((HMDDevice*)pDevice)->GetProfileName() :
00246 profileManager->GetDefaultProfileName(profileType);
00247
00248 return profileName ?
00249 profileManager->LoadProfile(profileType, profileName) :
00250 profileManager->GetDeviceDefaultProfile(profileType);
00251 }
00252
00253 bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
00254 {
00255 if ((info->InfoClassType != Device_HMD) &&
00256 (info->InfoClassType != Device_None))
00257 return false;
00258
00259 bool is7Inch = Is7Inch();
00260
00261 OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength,
00262 is7Inch ? "Oculus Rift DK1" :
00263 ((HResolution >= 1920) ? "Oculus Rift DK HD" : "Oculus Rift DK1-Prototype") );
00264 OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, "Oculus VR");
00265 info->Type = Device_HMD;
00266 info->Version = 0;
00267
00268
00269 if (info->InfoClassType == Device_HMD)
00270 {
00271 HMDInfo* hmdInfo = static_cast<HMDInfo*>(info);
00272
00273 hmdInfo->DesktopX = DesktopX;
00274 hmdInfo->DesktopY = DesktopY;
00275 hmdInfo->HResolution = HResolution;
00276 hmdInfo->VResolution = VResolution;
00277 hmdInfo->HScreenSize = HScreenSize;
00278 hmdInfo->VScreenSize = VScreenSize;
00279 hmdInfo->VScreenCenter = VScreenSize * 0.5f;
00280 hmdInfo->InterpupillaryDistance = 0.064f;
00281 hmdInfo->LensSeparationDistance = 0.0635f;
00282
00283
00284 Ptr<Profile> profile = *GetProfileAddRef();
00285
00286 if (profile)
00287 {
00288 hmdInfo->InterpupillaryDistance = profile->GetIPD();
00289
00290 }
00291
00292 if (Contents & Contents_Distortion)
00293 {
00294 memcpy(hmdInfo->DistortionK, DistortionK, sizeof(float)*4);
00295 }
00296 else
00297 {
00298 if (is7Inch)
00299 {
00300
00301 hmdInfo->DistortionK[0] = 1.0f;
00302 hmdInfo->DistortionK[1] = 0.22f;
00303 hmdInfo->DistortionK[2] = 0.24f;
00304 hmdInfo->EyeToScreenDistance = 0.041f;
00305 }
00306 else
00307 {
00308 hmdInfo->DistortionK[0] = 1.0f;
00309 hmdInfo->DistortionK[1] = 0.18f;
00310 hmdInfo->DistortionK[2] = 0.115f;
00311
00312 if (HResolution == 1920)
00313 hmdInfo->EyeToScreenDistance = 0.040f;
00314 else
00315 hmdInfo->EyeToScreenDistance = 0.0387f;
00316 }
00317
00318 hmdInfo->ChromaAbCorrection[0] = 0.996f;
00319 hmdInfo->ChromaAbCorrection[1] = -0.004f;
00320 hmdInfo->ChromaAbCorrection[2] = 1.014f;
00321 hmdInfo->ChromaAbCorrection[3] = 0.0f;
00322 }
00323
00324 OVR_strcpy(hmdInfo->DisplayDeviceName, sizeof(hmdInfo->DisplayDeviceName),
00325 DisplayDeviceName.ToCStr());
00326 hmdInfo->DisplayId = DisplayId;
00327 }
00328
00329 return true;
00330 }
00331
00332
00333
00334
00335 HMDDevice::HMDDevice(HMDDeviceCreateDesc* createDesc)
00336 : OVR::DeviceImpl<OVR::HMDDevice>(createDesc, 0)
00337 {
00338 }
00339 HMDDevice::~HMDDevice()
00340 {
00341 }
00342
00343 bool HMDDevice::Initialize(DeviceBase* parent)
00344 {
00345 pParent = parent;
00346
00347
00348 ProfileManager* profileManager = GetManager()->GetProfileManager();
00349 ProfileName = profileManager->GetDefaultProfileName(getDesc()->GetProfileType());
00350
00351 return true;
00352 }
00353 void HMDDevice::Shutdown()
00354 {
00355 ProfileName.Clear();
00356 pCachedProfile.Clear();
00357 pParent.Clear();
00358 }
00359
00360 Profile* HMDDevice::GetProfile() const
00361 {
00362 if (!pCachedProfile)
00363 pCachedProfile = *getDesc()->GetProfileAddRef();
00364 return pCachedProfile.GetPtr();
00365 }
00366
00367 const char* HMDDevice::GetProfileName() const
00368 {
00369 return ProfileName.ToCStr();
00370 }
00371
00372 bool HMDDevice::SetProfileName(const char* name)
00373 {
00374 pCachedProfile.Clear();
00375 if (!name)
00376 {
00377 ProfileName.Clear();
00378 return 0;
00379 }
00380 if (GetManager()->GetProfileManager()->HasProfile(getDesc()->GetProfileType(), name))
00381 {
00382 ProfileName = name;
00383 return true;
00384 }
00385 return false;
00386 }
00387
00388 OVR::SensorDevice* HMDDevice::GetSensor()
00389 {
00390
00391 OVR::SensorDevice* sensor = GetManager()->EnumerateDevices<SensorDevice>().CreateDevice();
00392 if (sensor)
00393 sensor->SetCoordinateFrame(SensorDevice::Coord_HMD);
00394 return sensor;
00395 }
00396
00397
00398 }}
00399
00400