mirror of
https://github.com/hannobraun/Fornjot
synced 2025-01-27 10:29:28 +00:00
Merge pull request #474 from hannobraun/viewer
Extract `fj-viewer` from `fj-app`
This commit is contained in:
commit
03b07732ac
1
.github/workflows/cd.yml
vendored
1
.github/workflows/cd.yml
vendored
@ -144,4 +144,5 @@ jobs:
|
|||||||
--crate ../fj-kernel \
|
--crate ../fj-kernel \
|
||||||
--crate ../fj-math \
|
--crate ../fj-math \
|
||||||
--crate ../fj-operations \
|
--crate ../fj-operations \
|
||||||
|
--crate ../fj-viewer \
|
||||||
--crate ../fj
|
--crate ../fj
|
||||||
|
30
Cargo.lock
generated
30
Cargo.lock
generated
@ -694,26 +694,17 @@ name = "fj-app"
|
|||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytemuck",
|
|
||||||
"clap",
|
"clap",
|
||||||
"figment",
|
"figment",
|
||||||
"fj",
|
"fj",
|
||||||
"fj-export",
|
"fj-export",
|
||||||
"fj-host",
|
"fj-host",
|
||||||
"fj-interop",
|
|
||||||
"fj-kernel",
|
"fj-kernel",
|
||||||
"fj-math",
|
"fj-math",
|
||||||
"fj-operations",
|
"fj-operations",
|
||||||
"futures",
|
"fj-viewer",
|
||||||
"nalgebra",
|
|
||||||
"parry3d-f64",
|
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
|
||||||
"tracing",
|
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"wgpu",
|
|
||||||
"wgpu_glyph",
|
|
||||||
"winit",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -786,6 +777,25 @@ dependencies = [
|
|||||||
"parry3d-f64",
|
"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]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
|
@ -9,6 +9,7 @@ members = [
|
|||||||
"fj-kernel",
|
"fj-kernel",
|
||||||
"fj-math",
|
"fj-math",
|
||||||
"fj-operations",
|
"fj-operations",
|
||||||
|
"fj-viewer",
|
||||||
|
|
||||||
"models/cuboid",
|
"models/cuboid",
|
||||||
"models/group",
|
"models/group",
|
||||||
@ -25,4 +26,5 @@ default-members = [
|
|||||||
"fj-kernel",
|
"fj-kernel",
|
||||||
"fj-math",
|
"fj-math",
|
||||||
"fj-operations",
|
"fj-operations",
|
||||||
|
"fj-viewer",
|
||||||
]
|
]
|
||||||
|
@ -13,15 +13,6 @@ categories = ["mathematics", "rendering"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.56"
|
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]
|
[dependencies.clap]
|
||||||
version = "3.1.8"
|
version = "3.1.8"
|
||||||
@ -43,10 +34,6 @@ path = "../fj-export"
|
|||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
path = "../fj-host"
|
path = "../fj-host"
|
||||||
|
|
||||||
[dependencies.fj-interop]
|
|
||||||
version = "0.5.0"
|
|
||||||
path = "../fj-interop"
|
|
||||||
|
|
||||||
[dependencies.fj-kernel]
|
[dependencies.fj-kernel]
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
path = "../fj-kernel"
|
path = "../fj-kernel"
|
||||||
@ -59,6 +46,10 @@ path = "../fj-math"
|
|||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
path = "../fj-operations"
|
path = "../fj-operations"
|
||||||
|
|
||||||
|
[dependencies.fj-viewer]
|
||||||
|
version = "0.5.0"
|
||||||
|
path = "../fj-viewer"
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1.0.136"
|
version = "1.0.136"
|
||||||
features = ["derive"]
|
features = ["derive"]
|
||||||
|
@ -1,33 +1,17 @@
|
|||||||
mod args;
|
mod args;
|
||||||
mod camera;
|
|
||||||
mod config;
|
mod config;
|
||||||
mod graphics;
|
|
||||||
mod input;
|
|
||||||
mod window;
|
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use fj_export::export;
|
use fj_export::export;
|
||||||
use fj_host::{Model, Parameters};
|
use fj_host::{Model, Parameters};
|
||||||
use fj_operations::shape_processor::ShapeProcessor;
|
use fj_operations::shape_processor::ShapeProcessor;
|
||||||
use futures::executor::block_on;
|
use fj_viewer::run::run;
|
||||||
use tracing::{trace, warn};
|
|
||||||
use tracing_subscriber::fmt::format;
|
use tracing_subscriber::fmt::format;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
use winit::{
|
|
||||||
event::{Event, WindowEvent},
|
|
||||||
event_loop::{ControlFlow, EventLoop},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{args::Args, config::Config};
|
||||||
args::Args,
|
|
||||||
camera::Camera,
|
|
||||||
config::Config,
|
|
||||||
graphics::{DrawConfig, Renderer},
|
|
||||||
window::Window,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
// Respect `RUST_LOG`. If that's not defined or erroneous, log warnings and
|
// 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)?;
|
let watcher = model.load_and_watch(parameters)?;
|
||||||
|
run(watcher, shape_processor)?;
|
||||||
|
|
||||||
let event_loop = EventLoop::new();
|
Ok(())
|
||||||
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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
39
fj-viewer/Cargo.toml
Normal file
39
fj-viewer/Cargo.toml
Normal 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"
|
@ -11,7 +11,7 @@ mod vertices;
|
|||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
draw_config::DrawConfig,
|
draw_config::DrawConfig,
|
||||||
renderer::{DrawError, Renderer},
|
renderer::{DrawError, InitError, Renderer},
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
@ -133,6 +133,7 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Actions {
|
pub struct Actions {
|
||||||
pub exit: bool,
|
pub exit: bool,
|
||||||
|
|
||||||
@ -143,12 +144,6 @@ pub struct Actions {
|
|||||||
|
|
||||||
impl Actions {
|
impl Actions {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self::default()
|
||||||
exit: false,
|
|
||||||
|
|
||||||
toggle_model: false,
|
|
||||||
toggle_mesh: false,
|
|
||||||
toggle_debug: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
5
fj-viewer/src/lib.rs
Normal file
5
fj-viewer/src/lib.rs
Normal 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
151
fj-viewer/src/run.rs
Normal 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user