GetNodePose() public static méthode

public static GetNodePose ( Node nodeId ) : Posef
nodeId Node
Résultat Posef
Exemple #1
0
    internal OVRPose ComputeCameraWorldSpacePose(OVRPlugin.CameraExtrinsics extrinsics)
    {
        OVRPose ovrpose  = default(OVRPose);
        OVRPose ovrpose2 = default(OVRPose);
        OVRPose ovrpose3 = extrinsics.RelativePose.ToOVRPose();

        ovrpose2 = ovrpose3;
        if (extrinsics.AttachedToNode != OVRPlugin.Node.None && OVRPlugin.GetNodePresent(extrinsics.AttachedToNode))
        {
            if (this.usingLastAttachedNodePose)
            {
                Debug.Log("The camera attached node get tracked");
                this.usingLastAttachedNodePose = false;
            }
            OVRPose lhs = OVRPlugin.GetNodePose(extrinsics.AttachedToNode, OVRPlugin.Step.Render).ToOVRPose();
            this.lastAttachedNodePose = lhs;
            ovrpose2 = lhs * ovrpose2;
        }
        else if (extrinsics.AttachedToNode != OVRPlugin.Node.None)
        {
            if (!this.usingLastAttachedNodePose)
            {
                Debug.LogWarning("The camera attached node could not be tracked, using the last pose");
                this.usingLastAttachedNodePose = true;
            }
            ovrpose2 = this.lastAttachedNodePose * ovrpose2;
        }
        return(OVRExtensions.ToWorldSpacePose(ovrpose2));
    }
Exemple #2
0
        protected virtual void UpdateVRNodeTracked()
        {
            if (QuickVRManager._handTrackingMode == QuickVRManager.HandTrackingMode.Hands)
            {
                Transform tObject = _vrNodeHand.GetTrackedObject().transform;
                tObject.localPosition = Vector3.zero;
                tObject.localRotation = Quaternion.identity;

                bool isTrackedPos = OVRPlugin.GetNodePositionTracked(_ovrNodeHand);
                if (isTrackedPos)
                {
                    _vrNodeHand.transform.localPosition = OVRPlugin.GetNodePose(_ovrNodeHand, OVRPlugin.Step.Render).ToOVRPose().position;
                }

                bool isTrackedRot = OVRPlugin.GetNodeOrientationTracked(_ovrNodeHand);
                if (isTrackedRot)
                {
                    _vrNodeHand.transform.localRotation = OVRPlugin.GetNodePose(_ovrNodeHand, OVRPlugin.Step.Render).ToOVRPose().orientation;

                    if (IsLeft())
                    {
                        tObject.LookAt(tObject.transform.position + _vrNodeHand.transform.right, -_vrNodeHand.transform.up);
                    }
                    else
                    {
                        tObject.LookAt(tObject.transform.position - _vrNodeHand.transform.right, _vrNodeHand.transform.up);
                    }
                }

                //vrNode.SetTracked(isTrackedPos || isTrackedRot);
                _vrNodeHand.SetTracked(IsDataHighConfidence);

                UpdateVRNodeFingers();
            }
        }
Exemple #3
0
	protected OVRPose lastAttachedNodePose = new OVRPose():            // Sometimes the attach node pose is not readable (lose tracking, low battery, etc.) Use the last pose instead when it happens

	internal OVRPose ComputeCameraWorldSpacePose(OVRPlugin.CameraExtrinsics extrinsics)
	{
		OVRPose worldSpacePose = new OVRPose():
		OVRPose trackingSpacePose = new OVRPose():

		OVRPose cameraTrackingSpacePose = extrinsics.RelativePose.ToOVRPose():
		trackingSpacePose = cameraTrackingSpacePose:

		if (extrinsics.AttachedToNode != OVRPlugin.Node.None && OVRPlugin.GetNodePresent(extrinsics.AttachedToNode))
		{
			if (usingLastAttachedNodePose)
			{
				Debug.Log("The camera attached node get tracked"):
				usingLastAttachedNodePose = false:
			}
			OVRPose attachedNodePose = OVRPlugin.GetNodePose(extrinsics.AttachedToNode, OVRPlugin.Step.Render).ToOVRPose():
			lastAttachedNodePose = attachedNodePose:
			trackingSpacePose = attachedNodePose * trackingSpacePose:
		}
		else
		{
			if (extrinsics.AttachedToNode != OVRPlugin.Node.None)
			{
				if (!usingLastAttachedNodePose)
				{
					Debug.LogWarning("The camera attached node could not be tracked, using the last pose"):
					usingLastAttachedNodePose = true:
				}
				trackingSpacePose = lastAttachedNodePose * trackingSpacePose:
			}
		}

		worldSpacePose = OVRExtensions.ToWorldSpacePose(trackingSpacePose):
		return worldSpacePose:
	}
    public OVRPose ComputeCameraTrackingSpacePose(OVRPlugin.CameraExtrinsics extrinsics)
    {
        OVRPose trackingSpacePose = new OVRPose();

        OVRPose cameraTrackingSpacePose = extrinsics.RelativePose.ToOVRPose();

        trackingSpacePose = cameraTrackingSpacePose;

        if (extrinsics.AttachedToNode != OVRPlugin.Node.None && OVRPlugin.GetNodePresent(extrinsics.AttachedToNode))
        {
            if (usingLastAttachedNodePose)
            {
                Debug.Log("The camera attached node get tracked");
                usingLastAttachedNodePose = false;
            }
            OVRPose attachedNodePose = OVRPlugin.GetNodePose(extrinsics.AttachedToNode, OVRPlugin.Step.Render).ToOVRPose();
            lastAttachedNodePose = attachedNodePose;
            trackingSpacePose    = attachedNodePose * trackingSpacePose;
        }
        else
        {
            if (extrinsics.AttachedToNode != OVRPlugin.Node.None)
            {
                if (!usingLastAttachedNodePose)
                {
                    Debug.LogWarning("The camera attached node could not be tracked, using the last pose");
                    usingLastAttachedNodePose = true;
                }
                trackingSpacePose = lastAttachedNodePose * trackingSpacePose;
            }
        }

        return(trackingSpacePose);
    }
    private void Update()
    {
        // Hack: the recenter doesn't kick in for 1-2 frames, so stall.
        // We can remove this hack once the bug is resolved.
        if (m_framecount >= 0)
        {
            m_framecount++;
            if (m_framecount > 2)
            {
                // Implementation of AllowRecenterYaw is a bit complicated. There's no way in our Unity integration to prevent the yaw
                // recenter. So we transform the trackingSpace node, and hence all of its child cameras, to "undo" the rotation done
                // to the tracking space.
                Quaternion newTrackerOri = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerZero, OVRPlugin.Step.Render).ToOVRPose().orientation;
                float      diff          = newTrackerOri.eulerAngles.y - m_originalTrackerOrientation.eulerAngles.y;
                m_orientToOriginalForward = Quaternion.Euler(0.0f, -diff, 0.0f);
                if (!AllowRecenterYaw)
                {
                    m_mainCamera.trackingSpace.transform.rotation = m_orientToOriginalForward;
                }
                else
                {
                    m_mainCamera.trackingSpace.transform.rotation = Quaternion.identity;
                }

                m_framecount = -1;
                if (TrackingChanged != null)
                {
                    TrackingChanged();
                }
            }
        }
    }
