Example #1
0
    public ConvergenceInfo(Convergence con)
    {
        FirstTime      = con.TimeOccurred;
        TowersInvolved = new int[con.OrbitersCount];
        int i = 0;

        foreach (var o in con)
        {
            var tower = o.gameObject.GetComponent <TowerBehavior>();
            if (tower != null)
            {
                TowersInvolved[i] = tower.Index;
            }
            i++;
        }
    }
Example #2
0
    public void Tick()
    {
#if TOBIIXR_HTCPROVIDER
        _hmdToWorldTransformer.Tick();
        EnsureHTCFrameworkRunning();

        if (SRanipal_Eye_Framework.Status != SRanipal_Eye_Framework.FrameworkStatus.WORKING)
        {
            return;
        }

        EyeTrackingData.Timestamp       = Time.unscaledTime;
        EyeTrackingData.GazeRay.IsValid = SRanipal_Eye.GetGazeRay(GazeIndex.COMBINE, out EyeTrackingData.GazeRay.Origin, out EyeTrackingData.GazeRay.Direction);

        // Blink
        float eyeOpenness        = 0;
        var   eyeOpennessIsValid = SRanipal_Eye.GetEyeOpenness(EyeIndex.LEFT, out eyeOpenness);
        EyeTrackingData.IsLeftEyeBlinking = !eyeOpennessIsValid || eyeOpenness < 0.1;
        eyeOpennessIsValid = SRanipal_Eye.GetEyeOpenness(EyeIndex.RIGHT, out eyeOpenness);
        EyeTrackingData.IsRightEyeBlinking = !eyeOpennessIsValid || eyeOpenness < 0.1;

        // Convergence distance
        Vector3 leftRayOrigin, rightRayOrigin, leftRayDirection, rightRayDirection;
        var     leftRayValid  = SRanipal_Eye.GetGazeRay(GazeIndex.LEFT, out leftRayOrigin, out leftRayDirection);
        var     rightRayValid = SRanipal_Eye.GetGazeRay(GazeIndex.RIGHT, out rightRayOrigin, out rightRayDirection);

        if (leftRayValid && rightRayValid)
        {
            EyeTrackingData.ConvergenceDistanceIsValid = true;
            var convergenceDistance_mm = Convergence.CalculateDistance(
                leftRayOrigin * 1000f,
                leftRayDirection,
                rightRayOrigin * 1000f,
                rightRayDirection
                );
            EyeTrackingData.ConvergenceDistance = convergenceDistance_mm / 1000f; // Convert to meters
        }
        else
        {
            EyeTrackingData.ConvergenceDistanceIsValid = false;
        }

        // Transform to world space
        _localToWorldMatrix = _hmdToWorldTransformer.GetLocalToWorldMatrix();
        EyeTrackingDataHelper.TransformGazeData(EyeTrackingData, _localToWorldMatrix);
#endif
    }
