123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "platform/input/oculusVR/oculusVRHMDDevice.h"
- OculusVRHMDDevice::OculusVRHMDDevice()
- {
- mIsValid = false;
- mIsSimulation = false;
- mDevice = NULL;
- }
- OculusVRHMDDevice::~OculusVRHMDDevice()
- {
- cleanUp();
- }
- void OculusVRHMDDevice::cleanUp()
- {
- if(mDevice)
- {
- mDevice->Release();
- mDevice = NULL;
- }
- mIsValid = false;
- }
- void OculusVRHMDDevice::set(OVR::HMDDevice* hmd, OVR::HMDInfo& info, bool calculateDistortionScale)
- {
- mIsValid = false;
- mIsSimulation = false;
- mDevice = hmd;
- // DeviceInfo
- mProductName = info.ProductName;
- mManufacturer = info.Manufacturer;
- mVersion = info.Version;
- mDisplayDeviceName = info.DisplayDeviceName;
- mDisplayId = info.DisplayId;
- mDesktopPosition.x = info.DesktopX;
- mDesktopPosition.y = info.DesktopY;
- mResolution.x = info.HResolution;
- mResolution.y = info.VResolution;
- mScreenSize.x = info.HScreenSize;
- mScreenSize.y = info.VScreenSize;
- mVerticalEyeCenter = info.VScreenCenter;
- mEyeToScreen = info.EyeToScreenDistance;
- mLensSeparation = info.LensSeparationDistance;
- mProfileInterpupillaryDistance = info.InterpupillaryDistance;
- mInterpupillaryDistance = mProfileInterpupillaryDistance;
- mKDistortion.x = info.DistortionK[0];
- mKDistortion.y = info.DistortionK[1];
- mKDistortion.z = info.DistortionK[2];
- mKDistortion.w = info.DistortionK[3];
- mChromaticAbCorrection.x = info.ChromaAbCorrection[0];
- mChromaticAbCorrection.y = info.ChromaAbCorrection[1];
- mChromaticAbCorrection.z = info.ChromaAbCorrection[2];
- mChromaticAbCorrection.w = info.ChromaAbCorrection[3];
- // Calculated values
- calculateValues(calculateDistortionScale);
- mIsValid = true;
- }
- void OculusVRHMDDevice::createSimulation(SimulationTypes simulationType, bool calculateDistortionScale)
- {
- if(simulationType == ST_RIFT_PREVIEW)
- {
- createSimulatedPreviewRift(calculateDistortionScale);
- }
- }
- void OculusVRHMDDevice::createSimulatedPreviewRift(bool calculateDistortionScale)
- {
- mIsValid = true;
- mIsSimulation = true;
- mProductName = "Oculus Rift DK1-SLA1";
- mManufacturer = "Oculus VR";
- mVersion = 0;
- mDisplayDeviceName = "";
- mResolution.x = 1280;
- mResolution.y = 800;
- mScreenSize.x = 0.14975999f;
- mScreenSize.y = 0.093599997f;
- mVerticalEyeCenter = 0.046799999f;
- mEyeToScreen = 0.041000001f;
- mLensSeparation = 0.064000003f;
- mProfileInterpupillaryDistance = 0.064000003f;
- mInterpupillaryDistance = mProfileInterpupillaryDistance;
- mKDistortion.x = 1.0000000f;
- mKDistortion.y = 0.22000000f;
- mKDistortion.z = 0.23999999f;
- mKDistortion.w = 0.00000000f;
- mChromaticAbCorrection.x = 0.995999f;
- mChromaticAbCorrection.y = -0.004f;
- mChromaticAbCorrection.z = 1.014f;
- mChromaticAbCorrection.w = 0.0f;
- calculateValues(calculateDistortionScale);
- }
- void OculusVRHMDDevice::setIPD(F32 ipd, bool calculateDistortionScale)
- {
- mInterpupillaryDistance = ipd;
- // Recalculate as some values rely on the IPD
- calculateValues(calculateDistortionScale);
- }
- // Computes scale that should be applied to the input render texture
- // before distortion to fit the result in the same screen size.
- // The 'fitRadius' parameter specifies the distance away from distortion center at
- // which the input and output coordinates will match, assuming [-1,1] range.
- F32 OculusVRHMDDevice::calcScale(F32 fitRadius)
- {
- F32 s = fitRadius;
- // This should match distortion equation used in shader.
- F32 ssq = s * s;
- F32 scale = s * (mKDistortion.x + mKDistortion.y * ssq + mKDistortion.z * ssq * ssq + mKDistortion.w * ssq * ssq * ssq);
- return scale;
- }
- void OculusVRHMDDevice::calculateValues(bool calculateDistortionScale)
- {
- F32 halfScreenX = mScreenSize.x * 0.5f;
- if(halfScreenX > 0)
- {
- F32 halfLensSeparation = mLensSeparation * 0.5;
- F32 offset = halfLensSeparation / halfScreenX;
- mEyeUVOffset.x = offset - 0.5;
- mEyeUVOffset.y = 1.0f - offset - 0.5;
- }
- else
- {
- mEyeUVOffset.x = 0.5f;
- mEyeUVOffset.y = 0.5f;
- }
- F32 lensOffset = mLensSeparation * 0.5f;
- F32 lensShift = mScreenSize.x * 0.25f - lensOffset;
- F32 lensViewportShift = 4.0f * lensShift / mScreenSize.x;
- mXCenterOffset= lensViewportShift;
- // Determine how the input texture should be scaled relative to the back buffer
- // so that we fit the distorted view to the backbuffer after calculating the
- // distortion. In reference to section 5.6.3 Distortion Scale and FOV in the
- // SDK docs.
- if(!calculateDistortionScale)
- {
- // Do not calculate a distortion scale for the input texture. This means that the input
- // texture and the backbuffer will be the same resolution.
- mDistortionFit.x = 0.0f;
- mDistortionFit.y = 0.0f;
- }
- else if (mScreenSize.x > 0.140f) // 7"
- {
- mDistortionFit.x = -1.0f;
- mDistortionFit.y = 0.0f;
- }
- else // 5"
- {
- mDistortionFit.x = 0.0f;
- mDistortionFit.y = 1.0f;
- }
- // Compute distortion scale from DistortionFitX & DistortionFitY.
- // Fit value of 0.0 means "no fit".
- if (mIsZero(mDistortionFit.x) && mIsZero(mDistortionFit.y))
- {
- mDistortionScale = 1.0f;
- }
- else
- {
- // Convert fit value to distortion-centered coordinates before fit radius
- // calculation.
- // NOTE: For now just assume a full view the same size as the HMD supports. It is
- // possible that this full view is smaller or larger.
- F32 stereoAspect = 0.5f * mResolution.x / mResolution.y;
- F32 dx = mDistortionFit.x - mXCenterOffset;
- F32 dy = mDistortionFit.y / stereoAspect;
- F32 fitRadius = sqrt(dx * dx + dy * dy);
- mDistortionScale = calcScale(fitRadius)/fitRadius;
- }
- // Calculate the vertical FOV for a single eye
- mAspectRatio = F32(mResolution.x * 0.5f) / F32(mResolution.y);
- F32 halfScreenDistance = mScreenSize.y * 0.5f * mDistortionScale;
- mYFOV = 2.0f * mAtan(halfScreenDistance / mEyeToScreen);
- F32 viewCenter = mScreenSize.x * 0.25f;
- F32 eyeProjectionShift = viewCenter - (mInterpupillaryDistance * 0.5f);
- mProjectionCenterOffset.set(4.0f * eyeProjectionShift / mScreenSize.x, 0.0f);
- mEyeWorldOffset.set(mInterpupillaryDistance * 0.5f, 0.0f, 0.0f);
- }
|