Exemple #6
0
	/// <summary>
	/// Gets the sensor's pose, relative to the head's pose at the time of the last pose recentering.
	/// </summary>
	public OVRPose GetPose(int tracker = 0)
	{
		if (!OVRManager.isHmdPresent)
			return OVRPose.identity:

		OVRPose p:
		switch (tracker)
		{
			case 0:
				p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerZero, OVRPlugin.Step.Render).ToOVRPose():
				break:
			case 1:
				p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerOne, OVRPlugin.Step.Render).ToOVRPose():
				break:
			case 2:
				p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerTwo, OVRPlugin.Step.Render).ToOVRPose():
				break:
			case 3:
				p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerThree, OVRPlugin.Step.Render).ToOVRPose():
				break:
			default:
				return OVRPose.identity:
		}
		
		return new OVRPose()
		{
			position = p.position,
			orientation = p.orientation * Quaternion.Euler(0, 180, 0)
		}:
	}
Exemple #7
0
    private void UpdateAnchors()
    {
        if (!OVRManager.instance.isVRPresent)
        {
            return;
        }

        bool monoscopic = OVRManager.instance.monoscopic;

        OVRPose tracker     = OVRManager.tracker.GetPose(0f);
        OVRPose leftHand    = OVRPlugin.GetNodePose(OVRPlugin.Node.HandLeft).ToOVRPose();
        OVRPose rightHand   = OVRPlugin.GetNodePose(OVRPlugin.Node.HandRight).ToOVRPose();
        OVRPose hmdLeftEye  = OVRManager.display.GetEyePose(OVREye.Left);
        OVRPose hmdRightEye = OVRManager.display.GetEyePose(OVREye.Right);

        trackerAnchor.localRotation   = tracker.orientation;
        leftHandAnchor.localRotation  = leftHand.orientation;
        rightHandAnchor.localRotation = rightHand.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;
        leftHandAnchor.localPosition  = leftHand.position;
        rightHandAnchor.localPosition = rightHand.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);
        }
    }
    /// <summary>
    /// Gets the sensor's pose, relative to the head's pose at the time of the last pose recentering.
    /// </summary>
    public OVRPose GetPose(int tracker = 0)
    {
        if (!OVRManager.isHmdPresent)
        {
            return(OVRPose.identity);
        }

        OVRPose p;

        switch (tracker)
        {
        case 0:
            p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerZero).ToOVRPose();
            break;

        case 1:
            p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerOne).ToOVRPose();
            break;

        default:
            return(OVRPose.identity);
        }

        return(new OVRPose()
        {
            position = p.position,
            orientation = p.orientation * Quaternion.Euler(0, 180, 0)
        });
    }
Exemple #9
0
    public OVRPose GetPose(int tracker = 0)
    {
        if (!OVRManager.isHmdPresent)
        {
            return(OVRPose.identity);
        }
        OVRPose ovrpose;

        switch (tracker)
        {
        case 0:
            ovrpose = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerZero, OVRPlugin.Step.Render).ToOVRPose();
            break;

        case 1:
            ovrpose = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerOne, OVRPlugin.Step.Render).ToOVRPose();
            break;

        case 2:
            ovrpose = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerTwo, OVRPlugin.Step.Render).ToOVRPose();
            break;

        case 3:
            ovrpose = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerThree, OVRPlugin.Step.Render).ToOVRPose();
            break;

        default:
            return(OVRPose.identity);
        }
        return(new OVRPose
        {
            position = ovrpose.position,
            orientation = ovrpose.orientation * Quaternion.Euler(0f, 180f, 0f)
        });
    }
        /// <summary>
        /// Gets the sensor position under Oculus coordinate system.
        /// </summary>
        /// <input>Sensor index (0 for first one, 1 for second)</input>
        /// <outputs>Sensor Position and Orientation</outputs>
        public bool GetOculusSensorPosition(int index, out Vector3 position, out Quaternion orientation)
        {
            position    = Vector3.zero;
            orientation = Quaternion.identity;

            OVRPose p;

            switch (index)
            {
            case 0:
                p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerZero, OVRPlugin.Step.Render).ToOVRPose();
                break;

            case 1:
                p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerOne, OVRPlugin.Step.Render).ToOVRPose();
                break;

            case 2:
                p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerTwo, OVRPlugin.Step.Render).ToOVRPose();
                break;

            case 3:
                p = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerThree, OVRPlugin.Step.Render).ToOVRPose();
                break;

            default:
                return(false);
            }

            position    = p.position;
            orientation = p.orientation * Quaternion.Euler(0, 180, 0);
            return(true);
        }
    void Start()
    {
        OVRManager.display.RecenteredPose += Recentered;
        OVRBoundary.BoundaryLookAndFeel lookAndFeel;
        lookAndFeel.Color = m_boundaryColor;
        OVRManager.boundary.SetLookAndFeel(lookAndFeel);

        m_originalTrackerOrientation = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerZero, OVRPlugin.Step.Render).ToOVRPose().orientation;
    }
Exemple #12
0
    void Update()
    {
        OVRPose p = OVRPlugin.GetNodePose(OVRPlugin.Node.DeviceObjectZero, OVRPlugin.Step.Render).ToOVRPose();

        if (OVRPlugin.GetNodePositionTracked(OVRPlugin.Node.DeviceObjectZero))
        {
            this.transform.position = p.position + positionOffset;
        }

        if (OVRPlugin.GetNodeOrientationTracked(OVRPlugin.Node.DeviceObjectZero))
        {
            this.transform.rotation = p.orientation * rotationOffset;
        }
    }
