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++; } }
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 }
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 }); }