use super::context::CameraMode;
use nightshade::prelude::*;
#[derive(Clone, Copy, PartialEq)]
pub enum CameraView {
Front,
Right,
Top,
}
pub fn set_camera_view(world: &mut World, view: CameraView) {
let Some(camera_entity) = world.resources.active_camera else {
return;
};
let Some(pan_orbit) = world.core.get_pan_orbit_camera_mut(camera_entity) else {
return;
};
let (yaw, pitch) = match view {
CameraView::Front => (0.0, 0.0),
CameraView::Right => (std::f32::consts::FRAC_PI_2, 0.0),
CameraView::Top => (0.0, std::f32::consts::FRAC_PI_2 - 0.001),
};
pan_orbit.target_yaw = yaw;
pan_orbit.target_pitch = pitch;
}
pub fn toggle_camera_orthographic(world: &mut World) {
use nightshade::ecs::camera::components::{OrthographicCamera, PerspectiveCamera};
let Some(camera_entity) = world.resources.active_camera else {
return;
};
let camera_distance = world
.core
.get_pan_orbit_camera(camera_entity)
.map(|orbit| orbit.radius)
.unwrap_or(10.0);
let Some(camera) = world.core.get_camera_mut(camera_entity) else {
return;
};
camera.projection = match &camera.projection {
Projection::Perspective(persp) => {
let half_height = camera_distance * (persp.y_fov_rad * 0.5).tan();
let aspect = persp.aspect_ratio.unwrap_or(16.0 / 9.0);
let half_width = half_height * aspect;
Projection::Orthographic(OrthographicCamera {
x_mag: half_width,
y_mag: half_height,
z_near: persp.z_near,
z_far: persp.z_far.unwrap_or(1000.0),
})
}
Projection::Orthographic(ortho) => Projection::Perspective(PerspectiveCamera {
y_fov_rad: 45.0_f32.to_radians(),
aspect_ratio: None,
z_near: ortho.z_near,
z_far: Some(ortho.z_far),
}),
};
}
pub fn toggle_camera_mode(world: &mut World, camera_mode: &mut CameraMode) {
let Some(camera_entity) = world.resources.active_camera else {
return;
};
match *camera_mode {
CameraMode::Orbit => {
if let Some(camera) = world.core.get_camera_mut(camera_entity) {
camera.smoothing = Some(nightshade::ecs::camera::components::Smoothing::default());
}
*camera_mode = CameraMode::Fly;
}
CameraMode::Fly => {
if let Some(camera) = world.core.get_camera_mut(camera_entity) {
camera.smoothing = None;
}
let (position, forward) =
if let Some(transform) = world.core.get_local_transform(camera_entity) {
(transform.translation, transform.forward_vector())
} else {
(Vec3::zeros(), nalgebra_glm::vec3(0.0, 0.0, -1.0))
};
let focus = position + forward * 5.0;
let direction = position - focus;
let radius = nalgebra_glm::length(&direction);
let horizontal = nalgebra_glm::vec3(direction.x, 0.0, direction.z);
let yaw = horizontal.x.atan2(horizontal.z);
let pitch = (direction.y / radius).asin();
if let Some(pan_orbit) = world.core.get_pan_orbit_camera_mut(camera_entity) {
pan_orbit.focus = focus;
pan_orbit.target_focus = focus;
pan_orbit.radius = radius;
pan_orbit.target_radius = radius;
pan_orbit.yaw = yaw;
pan_orbit.target_yaw = yaw;
pan_orbit.pitch = pitch;
pan_orbit.target_pitch = pitch;
}
*camera_mode = CameraMode::Orbit;
}
}
}
pub fn is_mouse_in_selected_viewport(world: &World) -> bool {
if let Some(viewport_rect) = &world.resources.window.active_viewport_rect {
let mouse_pos = world.resources.input.mouse.position;
return viewport_rect.contains(mouse_pos);
}
true
}