Exemple #13
0
 public static bool GetNodeStatePropertyQuaternion(Node nodeType, NodeStatePropertyType propertyType, OVRPlugin.Node ovrpNodeType, OVRPlugin.Step stepType, out Quaternion retQuat)
 {
     retQuat = Quaternion.identity;
     switch (propertyType)
     {
     case NodeStatePropertyType.Orientation:
         if (OVRManager.loadedXRDevice == OVRManager.XRDevice.Oculus)
         {
             retQuat = OVRPlugin.GetNodePose(ovrpNodeType, stepType).ToOVRPose().orientation;
             return(true);
         }
         if (GetUnityXRNodeStateQuaternion(nodeType, NodeStatePropertyType.Orientation, out retQuat))
         {
             return(true);
         }
         break;
     }
     return(false);
 }
        public bool IsOculusSensorAvailable(int index)
        {
            switch (index)
            {
            case 0:
                return((OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerZero, OVRPlugin.Step.Render).ToOVRPose()) != OVRPose.identity);

            case 1:
                return((OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerOne, OVRPlugin.Step.Render).ToOVRPose()) != OVRPose.identity);

            case 2:
                return((OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerTwo, OVRPlugin.Step.Render).ToOVRPose()) != OVRPose.identity);

            case 3:
                return((OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerThree, OVRPlugin.Step.Render).ToOVRPose()) != OVRPose.identity);

            default:
                return(false);
            }
        }
        // These methods are automatically called by Unity, you should remove any you aren't using.
        #region Monobehaviour Messages
        /// <summary>
        /// Only ever called once, mainly used to initialize variables.
        /// </summary>
        private void Awake()
        {
            // For this particular MonoBehaviour, we only want one instance to exist at any time, so store a reference to it in a static property
            //   and destroy any that are created while one already exists.
            if (Instance != null)
            {
                Plugin.Log?.Warn($"Instance of {GetType().Name} already exists, destroying.");
                GameObject.DestroyImmediate(this);
                return;
            }
            GameObject.DontDestroyOnLoad(this); // Don't destroy this object on scene changes
            Instance = this;


            //this._device = InputDevices.GetDeviceAtXRNode(XRNode.TrackingReference);
            this.client = new uOscClient();
            this.thread = new System.Threading.Thread(new ThreadStart(() =>
            {
                while (true)
                {
                    try {
                        pose = OVRPlugin.GetNodePose(OVRPlugin.Node.Head, OVRPlugin.Step.Render).ToOVRPose();

                        this.client.Send(new Message("/VMC/Ext/Hmd/Pos", new object[8]
                        {
                            DeviceSerial,
                            pose.position.x, pose.position.y, pose.position.z,
                            pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w
                        }));
                    }
                    catch (Exception e) {
                        Plugin.Log.Error(e);
                    }
                    System.Threading.Thread.Sleep(10);
                }
            }));
            this.thread.Start();
            Plugin.Log?.Debug($"{name}: Awake()");
        }
