use amethyst_assets::PrefabData;
use amethyst_core::ecs::{
Component, Entity, HashMapStorage, Join, ReadExpect, System, SystemData, WriteStorage,
};
use amethyst_derive::{PrefabData, SystemDesc};
use amethyst_error::Error;
use amethyst_rendy::camera::Camera;
use amethyst_window::ScreenDimensions;
use serde::{Deserialize, Serialize};
#[cfg(feature = "profiler")]
use thread_profiler::profile_scope;
#[derive(Clone, Debug, Deserialize, PrefabData, Serialize)]
#[prefab(Component)]
#[serde(default)]
pub struct AutoFov {
fov_y: f32,
z_near: f32,
dirty: bool,
}
impl AutoFov {
pub fn new() -> Self {
Default::default()
}
pub fn set_fov(&mut self, fov: f32) {
self.fov_y = fov;
self.dirty = true;
}
pub fn set_near(&mut self, near: f32) {
self.z_near = near;
self.dirty = true;
}
}
impl Default for AutoFov {
fn default() -> Self {
Self {
fov_y: std::f32::consts::FRAC_PI_3,
z_near: 0.125,
dirty: true,
}
}
}
impl Component for AutoFov {
type Storage = HashMapStorage<Self>;
}
#[derive(Debug, SystemDesc)]
pub struct AutoFovSystem {
last_dimensions: ScreenDimensions,
}
impl AutoFovSystem {
pub fn new() -> Self {
Default::default()
}
}
impl<'a> System<'a> for AutoFovSystem {
type SystemData = (
ReadExpect<'a, ScreenDimensions>,
WriteStorage<'a, AutoFov>,
WriteStorage<'a, Camera>,
);
fn run(&mut self, (screen, mut auto_fovs, mut cameras): Self::SystemData) {
#[cfg(feature = "profiler")]
profile_scope!("auto_fov_system");
for (camera, auto_fov) in (&mut cameras, &mut auto_fovs).join() {
if self.last_dimensions != *screen || auto_fov.dirty {
*camera =
Camera::perspective(screen.aspect_ratio(), auto_fov.fov_y, auto_fov.z_near);
auto_fov.dirty = false;
}
}
self.last_dimensions = screen.clone();
}
}
impl Default for AutoFovSystem {
fn default() -> Self {
Self {
last_dimensions: ScreenDimensions::new(0, 0, 0.0),
}
}
}