protected void UpdateMousePointerEventData(PointerData pointerData)
        {
            IMixedRealityPointer pointer = pointerData.pointer;

            // Reset the RaycastCamera for projecting (used in calculating deltas)
            Debug.Assert(pointer.Rays != null && pointer.Rays.Length > 0);

            if (pointer.Controller != null && pointer.Controller.IsRotationAvailable)
            {
                RaycastCamera.transform.position = pointer.Rays[0].Origin;
                RaycastCamera.transform.rotation = Quaternion.LookRotation(pointer.Rays[0].Direction);
            }
            else
            {
                // The pointer.Controller does not provide rotation, for example on HoloLens 1 hands.
                // In this case pointer.Rays[0].Origin will be the head position, but we want the
                // hand to do drag operations, not the head.
                // pointer.Position gives the position of the hand, use that to compute drag deltas.
                RaycastCamera.transform.position = pointer.Position;
                RaycastCamera.transform.rotation = Quaternion.LookRotation(pointer.Rays[0].Direction);
            }

            // Populate eventDataLeft
            pointerData.eventDataLeft.Reset();

            // The RayCastCamera is placed so that the current cursor position is in the center of the camera's view space.
            Vector3 viewportPos = new Vector3(0.5f, 0.5f, 1.0f);
            Vector2 newPos      = RaycastCamera.ViewportToScreenPoint(viewportPos);

            // Populate initial data or drag data
            Vector2 lastPosition;

            if (pointerData.lastMousePoint3d == null)
            {
                // For the first event, use the same position for 'last' and 'new'.
                lastPosition = newPos;
            }
            else
            {
                // Otherwise, re-project the last pointer position.
                lastPosition = RaycastCamera.WorldToScreenPoint(pointerData.lastMousePoint3d.Value);
            }

            // Save off the 3D position of the cursor.
            pointerData.lastMousePoint3d = RaycastCamera.ViewportToWorldPoint(viewportPos);

            // Calculate delta
            pointerData.eventDataLeft.delta    = newPos - lastPosition;
            pointerData.eventDataLeft.position = newPos;

            // Move the press position to allow dragging
            pointerData.eventDataLeft.pressPosition += pointerData.eventDataLeft.delta;

            // Populate raycast data
            pointerData.eventDataLeft.pointerCurrentRaycast = pointer.Result != null ? pointer.Result.Details.LastGraphicsRaycastResult : new RaycastResult();
            // TODO: Simulate raycast for 3D objects?

            // Populate the data for the buttons
            pointerData.eventDataLeft.button = PointerEventData.InputButton.Left;
            pointerData.mouseState.SetButtonState(PointerEventData.InputButton.Left, StateForPointer(pointerData), pointerData.eventDataLeft);

            // Need to provide data for middle and right button for MouseState, although not used by MRTK pointers.
            CopyFromTo(pointerData.eventDataLeft, pointerData.eventDataRight);
            pointerData.eventDataRight.button = PointerEventData.InputButton.Right;
            pointerData.mouseState.SetButtonState(PointerEventData.InputButton.Right, PointerEventData.FramePressState.NotChanged, pointerData.eventDataRight);

            CopyFromTo(pointerData.eventDataLeft, pointerData.eventDataMiddle);
            pointerData.eventDataMiddle.button = PointerEventData.InputButton.Middle;
            pointerData.mouseState.SetButtonState(PointerEventData.InputButton.Middle, PointerEventData.FramePressState.NotChanged, pointerData.eventDataMiddle);
        }
示例#2
0
 /// <summary>
 /// Used to initialize/reset the event and populate the data.
 /// </summary>
 /// <param name="pointer"></param>
 /// <param name="target"></param>
 public void Initialize(IMixedRealityPointer pointer, IMixedRealityTeleportHotSpot target)
 {
     BaseInitialize(pointer.InputSourceParent);
     Pointer = pointer;
     HotSpot = target;
 }
 public PointerData(IMixedRealityPointer pointer, Vector3 worldGrabPoint) : this()
 {
     this.pointer = pointer;
     this.initialGrabPointInPointer = Quaternion.Inverse(pointer.Rotation) * (worldGrabPoint - pointer.Position);
 }
