using Godot; using System; using ETPreferences; using System.Collections.Generic; using OpenCvSharp; public partial class CalibratePupilAlignment : Node { private MeshInstance3D eyeQuad; private XRCamera3D xrCamera; private CameraManager _cameraManager; public override void _Ready() { OpenXRManager.EnableOpenXR(this); // Find the XR camera in the scene xrCamera = GetNode("XROrigin3D/XRCamera3D"); _cameraManager = new CameraManager(); AddChild(_cameraManager); // Start camera initialization InitializeCamera(); EyeTrackingPreferences.ReadSettingsFile(); } private async void InitializeCamera() { await _cameraManager.InitializeCamera(); } public override void _Input(InputEvent @event) { if (@event is InputEventKey keyEvent && keyEvent.Pressed && !keyEvent.Echo) { if (keyEvent.Keycode == Key.Space) { DetectPupils(); SaveToPreferences(); } } } public void DetectPupils() { if (_cameraManager == null || !_cameraManager.IsInitialized) { return; } try { // Get a fresh color frame bool wasGrayscale = _cameraManager.UseGrayscale; _cameraManager.UseGrayscale = false; // Flush buffer by grabbing a few frames to ensure we get the latest Mat colorFrame = null; for (int i = 0; i < 3; i++) { colorFrame?.Dispose(); colorFrame = _cameraManager.GetCameraFrame(); } _cameraManager.UseGrayscale = wasGrayscale; if (colorFrame == null || colorFrame.Empty()) { return; } // Detect pupils List pupils = PupilDetector.FindPupilCenters(colorFrame); // Update preferences if both pupils detected if (pupils.Count == 2) { ET_Preferences.Instance.left_pupil_center_x = pupils[0].X / (float)colorFrame.Width; ET_Preferences.Instance.left_pupil_center_y = pupils[0].Y / (float)colorFrame.Height; ET_Preferences.Instance.right_pupil_center_x = pupils[1].X / (float)colorFrame.Width; ET_Preferences.Instance.right_pupil_center_y = pupils[1].Y / (float)colorFrame.Height; } colorFrame.Dispose(); } catch (Exception ex) { GD.PrintErr($"Error during pupil detection: {ex.Message}"); } } public void SaveToPreferences() { EyeTrackingPreferences.WriteSettingsFile(); } public override void _ExitTree() { if (_cameraManager != null) { _cameraManager.ReleaseCamera(); _cameraManager.QueueFree(); } base._ExitTree(); } }