GearVR SDK代码剖析    接下来我们来了解一下GearVR开发包的底层代码,它底层的代码和之前在第三章中讲的桌面SDK代码非常类似,当然,也有许多不同的地方。 
 
    首先,我们看看如何构建场景。在开发包中有一个具有camera Rig的预设体,这个预设体提供了Oculus的立体渲染技术和GearVR配套的头动追踪技术。 
 
    将Hierarchy中的OVRCameraRig物体展开,它下面包含有一个TrackingSpace的子物体,TrackingSpace下面包含四个子物体:LeftEyeAnchor、CenterEyeAnchor、RightEyeAnchor和TrackerAnchor。其中,左右眼的Anchor是关键,选中其中一个然后再Inspector面板中可以看到它包含一个相机组件,这个相机组件具有一些默认值,有些值会在脚本代码中更新,下面我们来看看这些更新的代码。 
 
    再次选中OVRCameraRig物体,然后再Inspector面板中双击打开OVR Camera Rig脚本。脚本打开以后找到Update这个函数,如下: 
[C#] 纯文本查看 复制代码 
? 
#if !UNITY_ANDROID || UNITY_EDITOR 
    private void LateUpdate() 
#else 
    private void Update() 
#endif 
    { 
        EnsureGameObjectIntegrity(); 
        if (!Application.isPlaying) 
            return; 
        UpdateCameras(); 
        UpdateAnchors(); 
} 
 
 |  
  
 
 
 
    因为我们为安卓构建应用,所以#if语句判断为false,程序将采用Update函数,Unity在程序运行的每一帧都会调用这个函数。在我们的Update函数中首先调用EnsureGameObjectIntegrity函数以确保场景中包含所有必须的物体,如OVRCameraRig这个物体就是必须的。 
 
    确保程序正在运行之后,我们开始真正的更新操作。首先更新相机的参数,调用UpdateCameras函数用以更新两个眼睛的相机参数,代码如下: 
[C#] 纯文本查看 复制代码 
? 
private void UpdateCameras() 
{ 
    if (needsCameraConfigure) 
    { 
        leftEyeCamera = ConfigureCamera(OVREye.Left); 
        rightEyeCamera = ConfigureCamera(OVREye.Right); 
#if !UNITY_ANDROID || UNITY_EDITOR 
        needsCameraConfigure = false; 
#endif 
    } 
} 
 
 |  
  
 
 
 
    下面的代码是获取每个眼睛的相机参数函数: 
[C#] 纯文本查看 复制代码 
? 
private Camera ConfigureCamera(OVREye eye) 
{ 
    Transform anchor = (eye == OVREye.Left) ? leftEyeAnchor : rightEyeAnchor; 
    Camera cam = anchor.GetComponent<Camera>(); 
    OVRDisplay.EyeRenderDesc eyeDesc = OVRManager.display.GetEyeRenderDesc(eye); 
    cam.fieldOfView = eyeDesc.fov.y; 
    cam.aspect = eyeDesc.resolution.x / eyeDesc.resolution.y; 
    cam.rect = new Rect(0f, 0f, OVRManager.instance.virtualTextureScale, 
        OVRManager.instance.virtualTextureScale); 
    cam.targetTexture = OVRManager.display.GetEyeTexture(eye); 
    cam.hdr = OVRManager.instance.hdr; 
    ... 
    return cam; 
} 
 
 |  
  
 
 
 
    函数中,根据传入的参数相应地获取左右眼睛的相机参数,其中,我们具体看看下面一行代码: 
OVRManager.display.GetEyeRenderDesc(eye) 
    
    OVRManager这个类是Oculus Mobile SDK的主要接口类,它负责与安卓原生代码交互,如果你对它内部的实现非常感兴趣,你可以回到Unity的编辑器中选中OVRCameraRig,然后打开它的OVR Manager脚本进行研究。至此,我们利用SDK作为黑盒获取了左右眼睛相机的参数,包括:FOV、屏幕尺寸比、视口、渲染目标以及是否支持HDR。 
 
    我们相机的基本参数已经设置好了,但是它的坐标和朝向必须通过GearVR头显获取,在UpdateAnchors这个函数中实现这个: 
[C#] 纯文本查看 复制代码 
? 
private void UpdateAnchors() 
{ 
    bool monoscopic = OVRManager.instance.monoscopic; 
    OVRPose tracker = OVRManager.tracker.GetPose(); 
    OVRPose hmdLeftEye = OVRManager.display.GetEyePose(OVREye.Left); 
    OVRPose hmdRightEye = OVRManager.display.GetEyePose(OVREye.Right); 
    trackerAnchor.localRotation = tracker.orientation; 
    centerEyeAnchor.localRotation = hmdLeftEye.orientation; // using left eye for now 
    leftEyeAnchor.localRotation = monoscopic ? centerEyeAnchor.localRotation 
        : hmdLeftEye.orientation; 
    rightEyeAnchor.localRotation = monoscopic ? centerEyeAnchor.localRotation 
        : hmdRightEye.orientation; 
    trackerAnchor.localPosition = tracker.position; 
    centerEyeAnchor.localPosition = 0.5f * (hmdLeftEye.position + hmdRightEye.position); 
    leftEyeAnchor.localPosition = monoscopic ? centerEyeAnchor.localPosition 
        : hmdLeftEye.position; 
    rightEyeAnchor.localPosition = monoscopic ? centerEyeAnchor.localPosition 
        : hmdRightEye.position; 
    if (UpdatedAnchors != null) 
    { 
        UpdatedAnchors(this); 
    } 
} 
 
 
 |  
  |