<commit_before>﻿// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using Microsoft.MixedReality.Toolkit.Physics;
using UnityEngine;

namespace Microsoft.MixedReality.Toolkit.Input
{
    public class PokePointer : BaseControllerPointer, IMixedRealityNearPointer
    {
        [SerializeField]
        protected LineRenderer line;

        [SerializeField]
        protected GameObject visuals;
        
        private float closestDistance = 0.0f;

        private Vector3 closestNormal = Vector3.forward;

        // The closest touchable component limits the set of objects which are currently touchable.
        // These are all the game objects in the subtree of the closest touchable component's owner object.
        private BaseNearInteractionTouchable closestProximityTouchable = null;
        // The current object that is being touched. We need to make sure to consistently fire 
        // poke-down / poke-up events for this object. This is also the case when the object within
        // the same current closest touchable component's changes (e.g. Unity UI control elements).
        private GameObject currentTouchableObjectDown = null;

        protected void OnValidate()
        {
            Debug.Assert(line != null, this);
            Debug.Assert(visuals != null, this);
        }

        public bool IsNearObject
        {
            get { return (closestProximityTouchable != null); }
        }

        public override void OnPreSceneQuery()
        {
            if (Rays == null)
            {
                Rays = new RayStep[1];
            }

            closestNormal = Rotation * Vector3.forward;

            // Check proximity
            BaseNearInteractionTouchable newClosestTouchable = null;
            {
                closestDistance = float.PositiveInfinity;
                foreach (var prox in BaseNearInteractionTouchable.Instances)
                {
                    if (prox.ColliderEnabled)
                    {
                        Vector3 normal;
                        float dist = prox.DistanceToTouchable(Position, out normal);
                        if (dist < closestDistance)
                        {   
                            closestDistance = dist;
                            newClosestTouchable = prox;
                            closestNormal = normal;
                        }
                    }
                }
            }

            if (newClosestTouchable != null)
            {
                // Build ray (poke from in front to the back of the pointer position)
                Vector3 start = Position - newClosestTouchable.DistBack * -closestNormal;
                Vector3 end = Position + newClosestTouchable.DistFront * -closestNormal;
                Rays[0].UpdateRayStep(ref start, ref end);

                line.SetPosition(0, Position);
                line.SetPosition(1, end);
            }

            // Check if the currently touched object is still part of the new touchable.
            if (currentTouchableObjectDown != null)
            {
                if (!IsObjectPartOfTouchable(currentTouchableObjectDown, newClosestTouchable))
                {
                    TryRaisePokeUp(Result.CurrentPointerTarget, Position);
                }
            }

            // Set new touchable only now: If we have to raise a poke-up event for the previous touchable object,
            // we need to do so using the previous touchable in TryRaisePokeUp().<commit_msg>Add check to assure that closestProximityTouchable is at least distFront away<commit_after>﻿// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using Microsoft.MixedReality.Toolkit.Physics;
using UnityEngine;

namespace Microsoft.MixedReality.Toolkit.Input
{
    public class PokePointer : BaseControllerPointer, IMixedRealityNearPointer
    {
        [SerializeField]
        protected LineRenderer line;

        [SerializeField]
        protected GameObject visuals;
        
        private float closestDistance = 0.0f;

        private Vector3 closestNormal = Vector3.forward;

        // The closest touchable component limits the set of objects which are currently touchable.
        // These are all the game objects in the subtree of the closest touchable component's owner object.
        private BaseNearInteractionTouchable closestProximityTouchable = null;
        // The current object that is being touched. We need to make sure to consistently fire 
        // poke-down / poke-up events for this object. This is also the case when the object within
        // the same current closest touchable component's changes (e.g. Unity UI control elements).
        private GameObject currentTouchableObjectDown = null;

        protected void OnValidate()
        {
            Debug.Assert(line != null, this);
            Debug.Assert(visuals != null, this);
        }

        public bool IsNearObject
        {
            get { return (closestProximityTouchable != null); }
        }

        public override void OnPreSceneQuery()
        {
            if (Rays == null)
            {
                Rays = new RayStep[1];
            }

            closestNormal = Rotation * Vector3.forward;

            // Check proximity
            BaseNearInteractionTouchable newClosestTouchable = null;
            {
                closestDistance = float.PositiveInfinity;
                foreach (var prox in BaseNearInteractionTouchable.Instances)
                {
                    if (prox.ColliderEnabled)
                    {
                        Vector3 normal;
                        float dist = prox.DistanceToTouchable(Position, out normal);
                        if (dist < prox.DistFront && dist < closestDistance)
                        {   
                            closestDistance = dist;
                            newClosestTouchable = prox;
                            closestNormal = normal;
                        }
                    }
                }
            }

            if (newClosestTouchable != null)
            {
                // Build ray (poke from in front to the back of the pointer position)
                Vector3 start = Position - newClosestTouchable.DistBack * -closestNormal;
                Vector3 end = Position + newClosestTouchable.DistFront * -closestNormal;
                Rays[0].UpdateRayStep(ref start, ref end);

                line.SetPosition(0, Position);
                line.SetPosition(1, end);
            }

            // Check if the currently touched object is still part of the new touchable.
            if (currentTouchableObjectDown != null)
            {
                if (!IsObjectPartOfTouchable(currentTouchableObjectDown, newClosestTouchable))
                {
                    TryRaisePokeUp(Result.CurrentPointerTarget, Position);
                }
            }

            // Set new touchable only now: If we have to raise a poke-up event for the previous touchable object,
            // we need to do so using the previous touchable in TryRaisePokeUp().
{'fraction_non_alphanumeric': 0.060514372163388806, 'fraction_numerical': 0.003300783936184844, 'mean_word_length': 1.6774668630338734, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3958554', 'n_tokens_mistral': 1747, 'n_tokens_neox': 1661, 'n_words': 553}