/// <summary>
        /// Generate the points for SLAM initialization that the user has to look at.
        /// TODO: If we go with the current version, only one point will be needed. If we go with the arrow version, all points are needed.
        /// </summary>
        private void Start()
        {
            // build all slam init points for the specified angle and step settings
            // "halfCircleCount * 2" pieces for "fromAngle" to "toAngle"
            // save them in an array
            // then do calibration fromIndex toIndex and use these points (activate/deactivate/show correct graphics/animation/light)

            _slamLocalizer = FindObjectOfType <SlamLocalizer>();

            if (eyeCamera == null)
            {
                eyeCamera = GameObject.Find("StereoCameras").transform;
            }

            if (eyeCamera == null)
            {
                Debug.LogError("Couldn't find stereo cameras!");
            }

            particles.gameObject.SetActive(false);
            leftArrows.gameObject.SetActive(useDirectionArrows);
            rightArrows.gameObject.SetActive(useDirectionArrows);

            var pointCount = useArrowAnimation ? stepCountHalfCircle * 2 : 1;

            pointCount = Mathf.RoundToInt(useArrowAnimation ? (stepCountHalfCircle * 2) : 1);

            _points = new SLAMInitializationGazePoint[pointCount];
            for (int i = 0; i < pointCount; i++)
            {
                var angle = Mathf.Lerp(-180, 180, (float)i / (pointCount + 1));

                SLAMInitializationGazePoint gazePoint = Instantiate(slamInitPrefab);
                gazePoint.EyeCamera               = eyeCamera;
                gazePoint.transform.parent        = transform;
                gazePoint.transform.localPosition = Vector3.zero;
                gazePoint.transform.localRotation = Quaternion.Euler(0, angle, 0);
                gazePoint.requiredLookAtTime      = lookAtTime;

                // initialize and hide these points
                // in non-arrow mode, they are invisible anyways
                gazePoint.direction = 1;
                gazePoint.Activate(false);
                gazePoint.number = i;
                gazePoint.slamUI = this;
                _points[i]       = gazePoint;
            }
        }
        /// <summary>
        /// Shows multiple points at the same time and animates their blinking.
        /// </summary>
        private IEnumerator CalibrateDirectional_Arrows(int fromIndex, int toIndex)
        {
            timeSinceLastPoint = 0;
            direction          = fromIndex > toIndex ? -1 : 1;

            if (useDirectionArrows && leftArrows && rightArrows)
            {
                leftArrows.SetBool("IsOn", direction > 0);
                rightArrows.SetBool("IsOn", direction < 0);
            }

            int i = fromIndex;

            while (i != toIndex)
            {
                Debug.Log("waiting for point " + i);
                SLAMInitializationGazePoint pCurrent = _points[i];

                pCurrent.direction   = -direction;
                pCurrent.allowGazing = true;
                pCurrent.Init();
                pCurrent.Activate(true);

                currentTarget = pCurrent.r.transform;

                // wait until this point is detected (looked at for a minimum time set in the point prefab)
                while (pCurrent.isActive)
                {
                    Debug.DrawLine(Vector3.zero, pCurrent.r.transform.position, Color.green);

                    // check for early-out if slam calibration is fully done already
                    if (CheckForSLAMInitComplete())
                    {
                        timeSinceLastPoint = 0;
                        yield break;
                    }

                    timeSinceLastPoint += Time.unscaledDeltaTime;
                    yield return(null);
                }

                timeSinceLastPoint = 0;
                i += direction;
            }

            // wait for points to fade out
        }
        /// <summary>
        /// Activates a single (invisible) point at a time and moves that around to have the user look at it.
        /// </summary>
        IEnumerator CalibrateDirectional_SinglePoint(int fromIndex, int toIndex)
        {
            timeSinceLastPoint = 0;
            direction          = fromIndex > toIndex ? -1 : 1;
            leftArrows.SetBool("IsOn", direction > 0);
            rightArrows.SetBool("IsOn", direction < 0);

            int i = fromIndex;

            while (i != toIndex)
            {
                SLAMInitializationGazePoint pCurrent = _points[0];

                // set point rotation
                var angle = Mathf.Lerp(fromAngle, toAngle, (float)i / (stepCountHalfCircle * 2 + 1));
                pCurrent.transform.localRotation = Quaternion.Euler(0, angle, 0);

                // set up point for gazing
                pCurrent.direction   = -direction;
                pCurrent.allowGazing = true;
                pCurrent.Init();
                pCurrent.Activate(true);

                currentTarget = pCurrent.r.transform;

                // wait until point has been gazed at for long enough
                while (pCurrent.isActive)
                {
                    // check for early-out if slam calibration is fully done already
                    if (CheckForSLAMInitComplete())
                    {
                        timeSinceLastPoint = 0;
                        yield break;
                    }

                    timeSinceLastPoint += Time.unscaledDeltaTime;
                    yield return(null);
                }

                timeSinceLastPoint = 0;
                i += direction;
            }
        }