1use fj_interop::Model;
2use tracing::warn;
3
4use crate::{
5 camera::{Camera, FocusPoint},
6 graphics::{DrawConfig, Renderer},
7 input::InputHandler,
8 InputEvent, NormalizedScreenPosition, RendererInitError, Screen,
9 ScreenSize,
10};
11
12pub struct Viewer {
14 camera: Camera,
15 cursor: Option<NormalizedScreenPosition>,
16 draw_config: DrawConfig,
17 focus_point: Option<FocusPoint>,
18 renderer: Renderer,
19 model: Option<Model>,
20}
21
22impl Viewer {
23 pub async fn new(screen: &impl Screen) -> Result<Self, RendererInitError> {
25 let renderer = Renderer::new(screen).await?;
26
27 Ok(Self {
28 camera: Camera::default(),
29 cursor: None,
30 draw_config: DrawConfig::default(),
31 focus_point: None,
32 renderer,
33 model: None,
34 })
35 }
36
37 pub fn cursor(&mut self) -> &mut Option<NormalizedScreenPosition> {
39 &mut self.cursor
40 }
41
42 pub fn toggle_draw_model(&mut self) {
44 self.draw_config.draw_model = !self.draw_config.draw_model;
45 }
46
47 pub fn toggle_draw_mesh(&mut self) {
49 self.draw_config.draw_mesh = !self.draw_config.draw_mesh;
50 }
51
52 pub fn handle_model_update(&mut self, model: Model) {
54 self.renderer.update_geometry((&model.mesh).into());
55
56 let aabb = model.aabb;
57 if self.model.replace(model).is_none() {
58 self.camera.init_planes(&aabb);
59 }
60 }
61
62 pub fn handle_input_event(&mut self, event: InputEvent) {
64 if let Some(focus_point) = self.focus_point {
65 InputHandler::handle_event(event, focus_point, &mut self.camera);
66 }
67 }
68
69 pub fn handle_screen_resize(&mut self, screen_size: ScreenSize) {
71 self.renderer.handle_resize(screen_size);
72 }
73
74 pub fn add_focus_point(&mut self) {
76 if let Some(model) = &self.model {
77 if self.focus_point.is_none() {
78 self.focus_point =
79 Some(self.camera.focus_point(self.cursor, model));
80 }
81 }
82 }
83
84 pub fn remove_focus_point(&mut self) {
86 self.focus_point = None;
87 }
88
89 pub fn draw(&mut self) {
91 let aabb = self
92 .model
93 .as_ref()
94 .map(|shape| shape.aabb)
95 .unwrap_or_default();
96
97 self.camera.update_planes(&aabb);
98
99 if let Err(err) = self.renderer.draw(&self.camera, &self.draw_config) {
100 warn!("Draw error: {}", err);
101 }
102 }
103}