kengaai-lod 0.1.1

Level of Detail (LOD) system for KengaAI Engine
Documentation
use glam::Vec3;
use std::collections::HashMap;

/// Уровень детализации модели
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum LodLevel {
    /// Высокая детализация (близко к камере)
    High = 0,
    /// Средняя детализация
    Medium = 1,
    /// Низкая детализация (далеко от камеры)
    Low = 2,
    /// Очень низкая детализация (очень далеко)
    VeryLow = 3,
}

/// Конфигурация LOD для модели
#[derive(Debug, Clone)]
pub struct LodConfig {
    /// Расстояния переключения между уровнями LOD
    pub distances: [f32; 4],
    /// Имена моделей для каждого уровня LOD
    pub model_names: [Option<String>; 4],
}

impl Default for LodConfig {
    fn default() -> Self {
        Self {
            distances: [10.0, 30.0, 60.0, 200.0],
            model_names: [None, None, None, None],
        }
    }
}

/// Менеджер LOD системы
pub struct LodManager {
    /// Конфигурации LOD для каждой модели
    configs: HashMap<String, LodConfig>,
    /// Позиция камеры для расчета расстояний
    camera_position: Vec3,
}

impl LodManager {
    pub fn new() -> Self {
        Self {
            configs: HashMap::new(),
            camera_position: Vec3::ZERO,
        }
    }

    /// Регистрирует модель с LOD конфигурацией
    pub fn register_model(&mut self, model_name: String, config: LodConfig) {
        self.configs.insert(model_name, config);
    }

    /// Обновляет позицию камеры
    pub fn update_camera_position(&mut self, position: Vec3) {
        self.camera_position = position;
    }

    /// Определяет необходимый уровень LOD для модели на основе расстояния до камеры
    pub fn get_lod_level(&self, model_name: &str, model_position: Vec3) -> LodLevel {
        if let Some(config) = self.configs.get(model_name) {
            let distance = model_position.distance(self.camera_position);
            
            if distance < config.distances[0] {
                LodLevel::High
            } else if distance < config.distances[1] {
                LodLevel::Medium
            } else if distance < config.distances[2] {
                LodLevel::Low
            } else {
                LodLevel::VeryLow
            }
        } else {
            // Если модель не зарегистрирована, используем высокий уровень детализации
            LodLevel::High
        }
    }

    /// Получает имя модели для конкретного уровня LOD
    pub fn get_model_name_for_lod(&self, model_name: &str, lod_level: LodLevel) -> Option<String> {
        self.configs
            .get(model_name)
            .and_then(|config| config.model_names[lod_level as usize].clone())
    }

    /// Проверяет, нужно ли переключать LOD для модели
    pub fn should_switch_lod(&self, model_name: &str, current_lod: LodLevel, model_position: Vec3) -> bool {
        let new_lod = self.get_lod_level(model_name, model_position);
        new_lod != current_lod
    }
}

impl Default for LodManager {
    fn default() -> Self {
        Self::new()
    }
}