示例#4
0
 /// <inheritdoc/>
 public override void DwellCanceled(IMixedRealityPointer pointer)
 {
     base.DwellCanceled(pointer);
     buttonBackground.material.color = isDwellEnabled ? this.dwellOnColor : this.dwellOffColor;
     cancelStartScale = dwellVisualImage.material.GetFloat("_BorderWidth");
 }
示例#5
0
 private static bool Equals(IMixedRealityPointer left, IMixedRealityPointer right)
 {
     return(left != null && left.Equals(right));
 }
示例#6
0
 public static bool Equals(IMixedRealityPointer left, IMixedRealityPointer right)
 {
     return(left.Equals(right));
 }
 /// <summary>
 /// Function called when entering dwell started state
 /// </summary>
 public virtual void DwellStarted(IMixedRealityPointer pointer)
 {
     IsDwelling = true;
 }
示例#8
0
 /// <summary>
 /// Removes a pointer, lost focus
 /// </summary>
 /// <param name="pointer"></param>
 private void RemovePointer(IMixedRealityPointer pointer)
 {
     pointers.Remove(pointer);
 }
示例#9
0
 /// <summary>
 /// Used to initialize/reset the event and populate the data.
 /// </summary>
 /// <param name="pointer"></param>
 public void Initialize(IMixedRealityPointer pointer)
 {
     Reset();
     Pointer = pointer;
 }
 public override void DwellCanceled(IMixedRealityPointer pointer)
 {
     base.DwellCanceled(pointer);
     buttonBackground.color = isDwellEnabled ? this.dwellOnColor : this.dwellOffColor;
     cancelStartScale       = dwellVisualImage.transform.localScale.x;
 }
 public override void DwellCompleted(IMixedRealityPointer pointer)
 {
     base.DwellCompleted(pointer);
     dwellVisualImage.transform.localScale = Vector3.zero;
 }
 public override void DwellIntended(IMixedRealityPointer pointer)
 {
     buttonBackground.color = dwellIntendedColor;
     dwellVisualImage.transform.localScale = Vector3.zero;
 }
示例#13
0
 /// <inheritdoc />
 public bool IsPointerRegistered(IMixedRealityPointer pointer)
 {
     Debug.Assert(pointer.PointerId != 0, $"{pointer} does not have a valid pointer id!");
     return(TryGetPointerData(pointer, out PointerData _));
 }
示例#14
0
 /// <inheritdoc/>
 public override void DwellCompleted(IMixedRealityPointer pointer)
 {
     base.DwellCompleted(pointer);
     buttonBackground.material.color = isDwellEnabled ? this.dwellOnColor : this.dwellOffColor;
 }
示例#15
0
 public void OnTouchCompleted(HandTrackingInputEventData eventData)
 {
     _panningPointer = null;
 }
 public PointerData(IMixedRealityPointer pointer)
 {
     Pointer = pointer;
 }
