/* * SPDX-License-Identifier: AGPL-3.0-or-later * Copyright (C) 2025 Sergej Görzen * This file is part of OmiLAXR. */ using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace OmiLAXR.TrackingBehaviours.Learner.HeadTracking { /// /// Singleton class for tracking HMD position data using the main camera. /// Provides utilities for position sampling and extrema detection. /// public class HmdPosition { /// /// Reference to the main camera for position tracking. /// private readonly Camera _mMainCamera; /// /// Singleton instance holder. /// private static HmdPosition _instance; #if UNITY_2019 /// /// Singleton accessor with lazy initialization for Unity 2019. /// public static HmdPosition Instance { get { if (_instance == null) _instance = new HmdPosition(); return _instance; } } #else /// /// Singleton accessor with null-coalescing assignment for Unity 2020+. /// public static HmdPosition Instance => _instance ??= new HmdPosition(); #endif /// /// Private constructor initializes main camera reference. /// private HmdPosition() { _mMainCamera = Camera.main; } /// /// Gets current HMD position with timestamp. Returns default if no main camera exists. /// public HmdTimedPosition GetHmdPosition() => _mMainCamera != null ? new HmdTimedPosition(DateTime.Now, _mMainCamera.transform.position) : default; /// /// Finds maximum or minimum position in list along specified axis. /// /// "max" for maximum, "min" for minimum /// "x", "y", or "z" axis /// List of positions to search /// Extrema position and its index, or default values if list is empty public (HmdTimedPosition hmdPosition, int index) GetMaxMinPosition(string maxmin, string axis, List list) { if (list.Count > 0) { // Extract axis values from position list var values = new List(); switch (axis) { case "x": values.AddRange(list.Select(pos => pos.Position.x)); break; case "y": values.AddRange(list.Select(pos => pos.Position.y)); break; case "z": values.AddRange(list.Select(pos => pos.Position.z)); break; } switch (maxmin) { // Find maximum value and its index case "max": var maxValue = values.Max(); var maxIndex = values.IndexOf(maxValue); return (list[maxIndex], maxIndex); // Find minimum value and its index case "min": var minValue = values.Min(); var minIndex = values.IndexOf(minValue); return (list[minIndex], minIndex); } } // Return default values if list is empty var defaultHmdPosition = new HmdTimedPosition(); return (defaultHmdPosition, -1); } } }