Exemple #16
0
    public OVRPose ComputeCameraTrackingSpacePose(OVRPlugin.CameraExtrinsics extrinsics, OVRPlugin.Posef calibrationRawPose)
    {
        OVRPose trackingSpacePose = new OVRPose();

        OVRPose cameraTrackingSpacePose = extrinsics.RelativePose.ToOVRPose();

#if OVR_ANDROID_MRC
        OVRPose rawPose = OVRPlugin.GetTrackingTransformRawPose().ToOVRPose();
        cameraTrackingSpacePose = rawPose * (calibrationRawPose.ToOVRPose().Inverse() * cameraTrackingSpacePose);
#endif
        trackingSpacePose = cameraTrackingSpacePose;

        if (extrinsics.AttachedToNode != OVRPlugin.Node.None && OVRPlugin.GetNodePresent(extrinsics.AttachedToNode))
        {
            if (usingLastAttachedNodePose)
            {
                Debug.Log("The camera attached node get tracked");
                usingLastAttachedNodePose = false;
            }
            OVRPose attachedNodePose = OVRPlugin.GetNodePose(extrinsics.AttachedToNode, OVRPlugin.Step.Render).ToOVRPose();
            lastAttachedNodePose = attachedNodePose;
            trackingSpacePose    = attachedNodePose * trackingSpacePose;
        }
        else
        {
            if (extrinsics.AttachedToNode != OVRPlugin.Node.None)
            {
                if (!usingLastAttachedNodePose)
                {
                    Debug.LogWarning("The camera attached node could not be tracked, using the last pose");
                    usingLastAttachedNodePose = true;
                }
                trackingSpacePose = lastAttachedNodePose * trackingSpacePose;
            }
        }

        return(trackingSpacePose);
    }
        public bool GetDeviceTransformByRole_Oculus(DeviceRole role, out Vector3 position, out Quaternion rotation)
        {
            OVRPlugin.Node node;
            switch (role)
            {
            case DeviceRole.Head:
                node = OVRPlugin.Node.Head;
                break;

            case DeviceRole.LeftHand:
                node = OVRPlugin.Node.HandLeft;
                break;

            case DeviceRole.RightHand:
                node = OVRPlugin.Node.HandRight;
                break;

            default:
                position = Vector3.zero;
                rotation = Quaternion.identity;
                return(false);
            }
            if (OVRPlugin.GetNodePositionTracked(node) && OVRPlugin.GetNodeOrientationTracked(node))
            {
                OVRPlugin.Posef pose = OVRPlugin.GetNodePose(node, OVRPlugin.Step.Render);
                position = new Vector3(pose.Position.x, pose.Position.y, pose.Position.z);
                rotation = new Quaternion(pose.Orientation.x, pose.Orientation.y, pose.Orientation.z, pose.Orientation.w);
                return(true);
            }
            else
            {
                position = Vector3.zero;
                rotation = Quaternion.identity;
                return(false);
            }
        }
        public override void UpdateDeviceState(IVRModuleDeviceState[] prevState, IVRModuleDeviceStateRW[] currState)
        {
            for (uint i = 0; i < MAX_DEVICE_COUNT; ++i)
            {
                var node = s_index2node[i];
                if (node == OVRPlugin.Node.None)
                {
                    continue;
                }

                currState[i].isConnected = OVRPlugin.GetNodePresent(node);

                if (currState[i].isConnected)
                {
                    if (!prevState[i].isConnected)
                    {
                        var ovrProductName = OVRPlugin.productName;
                        var deviceClass    = s_node2class[(int)node];

                        switch (deviceClass)
                        {
                        case VRModuleDeviceClass.HMD:
                            currState[i].deviceModel = VRModuleDeviceModel.OculusHMD;
                            break;

                        case VRModuleDeviceClass.TrackingReference:
                            currState[i].deviceModel = VRModuleDeviceModel.OculusSensor;
                            break;

                        case VRModuleDeviceClass.Controller:
                            switch (ovrProductName)
                            {
                            case "Oculus Go":
                                currState[i].deviceModel = VRModuleDeviceModel.OculusGoController;
                                break;

                            case "Gear VR":
                                currState[i].deviceModel = VRModuleDeviceModel.OculusGearVrController;
                                break;

                            case "Oculus Rift":
                            default:
                                switch (node)
                                {
                                case OVRPlugin.Node.HandLeft:
                                    currState[i].deviceModel = VRModuleDeviceModel.OculusTouchLeft;
                                    break;

                                case OVRPlugin.Node.HandRight:
                                default:
                                    currState[i].deviceModel = VRModuleDeviceModel.OculusTouchRight;
                                    break;
                                }
                                break;
                            }
                            break;
                        }

                        currState[i].deviceClass = deviceClass;
                        // FIXME: how to get device id from OVRPlugin?
                        currState[i].modelNumber     = ovrProductName + " " + deviceClass;
                        currState[i].renderModelName = ovrProductName + " " + deviceClass;
                        currState[i].serialNumber    = ovrProductName + " " + deviceClass;
                    }

                    // update device status
                    currState[i].pose            = ToPose(OVRPlugin.GetNodePose(node, OVRPlugin.Step.Render));
                    currState[i].velocity        = OVRPlugin.GetNodeVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();
                    currState[i].angularVelocity = OVRPlugin.GetNodeAngularVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();

                    currState[i].isPoseValid = currState[i].pose != RigidPose.identity;

                    // update device input
                    switch (currState[i].deviceModel)
                    {
                    case VRModuleDeviceModel.OculusTouchLeft:
                    {
                        var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.LTouch);

                        currState[i].SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Y) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.X) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.LThumbstick) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Trigger), ctrlState.LIndexTrigger, 0.55f, 0.45f));
                        currState[i].SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Grip), ctrlState.LHandTrigger, 0.55f, 0.45f));
                        currState[i].SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.55f, 0.45f));

                        currState[i].SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.Y) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.X) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.LThumbstick) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.LIndexTrigger) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.25f, 0.20f));

                        currState[i].SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.LThumbstick.x);
                        currState[i].SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.LThumbstick.y);
                        currState[i].SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.LIndexTrigger);
                        currState[i].SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.LHandTrigger);
                        break;
                    }

                    case VRModuleDeviceModel.OculusTouchRight:
                    {
                        var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.RTouch);

                        currState[i].SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.B) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.A) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.RThumbstick) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Trigger), ctrlState.RIndexTrigger, 0.55f, 0.45f));
                        currState[i].SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Grip), ctrlState.RHandTrigger, 0.55f, 0.45f));
                        currState[i].SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.55f, 0.45f));

                        currState[i].SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.B) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.A) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.RThumbstick) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.RIndexTrigger) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.25f, 0.20f));

                        currState[i].SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.RThumbstick.x);
                        currState[i].SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.RThumbstick.y);
                        currState[i].SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.RIndexTrigger);
                        currState[i].SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.RHandTrigger);
                        break;
                    }

                    case VRModuleDeviceModel.OculusGoController:
                    case VRModuleDeviceModel.OculusGearVrController:
                        switch (node)
                        {
                        case OVRPlugin.Node.HandLeft:
                        {
                            var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.LTrackedRemote);

                            currState[i].SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.LTouchpad) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Back) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.Trigger, (ctrlState.Buttons & (uint)(OVRInput.RawButton.A | OVRInput.RawButton.LIndexTrigger)) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.DPadLeft, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadLeft) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.DPadUp, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadUp) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.DPadRight, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadRight) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.DPadDown, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadDown) != 0u);

                            currState[i].SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.LTouchpad) != 0u);
                        }
                        break;

                        case OVRPlugin.Node.HandRight:
                        default:
                        {
                            var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.RTrackedRemote);

                            currState[i].SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & unchecked ((uint)OVRInput.RawButton.RTouchpad)) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Back) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.Trigger, (ctrlState.Buttons & (uint)(OVRInput.RawButton.A | OVRInput.RawButton.RIndexTrigger)) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.DPadLeft, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadLeft) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.DPadUp, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadUp) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.DPadRight, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadRight) != 0u);
                            currState[i].SetButtonPress(VRModuleRawButton.DPadDown, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadDown) != 0u);

                            currState[i].SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & unchecked ((uint)OVRInput.RawTouch.RTouchpad)) != 0u);
                        }
                        break;
                        }
                        break;
                    }
                }
                else
                {
                    if (prevState[i].isConnected)
                    {
                        currState[i].Reset();
                    }
                }
            }
        }
