mirror of
https://github.com/hannobraun/Fornjot
synced 2025-10-09 17:38:22 +00:00
Add support for displaying faces
This commit is contained in:
parent
f910ebf6a5
commit
d56459da92
@ -9,6 +9,9 @@ use super::{
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Pipelines {
|
||||
ForFace {
|
||||
lines: Pipeline,
|
||||
},
|
||||
ForModel {
|
||||
model: Pipeline,
|
||||
mesh: Option<Pipeline>,
|
||||
@ -16,6 +19,24 @@ pub enum Pipelines {
|
||||
}
|
||||
|
||||
impl Pipelines {
|
||||
pub fn for_face(
|
||||
device: &wgpu::Device,
|
||||
shaders: &Shaders,
|
||||
pipeline_layout: &wgpu::PipelineLayout,
|
||||
color_format: wgpu::TextureFormat,
|
||||
) -> Self {
|
||||
let lines = Pipeline::new(
|
||||
device,
|
||||
pipeline_layout,
|
||||
shaders.face(),
|
||||
wgpu::PrimitiveTopology::TriangleList,
|
||||
wgpu::PolygonMode::Line,
|
||||
color_format,
|
||||
);
|
||||
|
||||
Self::ForFace { lines }
|
||||
}
|
||||
|
||||
pub fn for_model(
|
||||
device: &wgpu::Device,
|
||||
shaders: &Shaders,
|
||||
@ -58,6 +79,9 @@ impl Pipelines {
|
||||
render_pass: &mut wgpu::RenderPass,
|
||||
) {
|
||||
match self {
|
||||
Self::ForFace { lines } => {
|
||||
lines.draw(geometry, render_pass);
|
||||
}
|
||||
Self::ForModel { model, mesh } => {
|
||||
if config.draw_model {
|
||||
model.draw(geometry, render_pass);
|
||||
|
@ -188,6 +188,12 @@ impl Renderer {
|
||||
|
||||
let shaders = Shaders::new(&device.device);
|
||||
let pipelines = match mode {
|
||||
RenderMode::Face => Pipelines::for_face(
|
||||
&device.device,
|
||||
&shaders,
|
||||
&pipeline_layout,
|
||||
color_format,
|
||||
),
|
||||
RenderMode::Model => Pipelines::for_model(
|
||||
&device.device,
|
||||
&shaders,
|
||||
@ -381,6 +387,7 @@ impl Renderer {
|
||||
}
|
||||
|
||||
pub enum RenderMode {
|
||||
Face,
|
||||
Model,
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,13 @@ fn vertex(in: VertexInput) -> VertexOutput {
|
||||
|
||||
const pi: f32 = 3.14159265359;
|
||||
|
||||
@fragment
|
||||
fn frag_face(in: VertexOutput) -> FragmentOutput {
|
||||
var out: FragmentOutput;
|
||||
out.color = vec4<f32>(0.0, 0.0, 0.0, 1.0);
|
||||
return out;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn frag_model(in: VertexOutput) -> FragmentOutput {
|
||||
let light = vec3<f32>(0.0, 0.0, -1.0);
|
||||
|
@ -17,6 +17,13 @@ impl Shaders {
|
||||
Self { module }
|
||||
}
|
||||
|
||||
pub fn face(&self) -> Shader {
|
||||
Shader {
|
||||
module: &self.module,
|
||||
frag_entry: "frag_face",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn model(&self) -> Shader {
|
||||
Shader {
|
||||
module: &self.module,
|
||||
|
@ -1,5 +1,6 @@
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use fj_interop::{Index, TriMesh, vertices_to_indexed_vertices};
|
||||
use fj_math::{Point, Scalar};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Vertices {
|
||||
@ -8,6 +9,24 @@ pub struct Vertices {
|
||||
}
|
||||
|
||||
impl Vertices {
|
||||
pub fn for_face(points: &[Point<2>]) -> Self {
|
||||
let vertices = points
|
||||
.iter()
|
||||
.map(|point| {
|
||||
let [x, y] = point.coords.components.map(Scalar::into_f32);
|
||||
|
||||
Vertex {
|
||||
position: [x, y, 0.],
|
||||
normal: [0., 0., 1.],
|
||||
color: [0., 0., 0., 1.],
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let indices = (0..).take(points.len()).collect();
|
||||
|
||||
Self { vertices, indices }
|
||||
}
|
||||
|
||||
pub fn for_model(tri_mesh: &TriMesh) -> Self {
|
||||
let (vertices, indices) = vertices_to_indexed_vertices(
|
||||
tri_mesh.triangles.iter().flat_map(|triangle| {
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::{collections::BTreeMap, panic, thread};
|
||||
|
||||
use fj_interop::TriMesh;
|
||||
use fj_math::Point;
|
||||
use futures::executor::block_on;
|
||||
use winit::{
|
||||
application::ApplicationHandler,
|
||||
@ -63,6 +64,14 @@ pub struct Viewer {
|
||||
}
|
||||
|
||||
impl Viewer {
|
||||
/// # Display a 2D face in a new window
|
||||
pub fn display_face(&self, points: Vec<Point<2>>) {
|
||||
// If there's an error, that means the display thread has closed down
|
||||
// and we're on our way to shutting down as well. I don't think there's
|
||||
// much we can do about that.
|
||||
let _ = self.event_loop.send_event(ToDisplay::face(points));
|
||||
}
|
||||
|
||||
/// # Display a 3D model in a new window
|
||||
pub fn display_model(&self, tri_mesh: TriMesh) {
|
||||
// If there's an error, that means the display thread has closed down
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use fj_interop::TriMesh;
|
||||
use fj_math::Aabb;
|
||||
use fj_math::{Aabb, Point};
|
||||
use tracing::warn;
|
||||
use winit::{dpi::PhysicalSize, event_loop::ActiveEventLoop};
|
||||
|
||||
@ -30,6 +30,11 @@ impl Window {
|
||||
event_loop: &ActiveEventLoop,
|
||||
) -> Result<Self, WindowError> {
|
||||
let (vertices, render_mode, aabb) = match &to_display {
|
||||
ToDisplay::Face { points, aabb } => {
|
||||
let vertices = Vertices::for_face(points);
|
||||
let render_mode = RenderMode::Face;
|
||||
(vertices, render_mode, aabb)
|
||||
}
|
||||
ToDisplay::Model { tri_mesh, aabb } => {
|
||||
let vertices = Vertices::for_model(tri_mesh);
|
||||
let render_mode = RenderMode::Model;
|
||||
@ -78,13 +83,13 @@ impl Window {
|
||||
|
||||
/// # Compute and store a focus point, unless one is already stored
|
||||
pub fn add_focus_point(&mut self) {
|
||||
let ToDisplay::Model { tri_mesh, aabb } = &self.to_display;
|
||||
|
||||
if let ToDisplay::Model { tri_mesh, aabb } = &self.to_display {
|
||||
if self.focus_point.is_none() {
|
||||
self.focus_point =
|
||||
Some(self.camera.focus_point(self.cursor, tri_mesh, aabb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// # Handle the screen being resized
|
||||
pub fn on_screen_resize(&mut self, new_size: PhysicalSize<u32>) {
|
||||
@ -175,6 +180,7 @@ impl Window {
|
||||
}
|
||||
|
||||
let aabb = match &self.to_display {
|
||||
ToDisplay::Face { points: _, aabb } => aabb,
|
||||
ToDisplay::Model { tri_mesh: _, aabb } => aabb,
|
||||
};
|
||||
self.camera.update_planes(aabb);
|
||||
@ -186,10 +192,23 @@ impl Window {
|
||||
}
|
||||
|
||||
pub enum ToDisplay {
|
||||
Model { tri_mesh: TriMesh, aabb: Aabb<3> },
|
||||
Face {
|
||||
points: Vec<Point<2>>,
|
||||
aabb: Aabb<3>,
|
||||
},
|
||||
Model {
|
||||
tri_mesh: TriMesh,
|
||||
aabb: Aabb<3>,
|
||||
},
|
||||
}
|
||||
|
||||
impl ToDisplay {
|
||||
pub fn face(points: Vec<Point<2>>) -> Self {
|
||||
let aabb =
|
||||
Aabb::<3>::from_points(points.iter().map(|point| point.to_xyz()));
|
||||
Self::Face { points, aabb }
|
||||
}
|
||||
|
||||
pub fn model(tri_mesh: TriMesh) -> Self {
|
||||
let aabb = tri_mesh.aabb();
|
||||
Self::Model { tri_mesh, aabb }
|
||||
|
Loading…
x
Reference in New Issue
Block a user