comparison Orchestland/Assets/OVR/Scripts/OvrCapi.cs @ 1:f7675884f2a1

Add Orchestland project
author Daiki OYAKAWA <e135764@ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2015 23:09:20 +0900
parents
children
comparison
equal deleted inserted replaced
0:347d21cdfc22 1:f7675884f2a1
1 /************************************************************************************
2
3 Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved.
4
5 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
6 you may not use the Oculus VR Rift SDK except in compliance with the License,
7 which is provided at the time of installation or download, or which
8 otherwise accompanies this software in either electronic or hard copy form.
9
10 You may obtain a copy of the License at
11
12 http://www.oculusvr.com/licenses/LICENSE-3.2
13
14 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19
20 ************************************************************************************/
21
22 using System;
23 using System.Collections.Generic;
24 using System.Runtime.InteropServices;
25
26 namespace Ovr
27 {
28 /// <summary>
29 /// A 2D vector with integer components.
30 /// </summary>
31 [StructLayout(LayoutKind.Sequential)]
32 public struct Vector2i
33 {
34 public int x, y;
35
36 public Vector2i(int _x, int _y)
37 {
38 x = _x;
39 y = _y;
40 }
41 };
42
43 /// <summary>
44 /// A 2D size with integer components.
45 /// </summary>
46 [StructLayout(LayoutKind.Sequential)]
47 public struct Sizei
48 {
49 public int w, h;
50
51 public Sizei(int _w, int _h)
52 {
53 w = _w;
54 h = _h;
55 }
56 };
57
58 /// <summary>
59 /// A 2D rectangle with a position and size.
60 /// All components are integers.
61 /// </summary>
62 [StructLayout(LayoutKind.Sequential)]
63 public struct Recti
64 {
65 public Vector2i Pos;
66 public Sizei Size;
67 };
68
69 /// <summary>
70 /// A quaternion rotation.
71 /// </summary>
72 [StructLayout(LayoutKind.Sequential)]
73 public struct Quatf
74 {
75 public float x, y, z, w;
76
77 public Quatf(float _x, float _y, float _z, float _w)
78 {
79 x = _x;
80 y = _y;
81 z = _z;
82 w = _w;
83 }
84 };
85
86 /// <summary>
87 /// A 2D vector with float components.
88 /// </summary>
89 [StructLayout(LayoutKind.Sequential)]
90 public struct Vector2f
91 {
92 public float x, y;
93
94 public Vector2f(float _x, float _y)
95 {
96 x = _x;
97 y = _y;
98 }
99 };
100
101 /// <summary>
102 /// A 3D vector with float components.
103 /// </summary>
104 [StructLayout(LayoutKind.Sequential)]
105 public struct Vector3f
106 {
107 public float x, y, z;
108
109 public Vector3f(float _x, float _y, float _z)
110 {
111 x = _x;
112 y = _y;
113 z = _z;
114 }
115 };
116
117 /// <summary>
118 /// A 4x4 matrix with float elements.
119 /// </summary>
120 [StructLayout(LayoutKind.Sequential)]
121 public struct Matrix4f
122 {
123 public float[,] m;
124
125 internal Matrix4f(Matrix4f_Raw raw)
126 {
127 this.m = new float[,] {
128 { raw.m00, raw.m01, raw.m02, raw.m03 },
129 { raw.m10, raw.m11, raw.m12, raw.m13 },
130 { raw.m20, raw.m21, raw.m22, raw.m23 },
131 { raw.m30, raw.m31, raw.m32, raw.m33 } };
132 }
133 };
134
135 [StructLayout(LayoutKind.Sequential)]
136 internal struct Matrix4f_Raw
137 {
138 public float m00;
139 public float m01;
140 public float m02;
141 public float m03;
142
143 public float m10;
144 public float m11;
145 public float m12;
146 public float m13;
147
148 public float m20;
149 public float m21;
150 public float m22;
151 public float m23;
152
153 public float m30;
154 public float m31;
155 public float m32;
156 public float m33;
157 };
158
159 /// <summary>
160 /// Position and orientation together.
161 /// </summary>
162 [StructLayout(LayoutKind.Sequential)]
163 public struct Posef
164 {
165 public Quatf Orientation;
166 public Vector3f Position;
167
168 public Posef(Quatf q, Vector3f p)
169 {
170 Orientation = q;
171 Position = p;
172 }
173 };
174
175 /// <summary>
176 /// A full pose (rigid body) configuration with first and second derivatives.
177 /// </summary>
178 [StructLayout(LayoutKind.Sequential)]
179 public struct PoseStatef
180 {
181 /// <summary>
182 /// The body's position and orientation.
183 /// </summary>
184 public Posef ThePose;
185 /// <summary>
186 /// The body's angular velocity in radians per second.
187 /// </summary>
188 public Vector3f AngularVelocity;
189 /// <summary>
190 /// The body's velocity in meters per second.
191 /// </summary>
192 public Vector3f LinearVelocity;
193 /// <summary>
194 /// The body's angular acceleration in radians per second per second.
195 /// </summary>
196 public Vector3f AngularAcceleration;
197 /// <summary>
198 /// The body's acceleration in meters per second per second.
199 /// </summary>
200 public Vector3f LinearAcceleration;
201 /// <summary>
202 /// Absolute time of this state sample.
203 /// </summary>
204 public double TimeInSeconds;
205 };
206
207 /// <summary>
208 /// Field Of View (FOV) in tangent of the angle units.
209 /// As an example, for a standard 90 degree vertical FOV, we would
210 /// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
211 /// </summary>
212 [StructLayout(LayoutKind.Sequential)]
213 public struct FovPort
214 {
215 /// <summary>
216 /// The tangent of the angle between the viewing vector and the top edge of the field of view.
217 /// </summary>
218 public float UpTan;
219 /// <summary>
220 /// The tangent of the angle between the viewing vector and the bottom edge of the field of view.
221 /// </summary>
222 public float DownTan;
223 /// <summary>
224 /// The tangent of the angle between the viewing vector and the left edge of the field of view.
225 /// </summary>
226 public float LeftTan;
227 /// <summary>
228 /// The tangent of the angle between the viewing vector and the right edge of the field of view.
229 /// </summary>
230 public float RightTan;
231 };
232
233 //-----------------------------------------------------------------------------------
234 // ***** HMD Types
235
236 /// <summary>
237 /// Enumerates all HMD types that we support.
238 /// </summary>
239 public enum HmdType
240 {
241 None = 0,
242 DK1 = 3,
243 DKHD = 4,
244 DK2 = 6,
245 Other // Some HMD other then the one in the enumeration.
246 };
247
248 /// <summary>
249 /// HMD capability bits reported by device.
250 /// </summary>
251 public enum HmdCaps
252 {
253 // Read-only flags.
254 /// <summary>
255 /// The HMD is plugged in and detected by the system.
256 /// </summary>
257 Present = 0x0001,
258 /// <summary>
259 /// The HMD and its sensor are available for ownership use.
260 /// i.e. it is not already owned by another application.
261 /// </summary>
262 Available = 0x0002,
263 /// <summary>
264 /// Set to 'true' if we captured ownership of this HMD.
265 /// </summary>
266 Captured = 0x0004,
267
268 // These flags are intended for use with the new driver display mode.
269
270 /// <summary>
271 /// (read only) Means the display driver is in compatibility mode.
272 /// </summary>
273 ExtendDesktop = 0x0008,
274
275 // Modifiable flags (through ovrHmd_SetEnabledCaps).
276
277 /// <summary>
278 /// Disables mirroring of HMD output to the window. This may improve
279 /// rendering performance slightly (only if 'ExtendDesktop' is off).
280 /// </summary>
281 NoMirrorToWindow = 0x2000,
282
283 /// <summary>
284 /// Turns off HMD screen and output (only if 'ExtendDesktop' is off).
285 /// </summary>
286 DisplayOff = 0x0040,
287
288 /// <summary>
289 /// HMD supports low persistence mode.
290 /// </summary>
291 LowPersistence = 0x0080,
292 /// <summary>
293 /// Adjust prediction dynamically based on internally measured latency.
294 /// </summary>
295 DynamicPrediction = 0x0200,
296 /// <summary>
297 /// Support rendering without VSync for debugging.
298 /// </summary>
299 NoVSync = 0x1000,
300
301 /// <summary>
302 /// These bits can be modified by ovrHmd_SetEnabledCaps.
303 /// </summary>
304 WritableMask = 0x33F0,
305
306 /// <summary>
307 /// These flags are currently passed into the service. May change without notice.
308 /// </summary>
309 ServiceMask = 0x23F0,
310 };
311
312 /// <summary>
313 /// Tracking capability bits reported by the device.
314 /// Used with ovrHmd_ConfigureTracking.
315 /// </summary>
316 public enum TrackingCaps
317 {
318 /// <summary>
319 /// Supports orientation tracking (IMU).
320 /// </summary>
321 Orientation = 0x0010,
322 /// <summary>
323 /// Supports yaw drift correction via a magnetometer or other means.
324 /// </summary>
325 MagYawCorrection = 0x0020,
326 /// <summary>
327 /// Supports positional tracking.
328 /// </summary>
329 Position = 0x0040,
330 /// <summary>
331 /// Overrides the other flags. Indicates that the application
332 /// doesn't care about tracking settings. This is the internal
333 /// default before ovrHmd_ConfigureTracking is called.
334 /// </summary>
335 Idle = 0x0100,
336 };
337
338 /// <summary>
339 /// Distortion capability bits reported by device.
340 /// Used with ovrHmd_ConfigureRendering and ovrHmd_CreateDistortionMesh.
341 /// </summary>
342 public enum DistortionCaps
343 {
344 /// <summary>
345 /// Supports chromatic aberration correction.
346 /// </summary>
347 Chromatic = 0x01,
348 /// <summary>
349 /// Supports timewarp.
350 /// </summary>
351 TimeWarp = 0x02,
352 /// <summary>
353 /// Supports vignetting around the edges of the view.
354 /// </summary>
355 Vignette = 0x08,
356 /// <summary>
357 /// Do not save and restore the graphics state when rendering distortion.
358 /// </summary>
359 NoRestore = 0x10,
360 /// <summary>
361 /// Flip the vertical texture coordinate of input images.
362 /// </summary>
363 FlipInput = 0x20,
364 /// <summary>
365 /// Assume input images are in sRGB gamma-corrected color space.
366 /// </summary>
367 SRGB = 0x40,
368 /// <summary>
369 /// Overdrive brightness transitions to reduce artifacts on DK2+ displays
370 /// </summary>
371 Overdrive = 0x80,
372 /// <summary>
373 /// High-quality sampling of distortion buffer for anti-aliasing
374 /// </summary>
375 HqDistortion = 0x100,
376 /// <summary>
377 /// Use when profiling with timewarp to remove false positives
378 /// </summary>
379 ProfileNoTimewarpSpinWaits = 0x10000,
380 };
381
382 /// <summary>
383 /// Specifies which eye is being used for rendering.
384 /// This type explicitly does not include a third "NoStereo" option, as such is
385 /// not required for an HMD-centered API.
386 /// </summary>
387 public enum Eye
388 {
389 Left = 0,
390 Right = 1,
391 Count = 2,
392 };
393
394 /// <summary>
395 /// This is a complete descriptor of the HMD.
396 /// </summary>
397 public struct HmdDesc
398 {
399 /// <summary>
400 /// Internal handle of this HMD.
401 /// </summary>
402 public IntPtr Handle;
403
404 /// <summary>
405 /// This HMD's type.
406 /// </summary>
407 public HmdType Type;
408
409 /// <summary>
410 /// Name string describing the product: "Oculus Rift DK1", etc.
411 /// </summary>
412 public string ProductName;
413 public string Manufacturer;
414
415 /// <summary>
416 /// HID Vendor and ProductId of the device.
417 /// </summary>
418 public short VendorId;
419 public short ProductId;
420 /// <summary>
421 /// Sensor (and display) serial number.
422 /// </summary>
423 public string SerialNumber;
424 /// <summary>
425 /// Sensor firmware version.
426 /// </summary>
427 public short FirmwareMajor;
428 public short FirmwareMinor;
429 /// <summary>
430 /// External tracking camera frustum dimensions (if present).
431 /// </summary>
432 public float CameraFrustumHFovInRadians;
433 public float CameraFrustumVFovInRadians;
434 public float CameraFrustumNearZInMeters;
435 public float CameraFrustumFarZInMeters;
436
437 /// <summary>
438 /// Capability bits described by ovrHmdCaps.
439 /// </summary>
440 public uint HmdCaps;
441 /// <summary>
442 /// Capability bits described by ovrTrackingCaps.
443 /// </summary>
444 public uint TrackingCaps;
445 /// <summary>
446 /// Capability bits described by ovrDistortionCaps.
447 /// </summary>
448 public uint DistortionCaps;
449
450 /// <summary>
451 /// Defines the recommended optical FOV for the HMD.
452 /// </summary>
453 public FovPort[] DefaultEyeFov;
454 /// <summary>
455 /// Defines the maximum optical FOV for the HMD.
456 /// </summary>
457 public FovPort[] MaxEyeFov;
458
459 /// <summary>
460 /// Preferred eye rendering order for best performance.
461 /// Can help reduce latency on sideways-scanned screens.
462 /// </summary>
463 public Eye[] EyeRenderOrder;
464
465 /// <summary>
466 /// Resolution of the full HMD screen (both eyes) in pixels.
467 /// </summary>
468 public Sizei Resolution;
469 /// <summary>
470 /// Location of the application window on the desktop (or 0,0).
471 /// </summary>
472 public Vector2i WindowsPos;
473
474 /// <summary>
475 /// Display that the HMD should present on.
476 /// TBD: It may be good to remove this information relying on WindowPos instead.
477 /// Ultimately, we may need to come up with a more convenient alternative,
478 /// such as API-specific functions that return adapter, or something that will
479 /// work with our monitor driver.
480 /// Windows: (e.g. "\\\\.\\DISPLAY3", can be used in EnumDisplaySettings/CreateDC).
481 /// </summary>
482 public string DisplayDeviceName;
483 /// <summary>
484 /// MacOS:
485 /// </summary>
486 public int DisplayId;
487
488 internal HmdDesc(HmdDesc_Raw raw)
489 {
490 this.Handle = raw.Handle;
491 this.Type = (HmdType)raw.Type;
492 this.ProductName = Marshal.PtrToStringAnsi(raw.ProductName);
493 this.Manufacturer = Marshal.PtrToStringAnsi(raw.Manufacturer);
494 this.VendorId = raw.VendorId;
495 this.ProductId = raw.ProductId;
496 this.SerialNumber = raw.SerialNumber;
497 this.FirmwareMajor = raw.FirmwareMajor;
498 this.FirmwareMinor = raw.FirmwareMinor;
499 this.CameraFrustumHFovInRadians = raw.CameraFrustumHFovInRadians;
500 this.CameraFrustumVFovInRadians = raw.CameraFrustumVFovInRadians;
501 this.CameraFrustumNearZInMeters = raw.CameraFrustumNearZInMeters;
502 this.CameraFrustumFarZInMeters = raw.CameraFrustumFarZInMeters;
503 this.HmdCaps = raw.HmdCaps;
504 this.TrackingCaps = raw.TrackingCaps;
505 this.DistortionCaps = raw.DistortionCaps;
506 this.Resolution = raw.Resolution;
507 this.WindowsPos = raw.WindowsPos;
508 this.DefaultEyeFov = new FovPort[2] { raw.DefaultEyeFov_0, raw.DefaultEyeFov_1 };
509 this.MaxEyeFov = new FovPort[2] { raw.MaxEyeFov_0, raw.MaxEyeFov_1 };
510 this.EyeRenderOrder = new Eye[2] { Eye.Left, Eye.Right };
511 this.DisplayDeviceName = Marshal.PtrToStringAnsi(raw.DisplayDeviceName);
512 this.DisplayId = raw.DisplayId;
513 }
514 };
515
516 // Internal description for HMD; must match C 'ovrHmdDesc' layout.
517 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
518 internal struct HmdDesc_Raw
519 {
520 public IntPtr Handle;
521 public uint Type;
522 // Use IntPtr so that CLR doesn't try to deallocate string.
523 public IntPtr ProductName;
524 public IntPtr Manufacturer;
525 // HID Vendor and ProductId of the device.
526 public short VendorId;
527 public short ProductId;
528 // Sensor (and display) serial number.
529 [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 24)]
530 public string SerialNumber;
531 // Sensor firmware
532 public short FirmwareMajor;
533 public short FirmwareMinor;
534 // Fixed camera frustum dimensions, if present
535 public float CameraFrustumHFovInRadians;
536 public float CameraFrustumVFovInRadians;
537 public float CameraFrustumNearZInMeters;
538 public float CameraFrustumFarZInMeters;
539 public uint HmdCaps;
540 public uint TrackingCaps;
541 public uint DistortionCaps;
542 // C# arrays are dynamic and thus not supported as return values, so just expand the struct.
543 public FovPort DefaultEyeFov_0;
544 public FovPort DefaultEyeFov_1;
545 public FovPort MaxEyeFov_0;
546 public FovPort MaxEyeFov_1;
547 public Eye EyeRenderOrder_0;
548 public Eye EyeRenderOrder_1;
549 public Sizei Resolution;
550 public Vector2i WindowsPos;
551 public IntPtr DisplayDeviceName;
552 public int DisplayId;
553 };
554
555 /// <summary>
556 /// Bit flags describing the current status of sensor tracking.
557 /// </summary>
558 public enum StatusBits
559 {
560 /// <summary>
561 /// Orientation is currently tracked (connected and in use).
562 /// </summary>
563 OrientationTracked = 0x0001,
564 /// <summary>
565 /// Position is currently tracked (false if out of range).
566 /// </summary>
567 PositionTracked = 0x0002,
568 /// <summary>
569 /// Camera pose is currently tracked.
570 /// </summary>
571 CameraPoseTracked = 0x0004,
572 /// <summary>
573 /// Position tracking hardware is connected.
574 /// </summary>
575 PositionConnected = 0x0020,
576 /// <summary>
577 /// HMD Display is available and connected.
578 /// </summary>
579 HmdConnected = 0x0080,
580 };
581
582 /// <summary>
583 /// Specifies a reading we can query from the sensor.
584 /// </summary>
585 public struct SensorData
586 {
587 /// <summary>
588 /// Acceleration reading in m/s^2.
589 /// </summary>
590 public Vector3f Accelerometer;
591 /// <summary>
592 /// Rotation rate in rad/s.
593 /// </summary>
594 public Vector3f Gyro;
595 /// <summary>
596 /// Magnetic field in Gauss.
597 /// </summary>
598 public Vector3f Magnetometer;
599 /// <summary>
600 /// Temperature of the sensor in degrees Celsius.
601 /// </summary>
602 public float Temperature;
603 /// <summary>
604 /// Time when the reported IMU reading took place, in seconds.
605 /// </summary>
606 public float TimeInSeconds;
607 };
608
609 /// <summary>
610 /// Tracking state at a given absolute time (describes predicted HMD pose etc).
611 /// Returned by ovrHmd_GetTrackingState.
612 /// </summary>
613 [StructLayout(LayoutKind.Sequential)]
614 public struct TrackingState
615 {
616 /// <summary>
617 /// Predicted head pose (and derivatives) at the requested absolute time.
618 /// The look-ahead interval is equal to (HeadPose.TimeInSeconds - RawSensorData.TimeInSeconds).
619 /// </summary>
620 public PoseStatef HeadPose;
621
622 /// <summary>
623 /// Current pose of the external camera (if present).
624 /// This pose includes camera tilt (roll and pitch). For a leveled coordinate
625 /// system use LeveledCameraPose.
626 /// </summary>
627 public Posef CameraPose;
628
629 /// <summary>
630 /// Camera frame aligned with gravity.
631 /// This value includes position and yaw of the camera, but not roll and pitch.
632 /// It can be used as a reference point to render real-world objects in the correct location.
633 /// </summary>
634 public Posef LeveledCameraPose;
635
636 /// <summary>
637 /// The most recent sensor data received from the HMD.
638 /// </summary>
639 public SensorData RawSensorData;
640
641 /// <summary>
642 /// Tracking status described by ovrStatusBits.
643 /// </summary>
644 public uint StatusFlags;
645
646 //// 0.4.1
647
648 // Measures the time from receiving the camera frame until vision CPU processing completes.
649 public double LastVisionProcessingTime;
650
651 //// 0.4.3
652
653 /// <summary>
654 /// Measures the time from exposure until the pose is available for the frame, including processing time.
655 /// </summary>
656 public double LastVisionFrameLatency;
657
658 /// <summary>
659 /// Tag the vision processing results to a certain frame counter number.
660 /// </summary>
661 public uint LastCameraFrameCounter;
662 };
663
664 /// <summary>
665 /// Frame timing data reported by ovrHmd_BeginFrameTiming() or ovrHmd_BeginFrame().
666 /// </summary>
667 [StructLayout(LayoutKind.Sequential)]
668 public struct FrameTiming
669 {
670 /// <summary>
671 /// The amount of time that has passed since the previous frame's
672 /// ThisFrameSeconds value (usable for movement scaling).
673 /// This will be clamped to no more than 0.1 seconds to prevent
674 /// excessive movement after pauses due to loading or initialization.
675 /// </summary>
676 public float DeltaSeconds;
677
678 // It is generally expected that the following holds:
679 // ThisFrameSeconds < TimewarpPointSeconds < NextFrameSeconds <
680 // EyeScanoutSeconds[EyeOrder[0]] <= ScanoutMidpointSeconds <= EyeScanoutSeconds[EyeOrder[1]].
681
682 /// <summary>
683 /// Absolute time value when rendering of this frame began or is expected to
684 /// begin. Generally equal to NextFrameSeconds of the previous frame. Can be used
685 /// for animation timing.
686 /// </summary>
687 public double ThisFrameSeconds;
688 /// <summary>
689 /// Absolute point when IMU expects to be sampled for this frame.
690 /// </summary>
691 public double TimewarpPointSeconds;
692 /// <summary>
693 /// Absolute time when frame Present followed by GPU Flush will finish and the next frame begins.
694 /// </summary>
695 public double NextFrameSeconds;
696
697 /// <summary>
698 /// Time when half of the screen will be scanned out. Can be passed as an absolute time
699 /// to ovrHmd_GetTrackingState() to get the predicted general orientation.
700 /// </summary>
701 public double ScanoutMidpointSeconds;
702 /// <summary>
703 /// Timing points when each eye will be scanned out to display. Used when rendering each eye.
704 /// </summary>
705 public double[] EyeScanoutSeconds;
706
707 internal FrameTiming(FrameTiming_Raw raw)
708 {
709 this.DeltaSeconds = raw.DeltaSeconds;
710 this.ThisFrameSeconds = raw.ThisFrameSeconds;
711 this.TimewarpPointSeconds = raw.TimewarpPointSeconds;
712 this.NextFrameSeconds = raw.NextFrameSeconds;
713 this.ScanoutMidpointSeconds = raw.ScanoutMidpointSeconds;
714 this.EyeScanoutSeconds = new double[2] { raw.EyeScanoutSeconds_0, raw.EyeScanoutSeconds_1 };
715 }
716 };
717
718 // Internal description for ovrFrameTiming; must match C 'ovrFrameTiming' layout.
719 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
720 internal struct FrameTiming_Raw
721 {
722 public float DeltaSeconds;
723 public double ThisFrameSeconds;
724 public double TimewarpPointSeconds;
725 public double NextFrameSeconds;
726 public double ScanoutMidpointSeconds;
727 // C# arrays are dynamic and thus not supported as return values, so just expand the struct.
728 public double EyeScanoutSeconds_0;
729 public double EyeScanoutSeconds_1;
730 };
731
732 /// <summary>
733 /// Rendering information for each eye. Computed by either ovrHmd_ConfigureRendering()
734 /// or ovrHmd_GetRenderDesc() based on the specified FOV. Note that the rendering viewport
735 /// is not included here as it can be specified separately and modified per frame through:
736 /// (a) ovrHmd_GetRenderScaleAndOffset in the case of client rendered distortion,
737 /// or (b) passing different values via ovrTexture in the case of SDK rendered distortion.
738 /// </summary>
739 [StructLayout(LayoutKind.Sequential)]
740 public struct EyeRenderDesc
741 {
742 /// <summary>
743 /// The eye index this instance corresponds to.
744 /// </summary>
745 public Eye Eye;
746 /// <summary>
747 /// The field of view.
748 /// </summary>
749 public FovPort Fov;
750 /// <summary>
751 /// Distortion viewport.
752 /// </summary>
753 public Recti DistortedViewport;
754 /// <summary>
755 /// How many display pixels will fit in tan(angle) = 1.
756 /// </summary>
757 public Vector2f PixelsPerTanAngleAtCenter;
758 /// <summary>
759 /// Translation to be applied to view matrix for each eye offset.
760 /// </summary>
761 public Vector3f HmdToEyeViewOffset;
762 };
763
764 //-----------------------------------------------------------------------------------
765 // ***** Platform-independent Rendering Configuration
766
767 /// <summary>
768 /// These types are used to hide platform-specific details when passing
769 /// render device, OS, and texture data to the API.
770 ///
771 /// The benefit of having these wrappers versus platform-specific API functions is
772 /// that they allow game glue code to be portable. A typical example is an
773 /// engine that has multiple back ends, say GL and D3D. Portable code that calls
774 /// these back ends may also use LibOVR. To do this, back ends can be modified
775 /// to return portable types such as ovrTexture and ovrRenderAPIConfig.
776 /// </summary>
777 public enum RenderAPIType
778 {
779 None,
780 OpenGL,
781 Android_GLES, // May include extra native window pointers, etc.
782 D3D9,
783 D3D10,
784 D3D11,
785 Count,
786 };
787
788 /// <summary>
789 /// Platform-independent part of rendering API-configuration data.
790 /// It is a part of ovrRenderAPIConfig, passed to ovrHmd_Configure.
791 /// </summary>
792 [StructLayout(LayoutKind.Sequential)]
793 public struct RenderAPIConfigHeader
794 {
795 public RenderAPIType API;
796 public Sizei RTSize;
797 public int Multisample;
798 };
799
800 [StructLayout(LayoutKind.Sequential)]
801 internal struct RenderAPIConfig_Raw
802 {
803 public RenderAPIConfigHeader Header;
804 public IntPtr PlatformData0;
805 public IntPtr PlatformData1;
806 public IntPtr PlatformData2;
807 public IntPtr PlatformData3;
808 public IntPtr PlatformData4;
809 public IntPtr PlatformData5;
810 public IntPtr PlatformData6;
811 public IntPtr PlatformData7;
812 };
813
814 /// <summary>
815 /// Contains platform-specific information for rendering.
816 /// </summary>
817 public abstract class RenderAPIConfig
818 {
819 public RenderAPIConfig() { Header.API = RenderAPIType.None; }
820
821 public RenderAPIConfigHeader Header;
822
823 internal abstract RenderAPIConfig_Raw ToRaw();
824 }
825
826 /// <summary>
827 /// Contains OpenGL-specific rendering information for Windows.
828 /// </summary>
829 public class OpenGLWindowsConfig : RenderAPIConfig
830 {
831 public OpenGLWindowsConfig(Sizei rtSize, int multisample, IntPtr hwnd, IntPtr HDCDeviceContext)
832 {
833 Header.API = RenderAPIType.OpenGL;
834 Header.RTSize = rtSize;
835 Header.Multisample = multisample;
836 _hwnd = hwnd;
837 _HDCDeviceContext = HDCDeviceContext;
838 }
839
840 internal override RenderAPIConfig_Raw ToRaw()
841 {
842 RenderAPIConfig_Raw config = new RenderAPIConfig_Raw();
843 config.Header = this.Header;
844 config.PlatformData0 = this._hwnd;
845 config.PlatformData1 = this._HDCDeviceContext;
846 return config;
847 }
848
849 public IntPtr _hwnd;
850 public IntPtr _HDCDeviceContext;
851 }
852
853 /// <summary>
854 /// Contains OpenGL-specific rendering information for Linux.
855 /// </summary>
856 public class OpenGLLinuxConfig : RenderAPIConfig
857 {
858 public OpenGLLinuxConfig(Sizei rtSize, int multisample, IntPtr optionalXDisplay, IntPtr optionalWindow)
859 {
860 Header.API = RenderAPIType.OpenGL;
861 Header.RTSize = rtSize;
862 Header.Multisample = multisample;
863 _OptionalXDisplay = optionalXDisplay;
864 _OptionalWindow = optionalWindow;
865 }
866
867 internal override RenderAPIConfig_Raw ToRaw()
868 {
869 RenderAPIConfig_Raw config = new RenderAPIConfig_Raw();
870 config.Header = this.Header;
871 config.PlatformData0 = this._OptionalXDisplay;
872 config.PlatformData1 = this._OptionalWindow;
873 return config;
874 }
875
876 IntPtr _OptionalXDisplay;
877 IntPtr _OptionalWindow;
878 }
879
880 /// <summary>
881 /// Contains OpenGL ES-specific rendering information.
882 /// </summary>
883 public class AndroidGLESConfig : RenderAPIConfig
884 {
885 public AndroidGLESConfig(Sizei rtSize, int multisample)
886 {
887 Header.API = RenderAPIType.Android_GLES;
888 Header.RTSize = rtSize;
889 Header.Multisample = multisample;
890 }
891
892 internal override RenderAPIConfig_Raw ToRaw()
893 {
894 RenderAPIConfig_Raw config = new RenderAPIConfig_Raw();
895 config.Header = this.Header;
896 return config;
897 }
898 }
899
900 /// <summary>
901 /// Contains D3D9-specific rendering information.
902 /// </summary>
903 public class D3D9Config : RenderAPIConfig
904 {
905 public D3D9Config(Sizei rtSize, int multisample, IntPtr IDirect3DDevice9_pDevice, IntPtr IDirect3DSwapChain9_pSwapChain)
906 {
907 Header.API = RenderAPIType.D3D9;
908 Header.RTSize = rtSize;
909 Header.Multisample = multisample;
910 _IDirect3DDevice9_pDevice = IDirect3DDevice9_pDevice;
911 _IDirect3DSwapChain9_pSwapChain = IDirect3DSwapChain9_pSwapChain;
912 }
913
914 internal override RenderAPIConfig_Raw ToRaw()
915 {
916 RenderAPIConfig_Raw config = new RenderAPIConfig_Raw();
917 config.Header = this.Header;
918 config.PlatformData0 = this._IDirect3DDevice9_pDevice;
919 config.PlatformData1 = this._IDirect3DSwapChain9_pSwapChain;
920 return config;
921 }
922
923 IntPtr _IDirect3DDevice9_pDevice;
924 IntPtr _IDirect3DSwapChain9_pSwapChain;
925 }
926
927 /// <summary>
928 /// Contains D3D10-specific rendering information.
929 /// </summary>
930 public class D3D10Config : RenderAPIConfig
931 {
932 public D3D10Config(Sizei rtSize, int multisample, IntPtr ID3D10RenderTargetView_pBackBufferRT, IntPtr IDXGISwapChain_pSwapChain)
933 {
934 Header.API = RenderAPIType.D3D10;
935 Header.RTSize = rtSize;
936 Header.Multisample = multisample;
937 _ID3D10RenderTargetView_pBackBufferRT = ID3D10RenderTargetView_pBackBufferRT;
938 _IDXGISwapChain_pSwapChain = IDXGISwapChain_pSwapChain;
939 }
940
941 internal override RenderAPIConfig_Raw ToRaw()
942 {
943 RenderAPIConfig_Raw config = new RenderAPIConfig_Raw();
944 config.Header = this.Header;
945 config.PlatformData0 = IntPtr.Zero;
946 config.PlatformData1 = this._ID3D10RenderTargetView_pBackBufferRT;
947 config.PlatformData2 = this._IDXGISwapChain_pSwapChain;
948 return config;
949 }
950
951 IntPtr _ID3D10RenderTargetView_pBackBufferRT;
952 IntPtr _IDXGISwapChain_pSwapChain;
953 }
954
955 /// <summary>
956 /// Contains D3D11-specific rendering information.
957 /// </summary>
958 public class D3D11Config : RenderAPIConfig
959 {
960 public D3D11Config(Sizei rtSize, int multisample, IntPtr ID3D11Device_pDevice, IntPtr ID3D11DeviceContext_pDeviceContext, IntPtr ID3D11RenderTargetView_pBackBufferRT, IntPtr IDXGISwapChain_pSwapChain)
961 {
962 Header.API = RenderAPIType.D3D11;
963 Header.RTSize = rtSize;
964 Header.Multisample = multisample;
965 _ID3D11Device_pDevice = ID3D11Device_pDevice;
966 _ID3D11DeviceContext_pDeviceContext = ID3D11DeviceContext_pDeviceContext;
967 _ID3D11RenderTargetView_pBackBufferRT = ID3D11RenderTargetView_pBackBufferRT;
968 _IDXGISwapChain_pSwapChain = IDXGISwapChain_pSwapChain;
969 }
970
971 internal override RenderAPIConfig_Raw ToRaw()
972 {
973 RenderAPIConfig_Raw config = new RenderAPIConfig_Raw();
974 config.Header = this.Header;
975 config.PlatformData0 = this._ID3D11Device_pDevice;
976 config.PlatformData1 = this._ID3D11DeviceContext_pDeviceContext;
977 config.PlatformData2 = this._ID3D11RenderTargetView_pBackBufferRT;
978 config.PlatformData3 = this._IDXGISwapChain_pSwapChain;
979 return config;
980 }
981
982 IntPtr _ID3D11Device_pDevice;
983 IntPtr _ID3D11DeviceContext_pDeviceContext;
984 IntPtr _ID3D11RenderTargetView_pBackBufferRT;
985 IntPtr _IDXGISwapChain_pSwapChain;
986 }
987
988 /// <summary>
989 /// Platform-independent part of the eye texture descriptor.
990 /// It is a part of ovrTexture, passed to ovrHmd_EndFrame.
991 /// If RenderViewport is all zeros then the full texture will be used.
992 /// </summary>
993 [StructLayout(LayoutKind.Sequential)]
994 public struct TextureHeader
995 {
996 public RenderAPIType API;
997 public Sizei TextureSize;
998 public Recti RenderViewport; // Pixel viewport in texture that holds eye image.
999 };
1000
1001 /// <summary>
1002 /// Contains platform-specific information for rendering.
1003 /// </summary>
1004 public abstract class Texture
1005 {
1006 public Texture() { Header.API = RenderAPIType.None; }
1007
1008 public TextureHeader Header;
1009
1010 internal abstract Texture_Raw ToRaw();
1011 }
1012
1013 /// <summary>
1014 /// Contains OpenGL-specific texture information
1015 /// </summary>
1016 public class GLTextureData : Texture
1017 {
1018 public GLTextureData(Sizei textureSize, Recti renderViewport, IntPtr texId)
1019 {
1020 Header.API = RenderAPIType.OpenGL;
1021 Header.TextureSize = textureSize;
1022 Header.RenderViewport = renderViewport;
1023 _texId = texId;
1024 }
1025
1026 internal override Texture_Raw ToRaw()
1027 {
1028 Texture_Raw config = new Texture_Raw();
1029 config.Header = this.Header;
1030 config.PlatformData_0 = this._texId;
1031 return config;
1032 }
1033
1034 public IntPtr _texId;
1035 }
1036
1037 /// <summary>
1038 /// Contains D3D9-specific texture information
1039 /// </summary>
1040 public class D3D9TextureData : Texture
1041 {
1042 public D3D9TextureData(Sizei textureSize, Recti renderViewport, IntPtr IDirect3DTexture9_pTexture)
1043 {
1044 Header.API = RenderAPIType.D3D9;
1045 Header.TextureSize = textureSize;
1046 Header.RenderViewport = renderViewport;
1047 _IDirect3DTexture9_pTexture = IDirect3DTexture9_pTexture;
1048 }
1049
1050 internal override Texture_Raw ToRaw()
1051 {
1052 Texture_Raw config = new Texture_Raw();
1053 config.Header = this.Header;
1054 config.PlatformData_0 = this._IDirect3DTexture9_pTexture;
1055 return config;
1056 }
1057
1058 public IntPtr _IDirect3DTexture9_pTexture;
1059 }
1060
1061 /// <summary>
1062 /// Contains D3D10-specific texture information
1063 /// </summary>
1064 public class D3D10TextureData : Texture
1065 {
1066 public D3D10TextureData(Sizei textureSize, Recti renderViewport, IntPtr ID3D10Texture2D_pTexture, IntPtr ID3D10ShaderResourceView_pSRView)
1067 {
1068 Header.API = RenderAPIType.D3D10;
1069 Header.TextureSize = textureSize;
1070 Header.RenderViewport = renderViewport;
1071 _ID3D10Texture2D_pTexture = ID3D10Texture2D_pTexture;
1072 _ID3D10ShaderResourceView_pSRView = ID3D10ShaderResourceView_pSRView;
1073 }
1074
1075 internal override Texture_Raw ToRaw()
1076 {
1077 Texture_Raw config = new Texture_Raw();
1078 config.Header = this.Header;
1079 config.PlatformData_0 = this._ID3D10Texture2D_pTexture;
1080 config.PlatformData_1 = this._ID3D10ShaderResourceView_pSRView;
1081 return config;
1082 }
1083
1084 public IntPtr _ID3D10Texture2D_pTexture, _ID3D10ShaderResourceView_pSRView;
1085 }
1086
1087
1088 /// <summary>
1089 /// Contains D3D11-specific texture information
1090 /// </summary>
1091 public class D3D11TextureData : Texture
1092 {
1093 public D3D11TextureData(Sizei textureSize, Recti renderViewport, IntPtr ID3D11Texture2D_pTexture, IntPtr ID3D11ShaderResourceView_pSRView)
1094 {
1095 Header.API = RenderAPIType.D3D11;
1096 Header.TextureSize = textureSize;
1097 Header.RenderViewport = renderViewport;
1098 _ID3D11Texture2D_pTexture = ID3D11Texture2D_pTexture;
1099 _ID3D11ShaderResourceView_pSRView = ID3D11ShaderResourceView_pSRView;
1100 }
1101
1102 internal override Texture_Raw ToRaw()
1103 {
1104 Texture_Raw config = new Texture_Raw();
1105 config.Header = this.Header;
1106 config.PlatformData_0 = this._ID3D11Texture2D_pTexture;
1107 config.PlatformData_1 = this._ID3D11ShaderResourceView_pSRView;
1108 return config;
1109 }
1110
1111 public IntPtr _ID3D11Texture2D_pTexture, _ID3D11ShaderResourceView_pSRView;
1112 }
1113
1114 // Internal description for ovrTexture; must match C 'ovrTexture' layout.
1115 [StructLayout(LayoutKind.Sequential)]
1116 internal struct Texture_Raw
1117 {
1118 public TextureHeader Header;
1119 public IntPtr PlatformData_0;
1120 public IntPtr PlatformData_1;
1121 public IntPtr PlatformData_2;
1122 public IntPtr PlatformData_3;
1123 public IntPtr PlatformData_4;
1124 public IntPtr PlatformData_5;
1125 public IntPtr PlatformData_6;
1126 public IntPtr PlatformData_7;
1127 };
1128
1129 /// <summary>
1130 /// Describes a vertex used by the distortion mesh. This is intended to be converted into
1131 /// the engine-specific format. Some fields may be unused based on the ovrDistortionCaps
1132 /// flags selected. TexG and TexB, for example, are not used if chromatic correction is
1133 /// not requested.
1134 /// </summary>
1135 [StructLayout(LayoutKind.Sequential)]
1136 public struct DistortionVertex
1137 {
1138 /// <summary>
1139 /// [-1,+1],[-1,+1] over the entire framebuffer.
1140 /// </summary>
1141 public Vector2f ScreenPosNDC;
1142 /// <summary>
1143 /// Lerp factor between time-warp matrices. Can be encoded in Pos.z.
1144 /// </summary>
1145 public float TimeWarpFactor;
1146 /// <summary>
1147 /// Vignette fade factor. Can be encoded in Pos.w.
1148 /// </summary>
1149 public float VignetteFactor;
1150 /// <summary>
1151 /// The tangents of the horizontal and vertical eye angles for the red channel.
1152 /// </summary>
1153 public Vector2f TanEyeAnglesR;
1154 /// <summary>
1155 /// The tangents of the horizontal and vertical eye angles for the green channel.
1156 /// </summary>
1157 public Vector2f TanEyeAnglesG;
1158 /// <summary>
1159 /// The tangents of the horizontal and vertical eye angles for the blue channel.
1160 /// </summary>
1161 public Vector2f TanEyeAnglesB;
1162 };
1163
1164 /// <summary>
1165 /// Describes a full set of distortion mesh data, filled in by ovrHmd_CreateDistortionMesh.
1166 /// Contents of this data structure, if not null, should be freed by ovrHmd_DestroyDistortionMesh.
1167 /// </summary>
1168 public struct DistortionMesh
1169 {
1170 /// <summary>
1171 /// The distortion vertices representing each point in the mesh.
1172 /// </summary>
1173 public DistortionVertex[] pVertexData;
1174 /// <summary>
1175 /// Indices for connecting the mesh vertices into polygons.
1176 /// </summary>
1177 public short[] pIndexData;
1178 /// <summary>
1179 /// The number of vertices in the mesh.
1180 /// </summary>
1181 public uint VertexCount;
1182 /// <summary>
1183 /// The number of indices in the mesh.
1184 /// </summary>
1185 public uint IndexCount;
1186
1187 internal DistortionMesh(DistortionMesh_Raw raw)
1188 {
1189 this.VertexCount = raw.VertexCount;
1190 this.pVertexData = new DistortionVertex[this.VertexCount];
1191 this.IndexCount = raw.IndexCount;
1192 this.pIndexData = new short[this.IndexCount];
1193
1194 // Copy data
1195 System.Type vertexType = typeof(DistortionVertex);
1196 Int32 vertexSize = Marshal.SizeOf(vertexType);
1197 Int32 indexSize = sizeof(short);
1198 Int64 pvertices = raw.pVertexData.ToInt64();
1199 Int64 pindices = raw.pIndexData.ToInt64();
1200
1201 // TODO: Investigate using Marshal.Copy() or Buffer.BlockCopy() for improved performance
1202
1203 for (int i = 0; i < raw.VertexCount; i++)
1204 {
1205 pVertexData[i] = (DistortionVertex)Marshal.PtrToStructure(new IntPtr(pvertices), vertexType);
1206 pvertices += vertexSize;
1207 }
1208 // Indices are stored as shorts.
1209 for (int j = 0; j < raw.IndexCount; j++)
1210 {
1211 pIndexData[j] = Marshal.ReadInt16(new IntPtr(pindices));
1212 pindices += indexSize;
1213 }
1214 }
1215 };
1216
1217 // Internal description for ovrDistortionMesh; must match C 'ovrDistortionMesh' layout.
1218 [StructLayout(LayoutKind.Sequential)]
1219 internal struct DistortionMesh_Raw
1220 {
1221 public IntPtr pVertexData;
1222 public IntPtr pIndexData;
1223 public uint VertexCount;
1224 public uint IndexCount;
1225 };
1226
1227 /// <summary>
1228 /// Used by ovrhmd_GetHSWDisplayState to report the current display state.
1229 /// </summary>
1230 [StructLayout(LayoutKind.Sequential)]
1231 public struct HSWDisplayState
1232 {
1233 /// <summary>
1234 /// If true then the warning should be currently visible
1235 /// and the following variables have meaning. Else there is no
1236 /// warning being displayed for this application on the given HMD.
1237 /// True if the Health&Safety Warning is currently displayed.
1238 /// </summary>
1239 public bool Displayed;
1240 /// <summary>
1241 /// Absolute time when the warning was first displayed. See ovr_GetTimeInSeconds().
1242 /// </summary>
1243 public double StartTime;
1244 /// <summary>
1245 /// Earliest absolute time when the warning can be dismissed. May be a time in the past.
1246 /// </summary>
1247 public double DismissibleTime;
1248 };
1249
1250 /// <summary>
1251 /// Provides an interface to a CAPI HMD object. The ovrHmd instance is normally
1252 /// created by ovrHmd::Create, after which its other methods can be called.
1253 /// The typical process would involve calling:
1254 ///
1255 /// Setup:
1256 /// - Initialize() to initialize the OVR SDK.
1257 /// - Create() to create an HMD.
1258 /// - Use hmd members and ovrHmd_GetFovTextureSize() to determine graphics configuration.
1259 /// - ConfigureTracking() to configure and initialize tracking.
1260 /// - ConfigureRendering() to setup graphics for SDK rendering.
1261 /// - If ovrHmdCap_ExtendDesktop is not set, use ovrHmd_AttachToWindow to associate the window with an Hmd.
1262 /// - Allocate textures as needed.
1263 ///
1264 /// Game Loop:
1265 /// - Call ovrHmd_BeginFrame() to get frame timing and orientation information.
1266 /// - Render each eye in between, using ovrHmd_GetEyePoses or ovrHmd_GetHmdPosePerEye to get the predicted hmd pose and each eye pose.
1267 /// - Call ovrHmd_EndFrame() to render distorted textures to the back buffer
1268 /// and present them on the Hmd.
1269 ///
1270 /// Shutdown:
1271 /// - Destroy() to release the HMD.
1272 /// - ovr_Shutdown() to shutdown the OVR SDK.
1273 /// </summary>
1274 public class Hmd
1275 {
1276 public const string OVR_VERSION_STRING = "0.4.4";
1277 public const string OVR_KEY_USER = "User";
1278 public const string OVR_KEY_NAME = "Name";
1279 public const string OVR_KEY_GENDER = "Gender";
1280 public const string OVR_KEY_PLAYER_HEIGHT = "PlayerHeight";
1281 public const string OVR_KEY_EYE_HEIGHT = "EyeHeight";
1282 public const string OVR_KEY_IPD = "IPD";
1283 public const string OVR_KEY_NECK_TO_EYE_DISTANCE = "NeckEyeDistance";
1284 public const string OVR_KEY_EYE_RELIEF_DIAL = "EyeReliefDial";
1285 public const string OVR_KEY_EYE_TO_NOSE_DISTANCE = "EyeToNoseDist";
1286 public const string OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE = "MaxEyeToPlateDist";
1287 public const string OVR_KEY_EYE_CUP = "EyeCup";
1288 public const string OVR_KEY_CUSTOM_EYE_RENDER = "CustomEyeRender";
1289 public const string OVR_KEY_CAMERA_POSITION = "CenteredFromWorld";
1290
1291 // Default measurements empirically determined at Oculus to make us happy
1292 // The neck model numbers were derived as an average of the male and female averages from ANSUR-88
1293 // NECK_TO_EYE_HORIZONTAL = H22 - H43 = INFRAORBITALE_BACK_OF_HEAD - TRAGION_BACK_OF_HEAD
1294 // NECK_TO_EYE_VERTICAL = H21 - H15 = GONION_TOP_OF_HEAD - ECTOORBITALE_TOP_OF_HEAD
1295 // These were determined to be the best in a small user study, clearly beating out the previous default values
1296 public const string OVR_DEFAULT_GENDER = "Unknown";
1297 public const float OVR_DEFAULT_PLAYER_HEIGHT = 1.778f;
1298 public const float OVR_DEFAULT_EYE_HEIGHT = 1.675f;
1299 public const float OVR_DEFAULT_IPD = 0.064f;
1300 public const float OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL = 0.0805f;
1301 public const float OVR_DEFAULT_NECK_TO_EYE_VERTICAL = 0.075f;
1302 public const float OVR_DEFAULT_EYE_RELIEF_DIAL = 3;
1303 public readonly float[] OVR_DEFAULT_CAMERA_POSITION = {0,0,0,1,0,0,0};
1304
1305 private IntPtr HmdPtr;
1306
1307 // Used to return color result to avoid per-frame allocation.
1308 private byte[] LatencyTestRgb = new byte[3];
1309
1310 // -----------------------------------------------------------------------------------
1311 // Static Methods
1312
1313 // ovr_InitializeRenderingShim initializes the rendering shim appart from everything
1314 // else in LibOVR. This may be helpful if the application prefers to avoid
1315 // creating any OVR resources (allocations, service connections, etc) at this point.
1316 // ovr_InitializeRenderingShim does not bring up anything within LibOVR except the
1317 // necessary hooks to enable the Direct-to-Rift functionality.
1318 //
1319 // Either ovr_InitializeRenderingShim() or ovr_Initialize() must be called before any
1320 // Direct3D or OpenGL initilization is done by applictaion (creation of devices, etc).
1321 // ovr_Initialize() must still be called after to use the rest of LibOVR APIs.
1322 public static void InitializeRenderingShim()
1323 {
1324 ovr_InitializeRenderingShim();
1325 }
1326
1327 // Library init/shutdown, must be called around all other OVR code.
1328 // No other functions calls besides ovr_InitializeRenderingShim are allowed
1329 // before ovr_Initialize succeeds or after ovr_Shutdown.
1330
1331 /// <summary>
1332 /// Initializes all Oculus functionality.
1333 /// </summary>
1334 public static bool Initialize()
1335 {
1336 return ovr_Initialize() != 0;
1337 }
1338
1339 /// <summary>
1340 /// Shuts down all Oculus functionality.
1341 /// </summary>
1342 public static void Shutdown()
1343 {
1344 ovr_Shutdown();
1345 }
1346
1347 /// <summary>
1348 /// Returns version string representing libOVR version.
1349 /// </summary>
1350 public static string GetVersionString()
1351 {
1352 return Marshal.PtrToStringAnsi(ovr_GetVersionString());
1353 }
1354
1355 /// <summary>
1356 /// Detects or re-detects HMDs and reports the total number detected.
1357 /// Users can get information about each HMD by calling ovrHmd_Create with an index.
1358 /// </summary>
1359 public static int Detect()
1360 {
1361 return ovrHmd_Detect();
1362 }
1363
1364 /// <summary>
1365 /// Creates a handle to an HMD which doubles as a description structure.
1366 /// Index can [0 .. ovrHmd_Detect()-1]. Index mappings can cange after each ovrHmd_Detect call.
1367 /// </summary>
1368 public static Hmd Create(int index)
1369 {
1370 IntPtr hmdPtr = ovrHmd_Create(index);
1371 if (hmdPtr == IntPtr.Zero)
1372 return null;
1373
1374 return new Hmd(hmdPtr);
1375 }
1376
1377 /// <summary>
1378 /// Creates a 'fake' HMD used for debugging only. This is not tied to specific hardware,
1379 /// but may be used to debug some of the related rendering.
1380 /// </summary>
1381 public static Hmd CreateDebug(HmdType type)
1382 {
1383 IntPtr hmdPtr = ovrHmd_CreateDebug(type);
1384 if (hmdPtr == IntPtr.Zero)
1385 return null;
1386
1387 return new Hmd(hmdPtr);
1388 }
1389
1390 /// <summary>
1391 /// Used to generate projection from ovrEyeDesc::Fov.
1392 /// </summary>
1393 public static Matrix4f GetProjection(FovPort fov, float znear, float zfar, bool rightHanded)
1394 {
1395 return new Matrix4f(ovrMatrix4f_Projection(fov, znear, zfar, rightHanded));
1396 }
1397
1398 /// <summary>
1399 /// Used for 2D rendering, Y is down
1400 /// orthoScale = 1.0f / pixelsPerTanAngleAtCenter
1401 /// orthoDistance = distance from camera, such as 0.8m
1402 /// </summary>
1403 public static Matrix4f GetOrthoSubProjection(Matrix4f projection, Vector2f orthoScale, float orthoDistance, float hmdToEyeViewOffsetX)
1404 {
1405 return new Matrix4f(ovrMatrix4f_OrthoSubProjection(projection, orthoScale, orthoDistance, hmdToEyeViewOffsetX));
1406 }
1407
1408 /// <summary>
1409 /// Returns global, absolute high-resolution time in seconds. This is the same
1410 /// value as used in sensor messages.
1411 /// </summary>
1412 public static double GetTimeInSeconds()
1413 {
1414 return ovr_GetTimeInSeconds();
1415 }
1416
1417 /// <summary>
1418 /// Waits until the specified absolute time.
1419 /// </summary>
1420 public static double WaitTillTime(double absTime)
1421 {
1422 return ovr_WaitTillTime(absTime);
1423 }
1424
1425 // -----------------------------------------------------------------------------------
1426 // **** Constructor
1427
1428 public Hmd(IntPtr hmdPtr)
1429 {
1430 this.HmdPtr = hmdPtr;
1431 }
1432
1433 /// <summary>
1434 /// Returns last error for HMD state. Returns null for no error.
1435 /// String is valid until next call or GetLastError or HMD is destroyed.
1436 /// </summary>
1437 public string GetLastError()
1438 {
1439 return ovrHmd_GetLastError(HmdPtr);
1440 }
1441
1442 /// <summary>
1443 /// Platform specific function to specify the application window whose output will be
1444 /// displayed on the HMD. Only used if the ovrHmdCap_ExtendDesktop flag is false.
1445 /// Windows: SwapChain associated with this window will be displayed on the HMD.
1446 /// Specify 'destMirrorRect' in window coordinates to indicate an area
1447 /// of the render target output that will be mirrored from 'sourceRenderTargetRect'.
1448 /// Null pointers mean "full size".
1449 /// @note Source and dest mirror rects are not yet implemented.
1450 /// </summary>
1451 public bool AttachToWindow(Recti destMirrorRect, Recti sourceRenderTargetRect, IntPtr WindowPtr = default(IntPtr))
1452 {
1453 return ovrHmd_AttachToWindow(HmdPtr, WindowPtr, destMirrorRect, sourceRenderTargetRect) != 0;
1454 }
1455
1456 /// <summary>
1457 /// Returns capability bits that are enabled at this time as described by ovrHmdCaps.
1458 /// Note that this value is different font ovrHmdDesc::HmdCaps, which describes what
1459 /// capabilities are available for that HMD.
1460 /// </summary>
1461 public uint GetEnabledCaps()
1462 {
1463 return ovrHmd_GetEnabledCaps(HmdPtr);
1464 }
1465
1466 /// <summary>
1467 /// Modifies capability bits described by ovrHmdCaps that can be modified,
1468 /// such as ovrHmdCap_LowPersistance.
1469 /// </summary>
1470 public void SetEnabledCaps(uint capsBits)
1471 {
1472 ovrHmd_SetEnabledCaps(HmdPtr, capsBits);
1473 }
1474
1475 /// <summary>
1476 /// Returns an ovrHmdDesc, which provides a complete description for the HMD
1477 /// </summary>
1478 public HmdDesc GetDesc()
1479 {
1480 HmdDesc_Raw rawDesc = (HmdDesc_Raw)Marshal.PtrToStructure(HmdPtr, typeof(HmdDesc_Raw));
1481 return new HmdDesc(rawDesc);
1482 }
1483
1484 //-------------------------------------------------------------------------------------
1485 // ***** Tracking Interface
1486
1487 /// <summary>
1488 /// All tracking interface functions are thread-safe, allowing tracking state to be sampled
1489 /// from different threads.
1490 /// ConfigureTracking starts sensor sampling, enabling specified capabilities,
1491 /// described by ovrTrackingCaps.
1492 /// - supportedTrackingCaps specifies support that is requested. The function will succeed
1493 /// even if these caps are not available (i.e. sensor or camera is unplugged). Support
1494 /// will automatically be enabled if such device is plugged in later. Software should
1495 /// check ovrTrackingState.StatusFlags for real-time status.
1496 /// - requiredTrackingCaps specify sensor capabilities required at the time of the call.
1497 /// If they are not available, the function will fail. Pass 0 if only specifying
1498 /// supportedTrackingCaps.
1499 /// - Pass 0 for both supportedTrackingCaps and requiredTrackingCaps to disable tracking.
1500 /// </summary>
1501 public bool ConfigureTracking(uint supportedTrackingCaps, uint requiredTrackingCaps)
1502 {
1503 return ovrHmd_ConfigureTracking(HmdPtr, supportedTrackingCaps, requiredTrackingCaps) != 0;
1504 }
1505
1506 /// <summary>
1507 /// Re-centers the sensor orientation.
1508 /// Normally this will recenter the (x,y,z) translational components and the yaw
1509 /// component of orientation.
1510 /// </summary>
1511 public void RecenterPose()
1512 {
1513 ovrHmd_RecenterPose(HmdPtr);
1514 }
1515
1516 /// <summary>
1517 /// Returns tracking state reading based on the specified absolute system time.
1518 /// Pass an absTime value of 0.0 to request the most recent sensor reading. In this case
1519 /// both PredictedPose and SamplePose will have the same value.
1520 /// ovrHmd_GetEyePoses relies on this function internally.
1521 /// This may also be used for more refined timing of FrontBuffer rendering logic, etc.
1522 /// </summary>
1523 public TrackingState GetTrackingState(double absTime = 0.0d)
1524 {
1525 return ovrHmd_GetTrackingState(HmdPtr, absTime);
1526 }
1527
1528 //-------------------------------------------------------------------------------------
1529 // ***** Graphics Setup
1530
1531 /// <summary>
1532 /// Calculates the recommended texture size for rendering a given eye within the HMD
1533 /// with a given FOV cone. Higher FOV will generally require larger textures to
1534 /// maintain quality.
1535 /// - pixelsPerDisplayPixel specifies the ratio of the number of render target pixels
1536 /// to display pixels at the center of distortion. 1.0 is the default value. Lower
1537 /// values can improve performance.
1538 /// </summary>
1539 public Sizei GetFovTextureSize(Eye eye, FovPort fov, float pixelsPerDisplayPixel = 1.0f)
1540 {
1541 return ovrHmd_GetFovTextureSize(HmdPtr, eye, fov, pixelsPerDisplayPixel);
1542 }
1543
1544 //-------------------------------------------------------------------------------------
1545 // ***** Rendering API Thread Safety
1546
1547 // All of rendering functions including the configure and frame functions
1548 // are *NOT thread safe*. It is ok to use ConfigureRendering on one thread and handle
1549 // frames on another thread, but explicit synchronization must be done since
1550 // functions that depend on configured state are not reentrant.
1551 //
1552 // As an extra requirement, any of the following calls must be done on
1553 // the render thread, which is the same thread that calls ovrHmd_BeginFrame
1554 // or ovrHmd_BeginFrameTiming.
1555 // - ovrHmd_EndFrame
1556 // - ovrHmd_GetEyeTimewarpMatrices
1557
1558 //-------------------------------------------------------------------------------------
1559 // ***** SDK Distortion Rendering Functions
1560
1561 // These functions support rendering of distortion by the SDK through direct
1562 // access to the underlying rendering API, such as D3D or GL.
1563 // This is the recommended approach since it allows better support for future
1564 // Oculus hardware, and enables a range of low-level optimizations.
1565
1566 /// <summary>
1567 /// Configures rendering and fills in computed render parameters.
1568 /// This function can be called multiple times to change rendering settings.
1569 /// eyeRenderDescOut is a pointer to an array of two EyeRenderDesc structs
1570 /// that are used to return complete rendering information for each eye.
1571 /// - apiConfig provides D3D/OpenGL specific parameters. Pass null
1572 /// to shutdown rendering and release all resources.
1573 /// - distortionCaps describe desired distortion settings.
1574 /// </summary>
1575 public EyeRenderDesc[] ConfigureRendering(ref RenderAPIConfig renderAPIConfig, FovPort[] eyeFovIn, uint distortionCaps)
1576 {
1577 EyeRenderDesc[] eyeRenderDesc = new EyeRenderDesc[] { new EyeRenderDesc(), new EyeRenderDesc() };
1578 RenderAPIConfig_Raw rawConfig = renderAPIConfig.ToRaw();
1579
1580 bool result = ovrHmd_ConfigureRendering(HmdPtr, ref rawConfig, distortionCaps, eyeFovIn, eyeRenderDesc) != 0;
1581 if (result)
1582 return eyeRenderDesc;
1583 return null;
1584 }
1585
1586 /// <summary>
1587 /// Begins a frame, returning timing information.
1588 /// This should be called at the beginning of the game rendering loop (on the render thread).
1589 /// Pass 0 for the frame index if not using ovrHmd_GetFrameTiming.
1590 /// </summary>
1591 public FrameTiming BeginFrame(uint frameIndex = 0)
1592 {
1593 FrameTiming_Raw raw = ovrHmd_BeginFrame(HmdPtr, frameIndex);
1594 return new FrameTiming(raw);
1595 }
1596
1597 /// <summary>
1598 /// Ends a frame, submitting the rendered textures to the frame buffer.
1599 /// - RenderViewport within each eyeTexture can change per frame if necessary.
1600 /// - 'renderPose' will typically be the value returned from ovrHmd_GetEyePoses,
1601 /// ovrHmd_GetHmdPosePerEye but can be different if a different head pose was
1602 /// used for rendering.
1603 /// - This may perform distortion and scaling internally, assuming is it not
1604 /// delegated to another thread.
1605 /// - Must be called on the same thread as BeginFrame.
1606 /// - *** This Function will call Present/SwapBuffers and potentially wait for GPU Sync ***.
1607 /// </summary>
1608 public void EndFrame(Posef[] renderPose, Texture[] eyeTexture)
1609 {
1610 Texture_Raw[] raw = new Texture_Raw[eyeTexture.Length];
1611 for (int i = 0; i < eyeTexture.Length; i++)
1612 {
1613 raw[i] = eyeTexture[i].ToRaw();
1614 }
1615
1616 ovrHmd_EndFrame(HmdPtr, renderPose, raw);
1617 }
1618
1619 /// <summary>
1620 /// Returns predicted head pose in outHmdTrackingState and offset eye poses in outEyePoses
1621 /// as an atomic operation. Caller need not worry about applying HmdToEyeViewOffset to the
1622 /// returned outEyePoses variables.
1623 /// - Thread-safe function where caller should increment frameIndex with every frame
1624 /// and pass the index where applicable to functions called on the rendering thread.
1625 /// - hmdToEyeViewOffset[2] can be EyeRenderDesc.HmdToEyeViewOffset returned from
1626 /// ovrHmd_ConfigureRendering or ovrHmd_GetRenderDesc. For monoscopic rendering,
1627 /// use a vector that is the average of the two vectors for both eyes.
1628 /// - If frameIndex is not being used, pass in 0.
1629 /// - Assuming outEyePoses are used for rendering, it should be passed into ovrHmd_EndFrame.
1630 /// - If called doesn't need outHmdTrackingState, it can be NULL
1631 /// </summary>
1632 public Posef[] GetEyePoses(uint frameIndex)
1633 {
1634 FovPort leftFov = GetDesc().DefaultEyeFov[(int)Eye.Left];
1635 FovPort rightFov = GetDesc().DefaultEyeFov[(int)Eye.Right];
1636
1637 EyeRenderDesc leftDesc = GetRenderDesc(Eye.Left, leftFov);
1638 EyeRenderDesc rightDesc = GetRenderDesc(Eye.Right, rightFov);
1639
1640 TrackingState trackingState = new TrackingState();
1641 Vector3f[] eyeOffsets = { leftDesc.HmdToEyeViewOffset, rightDesc.HmdToEyeViewOffset };
1642 Posef[] eyePoses = { new Posef(), new Posef() };
1643
1644 ovrHmd_GetEyePoses(HmdPtr, frameIndex, eyeOffsets, eyePoses, ref trackingState);
1645
1646 return eyePoses;
1647 }
1648
1649 /// <summary>
1650 /// Function was previously called ovrHmd_GetEyePose
1651 /// Returns the predicted head pose to use when rendering the specified eye.
1652 /// - Important: Caller must apply HmdToEyeViewOffset before using ovrPosef for rendering
1653 /// - Must be called between ovrHmd_BeginFrameTiming and ovrHmd_EndFrameTiming.
1654 /// - If the pose is used for rendering the eye, it should be passed to ovrHmd_EndFrame.
1655 /// - Parameter 'eye' is used for prediction timing only
1656 /// </summary>
1657 public Posef GetHmdPosePerEye(Eye eye)
1658 {
1659 return ovrHmd_GetHmdPosePerEye(HmdPtr, eye);
1660 }
1661
1662 //-------------------------------------------------------------------------------------
1663 // ***** Client Distortion Rendering Functions
1664
1665 // These functions provide the distortion data and render timing support necessary to allow
1666 // client rendering of distortion. Client-side rendering involves the following steps:
1667 //
1668 // 1. Setup ovrEyeDesc based on the desired texture size and FOV.
1669 // Call ovrHmd_GetRenderDesc to get the necessary rendering parameters for each eye.
1670 //
1671 // 2. Use ovrHmd_CreateDistortionMesh to generate the distortion mesh.
1672 //
1673 // 3. Use ovrHmd_BeginFrameTiming, ovrHmd_GetEyePoses, and ovrHmd_BeginFrameTiming in
1674 // the rendering loop to obtain timing and predicted head orientation when rendering each eye.
1675 // - When using timewarp, use ovr_WaitTillTime after the rendering and gpu flush, followed
1676 // by ovrHmd_GetEyeTimewarpMatrices to obtain the timewarp matrices used
1677 // by the distortion pixel shader. This will minimize latency.
1678 //
1679
1680 /// <summary>
1681 /// Computes the distortion viewport, view adjust, and other rendering parameters for
1682 /// the specified eye. This can be used instead of ovrHmd_ConfigureRendering to do
1683 /// setup for client rendered distortion.
1684 /// </summary>
1685 public EyeRenderDesc GetRenderDesc(Eye eyeType, FovPort fov)
1686 {
1687 return ovrHmd_GetRenderDesc(HmdPtr, eyeType, fov);
1688 }
1689
1690 /// <summary>
1691 /// Generate distortion mesh per eye.
1692 /// Distortion capabilities will depend on 'distortionCaps' flags. Users should
1693 /// render using the appropriate shaders based on their settings.
1694 /// Distortion mesh data will be allocated and written into the ovrDistortionMesh data structure,
1695 /// which should be explicitly freed with ovrHmd_DestroyDistortionMesh.
1696 /// Users should call ovrHmd_GetRenderScaleAndOffset to get uvScale and Offset values for rendering.
1697 /// The function shouldn't fail unless theres is a configuration or memory error, in which case
1698 /// ovrDistortionMesh values will be set to null.
1699 /// This is the only function in the SDK reliant on eye relief, currently imported from profiles,
1700 /// or overridden here.
1701 /// </summary>
1702 public DistortionMesh? CreateDistortionMesh(Eye eye, FovPort fov, uint distortionCaps)
1703 {
1704 DistortionMesh_Raw rawMesh = new DistortionMesh_Raw();
1705
1706 bool result = ovrHmd_CreateDistortionMesh(HmdPtr, eye, fov, distortionCaps, out rawMesh) != 0;
1707 if (!result)
1708 {
1709 return null;
1710 }
1711
1712 DistortionMesh mesh = new DistortionMesh(rawMesh);
1713 ovrHmd_DestroyDistortionMesh(ref rawMesh);
1714 return mesh;
1715 }
1716
1717 /// <summary>
1718 /// Computes updated 'uvScaleOffsetOut' to be used with a distortion if render target size or
1719 /// viewport changes after the fact. This can be used to adjust render size every frame if desired.
1720 /// </summary>
1721 public Vector2f[] GetRenderScaleAndOffset(FovPort fov, Sizei textureSize, Recti renderViewport)
1722 {
1723 Vector2f[] uvScaleOffsetOut = new Vector2f[] { new Vector2f(), new Vector2f() };
1724 ovrHmd_GetRenderScaleAndOffset(fov, textureSize, renderViewport, uvScaleOffsetOut);
1725 return uvScaleOffsetOut;
1726 }
1727
1728 /// <summary>
1729 /// Thread-safe timing function for the main thread. Caller should increment frameIndex
1730 /// with every frame and pass the index where applicable to functions called on the
1731 /// rendering thread.
1732 /// </summary>
1733 public FrameTiming GetFrameTiming(uint frameIndex)
1734 {
1735 FrameTiming_Raw raw = ovrHmd_GetFrameTiming(HmdPtr, frameIndex);
1736 return new FrameTiming(raw);
1737 }
1738
1739 /// <summary>
1740 /// Called at the beginning of the frame on the rendering thread.
1741 /// Pass frameIndex == 0 if ovrHmd_GetFrameTiming isn't being used. Otherwise,
1742 /// pass the same frame index as was used for GetFrameTiming on the main thread.
1743 /// </summary>
1744 public FrameTiming BeginFrameTiming(uint frameIndex)
1745 {
1746 FrameTiming_Raw raw = ovrHmd_BeginFrameTiming(HmdPtr, frameIndex);
1747 return new FrameTiming(raw);
1748 }
1749
1750 /// <summary>
1751 /// Marks the end of client distortion rendered frame, tracking the necessary timing information.
1752 /// This function must be called immediately after Present/SwapBuffers + GPU sync. GPU sync is
1753 /// important before this call to reduce latency and ensure proper timing.
1754 /// </summary>
1755 public void EndFrameTiming()
1756 {
1757 ovrHmd_EndFrameTiming(HmdPtr);
1758 }
1759
1760 /// <summary>
1761 /// Initializes and resets frame time tracking. This is typically not necessary, but
1762 /// is helpful if game changes vsync state or video mode. vsync is assumed to be on if this
1763 /// isn't called. Resets internal frame index to the specified number.
1764 /// </summary>
1765 public void ResetFrameTiming(uint frameIndex)
1766 {
1767 ovrHmd_ResetFrameTiming(HmdPtr, frameIndex);
1768 }
1769
1770 /// <summary>
1771 /// Computes timewarp matrices used by distortion mesh shader, these are used to adjust
1772 /// for head orientation change since the last call to ovrHmd_GetEyePoses
1773 /// when rendering this eye. The ovrDistortionVertex::TimeWarpFactor is used to blend between the
1774 /// matrices, usually representing two different sides of the screen.
1775 /// Must be called on the same thread as ovrHmd_BeginFrameTiming.
1776 /// </summary>
1777 public Matrix4f[] GetEyeTimewarpMatrices(Eye eye, Posef renderPose)
1778 {
1779 Matrix4f_Raw[] rawMats = {new Matrix4f_Raw(), new Matrix4f_Raw()};
1780 ovrHmd_GetEyeTimewarpMatrices(HmdPtr, eye, renderPose, rawMats);
1781
1782 Matrix4f[] mats = {new Matrix4f(rawMats[0]), new Matrix4f(rawMats[1])};
1783 return mats;
1784 }
1785
1786 // -----------------------------------------------------------------------------------
1787 // ***** Latency Test interface
1788
1789 /// <summary>
1790 /// Does latency test processing and returns 'TRUE' if specified rgb color should
1791 /// be used to clear the screen.
1792 /// </summary>
1793 public byte[] ProcessLatencyTest()
1794 {
1795 if (ovrHmd_ProcessLatencyTest(HmdPtr, LatencyTestRgb) != 0)
1796 return LatencyTestRgb;
1797 return null;
1798 }
1799
1800 /// <summary>
1801 /// Returns non-null string once with latency test result, when it is available.
1802 /// Buffer is valid until next call.
1803 /// </summary>
1804 public string GetLatencyTestResult()
1805 {
1806 IntPtr p = ovrHmd_GetLatencyTestResult(HmdPtr);
1807 return (p == IntPtr.Zero) ? null : Marshal.PtrToStringAnsi(p);
1808 }
1809
1810 /// <summary>
1811 /// Returns the latency testing color in rgbColorOut to render when using a DK2
1812 /// Returns false if this feature is disabled or not-applicable (e.g. using a DK1)
1813 /// </summary>
1814 public byte[] GetLatencyTest2DrawColor()
1815 {
1816 if (ovrHmd_GetLatencyTest2DrawColor(HmdPtr, LatencyTestRgb) != 0)
1817 return LatencyTestRgb;
1818 return null;
1819 }
1820
1821 //-------------------------------------------------------------------------------------
1822 // ***** Health and Safety Warning Display interface
1823 //
1824
1825 /// <summary>
1826 /// Returns the current state of the HSW display. If the application is doing the rendering of
1827 /// the HSW display then this function serves to indicate that the warning should be
1828 /// currently displayed. If the application is using SDK-based eye rendering then the SDK by
1829 /// default automatically handles the drawing of the HSW display. An application that uses
1830 /// application-based eye rendering should use this function to know when to start drawing the
1831 /// HSW display itself and can optionally use it in conjunction with ovrhmd_DismissHSWDisplay
1832 /// as described below.
1833 ///
1834 /// Example usage for application-based rendering:
1835 /// bool HSWDisplayCurrentlyDisplayed = false; // global or class member variable
1836 /// ovrHSWDisplayState hswDisplayState = hmd.GetHSWDisplayState();
1837 ///
1838 /// if (hswDisplayState.Displayed && !HSWDisplayCurrentlyDisplayed)
1839 /// {
1840 /// <insert model into the scene that stays in front of the user>
1841 /// HSWDisplayCurrentlyDisplayed = true;
1842 /// }
1843 /// </summary>
1844 public HSWDisplayState GetHSWDisplayState()
1845 {
1846 HSWDisplayState hswDisplayState;
1847 ovrHmd_GetHSWDisplayState(HmdPtr, out hswDisplayState);
1848 return hswDisplayState;
1849 }
1850
1851 /// <summary>
1852 /// Dismisses the HSW display if the warning is dismissible and the earliest dismissal time
1853 /// has occurred. Returns true if the display is valid and could be dismissed. The application
1854 /// should recognize that the HSW display is being displayed (via ovrhmd_GetHSWDisplayState)
1855 /// and if so then call this function when the appropriate user input to dismiss the warning
1856 /// occurs.
1857 ///
1858 /// Example usage :
1859 /// void ProcessEvent(int key)
1860 /// {
1861 /// if (key == escape)
1862 /// {
1863 /// ovrHSWDisplayState hswDisplayState = hmd.GetHSWDisplayState();
1864 ///
1865 /// if (hswDisplayState.Displayed && hmd.DismissHSWDisplay())
1866 /// {
1867 /// <remove model from the scene>
1868 /// HSWDisplayCurrentlyDisplayed = false;
1869 /// }
1870 /// }
1871 /// }
1872 /// <summary>
1873 public bool DismissHSWDisplay()
1874 {
1875 return ovrHmd_DismissHSWDisplay(HmdPtr) != 0;
1876 }
1877
1878 // -----------------------------------------------------------------------------------
1879 // ***** Property Access
1880
1881 // NOTICE: This is experimental part of API that is likely to go away or change.
1882
1883 // These allow accessing different properties of the HMD and profile.
1884 // Some of the properties may go away with profile/HMD versions, so software should
1885 // use defaults and/or proper fallbacks.
1886
1887 /// <summary>
1888 /// Get boolean property. Returns first element if property is a boolean array.
1889 /// Returns defaultValue if property doesn't exist.
1890 /// </summary>
1891 public bool GetBool(string propertyName, bool defaultVal = false)
1892 {
1893 return ovrHmd_GetBool(HmdPtr, propertyName, defaultVal) != 0;
1894 }
1895
1896 /// <summary>
1897 /// Modify bool property; false if property doesn't exist or is readonly.
1898 /// </summary>
1899 public bool SetBool(string propertyName, bool val)
1900 {
1901 return ovrHmd_SetBool(HmdPtr, propertyName, val) != 0;
1902 }
1903
1904 /// <summary>
1905 /// Get integer property. Returns first element if property is an integer array.
1906 /// Returns defaultValue if property doesn't exist.
1907 /// </summary>
1908 public int GetInt(string propertyName, int defaultVal = 0)
1909 {
1910 return ovrHmd_GetInt(HmdPtr, propertyName, defaultVal);
1911 }
1912
1913 /// <summary>
1914 /// Modify integer property; false if property doesn't exist or is readonly.
1915 /// </summary>
1916 public bool SetInt(string propertyName, int val)
1917 {
1918 return ovrHmd_SetInt(HmdPtr, propertyName, val) != 0;
1919 }
1920
1921 /// <summary>
1922 /// Get float property. Returns first element if property is a float array.
1923 /// Returns defaultValue if property doesn't exist.
1924 /// </summary>
1925 public float GetFloat(string propertyName, float defaultVal = 0.0f)
1926 {
1927 return ovrHmd_GetFloat(HmdPtr, propertyName, defaultVal);
1928 }
1929
1930 /// <summary>
1931 /// Modify float property; false if property doesn't exist or is readonly.
1932 /// </summary>
1933 public bool SetFloat(string propertyName, float val)
1934 {
1935 return ovrHmd_SetFloat(HmdPtr, propertyName, val) != 0;
1936 }
1937
1938 /// <summary>
1939 /// Get float[] property. Returns the number of elements filled in, 0 if property doesn't exist.
1940 /// Maximum of arraySize elements will be written.
1941 /// </summary>
1942 public float[] GetFloatArray(string propertyName, float[] values)
1943 {
1944 if (values == null)
1945 return null;
1946
1947 ovrHmd_GetFloatArray(HmdPtr, propertyName, values, (uint)values.Length);
1948 return values;
1949 }
1950
1951 /// <summary>
1952 /// Modify float[] property; false if property doesn't exist or is readonly.
1953 /// </summary>
1954 public bool SetFloatArray(string propertyName, float[] values)
1955 {
1956 if (values == null)
1957 values = new float[0];
1958
1959 return ovrHmd_SetFloatArray(HmdPtr, propertyName, values, (uint)values.Length) != 0;
1960 }
1961
1962 /// <summary>
1963 /// Get string property. Returns first element if property is a string array.
1964 /// Returns defaultValue if property doesn't exist.
1965 /// String memory is guaranteed to exist until next call to GetString or GetStringArray, or HMD is destroyed.
1966 /// </summary>
1967 public string GetString(string propertyName, string defaultVal = null)
1968 {
1969 IntPtr p = ovrHmd_GetString(HmdPtr, propertyName, null);
1970 if (p == IntPtr.Zero)
1971 return defaultVal;
1972 return Marshal.PtrToStringAnsi(p);
1973 }
1974
1975 /// <summary>
1976 /// Set string property
1977 /// </summary>
1978 public bool SetString(string propertyName, string val)
1979 {
1980 return ovrHmd_SetString(HmdPtr, propertyName, val) != 0;
1981 }
1982
1983 // -----------------------------------------------------------------------------------
1984 // ***** Logging
1985
1986 /// <summary>
1987 /// Start performance logging. guid is optional and if included is written with each file entry.
1988 /// If called while logging is already active with the same filename, only the guid will be updated
1989 /// If called while logging is already active with a different filename, ovrHmd_StopPerfLog() will be called, followed by ovrHmd_StartPerfLog()
1990 /// </summary>
1991 public bool StartPerfLog(string fileName, string userData1)
1992 {
1993 return ovrHmd_StartPerfLog(HmdPtr, fileName, userData1) != 0;
1994 }
1995
1996 /// <summary>
1997 /// Stop performance logging.
1998 /// </summary>
1999 public bool StopPerfLog()
2000 {
2001 return ovrHmd_StopPerfLog(HmdPtr) != 0;
2002 }
2003
2004 public const string LibFile = "OculusPlugin";
2005
2006 // Imported functions from
2007 // OVRPlugin.dll (PC)
2008 // OVRPlugin.bundle (OSX)
2009 // OVRPlugin.so (Linux, Android)
2010
2011 // -----------------------------------------------------------------------------------
2012 // ***** Private Interface to libOVR
2013 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2014 private static extern void ovr_InitializeRenderingShim();
2015 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2016 private static extern sbyte ovr_Initialize();
2017 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2018 private static extern void ovr_Shutdown();
2019 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2020 private static extern IntPtr ovr_GetVersionString();
2021 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2022 private static extern int ovrHmd_Detect();
2023 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2024 private static extern IntPtr ovrHmd_Create(int index);
2025 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2026 private static extern void ovrHmd_Destroy(IntPtr hmd);
2027 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2028 private static extern IntPtr ovrHmd_CreateDebug(HmdType type);
2029 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2030 private static extern string ovrHmd_GetLastError(IntPtr hmd);
2031 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2032 private static extern sbyte ovrHmd_AttachToWindow(
2033 IntPtr hmd,
2034 IntPtr window,
2035 Recti destMirrorRect,
2036 Recti sourceRenderTargetRect);
2037 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2038 private static extern uint ovrHmd_GetEnabledCaps(IntPtr hmd);
2039 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2040 private static extern void ovrHmd_SetEnabledCaps(IntPtr hmd, uint capsBits);
2041
2042 //-------------------------------------------------------------------------------------
2043 // ***** Sensor Interface
2044 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2045 private static extern sbyte ovrHmd_ConfigureTracking(
2046 IntPtr hmd,
2047 uint supportedTrackingCaps,
2048 uint requiredTrackingCaps);
2049 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2050 private static extern void ovrHmd_RecenterPose(IntPtr hmd);
2051 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2052 private static extern TrackingState ovrHmd_GetTrackingState(IntPtr hmd, double absTime);
2053
2054 //-------------------------------------------------------------------------------------
2055 // ***** Graphics Setup
2056 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2057 private static extern Sizei ovrHmd_GetFovTextureSize(
2058 IntPtr hmd,
2059 Eye eye,
2060 FovPort fov,
2061 float pixelsPerDisplayPixel);
2062 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2063 private static extern sbyte ovrHmd_ConfigureRendering(
2064 IntPtr hmd,
2065 ref RenderAPIConfig_Raw apiConfig,
2066 uint distortionCaps,
2067 [In] FovPort[] eyeFovIn,
2068 [In, Out] EyeRenderDesc[] eyeRenderDescOut);
2069 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2070 private static extern FrameTiming_Raw ovrHmd_BeginFrame(IntPtr hmd, uint frameIndex);
2071 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2072 private static extern void ovrHmd_EndFrame(
2073 IntPtr hmd,
2074 [In] Posef[] renderPose,
2075 [In] Texture_Raw[] eyeTexture);
2076 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2077 private static extern void ovrHmd_GetEyePoses(
2078 IntPtr hmd,
2079 uint frameIndex,
2080 [In] Vector3f[] hmdToEyeViewOffset,
2081 [In, Out] Posef[] eyePosesOut,
2082 [In, Out] ref TrackingState hmdTrackingStateOut);
2083 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2084 private static extern Posef ovrHmd_GetHmdPosePerEye(
2085 IntPtr hmd,
2086 Eye eye);
2087 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2088 private static extern EyeRenderDesc ovrHmd_GetRenderDesc(IntPtr hmd, Eye eye, FovPort fov);
2089
2090 // -----------------------------------------------------------------------------------
2091 // **** Game-side rendering API
2092 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2093 private static extern sbyte ovrHmd_CreateDistortionMesh(
2094 IntPtr hmd,
2095 Eye eye,
2096 FovPort fov,
2097 uint distortionCaps,
2098 [Out] out DistortionMesh_Raw meshData);
2099 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2100 private static extern void ovrHmd_DestroyDistortionMesh(ref DistortionMesh_Raw meshData);
2101 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2102 private static extern void ovrHmd_GetRenderScaleAndOffset(
2103 FovPort fov,
2104 Sizei textureSize,
2105 Recti renderViewport,
2106 [MarshalAs(UnmanagedType.LPArray, SizeConst = 2)]
2107 [Out] Vector2f[] uvScaleOffsetOut);
2108 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2109 private static extern FrameTiming_Raw ovrHmd_GetFrameTiming(IntPtr hmd, uint frameIndex);
2110 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2111 private static extern FrameTiming_Raw ovrHmd_BeginFrameTiming(IntPtr hmd, uint frameIndex);
2112 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2113 private static extern void ovrHmd_EndFrameTiming(IntPtr hmd);
2114 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2115 private static extern void ovrHmd_ResetFrameTiming(IntPtr hmd, uint frameIndex);
2116 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2117 private static extern void ovrHmd_GetEyeTimewarpMatrices(
2118 IntPtr hmd,
2119 Eye eye,
2120 Posef renderPose,
2121 [MarshalAs(UnmanagedType.LPArray, SizeConst = 2)]
2122 [Out] Matrix4f_Raw[] twnOut);
2123
2124 //-------------------------------------------------------------------------------------
2125 // Stateless math setup functions
2126 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2127 private static extern Matrix4f_Raw ovrMatrix4f_Projection(
2128 FovPort fov,
2129 float znear,
2130 float zfar,
2131 bool rightHanded);
2132 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2133 private static extern Matrix4f_Raw ovrMatrix4f_OrthoSubProjection(
2134 Matrix4f projection,
2135 Vector2f orthoScale,
2136 float orthoDistance,
2137 float hmdToEyeViewOffsetX);
2138 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2139 private static extern double ovr_GetTimeInSeconds();
2140 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2141 private static extern double ovr_WaitTillTime(double absTime);
2142
2143 // -----------------------------------------------------------------------------------
2144 // ***** Latency Test interface
2145 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2146 private static extern sbyte ovrHmd_ProcessLatencyTest(
2147 IntPtr hmd,
2148 [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)]
2149 [Out] byte[] rgbColorOut);
2150 // Returns IntPtr to avoid allocation.
2151 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2152 private static extern IntPtr ovrHmd_GetLatencyTestResult(IntPtr hmd);
2153 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2154 private static extern sbyte ovrHmd_GetLatencyTest2DrawColor(
2155 IntPtr hmd,
2156 [MarshalAs(UnmanagedType.LPArray, SizeConst = 3)]
2157 [Out] byte[] rgbColorOut);
2158
2159 //-------------------------------------------------------------------------------------
2160 // ***** Health and Safety Warning Display interface
2161 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2162 private static extern void ovrHmd_GetHSWDisplayState(
2163 IntPtr hmd,
2164 [Out] out HSWDisplayState hasWarningState);
2165 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2166 private static extern sbyte ovrHmd_DismissHSWDisplay(IntPtr hmd);
2167
2168 // -----------------------------------------------------------------------------------
2169 // ***** Property Access
2170 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2171 private static extern sbyte ovrHmd_GetBool(
2172 IntPtr hmd,
2173 [MarshalAs(UnmanagedType.LPStr)]
2174 string propertyName,
2175 bool defaultVal);
2176 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2177 private static extern sbyte ovrHmd_SetBool(
2178 IntPtr hmd,
2179 [MarshalAs(UnmanagedType.LPStr)]
2180 string propertyName,
2181 bool val);
2182 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2183 private static extern int ovrHmd_GetInt(
2184 IntPtr hmd,
2185 [MarshalAs(UnmanagedType.LPStr)]
2186 string propertyName,
2187 int defaultVal);
2188 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2189 private static extern sbyte ovrHmd_SetInt(
2190 IntPtr hmd,
2191 [MarshalAs(UnmanagedType.LPStr)]
2192 string propertyName,
2193 int val);
2194 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2195 private static extern float ovrHmd_GetFloat(
2196 IntPtr hmd,
2197 [MarshalAs(UnmanagedType.LPStr)]
2198 string propertyName,
2199 float defaultVal);
2200 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2201 private static extern sbyte ovrHmd_SetFloat(
2202 IntPtr hmd,
2203 [MarshalAs(UnmanagedType.LPStr)]
2204 string propertyName,
2205 float val);
2206 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2207 private static extern uint ovrHmd_GetFloatArray(
2208 IntPtr hmd,
2209 [MarshalAs(UnmanagedType.LPStr)]
2210 string propertyName,
2211 float[] values, // TBD: Passing var size?
2212 uint arraySize);
2213 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2214 private static extern sbyte ovrHmd_SetFloatArray(
2215 IntPtr hmd,
2216 [MarshalAs(UnmanagedType.LPStr)]
2217 string propertyName,
2218 float[] values, // TBD: Passing var size?
2219 uint arraySize);
2220 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2221 private static extern IntPtr ovrHmd_GetString(
2222 IntPtr hmd,
2223 [MarshalAs(UnmanagedType.LPStr)]
2224 string propertyName,
2225 [MarshalAs(UnmanagedType.LPStr)]
2226 string defaultVal);
2227 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2228 private static extern sbyte ovrHmd_SetString(
2229 IntPtr hmd,
2230 [MarshalAs(UnmanagedType.LPStr)]
2231 string propertyName,
2232 [MarshalAs(UnmanagedType.LPStr)]
2233 string val);
2234 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2235 private static extern sbyte ovrHmd_StartPerfLog(
2236 IntPtr hmd,
2237 [MarshalAs(UnmanagedType.LPStr)]
2238 string fileName,
2239 [MarshalAs(UnmanagedType.LPStr)]
2240 string userData1);
2241 [DllImport(LibFile, CallingConvention = CallingConvention.Cdecl)]
2242 private static extern sbyte ovrHmd_StopPerfLog(IntPtr hmd);
2243 }
2244 }