ovr_sdk

annotate LibOVR/Src/OVR_Stereo.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
rev   line source
nuclear@0 1 /************************************************************************************
nuclear@0 2
nuclear@0 3 Filename : OVR_Stereo.h
nuclear@0 4 Content : Stereo rendering functions
nuclear@0 5 Created : November 30, 2013
nuclear@0 6 Authors : Tom Fosyth
nuclear@0 7
nuclear@0 8 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
nuclear@0 9
nuclear@0 10 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
nuclear@0 11 you may not use the Oculus VR Rift SDK except in compliance with the License,
nuclear@0 12 which is provided at the time of installation or download, or which
nuclear@0 13 otherwise accompanies this software in either electronic or hard copy form.
nuclear@0 14
nuclear@0 15 You may obtain a copy of the License at
nuclear@0 16
nuclear@0 17 http://www.oculusvr.com/licenses/LICENSE-3.2
nuclear@0 18
nuclear@0 19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
nuclear@0 20 distributed under the License is distributed on an "AS IS" BASIS,
nuclear@0 21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nuclear@0 22 See the License for the specific language governing permissions and
nuclear@0 23 limitations under the License.
nuclear@0 24
nuclear@0 25 *************************************************************************************/
nuclear@0 26
nuclear@0 27 #ifndef OVR_Stereo_h
nuclear@0 28 #define OVR_Stereo_h
nuclear@0 29
nuclear@0 30 #include "Sensors/OVR_DeviceConstants.h"
nuclear@0 31 #include "Displays/OVR_Display.h"
nuclear@0 32 #include "OVR_Profile.h"
nuclear@0 33
nuclear@0 34 // CAPI Forward declaration.
nuclear@0 35 typedef struct ovrFovPort_ ovrFovPort;
nuclear@0 36 typedef struct ovrRecti_ ovrRecti;
nuclear@0 37
nuclear@0 38 namespace OVR {
nuclear@0 39
nuclear@0 40 class SensorDevice; // Opaque forward declaration
nuclear@0 41
nuclear@0 42
nuclear@0 43 //-----------------------------------------------------------------------------------
nuclear@0 44 // ***** Stereo Enumerations
nuclear@0 45
nuclear@0 46 // StereoEye specifies which eye we are rendering for; it is used to
nuclear@0 47 // retrieve StereoEyeParams.
nuclear@0 48 enum StereoEye
nuclear@0 49 {
nuclear@0 50 StereoEye_Center,
nuclear@0 51 StereoEye_Left,
nuclear@0 52 StereoEye_Right
nuclear@0 53 };
nuclear@0 54
nuclear@0 55
nuclear@0 56 //-----------------------------------------------------------------------------------
nuclear@0 57 // ***** FovPort
nuclear@0 58
nuclear@0 59 // FovPort describes Field Of View (FOV) of a viewport.
nuclear@0 60 // This class has values for up, down, left and right, stored in
nuclear@0 61 // tangent of the angle units to simplify calculations.
nuclear@0 62 //
nuclear@0 63 // As an example, for a standard 90 degree vertical FOV, we would
nuclear@0 64 // have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
nuclear@0 65 //
nuclear@0 66 // CreateFromRadians/Degrees helper functions can be used to
nuclear@0 67 // access FOV in different units.
nuclear@0 68
nuclear@0 69 struct FovPort
nuclear@0 70 {
nuclear@0 71 float UpTan;
nuclear@0 72 float DownTan;
nuclear@0 73 float LeftTan;
nuclear@0 74 float RightTan;
nuclear@0 75
nuclear@0 76 FovPort ( float sideTan = 0.0f ) :
nuclear@0 77 UpTan(sideTan), DownTan(sideTan), LeftTan(sideTan), RightTan(sideTan) { }
nuclear@0 78 FovPort ( float u, float d, float l, float r ) :
nuclear@0 79 UpTan(u), DownTan(d), LeftTan(l), RightTan(r) { }
nuclear@0 80
nuclear@0 81 // C-interop support: FovPort <-> ovrFovPort (implementation in OVR_CAPI.cpp).
nuclear@0 82 FovPort(const ovrFovPort& src);
nuclear@0 83 operator ovrFovPort () const;
nuclear@0 84
nuclear@0 85 static FovPort CreateFromRadians(float horizontalFov, float verticalFov)
nuclear@0 86 {
nuclear@0 87 FovPort result;
nuclear@0 88 result.UpTan = tanf ( verticalFov * 0.5f );
nuclear@0 89 result.DownTan = tanf ( verticalFov * 0.5f );
nuclear@0 90 result.LeftTan = tanf ( horizontalFov * 0.5f );
nuclear@0 91 result.RightTan = tanf ( horizontalFov * 0.5f );
nuclear@0 92 return result;
nuclear@0 93 }
nuclear@0 94
nuclear@0 95 static FovPort CreateFromDegrees(float horizontalFovDegrees,
nuclear@0 96 float verticalFovDegrees)
nuclear@0 97 {
nuclear@0 98 return CreateFromRadians(DegreeToRad(horizontalFovDegrees),
nuclear@0 99 DegreeToRad(verticalFovDegrees));
nuclear@0 100 }
nuclear@0 101
nuclear@0 102 // Get Horizontal/Vertical components of Fov in radians.
nuclear@0 103 float GetVerticalFovRadians() const { return atanf(UpTan) + atanf(DownTan); }
nuclear@0 104 float GetHorizontalFovRadians() const { return atanf(LeftTan) + atanf(RightTan); }
nuclear@0 105 // Get Horizontal/Vertical components of Fov in degrees.
nuclear@0 106 float GetVerticalFovDegrees() const { return RadToDegree(GetVerticalFovRadians()); }
nuclear@0 107 float GetHorizontalFovDegrees() const { return RadToDegree(GetHorizontalFovRadians()); }
nuclear@0 108
nuclear@0 109 // Compute maximum tangent value among all four sides.
nuclear@0 110 float GetMaxSideTan() const
nuclear@0 111 {
nuclear@0 112 return Alg::Max(Alg::Max(UpTan, DownTan), Alg::Max(LeftTan, RightTan));
nuclear@0 113 }
nuclear@0 114
nuclear@0 115 // Converts Fov Tan angle units to [-1,1] render target NDC space
nuclear@0 116 Vector2f TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle);
nuclear@0 117
nuclear@0 118
nuclear@0 119 // Compute per-channel minimum and maximum of Fov.
nuclear@0 120 static FovPort Min(const FovPort& a, const FovPort& b)
nuclear@0 121 {
nuclear@0 122 FovPort fov( Alg::Min( a.UpTan , b.UpTan ),
nuclear@0 123 Alg::Min( a.DownTan , b.DownTan ),
nuclear@0 124 Alg::Min( a.LeftTan , b.LeftTan ),
nuclear@0 125 Alg::Min( a.RightTan, b.RightTan ) );
nuclear@0 126 return fov;
nuclear@0 127 }
nuclear@0 128
nuclear@0 129 static FovPort Max(const FovPort& a, const FovPort& b)
nuclear@0 130 {
nuclear@0 131 FovPort fov( Alg::Max( a.UpTan , b.UpTan ),
nuclear@0 132 Alg::Max( a.DownTan , b.DownTan ),
nuclear@0 133 Alg::Max( a.LeftTan , b.LeftTan ),
nuclear@0 134 Alg::Max( a.RightTan, b.RightTan ) );
nuclear@0 135 return fov;
nuclear@0 136 }
nuclear@0 137 };
nuclear@0 138
nuclear@0 139
nuclear@0 140 //-----------------------------------------------------------------------------------
nuclear@0 141 // ***** ScaleAndOffset
nuclear@0 142
nuclear@0 143 struct ScaleAndOffset2D
nuclear@0 144 {
nuclear@0 145 Vector2f Scale;
nuclear@0 146 Vector2f Offset;
nuclear@0 147
nuclear@0 148 ScaleAndOffset2D(float sx = 0.0f, float sy = 0.0f, float ox = 0.0f, float oy = 0.0f)
nuclear@0 149 : Scale(sx, sy), Offset(ox, oy)
nuclear@0 150 { }
nuclear@0 151 };
nuclear@0 152
nuclear@0 153
nuclear@0 154 //-----------------------------------------------------------------------------------
nuclear@0 155 // ***** Misc. utility functions.
nuclear@0 156
nuclear@0 157 // Inputs are 4 points (pFitX[0],pFitY[0]) through (pFitX[3],pFitY[3])
nuclear@0 158 // Result is four coefficients in pResults[0] through pResults[3] such that
nuclear@0 159 // y = pResult[0] + x * ( pResult[1] + x * ( pResult[2] + x * ( pResult[3] ) ) );
nuclear@0 160 // passes through all four input points.
nuclear@0 161 // Return is true if it succeeded, false if it failed (because two control points
nuclear@0 162 // have the same pFitX value).
nuclear@0 163 bool FitCubicPolynomial ( float *pResult, const float *pFitX, const float *pFitY );
nuclear@0 164
nuclear@0 165 //-----------------------------------------------------------------------------------
nuclear@0 166 // ***** LensConfig
nuclear@0 167
nuclear@0 168 // LensConfig describes the configuration of a single lens in an HMD.
nuclear@0 169 // - Eqn and K[] describe a distortion function.
nuclear@0 170 // - MetersPerTanAngleAtCenter is the relationship between distance on a
nuclear@0 171 // screen (at the center of the lens), and the angle variance of the light after it
nuclear@0 172 // has passed through the lens.
nuclear@0 173 // - ChromaticAberration is an array of parameters for controlling
nuclear@0 174 // additional Red and Blue scaling in order to reduce chromatic aberration
nuclear@0 175 // caused by the Rift lenses.
nuclear@0 176 struct LensConfig
nuclear@0 177 {
nuclear@0 178 LensConfig()
nuclear@0 179 : Eqn(Distortion_CatmullRom10)
nuclear@0 180 //K()
nuclear@0 181 , MaxR(0.0f)
nuclear@0 182 , MetersPerTanAngleAtCenter(0.0f)
nuclear@0 183 //ChromaticAberration()
nuclear@0 184 //InvK()
nuclear@0 185 , MaxInvR(0.0f)
nuclear@0 186 {
nuclear@0 187 memset(&K, 0, sizeof(K));
nuclear@0 188 memset(&ChromaticAberration, 0, sizeof(ChromaticAberration));
nuclear@0 189 memset(&InvK, 0, sizeof(InvK));
nuclear@0 190 }
nuclear@0 191
nuclear@0 192 // The result is a scaling applied to the distance from the center of the lens.
nuclear@0 193 float DistortionFnScaleRadiusSquared (float rsq) const;
nuclear@0 194 // x,y,z components map to r,g,b scales.
nuclear@0 195 Vector3f DistortionFnScaleRadiusSquaredChroma (float rsq) const;
nuclear@0 196
nuclear@0 197 // DistortionFn applies distortion to the argument.
nuclear@0 198 // Input: the distance in TanAngle/NIC space from the optical center to the input pixel.
nuclear@0 199 // Output: the resulting distance after distortion.
nuclear@0 200 float DistortionFn(float r) const
nuclear@0 201 {
nuclear@0 202 return r * DistortionFnScaleRadiusSquared ( r * r );
nuclear@0 203 }
nuclear@0 204
nuclear@0 205 // DistortionFnInverse computes the inverse of the distortion function on an argument.
nuclear@0 206 float DistortionFnInverse(float r) const;
nuclear@0 207
nuclear@0 208 // Also computes the inverse, but using a polynomial approximation. Warning - it's just an approximation!
nuclear@0 209 float DistortionFnInverseApprox(float r) const;
nuclear@0 210 // Sets up InvK[].
nuclear@0 211 void SetUpInverseApprox();
nuclear@0 212
nuclear@0 213 // Sets a bunch of sensible defaults.
nuclear@0 214 void SetToIdentity();
nuclear@0 215
nuclear@0 216
nuclear@0 217
nuclear@0 218 enum { NumCoefficients = 11 };
nuclear@0 219
nuclear@0 220 DistortionEqnType Eqn;
nuclear@0 221 float K[NumCoefficients];
nuclear@0 222 float MaxR; // The highest R you're going to query for - the curve is unpredictable beyond it.
nuclear@0 223
nuclear@0 224 float MetersPerTanAngleAtCenter;
nuclear@0 225
nuclear@0 226 // Additional per-channel scaling is applied after distortion:
nuclear@0 227 // Index [0] - Red channel constant coefficient.
nuclear@0 228 // Index [1] - Red channel r^2 coefficient.
nuclear@0 229 // Index [2] - Blue channel constant coefficient.
nuclear@0 230 // Index [3] - Blue channel r^2 coefficient.
nuclear@0 231 float ChromaticAberration[4];
nuclear@0 232
nuclear@0 233 float InvK[NumCoefficients];
nuclear@0 234 float MaxInvR;
nuclear@0 235 };
nuclear@0 236
nuclear@0 237
nuclear@0 238 // For internal use - storing and loading lens config data
nuclear@0 239
nuclear@0 240 // Returns true on success.
nuclear@0 241 bool LoadLensConfig ( LensConfig *presult, uint8_t const *pbuffer, int bufferSizeInBytes );
nuclear@0 242
nuclear@0 243 // Returns number of bytes needed.
nuclear@0 244 int SaveLensConfigSizeInBytes ( LensConfig const &config );
nuclear@0 245 // Returns true on success.
nuclear@0 246 bool SaveLensConfig ( uint8_t *pbuffer, int bufferSizeInBytes, LensConfig const &config );
nuclear@0 247
nuclear@0 248
nuclear@0 249 //-----------------------------------------------------------------------------------
nuclear@0 250 // ***** DistortionRenderDesc
nuclear@0 251
nuclear@0 252 // This describes distortion for a single eye in an HMD with a display, not just the lens by itself.
nuclear@0 253 struct DistortionRenderDesc
nuclear@0 254 {
nuclear@0 255 // The raw lens values.
nuclear@0 256 LensConfig Lens;
nuclear@0 257
nuclear@0 258 // These map from [-1,1] across the eye being rendered into TanEyeAngle space (but still distorted)
nuclear@0 259 Vector2f LensCenter;
nuclear@0 260 Vector2f TanEyeAngleScale;
nuclear@0 261 // Computed from device characteristics, IPD and eye-relief.
nuclear@0 262 // (not directly used for rendering, but very useful)
nuclear@0 263 Vector2f PixelsPerTanAngleAtCenter;
nuclear@0 264 };
nuclear@0 265
nuclear@0 266
nuclear@0 267 //-------------------------------------------------------------------------------------
nuclear@0 268 // ***** HMDInfo
nuclear@0 269
nuclear@0 270 // This structure describes various aspects of the HMD allowing us to configure rendering.
nuclear@0 271 //
nuclear@0 272 // Currently included data:
nuclear@0 273 // - Physical screen dimensions, resolution, and eye distances.
nuclear@0 274 // (some of these will be configurable with a tool in the future).
nuclear@0 275 // These arguments allow us to properly setup projection across HMDs.
nuclear@0 276 // - DisplayDeviceName for identifying HMD screen; system-specific interpretation.
nuclear@0 277 //
nuclear@0 278 // TBD:
nuclear@0 279 // - Power on/ off?
nuclear@0 280 // - Sensor rates and capabilities
nuclear@0 281 // - Distortion radius/variables
nuclear@0 282 // - Screen update frequency
nuclear@0 283 // - Distortion needed flag
nuclear@0 284 // - Update modes:
nuclear@0 285 // Set update mode: Stereo (both sides together), mono (same in both eyes),
nuclear@0 286 // Alternating, Alternating scan-lines.
nuclear@0 287
nuclear@0 288 // Win32 Oculus VR Display Driver Shim Information
nuclear@0 289 struct Win32ShimInfo
nuclear@0 290 {
nuclear@0 291 int DeviceNumber;
nuclear@0 292 int NativeWidth;
nuclear@0 293 int NativeHeight;
nuclear@0 294 int Rotation;
nuclear@0 295 int UseMirroring;
nuclear@0 296
nuclear@0 297 Win32ShimInfo() :
nuclear@0 298 DeviceNumber(-1),
nuclear@0 299 NativeWidth(-1),
nuclear@0 300 NativeHeight(-1),
nuclear@0 301 Rotation(-1),
nuclear@0 302 UseMirroring(1)
nuclear@0 303 {
nuclear@0 304 }
nuclear@0 305 };
nuclear@0 306
nuclear@0 307 class HMDInfo
nuclear@0 308 {
nuclear@0 309 public:
nuclear@0 310 // Name string describing the product: "Oculus Rift DK1", etc.
nuclear@0 311 String ProductName;
nuclear@0 312 String Manufacturer;
nuclear@0 313
nuclear@0 314 unsigned Version;
nuclear@0 315
nuclear@0 316 // Characteristics of the HMD screen and enclosure
nuclear@0 317 HmdTypeEnum HmdType;
nuclear@0 318 Size<int> ResolutionInPixels;
nuclear@0 319 Size<float> ScreenSizeInMeters;
nuclear@0 320 float ScreenGapSizeInMeters;
nuclear@0 321 float CenterFromTopInMeters;
nuclear@0 322 float LensSeparationInMeters;
nuclear@0 323 Vector2f PelOffsetR; // Offsets from the green pel in pixels (i.e. usual values are 0.5 or 0.333)
nuclear@0 324 Vector2f PelOffsetB;
nuclear@0 325
nuclear@0 326
nuclear@0 327 // Timing & shutter data. All values in seconds.
nuclear@0 328 struct ShutterInfo
nuclear@0 329 {
nuclear@0 330 HmdShutterTypeEnum Type;
nuclear@0 331 float VsyncToNextVsync; // 1/framerate
nuclear@0 332 float VsyncToFirstScanline; // for global shutter, vsync->shutter open.
nuclear@0 333 float FirstScanlineToLastScanline; // for global shutter, will be zero.
nuclear@0 334 float PixelSettleTime; // estimated.
nuclear@0 335 float PixelPersistence; // Full persistence = 1/framerate.
nuclear@0 336 } Shutter;
nuclear@0 337
nuclear@0 338 // Desktop coordinate position of the screen (can be negative; may not be present on all platforms)
nuclear@0 339 int DesktopX;
nuclear@0 340 int DesktopY;
nuclear@0 341
nuclear@0 342 // Windows:
nuclear@0 343 // "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC.
nuclear@0 344 String DisplayDeviceName;
nuclear@0 345 Win32ShimInfo ShimInfo;
nuclear@0 346
nuclear@0 347 // MacOS:
nuclear@0 348 int DisplayId;
nuclear@0 349
nuclear@0 350 bool InCompatibilityMode;
nuclear@0 351
nuclear@0 352 // Printed serial number for the HMD; should match external sticker
nuclear@0 353 String PrintedSerial;
nuclear@0 354
nuclear@0 355 // Tracker descriptor information:
nuclear@0 356 int VendorId;
nuclear@0 357 int ProductId;
nuclear@0 358 int FirmwareMajor;
nuclear@0 359 int FirmwareMinor;
nuclear@0 360
nuclear@0 361 float CameraFrustumHFovInRadians;
nuclear@0 362 float CameraFrustumVFovInRadians;
nuclear@0 363 float CameraFrustumNearZInMeters;
nuclear@0 364 float CameraFrustumFarZInMeters;
nuclear@0 365
nuclear@0 366 // Constructor initializes all values to 0s.
nuclear@0 367 // To create a "virtualized" HMDInfo, use CreateDebugHMDInfo instead.
nuclear@0 368 HMDInfo() :
nuclear@0 369 ProductName(),
nuclear@0 370 Manufacturer(),
nuclear@0 371 Version(0),
nuclear@0 372 HmdType(HmdType_None),
nuclear@0 373 ResolutionInPixels(0),
nuclear@0 374 ScreenSizeInMeters(0.0f),
nuclear@0 375 ScreenGapSizeInMeters(0.0f),
nuclear@0 376 CenterFromTopInMeters(0),
nuclear@0 377 LensSeparationInMeters(0),
nuclear@0 378 PelOffsetR(0.0f,0.0f),
nuclear@0 379 PelOffsetB(0.0f,0.0f),
nuclear@0 380 //Shutter (initialized below)
nuclear@0 381 DesktopX(0),
nuclear@0 382 DesktopY(0),
nuclear@0 383 DisplayDeviceName(),
nuclear@0 384 ShimInfo(),
nuclear@0 385 DisplayId(-1),
nuclear@0 386 InCompatibilityMode(false),
nuclear@0 387 PrintedSerial(),
nuclear@0 388 VendorId(-1),
nuclear@0 389 ProductId(-1),
nuclear@0 390 FirmwareMajor(-1),
nuclear@0 391 FirmwareMinor(-1),
nuclear@0 392 CameraFrustumHFovInRadians(0.0f),
nuclear@0 393 CameraFrustumVFovInRadians(0.0f),
nuclear@0 394 CameraFrustumNearZInMeters(0.0f),
nuclear@0 395 CameraFrustumFarZInMeters(0.0f)
nuclear@0 396 {
nuclear@0 397 Shutter.Type = HmdShutter_LAST;
nuclear@0 398 Shutter.VsyncToNextVsync = 0.0f;
nuclear@0 399 Shutter.VsyncToFirstScanline = 0.0f;
nuclear@0 400 Shutter.FirstScanlineToLastScanline = 0.0f;
nuclear@0 401 Shutter.PixelSettleTime = 0.0f;
nuclear@0 402 Shutter.PixelPersistence = 0.0f;
nuclear@0 403 }
nuclear@0 404
nuclear@0 405 // Operator = copies local fields only (base class must be correct already)
nuclear@0 406 void operator=(const HMDInfo& src)
nuclear@0 407 {
nuclear@0 408 ProductName = src.ProductName;
nuclear@0 409 Manufacturer = src.Manufacturer;
nuclear@0 410 Version = src.Version;
nuclear@0 411 HmdType = src.HmdType;
nuclear@0 412 ResolutionInPixels = src.ResolutionInPixels;
nuclear@0 413 ScreenSizeInMeters = src.ScreenSizeInMeters;
nuclear@0 414 ScreenGapSizeInMeters = src.ScreenGapSizeInMeters;
nuclear@0 415 CenterFromTopInMeters = src.CenterFromTopInMeters;
nuclear@0 416 LensSeparationInMeters = src.LensSeparationInMeters;
nuclear@0 417 PelOffsetR = src.PelOffsetR;
nuclear@0 418 PelOffsetB = src.PelOffsetB;
nuclear@0 419 DesktopX = src.DesktopX;
nuclear@0 420 DesktopY = src.DesktopY;
nuclear@0 421 Shutter = src.Shutter;
nuclear@0 422 DisplayDeviceName = src.DisplayDeviceName;
nuclear@0 423 ShimInfo = src.ShimInfo;
nuclear@0 424 DisplayId = src.DisplayId;
nuclear@0 425 InCompatibilityMode = src.InCompatibilityMode;
nuclear@0 426 VendorId = src.VendorId;
nuclear@0 427 ProductId = src.ProductId;
nuclear@0 428 FirmwareMajor = src.FirmwareMajor;
nuclear@0 429 FirmwareMinor = src.FirmwareMinor;
nuclear@0 430 PrintedSerial = src.PrintedSerial;
nuclear@0 431 CameraFrustumHFovInRadians = src.CameraFrustumHFovInRadians;
nuclear@0 432 CameraFrustumVFovInRadians = src.CameraFrustumVFovInRadians;
nuclear@0 433 CameraFrustumNearZInMeters = src.CameraFrustumNearZInMeters;
nuclear@0 434 CameraFrustumFarZInMeters = src.CameraFrustumFarZInMeters;
nuclear@0 435 }
nuclear@0 436
nuclear@0 437 void SetScreenParameters(int hres, int vres,
nuclear@0 438 float hsize, float vsize,
nuclear@0 439 float vCenterFromTopInMeters, float lensSeparationInMeters,
nuclear@0 440 bool compatibilityMode)
nuclear@0 441 {
nuclear@0 442 ResolutionInPixels = Sizei(hres, vres);
nuclear@0 443 ScreenSizeInMeters = Sizef(hsize, vsize);
nuclear@0 444 CenterFromTopInMeters = vCenterFromTopInMeters;
nuclear@0 445 LensSeparationInMeters = lensSeparationInMeters;
nuclear@0 446 InCompatibilityMode = compatibilityMode;
nuclear@0 447 }
nuclear@0 448
nuclear@0 449 bool IsSameDisplay(const HMDInfo& o) const
nuclear@0 450 {
nuclear@0 451 return DisplayId == o.DisplayId &&
nuclear@0 452 DisplayDeviceName.CompareNoCase(o.DisplayDeviceName) == 0;
nuclear@0 453 }
nuclear@0 454
nuclear@0 455 static bool CreateFromSensorAndDisplay(SensorDevice* sensor, Display* display, HMDInfo* hmdi);
nuclear@0 456 };
nuclear@0 457
nuclear@0 458
nuclear@0 459 //-----------------------------------------------------------------------------------
nuclear@0 460 // ***** HmdRenderInfo
nuclear@0 461
nuclear@0 462 // All the parts of the HMD info that are needed to set up the rendering system.
nuclear@0 463
nuclear@0 464 struct HmdRenderInfo
nuclear@0 465 {
nuclear@0 466 // The start of this structure is intentionally very similar to HMDInfo in OVER_Device.h
nuclear@0 467 // However to reduce interdependencies, one does not simply #include the other.
nuclear@0 468
nuclear@0 469 HmdTypeEnum HmdType;
nuclear@0 470
nuclear@0 471 // Size of the entire screen
nuclear@0 472 Size<int> ResolutionInPixels;
nuclear@0 473 Size<float> ScreenSizeInMeters;
nuclear@0 474 float ScreenGapSizeInMeters;
nuclear@0 475 Vector2f PelOffsetR; // Offsets from the green pel in pixels (i.e. usual values are 0.5 or 0.333)
nuclear@0 476 Vector2f PelOffsetB;
nuclear@0 477
nuclear@0 478 // Characteristics of the lenses.
nuclear@0 479 float CenterFromTopInMeters;
nuclear@0 480 float LensSeparationInMeters;
nuclear@0 481 float LensDiameterInMeters;
nuclear@0 482 float LensSurfaceToMidplateInMeters;
nuclear@0 483 EyeCupType EyeCups;
nuclear@0 484
nuclear@0 485 // Timing & shutter data. All values in seconds.
nuclear@0 486 struct ShutterInfo
nuclear@0 487 {
nuclear@0 488 HmdShutterTypeEnum Type;
nuclear@0 489 float VsyncToNextVsync; // 1/framerate
nuclear@0 490 float VsyncToFirstScanline; // for global shutter, vsync->shutter open.
nuclear@0 491 float FirstScanlineToLastScanline; // for global shutter, will be zero.
nuclear@0 492 float PixelSettleTime; // estimated.
nuclear@0 493 float PixelPersistence; // Full persistence = 1/framerate.
nuclear@0 494 } Shutter;
nuclear@0 495
nuclear@0 496
nuclear@0 497 // These are all set from the user's profile.
nuclear@0 498 struct EyeConfig
nuclear@0 499 {
nuclear@0 500 // Distance from center of eyeball to front plane of lens.
nuclear@0 501 float ReliefInMeters;
nuclear@0 502 // Distance from nose (technically, center of Rift) to the middle of the eye.
nuclear@0 503 float NoseToPupilInMeters;
nuclear@0 504
nuclear@0 505 LensConfig Distortion;
nuclear@0 506 } EyeLeft, EyeRight;
nuclear@0 507
nuclear@0 508
nuclear@0 509 HmdRenderInfo()
nuclear@0 510 {
nuclear@0 511 HmdType = HmdType_None;
nuclear@0 512 ResolutionInPixels.w = 0;
nuclear@0 513 ResolutionInPixels.h = 0;
nuclear@0 514 ScreenSizeInMeters.w = 0.0f;
nuclear@0 515 ScreenSizeInMeters.h = 0.0f;
nuclear@0 516 ScreenGapSizeInMeters = 0.0f;
nuclear@0 517 CenterFromTopInMeters = 0.0f;
nuclear@0 518 LensSeparationInMeters = 0.0f;
nuclear@0 519 LensDiameterInMeters = 0.0f;
nuclear@0 520 LensSurfaceToMidplateInMeters = 0.0f;
nuclear@0 521 PelOffsetR = Vector2f ( 0.0f, 0.0f );
nuclear@0 522 PelOffsetB = Vector2f ( 0.0f, 0.0f );
nuclear@0 523 Shutter.Type = HmdShutter_LAST;
nuclear@0 524 Shutter.VsyncToNextVsync = 0.0f;
nuclear@0 525 Shutter.VsyncToFirstScanline = 0.0f;
nuclear@0 526 Shutter.FirstScanlineToLastScanline = 0.0f;
nuclear@0 527 Shutter.PixelSettleTime = 0.0f;
nuclear@0 528 Shutter.PixelPersistence = 0.0f;
nuclear@0 529 EyeCups = EyeCup_DK1A;
nuclear@0 530 EyeLeft.ReliefInMeters = 0.0f;
nuclear@0 531 EyeLeft.NoseToPupilInMeters = 0.0f;
nuclear@0 532 EyeLeft.Distortion.SetToIdentity();
nuclear@0 533 EyeRight = EyeLeft;
nuclear@0 534 }
nuclear@0 535
nuclear@0 536 // The "center eye" is the position the HMD tracking returns,
nuclear@0 537 // and games will also usually use it for audio, aiming reticles, some line-of-sight tests, etc.
nuclear@0 538 EyeConfig GetEyeCenter() const
nuclear@0 539 {
nuclear@0 540 EyeConfig result;
nuclear@0 541 result.ReliefInMeters = 0.5f * ( EyeLeft.ReliefInMeters + EyeRight.ReliefInMeters );
nuclear@0 542 result.NoseToPupilInMeters = 0.0f;
nuclear@0 543 result.Distortion.SetToIdentity();
nuclear@0 544 return result;
nuclear@0 545 }
nuclear@0 546
nuclear@0 547 };
nuclear@0 548
nuclear@0 549
nuclear@0 550 //-----------------------------------------------------------------------------------
nuclear@0 551
nuclear@0 552 // Stateless computation functions, in somewhat recommended execution order.
nuclear@0 553 // For examples on how to use many of them, see the StereoConfig::UpdateComputedState function.
nuclear@0 554
nuclear@0 555 const float OVR_DEFAULT_EXTRA_EYE_ROTATION = 30.0f * MATH_FLOAT_DEGREETORADFACTOR;
nuclear@0 556
nuclear@0 557 // Creates a dummy debug HMDInfo matching a particular HMD model.
nuclear@0 558 // Useful for development without an actual HMD attached.
nuclear@0 559 HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType);
nuclear@0 560
nuclear@0 561
nuclear@0 562 // profile may be NULL, in which case it uses the hard-coded defaults.
nuclear@0 563 // distortionType should be left at the default unless you require something specific for your distortion shaders.
nuclear@0 564 // eyeCupOverride can be EyeCup_LAST, in which case it uses the one in the profile.
nuclear@0 565 HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo,
nuclear@0 566 Profile const *profile = NULL,
nuclear@0 567 DistortionEqnType distortionType = Distortion_CatmullRom10,
nuclear@0 568 EyeCupType eyeCupOverride = EyeCup_LAST );
nuclear@0 569
nuclear@0 570 LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderInfo const &hmd,
nuclear@0 571 DistortionEqnType distortionType = Distortion_CatmullRom10 );
nuclear@0 572
nuclear@0 573 DistortionRenderDesc CalculateDistortionRenderDesc ( StereoEye eyeType, HmdRenderInfo const &hmd,
nuclear@0 574 LensConfig const *pLensOverride = NULL );
nuclear@0 575
nuclear@0 576 FovPort CalculateFovFromEyePosition ( float eyeReliefInMeters,
nuclear@0 577 float offsetToRightInMeters,
nuclear@0 578 float offsetDownwardsInMeters,
nuclear@0 579 float lensDiameterInMeters,
nuclear@0 580 float extraEyeRotationInRadians = OVR_DEFAULT_EXTRA_EYE_ROTATION);
nuclear@0 581
nuclear@0 582 FovPort CalculateFovFromHmdInfo ( StereoEye eyeType,
nuclear@0 583 DistortionRenderDesc const &distortion,
nuclear@0 584 HmdRenderInfo const &hmd,
nuclear@0 585 float extraEyeRotationInRadians = OVR_DEFAULT_EXTRA_EYE_ROTATION );
nuclear@0 586
nuclear@0 587 FovPort GetPhysicalScreenFov ( StereoEye eyeType, DistortionRenderDesc const &distortion );
nuclear@0 588
nuclear@0 589 FovPort ClampToPhysicalScreenFov ( StereoEye eyeType, DistortionRenderDesc const &distortion,
nuclear@0 590 FovPort inputFovPort );
nuclear@0 591
nuclear@0 592 Sizei CalculateIdealPixelSize ( StereoEye eyeType, DistortionRenderDesc const &distortion,
nuclear@0 593 FovPort fov, float pixelsPerDisplayPixel );
nuclear@0 594
nuclear@0 595 Recti GetFramebufferViewport ( StereoEye eyeType, HmdRenderInfo const &hmd );
nuclear@0 596
nuclear@0 597 Matrix4f CreateProjection ( bool rightHanded, FovPort fov,
nuclear@0 598 float zNear = 0.01f, float zFar = 10000.0f );
nuclear@0 599
nuclear@0 600 Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType,
nuclear@0 601 float tanHalfFovX, float tanHalfFovY,
nuclear@0 602 float unitsX, float unitsY, float distanceFromCamera,
nuclear@0 603 float interpupillaryDistance, Matrix4f const &projection,
nuclear@0 604 float zNear = 0.0f, float zFar = 0.0f );
nuclear@0 605
nuclear@0 606 ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort fov );
nuclear@0 607
nuclear@0 608 ScaleAndOffset2D CreateUVScaleAndOffsetfromNDCScaleandOffset ( ScaleAndOffset2D scaleAndOffsetNDC,
nuclear@0 609 Recti renderedViewport,
nuclear@0 610 Sizei renderTargetSize );
nuclear@0 611
nuclear@0 612
nuclear@0 613 //-----------------------------------------------------------------------------------
nuclear@0 614 // ***** StereoEyeParams
nuclear@0 615
nuclear@0 616 // StereoEyeParams describes RenderDevice configuration needed to render
nuclear@0 617 // the scene for one eye.
nuclear@0 618 struct StereoEyeParams
nuclear@0 619 {
nuclear@0 620 StereoEye Eye;
nuclear@0 621 Matrix4f HmdToEyeViewOffset; // Translation to be applied to view matrix.
nuclear@0 622
nuclear@0 623 // Distortion and the VP on the physical display - the thing to run the distortion shader on.
nuclear@0 624 DistortionRenderDesc Distortion;
nuclear@0 625 Recti DistortionViewport;
nuclear@0 626
nuclear@0 627 // Projection and VP of a particular view (you could have multiple of these).
nuclear@0 628 Recti RenderedViewport; // Viewport that we render the standard scene to.
nuclear@0 629 FovPort Fov; // The FOVs of this scene.
nuclear@0 630 Matrix4f RenderedProjection; // Projection matrix used with this eye.
nuclear@0 631 ScaleAndOffset2D EyeToSourceNDC; // Mapping from TanEyeAngle space to [-1,+1] on the rendered image.
nuclear@0 632 ScaleAndOffset2D EyeToSourceUV; // Mapping from TanEyeAngle space to actual texture UV coords.
nuclear@0 633 };
nuclear@0 634
nuclear@0 635
nuclear@0 636 //-----------------------------------------------------------------------------------
nuclear@0 637 // A set of "forward-mapping" functions, mapping from framebuffer space to real-world and/or texture space.
nuclear@0 638 Vector2f TransformScreenNDCToTanFovSpace ( DistortionRenderDesc const &distortion,
nuclear@0 639 const Vector2f &framebufferNDC );
nuclear@0 640 void TransformScreenNDCToTanFovSpaceChroma ( Vector2f *resultR, Vector2f *resultG, Vector2f *resultB,
nuclear@0 641 DistortionRenderDesc const &distortion,
nuclear@0 642 const Vector2f &framebufferNDC );
nuclear@0 643 Vector2f TransformTanFovSpaceToRendertargetTexUV ( ScaleAndOffset2D const &eyeToSourceUV,
nuclear@0 644 Vector2f const &tanEyeAngle );
nuclear@0 645 Vector2f TransformTanFovSpaceToRendertargetNDC ( ScaleAndOffset2D const &eyeToSourceNDC,
nuclear@0 646 Vector2f const &tanEyeAngle );
nuclear@0 647 Vector2f TransformScreenPixelToScreenNDC( Recti const &distortionViewport,
nuclear@0 648 Vector2f const &pixel );
nuclear@0 649 Vector2f TransformScreenPixelToTanFovSpace ( Recti const &distortionViewport,
nuclear@0 650 DistortionRenderDesc const &distortion,
nuclear@0 651 Vector2f const &pixel );
nuclear@0 652 Vector2f TransformScreenNDCToRendertargetTexUV( DistortionRenderDesc const &distortion,
nuclear@0 653 StereoEyeParams const &eyeParams,
nuclear@0 654 Vector2f const &pixel );
nuclear@0 655 Vector2f TransformScreenPixelToRendertargetTexUV( Recti const &distortionViewport,
nuclear@0 656 DistortionRenderDesc const &distortion,
nuclear@0 657 StereoEyeParams const &eyeParams,
nuclear@0 658 Vector2f const &pixel );
nuclear@0 659
nuclear@0 660 // A set of "reverse-mapping" functions, mapping from real-world and/or texture space back to the framebuffer.
nuclear@0 661 // Be aware that many of these are significantly slower than their forward-mapping counterparts.
nuclear@0 662 Vector2f TransformTanFovSpaceToScreenNDC( DistortionRenderDesc const &distortion,
nuclear@0 663 const Vector2f &tanEyeAngle, bool usePolyApprox = false );
nuclear@0 664 Vector2f TransformRendertargetNDCToTanFovSpace( const ScaleAndOffset2D &eyeToSourceNDC,
nuclear@0 665 const Vector2f &textureNDC );
nuclear@0 666
nuclear@0 667 // Handy wrappers.
nuclear@0 668 inline Vector2f TransformTanFovSpaceToRendertargetTexUV ( StereoEyeParams const &eyeParams,
nuclear@0 669 Vector2f const &tanEyeAngle )
nuclear@0 670 {
nuclear@0 671 return TransformTanFovSpaceToRendertargetTexUV ( eyeParams.EyeToSourceUV, tanEyeAngle );
nuclear@0 672 }
nuclear@0 673 inline Vector2f TransformTanFovSpaceToRendertargetNDC ( StereoEyeParams const &eyeParams,
nuclear@0 674 Vector2f const &tanEyeAngle )
nuclear@0 675 {
nuclear@0 676 return TransformTanFovSpaceToRendertargetNDC ( eyeParams.EyeToSourceNDC, tanEyeAngle );
nuclear@0 677 }
nuclear@0 678
nuclear@0 679 } //namespace OVR
nuclear@0 680
nuclear@0 681 #endif // OVR_Stereo_h