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
|