/// <summary>
    /// This method checks if a relative movement was started by the user.
    /// If started, the relative quaternion start value is set and the gain function reseted.
    /// </summary>
    public void CheckStartOfRelativeMovement()
    {
        Vector3    angularVelocity;
        Quaternion rotation;

        if (HandManager.IsRayRelativeUp())
        {
            foreach (GameObject part in partsVisualRay)
            {
                part.GetComponent <Renderer>().material = rayInactiveMaterial;
            }
        }

        if (HandManager.IsRayRelativeDown())
        {
            if (HandManager.CurrentHand.TryGetRotation(out rotation))
            {
                currentRelativeRotation = Quaternion.identity;
                lastRelativeRotation    = rotation;
                startRelativeQuat       = rotation;
                foreach (GameObject part in partsVisualRay)
                {
                    part.GetComponent <Renderer>().material = rayActiveMaterial;
                }
                if (HandManager.CurrentHand.TryGetAngularVelocity(out angularVelocity))
                {
                    GainFunction.ResetFunction(angularVelocity);
                }
                else
                {
                    GainFunction.ResetFunction(startRelativeQuat, Time.time);
                }
            }
            else
            {
                startRelativeQuat = Quaternion.identity;
                GainFunction.ResetFunction(startRelativeQuat, Time.time);
                Debug.LogError("No start rotation data avaiable.");
                return;
            }
        }

        if (HandManager.IsRayRelative() || HandManager.IsRayRelativeUp())
        {
            if (HandManager.CurrentHand.TryGetAngularVelocity(out angularVelocity))
            {
                GainFunction.Instance.UpdateFunction(Mathf.Rad2Deg * angularVelocity.magnitude);
            }
            else if (HandManager.CurrentHand.TryGetRotation(out rotation))
            {
                GainFunction.Instance.UpdateFunction(rotation, Time.time);
            }
            else
            {
                Debug.LogError("No velocity and rotation data avaiable");
            }
        }
    }
Пример #2
0
    /// <summary>
    /// This method evalutes if the button was released and which object was clicked.
    /// A delay is included to avoid false clicks due to movement while perfoming the click.
    /// </summary>
    private void CheckLeftClick()
    {
        if (HandManager.IsRayRelativeUp())
        {
            if (TargetManager.IsAnyObjectAttached())
            {
                TargetManager.DetachTargetFromDepthMarker();
                targetsInFoucsSinceLastClickDown = new List <Target>();
                return;
            }
            targetsInFoucsSinceLastClickDown = targetsInFoucsSinceLastClickDown.Distinct().ToList();

            GameObject clickedObj = currentFocusedObject;

            // If current object in focus is null
            // check if there is some older object in the list of targets since last click down
            // There we also check if the velocity was over a threshold and if so no click is made
            // Afterwards send event OnLeftClick
            if (currentFocusedObject == null &&
                targetsInFoucsSinceLastClickDown.Count == 1 && targetsInFoucsSinceLastClickDown[0] != null)
            {
                Target target = targetsInFoucsSinceLastClickDown[0];
                if (target.LastTimeInFocus > Time.time - VariablesManager.DelayClickTime)
                {
                    if (!velocityHandler.VelocityWasOverThSinceTimeStemp(target.LastTimeInFocus))
                    {
                        clickedObj = target.gameObject;
                        Logger.ClickCorrectionUsed(1);
                    }
                }
            }
            else if (currentFocusedObject == null && targetsInFoucsSinceLastClickDown.Count > 1)
            {
                float timeStempWithMinVel = velocityHandler.FindTimeStepWithMinVel();

                Target targetClosestToTimeStemp = null;
                float  timeDifference           = float.MaxValue;
                foreach (Target target in targetsInFoucsSinceLastClickDown)
                {
                    if (Mathf.Abs(target.LastTimeInFocus - timeStempWithMinVel) < timeDifference && target.LastTimeInFocus > Time.time - VariablesManager.DelayClickTime)
                    {
                        timeDifference           = Mathf.Abs(target.LastTimeInFocus - timeStempWithMinVel);
                        targetClosestToTimeStemp = target;
                    }
                }
                if (targetClosestToTimeStemp != null)
                {
                    clickedObj = targetClosestToTimeStemp.gameObject;
                    Logger.ClickCorrectionUsed(2);
                }
            }

            OnLeftClick(clickedObj);
            //Reset list
            targetsInFoucsSinceLastClickDown = new List <Target>();
        }
    }
    /// <summary>
    /// This method sets and updates the rays from the head into the scene.
    /// The gaze direction is changed when the relative movement is active.
    /// Then the direction is steered by the controller or myo armband.
    /// </summary>
    public virtual void OnPreRaycast()
    {
        Vector3 forward;
        Vector3 position;

        switch (VariablesManager.InputMode)
        {
        case InputMode.HeadMyoHybrid:
        case InputMode.HeadHybrid:
            if (head == null)
            {
                rays[0] = default(RayStep);
            }
            else if (HandManager.IsRayRelative() || HandManager.IsRayRelativeUp())
            {
                Quaternion quat;
                if (HandManager.CurrentHand.TryGetRotation(out quat))
                {
                    SetRays(quat);
                }
            }
            else
            {
                SetRaysWithHeadAsOrigin(head.transform.forward);
            }
            break;

        /*case InputMode.RayHeadOrigin:
         *  if (HandManager.RayHand.TryGetForward(out forward))
         *  {
         *      SetRaysWithHeadAsOrigin(forward);
         *  }
         *  break;*/
        case InputMode.RayControllerOrigin:
            if (HandManager.CurrentHand.TryGetForward(out forward) && HandManager.CurrentHand.TryGetPos(out position))
            {
                SetRays(forward, position);
            }
            break;
        }
    }