Nice wide lines
This commit is contained in:
parent
b8f0ce0b68
commit
d3d4048a5c
|
|
@ -20,6 +20,7 @@ mod scene;
|
|||
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
struct Vertex {
|
||||
position: [f32; 3],
|
||||
tangent: [f32; 3],
|
||||
}
|
||||
|
||||
struct Wireframe {
|
||||
|
|
@ -33,28 +34,14 @@ fn prepare_scene(device: &wgpu::Device) -> Vec<Wireframe> {
|
|||
.into_iter()
|
||||
.map(|line| {
|
||||
let color = line.color;
|
||||
let data: Vec<Vertex>;
|
||||
match line.line {
|
||||
scene::Line::Lines(_) => todo!(),
|
||||
scene::Line::Strip(pts) => {
|
||||
data = pts
|
||||
.into_iter()
|
||||
.map(|p| Vertex {
|
||||
position: p.to_array(),
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
scene::Line::Loop(pts) => {
|
||||
let first = pts.first().copied();
|
||||
data = pts
|
||||
.into_iter()
|
||||
.chain(first)
|
||||
.map(|p| Vertex {
|
||||
position: p.to_array(),
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
};
|
||||
let data: Vec<Vertex> = line
|
||||
.pts
|
||||
.into_iter()
|
||||
.map(|r| Vertex {
|
||||
position: r.pos.to_array(),
|
||||
tangent: r.dir.to_array(),
|
||||
})
|
||||
.collect();
|
||||
let size = data.len() as u32;
|
||||
let data = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Vertex Buffer"),
|
||||
|
|
@ -304,10 +291,21 @@ impl<'a> State<'a> {
|
|||
shader_location: 0,
|
||||
format: wgpu::VertexFormat::Float32x3,
|
||||
},
|
||||
wgpu::VertexAttribute {
|
||||
offset: mem::offset_of!(Vertex, tangent) as u64,
|
||||
shader_location: 1,
|
||||
format: wgpu::VertexFormat::Float32x3,
|
||||
},
|
||||
wgpu::VertexAttribute {
|
||||
offset: (mem::size_of::<Vertex>() + mem::offset_of!(Vertex, position))
|
||||
as u64,
|
||||
shader_location: 1,
|
||||
shader_location: 2,
|
||||
format: wgpu::VertexFormat::Float32x3,
|
||||
},
|
||||
wgpu::VertexAttribute {
|
||||
offset: (mem::size_of::<Vertex>() + mem::offset_of!(Vertex, tangent))
|
||||
as u64,
|
||||
shader_location: 3,
|
||||
format: wgpu::VertexFormat::Float32x3,
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ var<push_constant> line: LineUniform;
|
|||
|
||||
struct SegmentInput {
|
||||
@location(0) a: vec3<f32>,
|
||||
@location(1) b: vec3<f32>,
|
||||
@location(1) ad: vec3<f32>,
|
||||
@location(2) b: vec3<f32>,
|
||||
@location(3) bd: vec3<f32>,
|
||||
}
|
||||
struct OffsetInput {
|
||||
@builtin(vertex_index) idx: u32,
|
||||
|
|
@ -28,18 +30,27 @@ struct VertexOutput {
|
|||
fn vs_main(seg: SegmentInput, off: OffsetInput) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.vertex_color = line.color;
|
||||
let a = camera.mvp * vec4(seg.a, 1.);
|
||||
let b = camera.mvp * vec4(seg.b, 1.);
|
||||
let dir = normalize(b.xy / b.w - a.xy / a.w);
|
||||
let ortho = width * camera.scale * vec2(-dir.y, dir.x);
|
||||
let d = vec4(ortho, 0., 0.);
|
||||
var pt: vec3<f32>;
|
||||
var dir: vec3<f32>;
|
||||
switch (off.idx) {
|
||||
case 0u: { out.clip_position = a - d; }
|
||||
case 1u: { out.clip_position = a + d; }
|
||||
case 2u: { out.clip_position = b - d; }
|
||||
case 3u: { out.clip_position = b + d; }
|
||||
case 0u: { pt = seg.a; dir = seg.ad; }
|
||||
case 1u: { pt = seg.a; dir = seg.ad; }
|
||||
case 2u: { pt = seg.b; dir = seg.bd; }
|
||||
case 3u: { pt = seg.b; dir = seg.bd; }
|
||||
default: {}
|
||||
}
|
||||
var sgn: f32;
|
||||
switch (off.idx) {
|
||||
case 0u: { sgn = -1.; }
|
||||
case 1u: { sgn = 1.; }
|
||||
case 2u: { sgn = -1.; }
|
||||
case 3u: { sgn = 1.; }
|
||||
default: {}
|
||||
}
|
||||
let pt_cs = camera.mvp * vec4(pt, 1.);
|
||||
let dir_cs = camera.mvp * vec4(dir, 0.);
|
||||
let normal_cs = camera.scale * normalize(vec2(-dir_cs.y, dir_cs.x));
|
||||
out.clip_position = pt_cs + vec4(sgn * width * normal_cs, 0., 0.);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use glam::*;
|
||||
use itertools::{chain, iproduct, Itertools};
|
||||
use itertools::{chain, iproduct};
|
||||
|
||||
use refraction::ifaces::{DebugTraceable, Traceable};
|
||||
use refraction::tube::metric::Tube;
|
||||
|
|
@ -8,27 +8,44 @@ use refraction::types::{Location, Object, Ray};
|
|||
use refraction::utils::put_object;
|
||||
|
||||
pub enum Line {
|
||||
Lines(Vec<(Vec3, Vec3)>),
|
||||
Strip(Vec<Vec3>),
|
||||
Loop(Vec<Vec3>),
|
||||
Strip(Vec<Ray>),
|
||||
Loop(Vec<Ray>),
|
||||
}
|
||||
|
||||
pub struct FancyLine {
|
||||
pub color: Vec3,
|
||||
pub line: Line,
|
||||
pub pts: Vec<Ray>,
|
||||
}
|
||||
|
||||
fn paint(onto: &mut Vec<FancyLine>, color: Vec3, lines: Vec<Line>) {
|
||||
onto.extend(lines.into_iter().map(move |line| FancyLine { color, line }))
|
||||
onto.extend(lines.into_iter().map(move |line| FancyLine {
|
||||
color,
|
||||
pts: match line {
|
||||
Line::Strip(pts) => pts,
|
||||
Line::Loop(mut pts) => {
|
||||
pts.push(*pts.first().unwrap());
|
||||
pts
|
||||
}
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
fn draw_rect(center: Vec3, u: Vec3, v: Vec3) -> Line {
|
||||
Line::Loop(vec![
|
||||
center - u - v,
|
||||
center + u - v,
|
||||
center + u + v,
|
||||
center - u + v,
|
||||
])
|
||||
fn draw_line(a: Vec3, b: Vec3) -> Line {
|
||||
let dir = (b - a).normalize();
|
||||
Line::Strip(vec![Ray { pos: a, dir }, Ray { pos: b, dir }])
|
||||
}
|
||||
|
||||
fn draw_rect(center: Vec3, u: Vec3, v: Vec3) -> Vec<Line> {
|
||||
let a = center - u - v;
|
||||
let b = center + u - v;
|
||||
let c = center + u + v;
|
||||
let d = center - u + v;
|
||||
vec![
|
||||
draw_line(a, b),
|
||||
draw_line(b, c),
|
||||
draw_line(c, d),
|
||||
draw_line(d, a),
|
||||
]
|
||||
}
|
||||
|
||||
fn draw_ellipse(center: Vec3, u: Vec3, v: Vec3) -> Line {
|
||||
|
|
@ -38,7 +55,10 @@ fn draw_ellipse(center: Vec3, u: Vec3, v: Vec3) -> Line {
|
|||
(0..segments)
|
||||
.map(|k| k as f32 * step)
|
||||
.map(Vec2::from_angle)
|
||||
.map(|d| center + d.x * u + d.y * v)
|
||||
.map(|d| Ray {
|
||||
pos: center + d.x * u + d.y * v,
|
||||
dir: -d.y * u + d.x * v,
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
|
@ -109,7 +129,7 @@ fn draw_ray_2(gc: &mut Vec<Line>, space: &Space, camera: Location, dir: Vec3) {
|
|||
.expect("the starting point is always in the path");
|
||||
let dir_pos = end_pos.forward(10000.0);
|
||||
pts.push(dir_pos);
|
||||
gc.push(Line::Strip(pts.into_iter().map(|r| r.pos).collect()));
|
||||
gc.push(Line::Strip(pts));
|
||||
}
|
||||
|
||||
fn draw_fan_2(space: &Space, camera: Location, spread: f32) -> Vec<Line> {
|
||||
|
|
@ -135,7 +155,7 @@ impl Renderable for Tube {
|
|||
.map(|k| k as f32 * step)
|
||||
.map(Vec2::from_angle)
|
||||
.map(|d| vec3(d.x, 0., d.y))
|
||||
.map(|d| draw_rect(r * d, w * d, l));
|
||||
.flat_map(|d| draw_rect(r * d, w * d, l));
|
||||
let caps = iproduct!([self.inner_radius, self.outer_radius], [-l, l])
|
||||
.map(|(r, l)| draw_ellipse(l, vec3(r, 0., 0.), vec3(0., 0., r)));
|
||||
chain!(along, caps).collect()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user