初始化和传感器列举

时间:2021-03-06 19:49:59

这个例子是初始化LibOVR和请求关于有效HMD的信息。

回顾下面的代码:



// Include the OculusVR SDK
#include <OVR_CAPI.h>
void Application()
{
ovrResult result = ovr_Initialize(nullptr);
if (OVR_FAILURE(result))
return;

ovrSession session;
ovrGraphicsLuid luid;
result = ovr_Create(&session, &luid);
if (OVR_FAILURE(result))
{
ovr_Shutdown();
return;
}

ovrHmdDesc desc = ovr_GetHmdDesc(session);
ovrSizei resolution = desc.Resolution;

ovr_Destroy(session);
ovr_Shutdown();
}
就像你看到的,ovr_Initialize在任何API函数之前调用和ovr_Shutdown在你退出游戏之前来关闭这个库。在这两个函数之间,你可以*的创建HMD对象,使用追踪状态,和执行应用渲染。
在这个例子中,ovr_Create(&session&luid)创建HMD。使用ovr_Create()返回的LUID去选择IDXGIAdapter在你创建的ID3D11Device或者ID3D12Device上.最后,ovr_Destroy必须被调用去清理HMD在关闭库之前。
你能使用ovr_GetHmdDesc()去获得一个HMD的描述。
如果没有Rift没有插上,ovr_Create(&session,&luid)会返回一个失败的ovrResult除非一个虚拟的HMD是可以的通过RiftConfigUtil.虽然虚拟HMD不会提供任何传感器输入,它能调试Rift-compatible渲染代码和开发不用物理设备。
一个HMD的描述句柄能被恢复通过调用ovr_GetHmdDesc(session)。下面的表描述这些域:
FieldTypeDescription
TypeovrHmdTypeType of the HMD, such as ovr_DK2 or ovr_DK2 .
ProductNamechar[]Name of the product as a string.
Manufacturerchar[]Name of the manufacturer.
VendorIdshortVendor ID reported by the headset USB device.
ProductIdshortProduct ID reported by the headset USB device.
SerialNumberchar[]Serial number string reported by the headset USB deviceFirmwareMajorshortThe major version of the sensor firmware.
FirmwareMinorshortThe minor version of the sensor firmware.
AvailableHmdCapsunsigned intCapability bits described by ovrHmdCaps which the HMD currently supports
DefaultHmdCapsunsigned intDefault capability bits described by ovrHmdCaps for the current HMD.
AvailableTrackingCapsunsigned intCapability bits described by ovrTrackingCaps which the HMD currently supports.
DefaultTrackingCapsunsigned intDefault capability bits described by ovrTrackingCapsfor the current HMD.
DefaultEyeFovovrFovPort[]Recommended optical field of view for each eye.
MaxEyeFovovrFovPort[]Maximum optical field of view that can be practically rendered for each eye.
ResolutionovrSizeiResolution of the full HMD screen (both eyes) in pixelsDisplayRefreshRatefloatNominal refresh rate of the HMD in cycles per second at the time of HMD creation.
一个传感器句柄的描述能被恢复通过调用ovr_GetTrackerDesc(sensor).下面的表描述这些域:
 
 
Field Type Description
FrustumHFovInRadians float The
horizontal FOV of the position sensor frustum.
FrustumVFovInRadians float The
vertical FOV of the position sensor frustum.
FrustumNearZInMeters float The
distance from the position sensor to the near frustum bounds.
FrustumNearZInMeters float The
distance from the position sensor to the far frustum bounds.

头部追踪和传感器
Oculus Rift硬件包含大量的MEMS传感器包括一个陀螺仪,加速计和磁力计。
这儿也是一个传感器为了追踪头戴位置。来自每个传感器的信息被合并通过传感器融合处理来判定用户头部在真实世界中的移动和实时同步用户的视图。
一旦ovrSession被创建,你能为头部位置和方向检测传感器融合通过调用ovr_GetTrackingState.这些调用通过下面的代码证明:
// Query the HMD for ts current tracking state.
ovrTrackingState ts = ovr_GetTrackingState(session, ovr_GetTimeInSeconds(), ovrTrue);