Exemple #19
0
    public static bool GetNodeStatePropertyVector3(Node nodeType, NodeStatePropertyType propertyType, OVRPlugin.Node ovrpNodeType, OVRPlugin.Step stepType, out Vector3 retVec)
    {
        retVec = Vector3.zero;
        switch (propertyType)
        {
        case NodeStatePropertyType.Acceleration:
            if (OVRManager.loadedXRDevice == OVRManager.XRDevice.Oculus)
            {
                retVec = OVRPlugin.GetNodeAcceleration(ovrpNodeType, stepType).FromFlippedZVector3f();
                return(true);
            }
#if UNITY_2017_1_OR_NEWER
            if (GetUnityXRNodeStateVector3(nodeType, NodeStatePropertyType.Acceleration, out retVec))
            {
                return(true);
            }
#endif
            break;

        case NodeStatePropertyType.AngularAcceleration:
            if (OVRManager.loadedXRDevice == OVRManager.XRDevice.Oculus)
            {
                retVec = OVRPlugin.GetNodeAngularAcceleration(ovrpNodeType, stepType).FromFlippedZVector3f();
                return(true);
            }
#if UNITY_2017_2_OR_NEWER
            if (GetUnityXRNodeStateVector3(nodeType, NodeStatePropertyType.AngularAcceleration, out retVec))
            {
                return(true);
            }
#endif
            break;

        case NodeStatePropertyType.Velocity:
            if (OVRManager.loadedXRDevice == OVRManager.XRDevice.Oculus)
            {
                retVec = OVRPlugin.GetNodeVelocity(ovrpNodeType, stepType).FromFlippedZVector3f();
                return(true);
            }
#if UNITY_2017_1_OR_NEWER
            if (GetUnityXRNodeStateVector3(nodeType, NodeStatePropertyType.Velocity, out retVec))
            {
                return(true);
            }
#endif
            break;

        case NodeStatePropertyType.AngularVelocity:
            if (OVRManager.loadedXRDevice == OVRManager.XRDevice.Oculus)
            {
                retVec = OVRPlugin.GetNodeAngularVelocity(ovrpNodeType, stepType).FromFlippedZVector3f();
                return(true);
            }
#if UNITY_2017_2_OR_NEWER
            if (GetUnityXRNodeStateVector3(nodeType, NodeStatePropertyType.AngularVelocity, out retVec))
            {
                return(true);
            }
#endif
            break;

        case NodeStatePropertyType.Position:
            if (OVRManager.loadedXRDevice == OVRManager.XRDevice.Oculus)
            {
                retVec = OVRPlugin.GetNodePose(ovrpNodeType, stepType).ToOVRPose().position;
                return(true);
            }
#if UNITY_2017_1_OR_NEWER
            if (GetUnityXRNodeStateVector3(nodeType, NodeStatePropertyType.Position, out retVec))
            {
                return(true);
            }
#endif
            break;
        }

        return(false);
    }
        public override void BeforeRenderUpdate()
        {
            FlushDeviceState();

            for (uint i = 0u, imax = GetDeviceStateLength(); i < imax; ++i)
            {
                var node = s_index2node[i];
                if (node == OVRPlugin.Node.None)
                {
                    continue;
                }

                IVRModuleDeviceState   prevState;
                IVRModuleDeviceStateRW currState;
                EnsureValidDeviceState(i, out prevState, out currState);

                if (!OVRPlugin.GetNodePresent(node))
                {
                    if (prevState.isConnected)
                    {
                        currState.Reset();
                    }

                    continue;
                }

                // update device connected state
                if (!prevState.isConnected)
                {
                    var platform       = OVRPlugin.GetSystemHeadsetType();
                    var ovrProductName = platform.ToString();
                    var deviceClass    = s_node2class[(int)node];

                    currState.isConnected = true;
                    currState.deviceClass = deviceClass;
                    // FIXME: how to get device id from OVRPlugin?
                    currState.modelNumber     = ovrProductName + " " + deviceClass;
                    currState.renderModelName = ovrProductName + " " + deviceClass;
                    currState.serialNumber    = ovrProductName + " " + deviceClass;

                    switch (deviceClass)
                    {
                    case VRModuleDeviceClass.HMD:
                        currState.deviceModel = VRModuleDeviceModel.OculusHMD;
                        break;

                    case VRModuleDeviceClass.TrackingReference:
                        currState.deviceModel = VRModuleDeviceModel.OculusSensor;
                        break;

                    case VRModuleDeviceClass.Controller:
                        switch (platform)
                        {
                        case OVRPlugin.SystemHeadset.Oculus_Go:
                            currState.deviceModel = VRModuleDeviceModel.OculusGoController;
                            break;

                        case OVRPlugin.SystemHeadset.GearVR_R320:
                        case OVRPlugin.SystemHeadset.GearVR_R321:
                        case OVRPlugin.SystemHeadset.GearVR_R322:
                        case OVRPlugin.SystemHeadset.GearVR_R323:
                        case OVRPlugin.SystemHeadset.GearVR_R324:
                        case OVRPlugin.SystemHeadset.GearVR_R325:
                            currState.deviceModel = VRModuleDeviceModel.OculusGearVrController;
                            break;

                        case OVRPlugin.SystemHeadset.Rift_DK1:
                        case OVRPlugin.SystemHeadset.Rift_DK2:
                        case OVRPlugin.SystemHeadset.Rift_CV1:
                        default:
                            switch (node)
                            {
                            case OVRPlugin.Node.HandLeft:
                                currState.deviceModel = VRModuleDeviceModel.OculusTouchLeft;
                                break;

                            case OVRPlugin.Node.HandRight:
                            default:
                                currState.deviceModel = VRModuleDeviceModel.OculusTouchRight;
                                break;
                            }
                            break;
                        }
                        break;
                    }
                }

                // update device pose
                currState.pose            = ToPose(OVRPlugin.GetNodePose(node, OVRPlugin.Step.Render));
                currState.velocity        = OVRPlugin.GetNodeVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();
                currState.angularVelocity = OVRPlugin.GetNodeAngularVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();
                currState.isPoseValid     = currState.pose != RigidPose.identity;
                currState.isConnected     = OVRPlugin.GetNodePresent(node);

                // update device input
                switch (currState.deviceModel)
                {
                case VRModuleDeviceModel.OculusTouchLeft:
                {
                    var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.LTouch);

                    currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Y) != 0u);
                    currState.SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.X) != 0u);
                    currState.SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.LThumbstick) != 0u);
                    currState.SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState.GetButtonPress(VRModuleRawButton.Trigger), ctrlState.LIndexTrigger, 0.55f, 0.45f));
                    currState.SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState.GetButtonPress(VRModuleRawButton.Grip), ctrlState.LHandTrigger, 0.55f, 0.45f));
                    currState.SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState.GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.55f, 0.45f));

                    currState.SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.Y) != 0u);
                    currState.SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.X) != 0u);
                    currState.SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.LThumbstick) != 0u);
                    currState.SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.LIndexTrigger) != 0u);
                    currState.SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState.GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.25f, 0.20f));

                    currState.SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.LThumbstick.x);
                    currState.SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.LThumbstick.y);
                    currState.SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.LIndexTrigger);
                    currState.SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.LHandTrigger);
                    break;
                }

                case VRModuleDeviceModel.OculusTouchRight:
                {
                    var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.RTouch);

                    currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.B) != 0u);
                    currState.SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.A) != 0u);
                    currState.SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.RThumbstick) != 0u);
                    currState.SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState.GetButtonPress(VRModuleRawButton.Trigger), ctrlState.RIndexTrigger, 0.55f, 0.45f));
                    currState.SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState.GetButtonPress(VRModuleRawButton.Grip), ctrlState.RHandTrigger, 0.55f, 0.45f));
                    currState.SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState.GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.55f, 0.45f));

                    currState.SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.B) != 0u);
                    currState.SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.A) != 0u);
                    currState.SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.RThumbstick) != 0u);
                    currState.SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.RIndexTrigger) != 0u);
                    currState.SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState.GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.25f, 0.20f));

                    currState.SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.RThumbstick.x);
                    currState.SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.RThumbstick.y);
                    currState.SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.RIndexTrigger);
                    currState.SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.RHandTrigger);
                    break;
                }

                case VRModuleDeviceModel.OculusGoController:
                case VRModuleDeviceModel.OculusGearVrController:
                    switch (node)
                    {
                    case OVRPlugin.Node.HandLeft:
                    {
                        var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.LTrackedRemote);

                        currState.SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.LTouchpad) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Back) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.Trigger, (ctrlState.Buttons & (uint)(OVRInput.RawButton.A | OVRInput.RawButton.LIndexTrigger)) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.DPadLeft, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadLeft) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.DPadUp, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadUp) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.DPadRight, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadRight) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.DPadDown, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadDown) != 0u);

                        currState.SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.LTouchpad) != 0u);
                    }
                    break;

                    case OVRPlugin.Node.HandRight:
                    default:
                    {
                        var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.RTrackedRemote);

                        currState.SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & unchecked ((uint)OVRInput.RawButton.RTouchpad)) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Back) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.Trigger, (ctrlState.Buttons & (uint)(OVRInput.RawButton.A | OVRInput.RawButton.RIndexTrigger)) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.DPadLeft, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadLeft) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.DPadUp, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadUp) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.DPadRight, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadRight) != 0u);
                        currState.SetButtonPress(VRModuleRawButton.DPadDown, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadDown) != 0u);

                        currState.SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & unchecked ((uint)OVRInput.RawTouch.RTouchpad)) != 0u);
                    }
                    break;
                    }
                    break;
                }
            }

            ProcessConnectedDeviceChanged();
            ProcessDevicePoseChanged();
            ProcessDeviceInputChanged();
        }
    public override void Update(GameObject gameObject, Camera mainCamera)
    {
        RefreshCameraObjects(gameObject, mainCamera);

        OVRPlugin.SetHandNodePoseStateLatency(0.0);             // the HandNodePoseStateLatency doesn't apply to the external composition. Always enforce it to 0.0

        // For third-person camera to use for calculating camera position with different anchors
        OVRPose stageToLocalPose = OVRPlugin.GetTrackingTransformRelativePose(OVRPlugin.TrackingOrigin.Stage).ToOVRPose();
        OVRPose localToStagePose = stageToLocalPose.Inverse();
        OVRPose head             = localToStagePose * OVRPlugin.GetNodePose(OVRPlugin.Node.Head, OVRPlugin.Step.Render).ToOVRPose();
        OVRPose leftC            = localToStagePose * OVRPlugin.GetNodePose(OVRPlugin.Node.HandLeft, OVRPlugin.Step.Render).ToOVRPose();
        OVRPose rightC           = localToStagePose * OVRPlugin.GetNodePose(OVRPlugin.Node.HandRight, OVRPlugin.Step.Render).ToOVRPose();

        OVRPlugin.Media.SetMrcHeadsetControllerPose(head.ToPosef(), leftC.ToPosef(), rightC.ToPosef());

#if OVR_ANDROID_MRC
        RefreshAudioFilter();

        int drawTextureIndex = (frameIndex / 2) % 2;
        int castTextureIndex = 1 - drawTextureIndex;

        backgroundCamera.enabled = (frameIndex % 2) == 0;
        foregroundCamera.enabled = (frameIndex % 2) == 1;

        if (frameIndex % 2 == 0)
        {
            if (lastMrcEncodeFrameSyncId != -1)
            {
                OVRPlugin.Media.SyncMrcFrame(lastMrcEncodeFrameSyncId);
                lastMrcEncodeFrameSyncId = -1;
            }
            lastMrcEncodeFrameSyncId = CastMrcFrame(castTextureIndex);
            SetCameraTargetTexture(drawTextureIndex);
        }

        ++frameIndex;
#endif

        backgroundCamera.clearFlags      = mainCamera.clearFlags;
        backgroundCamera.backgroundColor = mainCamera.backgroundColor;
        backgroundCamera.cullingMask     = mainCamera.cullingMask & (~OVRManager.instance.extraHiddenLayers);
        backgroundCamera.nearClipPlane   = mainCamera.nearClipPlane;
        backgroundCamera.farClipPlane    = mainCamera.farClipPlane;

        foregroundCamera.cullingMask   = mainCamera.cullingMask & (~OVRManager.instance.extraHiddenLayers);
        foregroundCamera.nearClipPlane = mainCamera.nearClipPlane;
        foregroundCamera.farClipPlane  = mainCamera.farClipPlane;

        if (OVRMixedReality.useFakeExternalCamera || OVRPlugin.GetExternalCameraCount() == 0)
        {
            OVRPose worldSpacePose    = new OVRPose();
            OVRPose trackingSpacePose = new OVRPose();
            trackingSpacePose.position = OVRManager.instance.trackingOriginType == OVRManager.TrackingOrigin.EyeLevel ?
                                         OVRMixedReality.fakeCameraEyeLevelPosition :
                                         OVRMixedReality.fakeCameraFloorLevelPosition;
            trackingSpacePose.orientation = OVRMixedReality.fakeCameraRotation;
            worldSpacePose = OVRExtensions.ToWorldSpacePose(trackingSpacePose);

            backgroundCamera.fieldOfView = OVRMixedReality.fakeCameraFov;
            backgroundCamera.aspect      = OVRMixedReality.fakeCameraAspect;
            foregroundCamera.fieldOfView = OVRMixedReality.fakeCameraFov;
            foregroundCamera.aspect      = OVRMixedReality.fakeCameraAspect;

            if (cameraInTrackingSpace)
            {
                backgroundCamera.transform.FromOVRPose(trackingSpacePose, true);
                foregroundCamera.transform.FromOVRPose(trackingSpacePose, true);
            }
            else
            {
                backgroundCamera.transform.FromOVRPose(worldSpacePose);
                foregroundCamera.transform.FromOVRPose(worldSpacePose);
            }
        }
        else
        {
            OVRPlugin.CameraExtrinsics extrinsics;
            OVRPlugin.CameraIntrinsics intrinsics;

            // So far, only support 1 camera for MR and always use camera index 0
            if (OVRPlugin.GetMixedRealityCameraInfo(0, out extrinsics, out intrinsics))
            {
                float fovY   = Mathf.Atan(intrinsics.FOVPort.UpTan) * Mathf.Rad2Deg * 2;
                float aspect = intrinsics.FOVPort.LeftTan / intrinsics.FOVPort.UpTan;
                backgroundCamera.fieldOfView = fovY;
                backgroundCamera.aspect      = aspect;
                foregroundCamera.fieldOfView = fovY;
                foregroundCamera.aspect      = intrinsics.FOVPort.LeftTan / intrinsics.FOVPort.UpTan;

                if (cameraInTrackingSpace)
                {
                    OVRPose trackingSpacePose = ComputeCameraTrackingSpacePose(extrinsics);
                    backgroundCamera.transform.FromOVRPose(trackingSpacePose, true);
                    foregroundCamera.transform.FromOVRPose(trackingSpacePose, true);
                }
                else
                {
                    OVRPose worldSpacePose = ComputeCameraWorldSpacePose(extrinsics);
                    backgroundCamera.transform.FromOVRPose(worldSpacePose);
                    foregroundCamera.transform.FromOVRPose(worldSpacePose);
                }
#if OVR_ANDROID_MRC
                cameraPoseTimeArray[drawTextureIndex] = extrinsics.LastChangedTimeSeconds;
#endif
            }
            else
            {
                Debug.LogError("Failed to get external camera information");
                return;
            }
        }

        Vector3 headToExternalCameraVec = mainCamera.transform.position - foregroundCamera.transform.position;
        float   clipDistance            = Vector3.Dot(headToExternalCameraVec, foregroundCamera.transform.forward);
        foregroundCamera.farClipPlane = Mathf.Max(foregroundCamera.nearClipPlane + 0.001f, clipDistance);
    }
    private static void UpdateDirectCompositionObjects(Camera mainCamera)
    {
        directCompositionCamera.clearFlags      = mainCamera.clearFlags;
        directCompositionCamera.backgroundColor = mainCamera.backgroundColor;
        directCompositionCamera.cullingMask     = mainCamera.cullingMask;
        directCompositionCamera.nearClipPlane   = mainCamera.nearClipPlane;
        directCompositionCamera.farClipPlane    = mainCamera.farClipPlane;

        if (useFakeExternalCamera || OVRPlugin.GetExternalCameraCount() == 0)
        {
            OVRPose worldSpacePose    = new OVRPose();
            OVRPose trackingSpacePose = new OVRPose();
            trackingSpacePose.position    = fakeCameraPositon;
            trackingSpacePose.orientation = fakeCameraRotation;
            worldSpacePose = OVRExtensions.ToWorldSpacePose(trackingSpacePose);

            directCompositionCamera.fieldOfView = fakeCameraFov;
            directCompositionCamera.aspect      = fakeCameraAspect;
            directCompositionCamera.transform.FromOVRPose(worldSpacePose);
        }
        else
        {
            OVRPlugin.CameraExtrinsics extrinsics;
            OVRPlugin.CameraIntrinsics intrinsics;

            // So far, only support 1 camera for MR and always use camera index 0
            if (OVRPlugin.GetMixedRealityCameraInfo(0, out extrinsics, out intrinsics))
            {
                OVRPose worldSpacePose    = new OVRPose();
                OVRPose trackingSpacePose = new OVRPose();

                OVRPose cameraTrackingSpacePose = extrinsics.RelativePose.ToOVRPose();
                trackingSpacePose = cameraTrackingSpacePose;

                if (extrinsics.AttachedToNode != OVRPlugin.Node.None && OVRPlugin.GetNodePresent(extrinsics.AttachedToNode))
                {
                    OVRPose attachedNodePose = OVRPlugin.GetNodePose(extrinsics.AttachedToNode, OVRPlugin.Step.Render).ToOVRPose();
                    trackingSpacePose = attachedNodePose * trackingSpacePose;
                }

                worldSpacePose = OVRExtensions.ToWorldSpacePose(trackingSpacePose);

                float fovY   = Mathf.Atan(intrinsics.FOVPort.UpTan) * Mathf.Rad2Deg * 2;
                float aspect = intrinsics.FOVPort.LeftTan / intrinsics.FOVPort.UpTan;
                directCompositionCamera.fieldOfView = fovY;
                directCompositionCamera.aspect      = aspect;
                directCompositionCamera.transform.FromOVRPose(worldSpacePose);
            }
            else
            {
                Debug.LogWarning("Failed to get external camera information");
            }
        }

        if (OVRPlugin.HasCameraDeviceOpened(directCompositionCameraDevice))
        {
            if (OVRPlugin.IsCameraDeviceColorFrameAvailable(directCompositionCameraDevice))
            {
                cameraFramePlaneObject.GetComponent <MeshRenderer>().material.mainTexture = OVRPlugin.GetCameraDeviceColorFrameTexture(directCompositionCameraDevice);
            }
        }

        Vector3 offset   = mainCamera.transform.position - directCompositionCameraGameObject.transform.position;
        float   distance = Vector3.Dot(directCompositionCameraGameObject.transform.forward, offset);

        cameraFramePlaneObject.transform.position = directCompositionCameraGameObject.transform.position + directCompositionCameraGameObject.transform.forward * distance;
        cameraFramePlaneObject.transform.rotation = directCompositionCameraGameObject.transform.rotation;

        float tanFov = Mathf.Tan(directCompositionCamera.fieldOfView * Mathf.Deg2Rad * 0.5f);

        cameraFramePlaneObject.transform.localScale = new Vector3(distance * directCompositionCamera.aspect * tanFov * 2.0f, distance * tanFov * 2.0f, 1.0f);
    }
    private static void UpdateExternalCompositionObjects(Camera mainCamera)
    {
        backgroundCamera.clearFlags      = mainCamera.clearFlags;
        backgroundCamera.backgroundColor = mainCamera.backgroundColor;
        backgroundCamera.cullingMask     = mainCamera.cullingMask;
        backgroundCamera.nearClipPlane   = mainCamera.nearClipPlane;
        backgroundCamera.farClipPlane    = mainCamera.farClipPlane;

        foregroundCamera.cullingMask   = mainCamera.cullingMask;
        foregroundCamera.nearClipPlane = mainCamera.nearClipPlane;
        foregroundCamera.farClipPlane  = mainCamera.farClipPlane;

        if (useFakeExternalCamera || OVRPlugin.GetExternalCameraCount() == 0)
        {
            OVRPose worldSpacePose    = new OVRPose();
            OVRPose trackingSpacePose = new OVRPose();
            trackingSpacePose.position    = fakeCameraPositon;
            trackingSpacePose.orientation = fakeCameraRotation;
            worldSpacePose = OVRExtensions.ToWorldSpacePose(trackingSpacePose);

            backgroundCamera.fieldOfView = fakeCameraFov;
            backgroundCamera.aspect      = fakeCameraAspect;
            backgroundCamera.transform.FromOVRPose(worldSpacePose);

            foregroundCamera.fieldOfView = fakeCameraFov;
            foregroundCamera.aspect      = fakeCameraAspect;
            foregroundCamera.transform.FromOVRPose(worldSpacePose);
        }
        else
        {
            OVRPlugin.CameraExtrinsics extrinsics;
            OVRPlugin.CameraIntrinsics intrinsics;

            // So far, only support 1 camera for MR and always use camera index 0
            if (OVRPlugin.GetMixedRealityCameraInfo(0, out extrinsics, out intrinsics))
            {
                OVRPose worldSpacePose    = new OVRPose();
                OVRPose trackingSpacePose = new OVRPose();

                OVRPose cameraTrackingSpacePose = extrinsics.RelativePose.ToOVRPose();
                trackingSpacePose = cameraTrackingSpacePose;

                if (extrinsics.AttachedToNode != OVRPlugin.Node.None && OVRPlugin.GetNodePresent(extrinsics.AttachedToNode))
                {
                    OVRPose attachedNodePose = OVRPlugin.GetNodePose(extrinsics.AttachedToNode, OVRPlugin.Step.Render).ToOVRPose();
                    trackingSpacePose = attachedNodePose * trackingSpacePose;
                }

                worldSpacePose = OVRExtensions.ToWorldSpacePose(trackingSpacePose);

                float fovY   = Mathf.Atan(intrinsics.FOVPort.UpTan) * Mathf.Rad2Deg * 2;
                float aspect = intrinsics.FOVPort.LeftTan / intrinsics.FOVPort.UpTan;
                backgroundCamera.fieldOfView = fovY;
                backgroundCamera.aspect      = aspect;
                backgroundCamera.transform.FromOVRPose(worldSpacePose);
                foregroundCamera.fieldOfView = fovY;
                foregroundCamera.aspect      = intrinsics.FOVPort.LeftTan / intrinsics.FOVPort.UpTan;
                foregroundCamera.transform.FromOVRPose(worldSpacePose);
            }
            else
            {
                Debug.LogError("Failed to get external camera information");
                return;
            }
        }

        // Assume player always standing straightly
        Vector3 externalCameraToHeadXZ = mainCamera.transform.position - foregroundCamera.transform.position;

        externalCameraToHeadXZ.y            = 0;
        cameraProxyPlane.transform.position = mainCamera.transform.position;
        cameraProxyPlane.transform.LookAt(cameraProxyPlane.transform.position + externalCameraToHeadXZ);
    }
        public override void UpdateDeviceState(IVRModuleDeviceState[] prevState, IVRModuleDeviceStateRW[] currState)
        {
            for (uint i = 0; i < MAX_DEVICE_COUNT; ++i)
            {
                var node = s_index2node[i];
                if (node == OVRPlugin.Node.None)
                {
                    continue;
                }

                currState[i].isConnected = OVRPlugin.GetNodePresent(node);

                if (currState[i].isConnected)
                {
                    if (!prevState[i].isConnected)
                    {
                        currState[i].deviceClass = s_node2class[(int)node];
                        // FIXME: how to get product id from OVRPlugin?
                        currState[i].serialNumber    = OVRPlugin.productName + " " + node.ToString();
                        currState[i].modelNumber     = OVRPlugin.productName + " " + node.ToString();
                        currState[i].renderModelName = OVRPlugin.productName + " " + node.ToString();

                        SetupKnownDeviceModel(currState[i]);
                    }

                    // update device status
                    currState[i].pose            = ToPose(OVRPlugin.GetNodePose(node, OVRPlugin.Step.Render));
                    currState[i].velocity        = OVRPlugin.GetNodeVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();
                    currState[i].angularVelocity = OVRPlugin.GetNodeAngularVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();

                    currState[i].isPoseValid = currState[i].pose != RigidPose.identity;

                    // update device input
                    switch (currState[i].deviceModel)
                    {
                    case VRModuleDeviceModel.OculusTouchLeft:
                    {
                        var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.LTouch);

                        currState[i].SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Y) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.X) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.LThumbstick) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Trigger), ctrlState.LIndexTrigger, 0.55f, 0.45f));
                        currState[i].SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Grip), ctrlState.LHandTrigger, 0.55f, 0.45f));
                        currState[i].SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.55f, 0.45f));

                        currState[i].SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.Y) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.X) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.LThumbstick) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.LIndexTrigger) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.25f, 0.20f));

                        currState[i].SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.LThumbstick.x);
                        currState[i].SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.LThumbstick.y);
                        currState[i].SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.LIndexTrigger);
                        currState[i].SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.LHandTrigger);
                        break;
                    }

                    case VRModuleDeviceModel.OculusTouchRight:
                    {
                        var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.RTouch);

                        currState[i].SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.B) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.A) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.RThumbstick) != 0u);
                        currState[i].SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Trigger), ctrlState.RIndexTrigger, 0.55f, 0.45f));
                        currState[i].SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Grip), ctrlState.RHandTrigger, 0.55f, 0.45f));
                        currState[i].SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.55f, 0.45f));

                        currState[i].SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.B) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.A) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.RThumbstick) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.RIndexTrigger) != 0u);
                        currState[i].SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.25f, 0.20f));

                        currState[i].SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.RThumbstick.x);
                        currState[i].SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.RThumbstick.y);
                        currState[i].SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.RIndexTrigger);
                        currState[i].SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.RHandTrigger);
                        break;
                    }
                    }
                }
                else
                {
                    if (prevState[i].isConnected)
                    {
                        currState[i].Reset();
                    }
                }
            }
        }
    void Start()
    {
        OVRManager.display.RecenteredPose += Recentered;

        m_originalTrackerOrientation = OVRPlugin.GetNodePose(OVRPlugin.Node.TrackerZero, OVRPlugin.Step.Render).ToOVRPose().orientation;
    }