Merge pull request #474 from hannobraun/viewer

Extract `fj-viewer` from `fj-app`
This commit is contained in:
Hanno Braun 2022-04-13 14:41:26 +02:00 committed by GitHub
commit 03b07732ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 229 additions and 177 deletions

View File

@ -144,4 +144,5 @@ jobs:
--crate ../fj-kernel \
--crate ../fj-math \
--crate ../fj-operations \
--crate ../fj-viewer \
--crate ../fj

30
Cargo.lock generated
View File

@ -694,26 +694,17 @@ name = "fj-app"
version = "0.5.0"
dependencies = [
"anyhow",
"bytemuck",
"clap",
"figment",
"fj",
"fj-export",
"fj-host",
"fj-interop",
"fj-kernel",
"fj-math",
"fj-operations",
"futures",
"nalgebra",
"parry3d-f64",
"fj-viewer",
"serde",
"thiserror",
"tracing",
"tracing-subscriber",
"wgpu",
"wgpu_glyph",
"winit",
]
[[package]]
@ -786,6 +777,25 @@ dependencies = [
"parry3d-f64",
]
[[package]]
name = "fj-viewer"
version = "0.5.0"
dependencies = [
"bytemuck",
"fj-host",
"fj-interop",
"fj-math",
"fj-operations",
"futures",
"nalgebra",
"parry3d-f64",
"thiserror",
"tracing",
"wgpu",
"wgpu_glyph",
"winit",
]
[[package]]
name = "flate2"
version = "1.0.22"

View File

