private void ProcessLine(LineSegment line, ref MLInputDevice inputDevice)
        {
            Vector3?endPoint = null;
            Vector3 normal   = Vector3.zero;

            MLInputDeviceEventData pointerEventData = _cachedTrackedPointerEventData;

            if (pointerEventData == null)
            {
                return;
            }

            pointerEventData.Reset();
            inputDevice.CopyTo(ref pointerEventData);
            pointerEventData.pointerCurrentRaycast = PerformRaycast(pointerEventData);
            GameObject currentRaycastObject = pointerEventData.pointerCurrentRaycast.gameObject;

            // enable cursor for any canvas UI or any game object with an Event Trigger (assuming camera has physics raycaster on it)
            if (currentRaycastObject != null &&
                (currentRaycastObject.GetComponent <RectTransform>() != null || currentRaycastObject.GetComponent <EventTrigger>() != null))
            {
                // Relies on TrackedDeviceRaycaster and 3D world position to work with event system
                RaycastResult result = pointerEventData.pointerCurrentRaycast;
                endPoint = result.worldPosition;
                normal   = result.worldNormal;
            }

            inputDevice.CopyFrom(pointerEventData);
            inputDevice.OnFrameFinished();

            line.Set(inputDevice.Position, endPoint, normal);
        }
        private void ProcessTrackedDevice(ref MLInputDevice deviceState)
        {
            var eventData = _cachedTrackedPointerEventData;

            eventData.Reset();
            deviceState.CopyTo(ref eventData);

            eventData.button = PointerEventData.InputButton.Left;
            eventData.pointerCurrentRaycast = PerformRaycast(eventData);

            ProcessButton(deviceState.SelectDelta, ref eventData);
            ProcessMovement(eventData);
            ProcessScroll(eventData);

            deviceState.CopyFrom(eventData);
            deviceState.OnFrameFinished();
        }