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