@ -9,6 +9,7 @@ members = [
"fj-kernel",
"fj-math",
"fj-operations",
"fj-viewer",
"models/cuboid",
"models/group",
@ -25,4 +26,5 @@ default-members = [
"fj-kernel",
"fj-math",
"fj-operations",
"fj-viewer",
]

View File

@ -13,15 +13,6 @@ categories = ["mathematics", "rendering"]
[dependencies]
anyhow = "1.0.56"
bytemuck = "1.9.1"
futures = "0.3.21"
nalgebra = "0.30.0"
parry3d-f64 = "0.8.0"
thiserror = "1.0.30"
tracing = "0.1.33"
wgpu = "0.12.0"
wgpu_glyph = "0.16.0"
winit = "0.26.1"
[dependencies.clap]
version = "3.1.8"
@ -43,10 +34,6 @@ path = "../fj-export"
version = "0.5.0"
path = "../fj-host"
[dependencies.fj-interop]
version = "0.5.0"
path = "../fj-interop"
[dependencies.fj-kernel]
version = "0.5.0"
path = "../fj-kernel"
@ -59,6 +46,10 @@ path = "../fj-math"
version = "0.5.0"
path = "../fj-operations"
[dependencies.fj-viewer]
version = "0.5.0"
path = "../fj-viewer"
[dependencies.serde]
version = "1.0.136"
features = ["derive"]

View File

@ -1,33 +1,17 @@
mod args;
mod camera;
mod config;
mod graphics;
mod input;
mod window;
use std::path::PathBuf;
use std::time::Instant;
use anyhow::anyhow;
use fj_export::export;
use fj_host::{Model, Parameters};
use fj_operations::shape_processor::ShapeProcessor;
use futures::executor::block_on;
use tracing::{trace, warn};
use fj_viewer::run::run;
use tracing_subscriber::fmt::format;
use tracing_subscriber::EnvFilter;
use winit::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
};
use crate::{
args::Args,
camera::Camera,
config::Config,
graphics::{DrawConfig, Renderer},
window::Window,
};
use crate::{args::Args, config::Config};
fn main() -> anyhow::Result<()> {
// Respect `RUST_LOG`. If that's not defined or erroneous, log warnings and
@ -72,133 +56,7 @@ fn main() -> anyhow::Result<()> {
}
let watcher = model.load_and_watch(parameters)?;
run(watcher, shape_processor)?;
let event_loop = EventLoop::new();
let window = Window::new(&event_loop);
let mut previous_time = Instant::now();
let mut input_handler = input::Handler::new(previous_time);
let mut renderer = block_on(Renderer::new(&window))?;
let mut draw_config = DrawConfig::default();
let mut shape = None;
let mut camera = None;
event_loop.run(move |event, _, control_flow| {
trace!("Handling event: {:?}", event);
let mut actions = input::Actions::new();
let now = Instant::now();
if let Some(new_shape) = watcher.receive() {
let new_shape = shape_processor.process(&new_shape);
renderer.update_geometry(
(&new_shape.mesh).into(),
(&new_shape.debug_info).into(),
new_shape.aabb,
);
if camera.is_none() {
camera = Some(Camera::new(&new_shape.aabb));
}
shape = Some(new_shape);
}
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
*control_flow = ControlFlow::Exit;
}
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
renderer.handle_resize(size);
}
Event::WindowEvent {
event: WindowEvent::KeyboardInput { input, .. },
..
} => {
input_handler.handle_keyboard_input(input, &mut actions);
}
Event::WindowEvent {
event: WindowEvent::CursorMoved { position, .. },
..
} => {
if let Some(camera) = &mut camera {
input_handler
.handle_cursor_moved(position, camera, &window);
}
}
Event::WindowEvent {
event: WindowEvent::MouseInput { state, button, .. },
..
} => {
if let (Some(shape), Some(camera)) = (&shape, &camera) {
let focus_point = camera.focus_point(
&window,
input_handler.cursor(),
&shape.mesh,
);
input_handler.handle_mouse_input(
button,
state,
focus_point,
);
}
}
Event::WindowEvent {
event: WindowEvent::MouseWheel { delta, .. },
..
} => {
input_handler.handle_mouse_wheel(delta, now);
}
Event::MainEventsCleared => {
let delta_t = now.duration_since(previous_time);
previous_time = now;
if let (Some(shape), Some(camera)) = (&shape, &mut camera) {
input_handler.update(
delta_t.as_secs_f64(),
now,
camera,
&window,
&shape.mesh,
);
}
window.inner().request_redraw();
}
Event::RedrawRequested(_) => {
if let (Some(shape), Some(camera)) = (&shape, &mut camera) {
camera.update_planes(&shape.aabb);
if let Err(err) = renderer.draw(camera, &draw_config) {
warn!("Draw error: {}", err);
}
}
}
_ => {}
}
if actions.exit {
*control_flow = ControlFlow::Exit;
}
if actions.toggle_model {
draw_config.draw_model = !draw_config.draw_model;
}
if actions.toggle_mesh {
draw_config.draw_mesh = !draw_config.draw_mesh;
}
if actions.toggle_debug {
draw_config.draw_debug = !draw_config.draw_debug;
}
});
Ok(())
}

39
fj-viewer/Cargo.toml Normal file
View File

@ -0,0 +1,39 @@
[package]
name = "fj-viewer"
version = "0.5.0"
edition = "2021"
description = "The world needs another CAD program."
readme = "../README.md"
repository = "https://github.com/hannobraun/fornjot"
license = "0BSD"
keywords = ["cad", "programmatic", "code-cad"]
categories = ["rendering"]
[dependencies]
bytemuck = "1.9.1"
futures = "0.3.21"
nalgebra = "0.30.0"
parry3d-f64 = "0.8.0"
thiserror = "1.0.30"
tracing = "0.1.33"
wgpu = "0.12.0"
wgpu_glyph = "0.16.0"
winit = "0.26.1"
[dependencies.fj-host]
version = "0.5.0"
path = "../fj-host"
[dependencies.fj-interop]
version = "0.5.0"
path = "../fj-interop"
[dependencies.fj-math]
version = "0.5.0"
path = "../fj-math"
[dependencies.fj-operations]
version = "0.5.0"
path = "../fj-operations"

View File

@ -11,7 +11,7 @@ mod vertices;
pub use self::{
draw_config::DrawConfig,
renderer::{DrawError, Renderer},
renderer::{DrawError, InitError, Renderer},
};
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;