if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked))
{
ovrPosef pose = ts.HeadPose.ThePose;
...
}
这个例子初始化传感器用方向,修正角速度和位置追踪能力。如果传感器在调用期间是无效的,但随后被插入,传感器会自动恢复通过SDK。
传感器初始化后,传感器的状态通过调用ovr_GetTrackingState获得。这个状态包括预测头部姿势和当前HMD的追踪状态作为描述通过StatusFlags。这个状态在运行时会变化基于有效的设备和用户行为。例如,ovrStatus_PostionTracked标志只是报告HeadPose包括来自传感器的绝对位置追踪数据。
ovrPoseStatef包含6个角度的头部追踪数据(包括方向,位置,他们第一和第二派生物)。姿势值报告一个特殊绝对点及时使用预测,符合在未来会在显示器上显示的帧图像。为了促进预测,ovr_GetTrackingState花费绝对时间,秒,作为一个秒参数。当前的绝对时间值能被获得通过调用ovr_GetTimeInSeconds.如果传入进ovr_GetTrackingState的时间是当前时间或早一点,追踪状态会基于最晚的传感器数据不带预测的被返回。在一个应用中,然而,你应该使用实时计算值通过getPredictedDisplayTime返回的。在很多细节上预测值被覆盖在Frame Timing上。
就像已经讨论的,姿势包括一个3D位置向量和一个方向四元组。这个方向被表示为一个旋转在一个右手坐标系统中,就像下图展示的。
初始化和传感器列举
这个x-z平面是和地板对齐的不管摄像机位置。
就像在图中看到的,坐标系统使用下面的轴定义:
Y是在向上方向的位置。
X是在右方向的位置。
Z是在头后面方向的位置。
旋转被维持作为一个四元组单元,但是也能会被表示为偏航-倾斜-滚动形式。位置旋转是按顺时针计算的当看向每个轴的反方向时,组件旋转是:
。倾斜是围绕X轴,位置当向上倾斜时。
。偏航是围绕Y轴,位置当向左旋转时。
。滚动式围绕Z轴,位置是当倾斜向左在XY平面上。
最简单的在ovrPos提取偏航-倾斜-滚动的方式是使用C++OVR Math助手类它被包含在库中。下面的例子使用直接转换来赋值ovrPosef为等价的C++ Posef类。你能使用Quatf::GetEulerAngles<>来提取欧拉角度在期望轴旋转顺序。
所有简单C数学类型通过OVR提供就像ovrVector3f和ovrQuatf符合C++类型(提供便利的构造函数和操作)。这些类型能被交互使用。
如果一个应用使用了一个左手坐标系统,它能使用ovrPosef_FlipHandedness函数来转换任何右手ovrPosef通过ovr_GetTrackingState,ovr_GetEyePoses,或者ovr_CalcEyePoses函数提供的为左手的。注意RenderPose和QuadPoseCenterrequested为ovrLayers必须一直使用右手坐标系统。
位置追踪
截头椎体通过水平和垂直FOV定义,前和后截头椎体平面的距离。
这些参数的近似值能被访问通过ovrTrackerDesd结构就像下面:
ovrSession session;
ovrGraphicsLuid luid;
if(OVR_SUCCESS(ovr_Create(&session, &luid)))
{
// Extract tracking frustum parameters.
float frustomHorizontalFOV = session->CameraFrustumHFovInRadians;
...
下面的图展示了追踪传感器和一个追踪截面椎体的结果。
初始化和传感器列举
有关的参数和特值列在下面:

  
  
Field Type Typical Value
FrustumHFovInRadians float 1.292 radians (74 degrees)
FrustumVFovInRadians float 0.942 radians (54 degrees)
FrustumNearZInMeters float 0.4m
FrustumFarZInMeters float 2.5m
这些参数被提供给应用开发者来提供一个虚拟的追踪截面椎体的表述。先前的图也显示了默认的追踪原点和关联坐标系统。
注意:尽管传感器轴被展示的稍微向下倾斜,最终坐标系统一直是水平方向就像轴平行于地面。
通过默认,追踪原点位于离传感器一米的地方在光轴的方向上但用相同的高度作为传感器。默认原点方向是相对地面的在负轴点方向上传感器。另一方面,一个头戴偏航零角度符合用户看向传感器方向。
注意:这能被修改使用API调用ovr_RecenterTrackingOrigin重置追踪原点为头戴的当前位置,和设置偏航原点为当前头戴偏航值。
注意:追踪原点是设置每个应用的基础;转换聚焦在不同的VR app中也转换追踪原点。
头部姿势通过调用ovr_GetTrackingState返回。返回的ovrTrackingState结构体包含一些有关位置追踪的元素:
HeadPose-包含头部位置和方向。
Pose--传感器的姿势涉及追踪原点。
CalibratedOrigin--先前原点的位置通过用户校准和存储在配置文件中表示在新定位追踪原点空间中。这个值能改变当应用调用ovr_RecenterTrackingOrigin,虽然它涉及到在真实世界空间中的相同位置。另外它会保持作为一个标示姿势。不用的追踪原点类型会标明不同的CalibrateOrigin姿势,作为校准原点涉及到一个在真实世界空间中的固定位置但是两个追踪原点类型涉及不同的Y级别
StatusFlags变量包含下面的涉及位置追踪的状态位:
ovrStatus_PositionTracked--只当头戴正在被积极的追踪时才被设置。
这儿有一些条件可能会导致位置追踪被打断和标志变为零:
。头戴全部的或部分的移动出追踪界面椎体。
。头戴采取一个方向-当前硬件不能简单的追踪。
。头戴的表面部分的或全部的阻塞传感器视图的点。
。头戴的速度超过期望的范围。
在一个中断下,上述假设条件都不出现,追踪很快恢复正常和ovrStatus_PositionTracked标志被设置。
如果你想获得姿势和一个传感器的水平位置,调用ovr_GetTrackingState。返回的ovrTrackerPose结构体包含下面的内容
Pose--跟追踪原点有关的传感器的姿势。
LeveledPose--跟追踪原点有光的传感器的姿势但是没有滚动和倾斜出去。你能使用这个作为一个引用点去渲染真实世界物体在正确的地方。
用户输入集成
为了提供更舒适,直觉的和可用的界面为玩家,头部追踪应该可以被集成用一个控制计划为更多的应用。
例如:在第一人称设计游戏中,玩家通常前后左右移动使用左控制杆和看向左右上下使用右操纵杆,当使用Rift,玩家现在能看向左右上下使用他们的头。然而,玩家不能被要求频繁的180度转动他们的头因为这会建立一个坏的用户体验。大体上,他们需要一个方式去适应他们自己来人他们一直都是舒适的。
总结,开发者应该关心考虑他们的控制计划和怎样去集成头部追踪当为VR设计应用时。OculusRoomTiny应用提供一个源代码示例来展示怎么去集成Oculus 头部追踪用上面提及的标准FPS控制计划。
更多的关于好和坏实践的信息,设计Oculus 最佳实践。
健康和安全警告
所有应用使用Oculus Rift周期性显示一个健康和安全警告。
这个警告出现一小段时间当用户带上Rift;它能被解除通过按下一个键或凝视确认。随后屏幕被解除,它不应该显示至少30分钟。