示例#17
0
 public void OnPointerUp(MixedRealityPointerEventData eventData)
 {
     _panningPointer = null;
 }
        /// <summary>
        /// Perform a scene query to determine which scene objects with a collider is currently being gazed at, if any.
        /// </summary>
        /// <param name="pointerData"></param>
        /// <param name="prioritizedLayerMasks"></param>
        private static void QueryScene(IMixedRealityPointer pointer, LayerMask[] prioritizedLayerMasks, PointerHitResult hit)
        {
            float      rayStartDistance = 0;
            RaycastHit physicsHit;

            RayStep[] pointerRays = pointer.Rays;

            if (pointerRays == null)
            {
                Debug.LogError($"No valid rays for {pointer.PointerName} pointer.");
                return;
            }

            if (pointerRays.Length <= 0)
            {
                Debug.LogError($"No valid rays for {pointer.PointerName} pointer");
                return;
            }

            // Perform query for each step in the pointing source
            for (int i = 0; i < pointerRays.Length; i++)
            {
                switch (pointer.SceneQueryType)
                {
                case SceneQueryType.SimpleRaycast:
                    if (MixedRealityRaycaster.RaycastSimplePhysicsStep(pointerRays[i], prioritizedLayerMasks, out physicsHit))
                    {
                        UpdatePointerRayOnHit(pointerRays, physicsHit, i, rayStartDistance, hit);
                        return;
                    }
                    break;

                case SceneQueryType.BoxRaycast:
                    Debug.LogWarning("Box Raycasting Mode not supported for pointers.");
                    break;

                case SceneQueryType.SphereCast:
                    if (MixedRealityRaycaster.RaycastSpherePhysicsStep(pointerRays[i], pointer.SphereCastRadius, prioritizedLayerMasks, out physicsHit))
                    {
                        UpdatePointerRayOnHit(pointerRays, physicsHit, i, rayStartDistance, hit);
                        return;
                    }
                    break;

                case SceneQueryType.SphereOverlap:
                    Collider[] colliders = UnityEngine.Physics.OverlapSphere(pointer.Rays[i].Origin, pointer.SphereCastRadius, ~UnityEngine.Physics.IgnoreRaycastLayer);

                    if (colliders.Length > 0)
                    {
                        Vector3    testPoint       = pointer.Rays[i].Origin;
                        GameObject closest         = null;
                        float      closestDistance = Mathf.Infinity;
                        Vector3    objectHitPoint  = testPoint;

                        foreach (Collider collider in colliders)
                        {
                            // Policy: in order for an collider to be near interactable it must have
                            // a NearInteractionGrabbable component on it.
                            // FIXME: This is assuming only the grab pointer is using SceneQueryType.SphereOverlap,
                            //        but there may be other pointers using the same query type which have different semantics.
                            if (collider.GetComponent <NearInteractionGrabbable>() == null)
                            {
                                continue;
                            }
                            // From https://docs.unity3d.com/ScriptReference/Collider.ClosestPoint.html
                            // If location is in the collider the closestPoint will be inside.
                            Vector3 closestPointToCollider = collider.ClosestPoint(testPoint);
                            float   distance = (testPoint - closestPointToCollider).sqrMagnitude;
                            if (distance < closestDistance)
                            {
                                closestDistance = distance;
                                closest         = collider.gameObject;
                                objectHitPoint  = closestPointToCollider;
                            }
                        }
                        if (closest != null)
                        {
                            hit.Set(closest, objectHitPoint, Vector3.zero, pointer.Rays[i], 0, closestDistance);
                            return;
                        }
                    }
                    break;

                default:
                    Debug.LogError($"Invalid raycast mode {pointer.SceneQueryType} for {pointer.PointerName} pointer.");
                    break;
                }

                rayStartDistance += pointer.Rays[i].Length;
            }
        }
示例#19
0
 private bool Equals(IMixedRealityPointer other)
 {
     return(other != null && PointerId == other.PointerId && string.Equals(PointerName, other.PointerName));
 }
 /// <summary>
 /// Function called when entering dwell canceled state
 /// </summary>
 public virtual void DwellCanceled(IMixedRealityPointer pointer)
 {
     IsDwelling = false;
 }
 /// <summary>
 /// Function called when entering dwell intended state
 /// </summary>
 public virtual void DwellIntended(IMixedRealityPointer pointer)
 {
 }
示例#22
0
 /// <inheritdoc/>
 public override void DwellStarted(IMixedRealityPointer pointer)
 {
     base.DwellStarted(pointer);
     buttonBackground.material.color = dwellIntendedColor;
 }