Example #3
0
    public void Tick()
    {
        _hmdToWorldTransformer.Tick();
        EnsureHTCFrameworkRunning();

        if (SRanipal_Eye_Framework.Status != SRanipal_Eye_Framework.FrameworkStatus.WORKING)
        {
            return;
        }

        _eyeTrackingDataLocal.Timestamp       = Time.unscaledTime;
        _eyeTrackingDataLocal.GazeRay.IsValid = SRanipal_Eye.GetGazeRay(GazeIndex.COMBINE, out _eyeTrackingDataLocal.GazeRay.Origin, out _eyeTrackingDataLocal.GazeRay.Direction);

        // Blink
        float eyeOpenness;
        var   eyeOpennessIsValid = SRanipal_Eye.GetEyeOpenness(EyeIndex.LEFT, out eyeOpenness);

        _eyeTrackingDataLocal.IsLeftEyeBlinking = !eyeOpennessIsValid || eyeOpenness < 0.1;
        eyeOpennessIsValid = SRanipal_Eye.GetEyeOpenness(EyeIndex.RIGHT, out eyeOpenness);
        _eyeTrackingDataLocal.IsRightEyeBlinking = !eyeOpennessIsValid || eyeOpenness < 0.1;

        // Convergence distance
        Vector3 leftRayOrigin, rightRayOrigin, leftRayDirection, rightRayDirection;
        var     leftRayValid  = SRanipal_Eye.GetGazeRay(GazeIndex.LEFT, out leftRayOrigin, out leftRayDirection);
        var     rightRayValid = SRanipal_Eye.GetGazeRay(GazeIndex.RIGHT, out rightRayOrigin, out rightRayDirection);

        if (leftRayValid && rightRayValid)
        {
            _eyeTrackingDataLocal.ConvergenceDistanceIsValid = true;
            var convergenceDistance_mm = Convergence.CalculateDistance(
                leftRayOrigin * 1000f,
                leftRayDirection,
                rightRayOrigin * 1000f,
                rightRayDirection
                );
            _eyeTrackingDataLocal.ConvergenceDistance = convergenceDistance_mm / 1000f; // Convert to meters
        }
        else
        {
            _eyeTrackingDataLocal.ConvergenceDistanceIsValid = false;
        }

        // Update world transform
        _hmdToWorldTransformer.Tick();
        _localToWorldMatrix = _hmdToWorldTransformer.GetLocalToWorldMatrix();
    }
        protected override IterativeStatistics SolveInternal(int maxIterations, Func <IVector> zeroVectorInitializer)
        {
            iteration = 0;
            Preconditioner.SolveLinearSystem(residual, precondResidual);

            // d0 = s0 = inv(M) * r0
            //direction.CopyFrom(precondResidual);
            //Preconditioner.SolveLinearSystem(residual, direction);
            UpdateDirectionVector(precondResidual, direction);

            // q0 = A * d0
            Matrix.Multiply(direction, matrixTimesDirection);
            DirectionTimesMatrixTimesDirection = direction.DotProduct(matrixTimesDirection);

            // Update the direction vectors cache
            ReorthoCache.StoreDirectionData(this);

            // δnew = δ0 = r0 * s0 = r0 * d0
            resDotPrecondRes = residual.DotProduct(direction);

            // The convergence strategy must be initialized immediately after the first r and r*inv(M)*r are computed.
            Convergence.Initialize(this);
            Stagnation.StoreInitialError(Convergence.EstimateResidualNormRatio(this));

            // This is also used as output
            double residualNormRatio = double.NaN;

            // α0 = (d0 * r0) / (d0 * q0) = (s0 * r0) / (d0 * (A * d0))
            stepSize = resDotPrecondRes / DirectionTimesMatrixTimesDirection;

            for (iteration = 1; iteration < maxIterations; ++iteration)
            {
                // x = x + α * d
                solution.AxpyIntoThis(direction, stepSize);

                // Normally the residual vector is updated as: r = r - α * q. However corrections might need to be applied.
                residualUpdater.UpdateResidual(this, residual);

                // s = inv(M) * r
                Preconditioner.SolveLinearSystem(residual, precondResidual);

                // δold = δnew
                resDotPrecondResOld = resDotPrecondRes;

                // δnew = r * s
                resDotPrecondRes = residual.DotProduct(precondResidual);

                /// At this point we can check if CG has converged and exit, thus avoiding the uneccesary operations that follow.
                residualNormRatio = Convergence.EstimateResidualNormRatio(this);
                //Debug.WriteLine($"Reorthogonalized PCG iteration = {iteration}: residual norm ratio = {residualNormRatio}");
                Stagnation.StoreNewError(residualNormRatio);
                bool hasStagnated = Stagnation.HasStagnated();
                if (residualNormRatio <= ResidualTolerance)
                {
                    return(new IterativeStatistics
                    {
                        AlgorithmName = name,
                        HasConverged = true,
                        HasStagnated = false,
                        NumIterationsRequired = iteration + 1,
                        ResidualNormRatioEstimation = residualNormRatio
                    });
                }
                if (hasStagnated)
                {
                    return(new IterativeStatistics
                    {
                        AlgorithmName = name,
                        HasConverged = false,
                        HasStagnated = true,
                        NumIterationsRequired = iteration + 1,
                        ResidualNormRatioEstimation = residualNormRatio
                    });
                }

                // Update the direction vector using previous cached direction vectors.
                UpdateDirectionVector(precondResidual, direction);

                // q = A * d
                Matrix.Multiply(direction, matrixTimesDirection);
                DirectionTimesMatrixTimesDirection = direction.DotProduct(matrixTimesDirection);

                // Update the direction vectors cache
                ReorthoCache.StoreDirectionData(this);

                // α = (d * r) / (d * q) = (d * r) / (d * (A * d))
                stepSize = direction.DotProduct(residual) / DirectionTimesMatrixTimesDirection;
            }

            // We reached the max iterations before PCG converged
            return(new IterativeStatistics
            {
                AlgorithmName = name,
                HasConverged = false,
                HasStagnated = false,
                NumIterationsRequired = maxIterations,
                ResidualNormRatioEstimation = residualNormRatio
            });
        }