scena 1.0.0

A Rust-native scene-graph renderer with typed scene state, glTF assets, and explicit prepare/render lifecycles.
Documentation
use crate::assets::EnvironmentHandle;
use crate::diagnostics::DebugOverlay;
use crate::material::Color;
use crate::picking::InteractionStyle;

use super::{Renderer, Tonemapper};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum Profile {
    #[default]
    Auto,
    Quality,
    Balanced,
    Compatibility,
    Industrial,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum Quality {
    Low,
    #[default]
    Medium,
    High,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum RenderMode {
    #[default]
    Manual,
    OnChange,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct RendererOptions {
    profile: Profile,
    quality: Option<Quality>,
    render_mode: Option<RenderMode>,
}

impl RendererOptions {
    pub const fn with_profile(mut self, profile: Profile) -> Self {
        self.profile = profile;
        self
    }

    pub const fn with_quality(mut self, quality: Quality) -> Self {
        self.quality = Some(quality);
        self
    }

    pub const fn with_render_mode(mut self, render_mode: RenderMode) -> Self {
        self.render_mode = Some(render_mode);
        self
    }

    pub const fn profile(self) -> Profile {
        self.profile
    }

    pub const fn explicit_quality(self) -> Option<Quality> {
        self.quality
    }

    pub const fn explicit_render_mode(self) -> Option<RenderMode> {
        self.render_mode
    }
}

impl Renderer {
    pub fn profile(&self) -> Profile {
        self.profile
    }

    pub fn quality(&self) -> Quality {
        self.quality
    }

    pub fn render_mode(&self) -> RenderMode {
        self.render_mode
    }

    pub fn exposure_ev(&self) -> f32 {
        self.output.exposure_ev()
    }

    pub fn set_exposure_ev(&mut self, exposure_ev: f32) {
        let before = self.output.exposure_ev();
        self.output.set_exposure_ev(exposure_ev);
        if self.output.exposure_ev() != before {
            self.mark_output_changed();
        }
    }

    pub fn tonemapper(&self) -> Tonemapper {
        self.output.tonemapper()
    }

    pub fn set_tonemapper(&mut self, tonemapper: Tonemapper) {
        if self.output.tonemapper() != tonemapper {
            self.output.set_tonemapper(tonemapper);
            self.mark_output_changed();
        }
    }

    pub fn debug_overlay(&self) -> DebugOverlay {
        self.debug_overlay
    }

    pub fn set_debug(&mut self, overlay: DebugOverlay) {
        self.set_debug_overlay(overlay);
    }

    pub fn set_debug_overlay(&mut self, overlay: DebugOverlay) {
        if self.debug_overlay != overlay {
            self.debug_overlay = overlay;
            self.debug_revision = self.debug_revision.saturating_add(1);
        }
    }

    pub fn hover_style(&self) -> InteractionStyle {
        self.hover_style
    }

    pub fn set_hover_style(&mut self, style: InteractionStyle) {
        self.hover_style = style;
    }

    pub fn selection_style(&self) -> InteractionStyle {
        self.selection_style
    }

    pub fn set_selection_style(&mut self, style: InteractionStyle) {
        self.selection_style = style;
    }

    pub fn environment(&self) -> Option<EnvironmentHandle> {
        self.environment
    }

    pub fn set_environment(&mut self, environment: EnvironmentHandle) {
        if self.environment != Some(environment) {
            self.environment = Some(environment);
            self.environment_revision = self.environment_revision.saturating_add(1);
        }
    }

    pub fn clear_environment(&mut self) {
        if self.environment.is_some() {
            self.environment = None;
            self.environment_revision = self.environment_revision.saturating_add(1);
        }
    }

    pub fn background_color(&self) -> Color {
        self.background_color
    }

    pub fn set_background_color(&mut self, color: Color) {
        if self.background_color != color {
            self.background_color = color;
            self.mark_output_changed();
        }
    }

    fn mark_output_changed(&mut self) {
        self.render_generation = self.render_generation.saturating_add(1);
    }
}