use concinnity_core::components::Camera3D;
use concinnity_core::ecs::World;
use concinnity_core::ecs::{FrameTime, PickIndex};
use crate::editor::hook::EditorHook;
use crate::editor::hook::camera_pose;
use crate::editor::viewport::framing::CameraPose;
use crate::editor::worlds;
use crate::editor::worlds::cinematic::{Cinematic, Framing};
impl EditorHook {
pub(in crate::editor::hook) fn drive_cinematic(&mut self, world: &mut World) {
if !self.start_mode {
return self.reset_cinematic();
}
if self.rebuild_preview {
self.stop_cinematic(world);
self.cinematic = Some(Cinematic::new());
return;
}
if self.cinematic_restore.is_none() {
self.cinematic_restore = camera_pose::read(world);
}
let Some(home) = self.cinematic_restore else {
return self.reset_cinematic();
};
let Some(framing) = self.cinematic_framing(world, home) else {
return self.stop_cinematic(world);
};
let dt = self.cinematic_dt(world);
let pose = {
let cine = self.cinematic.get_or_insert_with(Cinematic::new);
cine.advance(dt);
cine.pose(&framing)
};
camera_pose::write(world, &pose);
}
pub(in crate::editor::hook) fn drive_cinematic_draw(
&self,
world: &mut World,
vp: [f32; 2],
shown: bool,
) {
match self.cinematic {
Some(cine) if shown && !self.loading_preview() => {
worlds::cinematic::place(world, vp, cine.fade_alpha())
}
_ => worlds::cinematic::hide(world),
}
}
pub(in crate::editor::hook) fn stop_cinematic(&mut self, world: &mut World) {
if let Some(pose) = self.cinematic_restore.take() {
camera_pose::write(world, &pose);
}
self.reset_cinematic();
}
pub(in crate::editor::hook) fn reset_cinematic(&mut self) {
self.cinematic = None;
self.cinematic_ticking = false;
self.cinematic_restore = None;
}
pub(in crate::editor::hook) fn restart_cinematic(&mut self) {
self.cinematic = None;
self.cinematic_ticking = false;
}
fn cinematic_framing(&self, world: &World, home: CameraPose) -> Option<Framing> {
let vp = self.viewport;
if vp[0] <= 0.0 || vp[1] <= 0.0 {
return None;
}
let cam = world.query::<Camera3D>().next()?;
if cam.controller.as_ref().is_some_and(|c| c.follow.is_some()) {
return None;
}
let fov = cam.fov_y_degrees.to_radians();
let index = world.resource::<PickIndex>()?;
let (mn, mx) = concinnity_core::render::reflection_probe::fold_world_bounds(
index.entries.iter().map(|e| (e.bb_min, e.bb_max)),
)?;
Framing::new(mn, mx, fov, vp[0] / vp[1], home)
}
fn cinematic_dt(&mut self, world: &World) -> f32 {
if !std::mem::replace(&mut self.cinematic_ticking, true) {
return 0.0;
}
world
.resource::<FrameTime>()
.copied()
.unwrap_or_default()
.dt
}
}