/** * Helper function for calibration setup. * This will perform the following procedures * * 1) Initialize eye tracking calibration * 2) Ensure Vive Tracker for Headset and Vive Controllers are connected * 3) Prompt to calibrate FOVE headset to Vive space (Press H) * 4) Load initial scene (Scene_000) if everything is completed */ private void RunCalibrationSetup() { if (eyeTrackerCalibrationStarted == false) { FoveInterface.EnsureEyeTrackingCalibration(); eyeTrackerCalibrationStarted = true; } if (RenderSettings.skybox != defaultSkyboxMaterial) { RenderSettings.skybox = defaultSkyboxMaterial; } bool eyeTrackerCalibrated = (!FoveInterface.IsEyeTrackingCalibrating() && FoveInterface.IsEyeTrackingCalibrated()); bool headsetCalibrated = headsetLocalizationInstance.IsHeadsetCalibrated(); bool viveTrackerHeadsetConnected = headsetLocalizationInstance.IsHeadsetPositionTracked(); bool controllersConnected = headsetLocalizationInstance.IsControllersConnected(); string uiPromptMessage = ""; if (viveTrackerHeadsetConnected == false) { uiPromptMessage += "Please turn on Vive Tracker for headset.\n"; } if (controllersConnected == false) { uiPromptMessage += "Please connect both Vive controllers.\n"; } if (eyeTrackerCalibrated == false) { uiPromptMessage += "Please calibrate eye tracking.\n"; } if (headsetCalibrated == false) { uiPromptMessage += "Please calibrate headset and vive to world space [H]\n"; } uiPrompt.SetUiPromptMessage(uiPromptMessage); uiPrompt.TurnOnUiPrompt(); if (eyeTrackerCalibrated && headsetCalibrated) { systemCalibrated = true; uiPrompt.TurnOffUiPrompt(); // Initialize a new scene headsetLocalizationInstance.ReCenterUser(); eyeTrackerInstance.CreateNewScene(GenerateSceneName(currentSceneNumber)); SceneManager.LoadSceneAsync(GenerateSceneName(currentSceneNumber), LoadSceneMode.Additive); ChangeSkybox(currentSceneNumber); currentSceneState = SCENE_CHANGE_STATE.Changing; } }
/** * Initialize the experiment * * This function will initiate a setup procedure for the fove vive setup, which includes * calibrating the FOVE headset to vive space and calibrating FOVE's eye tracking. It * will also create a logging instance to track which object the user is looking at. */ void Start() { // Initialize variables systemCalibrated = false; eyeTrackerCalibrationStarted = false; currentSceneNumber = 0; currentSceneState = SCENE_CHANGE_STATE.NotChanging; nextAllowedSceneChangeRequestTime = 0; testSubjectName = "TestSubject"; // Create logging directory experimentStartTime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); logDirectory = Directory.GetParent(Application.dataPath) + "/" + logRootDirectory + "/" + experimentStartTime; Directory.CreateDirectory(logDirectory); nextSceneTime = long.MaxValue; if (skipIntro) { systemCalibrated = true; } }
// Update is called once per frame void Update() { // Ensure everything is calibrated before starting experiment if (systemCalibrated == false) { RunCalibrationSetup(); return; } // Ensure that user has entered in the subject's name if (usernameInputGameObject.activeInHierarchy) { return; } // Debug purposes if skipIntro == TRUE. Allow to skip calibration if (skipIntro && (currentSceneNumber == 0)) { currentSceneNumber = 1; uiPrompt.TurnOffUiPrompt(); eyeTrackerInstance.CreateNewScene(GenerateSceneName(currentSceneNumber)); SceneManager.LoadSceneAsync(GenerateSceneName(currentSceneNumber), LoadSceneMode.Additive); ChangeSkybox(currentSceneNumber); currentSceneState = SCENE_CHANGE_STATE.NotChanging; nextSceneTime = DateTime.Now.Ticks + secondsBetweenScene * TimeSpan.TicksPerSecond; } // Check if we should begin transition onto the next scene if (DateTime.Now.Ticks >= nextSceneTime || currentSceneState != SCENE_CHANGE_STATE.NotChanging) { switch (currentSceneState) { // Initiate change scene if we're not at the last scene case SCENE_CHANGE_STATE.NotChanging: if (currentSceneNumber < totalNumberOfScenes) { eyeTrackerInstance.SaveToFile(logDirectory); fadeSceneTime = nextSceneTime; currentSceneState = SCENE_CHANGE_STATE.FadeOut; } break; // Fade scene out case SCENE_CHANGE_STATE.FadeOut: float fadeOutOpacity = 1.0f - ((float)(DateTime.Now.Ticks - fadeSceneTime)) / ((float)(fadeOutDuration * TimeSpan.TicksPerSecond)); fadeOutOpacity = Math.Max(0.0f, fadeOutOpacity); cameraFadeInstance.setOpacity(fadeOutOpacity); if (fadeOutOpacity == 0.0f) { currentSceneState = SCENE_CHANGE_STATE.InitiateChange; } break; // Tell program to start changing scene case SCENE_CHANGE_STATE.InitiateChange: headsetLocalizationInstance.ReCenterUser(); headsetLocalizationInstance.RotatePerson(0.0f); SceneManager.UnloadSceneAsync(GenerateSceneName(currentSceneNumber)); currentSceneNumber++; if (currentSceneNumber < totalNumberOfScenes) { SceneManager.LoadSceneAsync(GenerateSceneName(currentSceneNumber), LoadSceneMode.Additive); ChangeSkybox(currentSceneNumber); currentSceneState = SCENE_CHANGE_STATE.Changing; } else { ChangeSkybox(-1); uiPrompt.SetUiPromptMessage("Session has ended."); uiPrompt.TurnOnUiPrompt(); fadeSceneTime = DateTime.Now.Ticks; currentSceneState = SCENE_CHANGE_STATE.FadeIn; } break; // Wait for scene to finish loading case SCENE_CHANGE_STATE.Changing: if (SceneManager.GetSceneByName(GenerateSceneName(currentSceneNumber)).isLoaded) { fadeSceneTime = DateTime.Now.Ticks; currentSceneState = SCENE_CHANGE_STATE.FadeIn; } break; // Fade back in case SCENE_CHANGE_STATE.FadeIn: float fadeInOpacity = ((float)(DateTime.Now.Ticks - fadeSceneTime)) / ((float)(fadeOutDuration * TimeSpan.TicksPerSecond)); fadeInOpacity = Math.Min(1.0f, fadeInOpacity); cameraFadeInstance.setOpacity(fadeInOpacity); if (fadeInOpacity == 1.0f) { eyeTrackerInstance.CreateNewScene(GenerateSceneName(currentSceneNumber)); currentSceneState = SCENE_CHANGE_STATE.NotChanging; if (nextSceneTime <= DateTime.Now.Ticks) { nextSceneTime = DateTime.Now.Ticks + secondsBetweenScene * TimeSpan.TicksPerSecond; } } break; } } // Allow change to next scene if (Input.GetKeyDown(KeyCode.N)) { ChangeToNextScene(); } }