nightshade 0.8.0

A cross-platform data-oriented game engine.
Documentation
use super::{ComponentInspector, InspectorContext, impl_simple_inspector};
use crate::prelude::*;

fn camera_ui(
    world: &mut World,
    entity: Entity,
    ui: &mut egui::Ui,
    _context: &mut InspectorContext,
) {
    if let Some(camera) = world.get_camera_mut(entity) {
        let is_perspective = matches!(camera.projection, Projection::Perspective(_));

        ui.horizontal(|ui| {
            ui.label("Projection:");
            if ui.selectable_label(is_perspective, "Perspective").clicked() && !is_perspective {
                camera.projection = Projection::Perspective(PerspectiveCamera::default());
            }
            if ui
                .selectable_label(!is_perspective, "Orthographic")
                .clicked()
                && is_perspective
            {
                camera.projection = Projection::Orthographic(OrthographicCamera::default());
            }
        });

        ui.separator();

        match &mut camera.projection {
            Projection::Perspective(perspective) => {
                ui.label("Field of View:");
                let mut fov_degrees = perspective.y_fov_rad.to_degrees();
                if ui
                    .add(egui::Slider::new(&mut fov_degrees, 1.0..=120.0).suffix("°"))
                    .changed()
                {
                    perspective.y_fov_rad = fov_degrees.to_radians();
                }

                ui.label("Near Plane:");
                ui.add(egui::DragValue::new(&mut perspective.z_near).speed(0.01));

                ui.horizontal(|ui| {
                    let mut has_far = perspective.z_far.is_some();
                    if ui.checkbox(&mut has_far, "Far Plane:").changed() {
                        perspective.z_far = if has_far { Some(1000.0) } else { None };
                    }

                    if let Some(ref mut z_far) = perspective.z_far {
                        ui.add(egui::DragValue::new(z_far).speed(1.0));
                    }
                });
            }
            Projection::Orthographic(orthographic) => {
                ui.label("Width:");
                ui.add(egui::DragValue::new(&mut orthographic.x_mag).speed(0.1));

                ui.label("Height:");
                ui.add(egui::DragValue::new(&mut orthographic.y_mag).speed(0.1));

                ui.label("Near Plane:");
                ui.add(egui::DragValue::new(&mut orthographic.z_near).speed(0.1));

                ui.label("Far Plane:");
                ui.add(egui::DragValue::new(&mut orthographic.z_far).speed(1.0));
            }
        }
    }
}

impl_simple_inspector!(
    CameraInspector,
    "Camera",
    entity_has_camera,
    set_camera,
    remove_camera,
    Camera::default(),
    camera_ui
);