using Godot;
namespace EyeTracking
{
///
/// Handles eye convergence logic to create more natural gaze behavior
/// by reducing individual eye deviations and promoting coordinated eye movement
///
public static class EyeConvergence
{
///
/// Apply convergence logic to reduce individual eye deviations and create more natural gaze behavior
///
/// Left eye gaze vector
/// Right eye gaze vector
/// Strength of convergence (0.0 = no convergence, 1.0 = full convergence)
/// Tuple of converged left and right gaze vectors
public static (Vector2 leftGaze, Vector2 rightGaze) ApplyConvergence(Vector2 leftGaze, Vector2 rightGaze, float convergenceStrength = 0.5f)
{
// Calculate the average gaze direction (where both eyes should converge)
Vector2 averageGaze = new Vector2(
(leftGaze.X + rightGaze.X) * 0.5f,
(leftGaze.Y + rightGaze.Y) * 0.5f
);
// Calculate the individual eye deviations from the average
Vector2 leftDeviation = new Vector2(
leftGaze.X - averageGaze.X,
leftGaze.Y - averageGaze.Y
);
Vector2 rightDeviation = new Vector2(
rightGaze.X - averageGaze.X,
rightGaze.Y - averageGaze.Y
);
// Detect cross-eyed gaze (eyes pointing toward each other)
bool isCrossEyed = (leftGaze.X > 0.1f && rightGaze.X < -0.1f);
// For cross-eyed gaze, preserve more of the original individual characteristics
float effectiveConvergenceStrength = isCrossEyed ? convergenceStrength * 0.3f : convergenceStrength;
// Apply convergence strength to reduce individual deviations
Vector2 convergedLeft = new Vector2(
averageGaze.X + leftDeviation.X * (1.0f - effectiveConvergenceStrength),
averageGaze.Y + leftDeviation.Y * (1.0f - effectiveConvergenceStrength)
);
Vector2 convergedRight = new Vector2(
averageGaze.X + rightDeviation.X * (1.0f - effectiveConvergenceStrength),
averageGaze.Y + rightDeviation.Y * (1.0f - effectiveConvergenceStrength)
);
return (convergedLeft, convergedRight);
}
}
}