/// <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"); } } }
/// <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; } }