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