View File

@ -133,6 +133,7 @@ impl Handler {
}
}
#[derive(Default)]
pub struct Actions {
pub exit: bool,
@ -143,12 +144,6 @@ pub struct Actions {
impl Actions {
pub fn new() -> Self {
Self {
exit: false,
toggle_model: false,
toggle_mesh: false,
toggle_debug: false,
}
Self::default()
}
}

5
fj-viewer/src/lib.rs Normal file
View File

@ -0,0 +1,5 @@
pub mod camera;
pub mod graphics;
pub mod input;
pub mod run;
pub mod window;

151
fj-viewer/src/run.rs Normal file
View File

@ -0,0 +1,151 @@
use std::time::Instant;
use fj_host::Watcher;
use fj_operations::shape_processor::ShapeProcessor;
use futures::executor::block_on;
use tracing::{trace, warn};
use winit::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
};
use crate::{
camera::Camera,
graphics::{self, DrawConfig, Renderer},
input,
window::Window,
};
pub fn run(
watcher: Watcher,
shape_processor: ShapeProcessor,
) -> Result<(), graphics::InitError> {
let event_loop = EventLoop::new();
let window = Window::new(&event_loop);
let mut previous_time = Instant::now();
let mut input_handler = input::Handler::new(previous_time);
let mut renderer = block_on(Renderer::new(&window))?;
let mut draw_config = DrawConfig::default();
let mut shape = None;
let mut camera = None;
event_loop.run(move |event, _, control_flow| {
trace!("Handling event: {:?}", event);
let mut actions = input::Actions::new();
let now = Instant::now();
if let Some(new_shape) = watcher.receive() {
let new_shape = shape_processor.process(&new_shape);
renderer.update_geometry(
(&new_shape.mesh).into(),
(&new_shape.debug_info).into(),
new_shape.aabb,
);
if camera.is_none() {
camera = Some(Camera::new(&new_shape.aabb));
}
shape = Some(new_shape);
}
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
*control_flow = ControlFlow::Exit;
}
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
renderer.handle_resize(size);
}
Event::WindowEvent {
event: WindowEvent::KeyboardInput { input, .. },
..
} => {
input_handler.handle_keyboard_input(input, &mut actions);
}
Event::WindowEvent {
event: WindowEvent::CursorMoved { position, .. },
..
} => {
if let Some(camera) = &mut camera {
input_handler
.handle_cursor_moved(position, camera, &window);
}
}
Event::WindowEvent {
event: WindowEvent::MouseInput { state, button, .. },
..
} => {
if let (Some(shape), Some(camera)) = (&shape, &camera) {
let focus_point = camera.focus_point(
&window,
input_handler.cursor(),
&shape.mesh,
);
input_handler.handle_mouse_input(
button,
state,
focus_point,
);
}
}
Event::WindowEvent {
event: WindowEvent::MouseWheel { delta, .. },
..
} => {
input_handler.handle_mouse_wheel(delta, now);
}
Event::MainEventsCleared => {
let delta_t = now.duration_since(previous_time);
previous_time = now;
if let (Some(shape), Some(camera)) = (&shape, &mut camera) {
input_handler.update(
delta_t.as_secs_f64(),
now,
camera,
&window,
&shape.mesh,
);
}
window.inner().request_redraw();
}
Event::RedrawRequested(_) => {
if let (Some(shape), Some(camera)) = (&shape, &mut camera) {
camera.update_planes(&shape.aabb);
if let Err(err) = renderer.draw(camera, &draw_config) {
warn!("Draw error: {}", err);
}
}
}
_ => {}
}
if actions.exit {
*control_flow = ControlFlow::Exit;
}
if actions.toggle_model {
draw_config.draw_model = !draw_config.draw_model;
}
if actions.toggle_mesh {
draw_config.draw_mesh = !draw_config.draw_mesh;
}
if actions.toggle_debug {
draw_config.draw_debug = !draw_config.draw_debug;
}
});
}