fmt: increase line length limit
This commit is contained in:
parent
694816bd6c
commit
df921c621e
|
|
@ -1 +1,2 @@
|
||||||
hard_tabs = true
|
hard_tabs = true
|
||||||
|
max_width = 120
|
||||||
|
|
|
||||||
|
|
@ -52,20 +52,12 @@ pub fn main() {
|
||||||
let cam1 = put_object(&space.tube, vec3(-500., 0., 0.), Mat3::IDENTITY);
|
let cam1 = put_object(&space.tube, vec3(-500., 0., 0.), Mat3::IDENTITY);
|
||||||
let cam2 = put_object(
|
let cam2 = put_object(
|
||||||
&space.tube,
|
&space.tube,
|
||||||
vec3(
|
vec3(-2.5 * tube.outer_radius, 1.25 * tube.external_halflength, 0.),
|
||||||
-2.5 * tube.outer_radius,
|
|
||||||
1.25 * tube.external_halflength,
|
|
||||||
0.,
|
|
||||||
),
|
|
||||||
mat3(vec3(1., -1., 0.), vec3(1., 1., 0.), vec3(0., 0., 1.)),
|
mat3(vec3(1., -1., 0.), vec3(1., 1., 0.), vec3(0., 0., 1.)),
|
||||||
);
|
);
|
||||||
let cam3 = put_object(
|
let cam3 = put_object(
|
||||||
&space.tube,
|
&space.tube,
|
||||||
vec3(
|
vec3(0.25 * tube.inner_radius, 0.25 * tube.external_halflength, 0.),
|
||||||
0.25 * tube.inner_radius,
|
|
||||||
0.25 * tube.external_halflength,
|
|
||||||
0.,
|
|
||||||
),
|
|
||||||
mat3(vec3(0., -1., 0.), vec3(1., 0., 0.), vec3(0., 0., 1.)),
|
mat3(vec3(0., -1., 0.), vec3(1., 0., 0.), vec3(0., 0., 1.)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -134,11 +126,7 @@ pub fn main() {
|
||||||
let dir = Vec2::from_angle(φ);
|
let dir = Vec2::from_angle(φ);
|
||||||
let dir = vec3(dir.x, dir.y, 0.);
|
let dir = vec3(dir.x, dir.y, 0.);
|
||||||
let dir = obj.loc.rot * dir * d;
|
let dir = obj.loc.rot * dir * d;
|
||||||
space
|
space.trace_iter(Ray { pos, dir }).nth(n as usize).unwrap().pos
|
||||||
.trace_iter(Ray { pos, dir })
|
|
||||||
.nth(n as usize)
|
|
||||||
.unwrap()
|
|
||||||
.pos
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -169,10 +157,7 @@ fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, camera: Location, dir: Vec3) {
|
||||||
for pt in &path.points[1..] {
|
for pt in &path.points[1..] {
|
||||||
gc.line_to(pt.pos.x, pt.pos.y);
|
gc.line_to(pt.pos.x, pt.pos.y);
|
||||||
}
|
}
|
||||||
let end_pos = *path
|
let end_pos = *path.points.last().expect("the starting point is always in the path");
|
||||||
.points
|
|
||||||
.last()
|
|
||||||
.expect("the starting point is always in the path");
|
|
||||||
let dir_pos = end_pos.forward(1000. / DT).pos;
|
let dir_pos = end_pos.forward(1000. / DT).pos;
|
||||||
gc.line_to(dir_pos.x, dir_pos.y);
|
gc.line_to(dir_pos.x, dir_pos.y);
|
||||||
gc.stroke();
|
gc.stroke();
|
||||||
|
|
@ -192,11 +177,7 @@ fn draw_track(gc: &mut Vec<Draw>, space: &Space, start: Vec2, dir: Vec2) {
|
||||||
// let v = space.tube.normalize(start, dir);
|
// let v = space.tube.normalize(start, dir);
|
||||||
let mut loc = Location {
|
let mut loc = Location {
|
||||||
pos: vec3(start.x, start.y, 0.),
|
pos: vec3(start.x, start.y, 0.),
|
||||||
rot: mat3(
|
rot: mat3(vec3(dir.x, dir.y, 0.), vec3(-dir.y, dir.x, 0.), vec3(0., 0., 1.)),
|
||||||
vec3(dir.x, dir.y, 0.),
|
|
||||||
vec3(-dir.y, dir.x, 0.),
|
|
||||||
vec3(0., 0., 1.),
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
let v = vec3(1., 0., 0.);
|
let v = vec3(1., 0., 0.);
|
||||||
let mut draw = |loc: &Location| {
|
let mut draw = |loc: &Location| {
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,7 @@ fn render(mesh: &Mesh, camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image {
|
||||||
} else {
|
} else {
|
||||||
bkg
|
bkg
|
||||||
};
|
};
|
||||||
let color = (color * 255.0)
|
let color = (color * 255.0).as_ivec3().clamp(IVec3::splat(0), IVec3::splat(255));
|
||||||
.as_ivec3()
|
|
||||||
.clamp(IVec3::splat(0), IVec3::splat(255));
|
|
||||||
img.put_pixel(x, y, Color(color.x as u8, color.y as u8, color.z as u8));
|
img.put_pixel(x, y, Color(color.x as u8, color.y as u8, color.z as u8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,11 +139,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
loop {
|
loop {
|
||||||
for phi in 0..360 {
|
for phi in 0..360 {
|
||||||
let proj = PROJS[PROJ_INDEX.load(Relaxed)];
|
let proj = PROJS[PROJ_INDEX.load(Relaxed)];
|
||||||
let m_view = ypr_to_mat(vec3(
|
let m_view = ypr_to_mat(vec3((135.0 + phi as f32) * PI / 180.0, -30.0 * PI / 180.0, 0.0f32));
|
||||||
(135.0 + phi as f32) * PI / 180.0,
|
|
||||||
-30.0 * PI / 180.0,
|
|
||||||
0.0f32,
|
|
||||||
));
|
|
||||||
let m_camera = m_view.transpose();
|
let m_camera = m_view.transpose();
|
||||||
let img = render(mesh.as_slice(), |off| {
|
let img = render(mesh.as_slice(), |off| {
|
||||||
let (base, ray) = proj(40., 20. * off);
|
let (base, ray) = proj(40., 20. * off);
|
||||||
|
|
|
||||||
|
|
@ -112,14 +112,12 @@ impl LineRenderer {
|
||||||
format: wgpu::VertexFormat::Float32x3,
|
format: wgpu::VertexFormat::Float32x3,
|
||||||
},
|
},
|
||||||
wgpu::VertexAttribute {
|
wgpu::VertexAttribute {
|
||||||
offset: (mem::size_of::<Vertex>() + mem::offset_of!(Vertex, position))
|
offset: (mem::size_of::<Vertex>() + mem::offset_of!(Vertex, position)) as u64,
|
||||||
as u64,
|
|
||||||
shader_location: 2,
|
shader_location: 2,
|
||||||
format: wgpu::VertexFormat::Float32x3,
|
format: wgpu::VertexFormat::Float32x3,
|
||||||
},
|
},
|
||||||
wgpu::VertexAttribute {
|
wgpu::VertexAttribute {
|
||||||
offset: (mem::size_of::<Vertex>() + mem::offset_of!(Vertex, tangent))
|
offset: (mem::size_of::<Vertex>() + mem::offset_of!(Vertex, tangent)) as u64,
|
||||||
as u64,
|
|
||||||
shader_location: 3,
|
shader_location: 3,
|
||||||
format: wgpu::VertexFormat::Float32x3,
|
format: wgpu::VertexFormat::Float32x3,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,7 @@ impl<'a> State<'a> {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let viewport =
|
let viewport = viewport::Viewport::new(&adapter, &device, surface, uvec2(size.width, size.height));
|
||||||
viewport::Viewport::new(&adapter, &device, surface, uvec2(size.width, size.height));
|
|
||||||
|
|
||||||
let kbd = keyctl::Keyboard::new();
|
let kbd = keyctl::Keyboard::new();
|
||||||
let cam_loc = camctl::CameraLocation::new();
|
let cam_loc = camctl::CameraLocation::new();
|
||||||
|
|
@ -179,13 +178,7 @@ impl<'a> State<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let cam_obj = camera::Camera::new(&device);
|
let cam_obj = camera::Camera::new(&device);
|
||||||
let line_rend = lines::LineRenderer::new(
|
let line_rend = lines::LineRenderer::new(&device, cam_obj.bind_group_layout(), viewport.format(), depth, msaa);
|
||||||
&device,
|
|
||||||
cam_obj.bind_group_layout(),
|
|
||||||
viewport.format(),
|
|
||||||
depth,
|
|
||||||
msaa,
|
|
||||||
);
|
|
||||||
|
|
||||||
let scene = prepare_scene(&device);
|
let scene = prepare_scene(&device);
|
||||||
|
|
||||||
|
|
@ -226,10 +219,8 @@ impl<'a> State<'a> {
|
||||||
};
|
};
|
||||||
let size = self.viewport.size().as_vec2();
|
let size = self.viewport.size().as_vec2();
|
||||||
|
|
||||||
self.cam_loc
|
self.cam_loc.move_rel(100. * dt * self.kbd.control(&KEYS_MOVE));
|
||||||
.move_rel(100. * dt * self.kbd.control(&KEYS_MOVE));
|
self.cam_loc.rotate_rel_ypr(2. * dt * self.kbd.control(&KEYS_ROTATE));
|
||||||
self.cam_loc
|
|
||||||
.rotate_rel_ypr(2. * dt * self.kbd.control(&KEYS_ROTATE));
|
|
||||||
self.cam_obj.set(&self.queue, self.cam_loc.view_mtx(), size);
|
self.cam_obj.set(&self.queue, self.cam_loc.view_mtx(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,11 +230,8 @@ impl<'a> State<'a> {
|
||||||
.set_title(&format!("Space Refraction ({:.1} FPS)", self.fps.get()));
|
.set_title(&format!("Space Refraction ({:.1} FPS)", self.fps.get()));
|
||||||
self.viewport
|
self.viewport
|
||||||
.render_single_pass(&self.device, &self.queue, |mut render_pass| {
|
.render_single_pass(&self.device, &self.queue, |mut render_pass| {
|
||||||
self.line_rend.render(
|
self.line_rend
|
||||||
&mut render_pass,
|
.render(&mut render_pass, self.cam_obj.bind_group(), self.scene.iter());
|
||||||
self.cam_obj.bind_group(),
|
|
||||||
self.scene.iter(),
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -262,10 +250,7 @@ pub async fn run() {
|
||||||
event_loop
|
event_loop
|
||||||
.run(move |event, control_flow| {
|
.run(move |event, control_flow| {
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent {
|
Event::WindowEvent { ref event, window_id } if window_id == state.window().id() => {
|
||||||
ref event,
|
|
||||||
window_id,
|
|
||||||
} if window_id == state.window().id() => {
|
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
device_id: _,
|
device_id: _,
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,7 @@ fn draw_rect(center: Vec3, u: Vec3, v: Vec3) -> Vec<Line> {
|
||||||
let b = center + u - v;
|
let b = center + u - v;
|
||||||
let c = center + u + v;
|
let c = center + u + v;
|
||||||
let d = center - u + v;
|
let d = center - u + v;
|
||||||
vec![
|
vec![draw_line(a, b), draw_line(b, c), draw_line(c, d), draw_line(d, a)]
|
||||||
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 {
|
fn draw_ellipse(center: Vec3, u: Vec3, v: Vec3) -> Line {
|
||||||
|
|
@ -88,20 +83,12 @@ pub fn build() -> Vec<FancyLine> {
|
||||||
let cam1 = put_object(&space.tube, vec3(-500., 0., 0.), Mat3::IDENTITY);
|
let cam1 = put_object(&space.tube, vec3(-500., 0., 0.), Mat3::IDENTITY);
|
||||||
let cam2 = put_object(
|
let cam2 = put_object(
|
||||||
&space.tube,
|
&space.tube,
|
||||||
vec3(
|
vec3(-2.5 * tube.outer_radius, 1.25 * tube.external_halflength, 0.),
|
||||||
-2.5 * tube.outer_radius,
|
|
||||||
1.25 * tube.external_halflength,
|
|
||||||
0.,
|
|
||||||
),
|
|
||||||
mat3(vec3(1., -1., 0.), vec3(1., 1., 0.), vec3(0., 0., 1.)),
|
mat3(vec3(1., -1., 0.), vec3(1., 1., 0.), vec3(0., 0., 1.)),
|
||||||
);
|
);
|
||||||
let cam3 = put_object(
|
let cam3 = put_object(
|
||||||
&space.tube,
|
&space.tube,
|
||||||
vec3(
|
vec3(0.25 * tube.inner_radius, 0.25 * tube.external_halflength, 0.),
|
||||||
0.25 * tube.inner_radius,
|
|
||||||
0.25 * tube.external_halflength,
|
|
||||||
0.,
|
|
||||||
),
|
|
||||||
mat3(vec3(0., -1., 0.), vec3(1., 0., 0.), vec3(0., 0., 1.)),
|
mat3(vec3(0., -1., 0.), vec3(1., 0., 0.), vec3(0., 0., 1.)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -124,9 +111,7 @@ fn draw_ray_2(gc: &mut Vec<Line>, space: &Space, camera: Location, dir: Vec3) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pts = path.points;
|
let mut pts = path.points;
|
||||||
let end_pos = *pts
|
let end_pos = *pts.last().expect("the starting point is always in the path");
|
||||||
.last()
|
|
||||||
.expect("the starting point is always in the path");
|
|
||||||
pts.extend(itertools::iterate(end_pos, |r| r.forward(100.0)).take(1000));
|
pts.extend(itertools::iterate(end_pos, |r| r.forward(100.0)).take(1000));
|
||||||
gc.push(Line::Strip(pts));
|
gc.push(Line::Strip(pts));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,7 @@ pub struct Viewport<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Viewport<'a> {
|
impl<'a> Viewport<'a> {
|
||||||
pub fn new(
|
pub fn new(adapter: &wgpu::Adapter, device: &wgpu::Device, surface: wgpu::Surface<'a>, size: UVec2) -> Self {
|
||||||
adapter: &wgpu::Adapter,
|
|
||||||
device: &wgpu::Device,
|
|
||||||
surface: wgpu::Surface<'a>,
|
|
||||||
size: UVec2,
|
|
||||||
) -> Self {
|
|
||||||
let caps = surface.get_capabilities(adapter);
|
let caps = surface.get_capabilities(adapter);
|
||||||
let format = wgpu::TextureFormat::Bgra8UnormSrgb;
|
let format = wgpu::TextureFormat::Bgra8UnormSrgb;
|
||||||
let sample_count = adapter
|
let sample_count = adapter
|
||||||
|
|
@ -73,9 +68,7 @@ impl<'a> Viewport<'a> {
|
||||||
f: impl FnOnce(wgpu::RenderPass),
|
f: impl FnOnce(wgpu::RenderPass),
|
||||||
) -> Result<(), wgpu::SurfaceError> {
|
) -> Result<(), wgpu::SurfaceError> {
|
||||||
let output = self.surface.get_current_texture()?;
|
let output = self.surface.get_current_texture()?;
|
||||||
let view = output
|
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
.texture
|
|
||||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||||
label: Some("Render CommandEncoder"),
|
label: Some("Render CommandEncoder"),
|
||||||
});
|
});
|
||||||
|
|
@ -110,12 +103,7 @@ struct Multisample {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Multisample {
|
impl Multisample {
|
||||||
fn new(
|
fn new(device: &wgpu::Device, format: wgpu::TextureFormat, size: UVec2, sample_count: u32) -> Multisample {
|
||||||
device: &wgpu::Device,
|
|
||||||
format: wgpu::TextureFormat,
|
|
||||||
size: UVec2,
|
|
||||||
sample_count: u32,
|
|
||||||
) -> Multisample {
|
|
||||||
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: Some("Multisample texture"),
|
label: Some("Multisample texture"),
|
||||||
size: wgpu::Extent3d {
|
size: wgpu::Extent3d {
|
||||||
|
|
|
||||||
34
src/fns.rs
34
src/fns.rs
|
|
@ -82,12 +82,7 @@ impl QuadraticAccelerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x(&self, u: f32) -> f32 {
|
pub fn x(&self, u: f32) -> f32 {
|
||||||
extend_linear(
|
extend_linear(u, |u| (self.a() * u.abs() + self.b()) * u, self.internal, self.external)
|
||||||
u,
|
|
||||||
|u| (self.a() * u.abs() + self.b()) * u,
|
|
||||||
self.internal,
|
|
||||||
self.external,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
pub fn u(&self, x: f32) -> f32 {
|
pub fn u(&self, x: f32) -> f32 {
|
||||||
extend_linear(
|
extend_linear(
|
||||||
|
|
@ -98,12 +93,7 @@ impl QuadraticAccelerator {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn dx(&self, u: f32) -> f32 {
|
pub fn dx(&self, u: f32) -> f32 {
|
||||||
extend_const(
|
extend_const(u, |u| 2.0 * self.a() * u.abs() + self.b(), self.internal, 1.0)
|
||||||
u,
|
|
||||||
|u| 2.0 * self.a() * u.abs() + self.b(),
|
|
||||||
self.internal,
|
|
||||||
1.0,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
pub fn du(&self, x: f32) -> f32 {
|
pub fn du(&self, x: f32) -> f32 {
|
||||||
extend_const(x, |x| 1.0 / self.root(x), self.external, 1.0)
|
extend_const(x, |x| 1.0 / self.root(x), self.external, 1.0)
|
||||||
|
|
@ -148,28 +138,12 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_smoothstep_limiter() {
|
fn test_smoothstep_limiter() {
|
||||||
test_limiter(
|
test_limiter(SmoothstepLimiter { min: 20.0, max: 30.0 }, 20.0, 30.0, 1.0 / 32.0);
|
||||||
SmoothstepLimiter {
|
|
||||||
min: 20.0,
|
|
||||||
max: 30.0,
|
|
||||||
},
|
|
||||||
20.0,
|
|
||||||
30.0,
|
|
||||||
1.0 / 32.0,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_smootherstep_limiter() {
|
fn test_smootherstep_limiter() {
|
||||||
test_limiter(
|
test_limiter(SmootherstepLimiter { min: 20.0, max: 30.0 }, 20.0, 30.0, 1.0 / 32.0);
|
||||||
SmootherstepLimiter {
|
|
||||||
min: 20.0,
|
|
||||||
max: 30.0,
|
|
||||||
},
|
|
||||||
20.0,
|
|
||||||
30.0,
|
|
||||||
1.0 / 32.0,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,7 @@ impl MatExt for Mat3 {
|
||||||
fn orthonormalize(&self) -> Self {
|
fn orthonormalize(&self) -> Self {
|
||||||
let fx = self.x_axis.normalize();
|
let fx = self.x_axis.normalize();
|
||||||
let fy = (self.y_axis - self.y_axis.project_onto_normalized(fx)).normalize();
|
let fy = (self.y_axis - self.y_axis.project_onto_normalized(fx)).normalize();
|
||||||
let fz = (self.z_axis
|
let fz = (self.z_axis - self.z_axis.project_onto_normalized(fx) - self.z_axis.project_onto_normalized(fy))
|
||||||
- self.z_axis.project_onto_normalized(fx)
|
|
||||||
- self.z_axis.project_onto_normalized(fy))
|
|
||||||
.normalize();
|
.normalize();
|
||||||
Self::from_cols(fx, fy, fz)
|
Self::from_cols(fx, fy, fz)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,7 @@ impl ObjMesh {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_fv(desc: &&str) -> ObjVertex {
|
fn parse_fv(desc: &&str) -> ObjVertex {
|
||||||
let tokens: Vec<_> = desc
|
let tokens: Vec<_> = desc.split('/').map(|s| s.parse::<usize>().unwrap() - 1).collect();
|
||||||
.split('/')
|
|
||||||
.map(|s| s.parse::<usize>().unwrap() - 1)
|
|
||||||
.collect();
|
|
||||||
assert_eq!(tokens.len(), 3);
|
assert_eq!(tokens.len(), 3);
|
||||||
ObjVertex {
|
ObjVertex {
|
||||||
vertex: tokens[0],
|
vertex: tokens[0],
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,13 @@ pub struct TraceResult {
|
||||||
pub normal: Vec3,
|
pub normal: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trace_to_mesh_all(
|
pub fn trace_to_mesh_all(mesh: &Mesh, base: Vec3, ray: Vec3) -> impl Iterator<Item = TraceResult> + '_ {
|
||||||
mesh: &Mesh,
|
|
||||||
base: Vec3,
|
|
||||||
ray: Vec3,
|
|
||||||
) -> impl Iterator<Item = TraceResult> + '_ {
|
|
||||||
mesh.iter().filter_map(move |f| {
|
mesh.iter().filter_map(move |f| {
|
||||||
let fs = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray));
|
let fs = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray));
|
||||||
if fs.into_iter().any(|f| f < 0.0) {
|
if fs.into_iter().any(|f| f < 0.0) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let m = mat3(
|
let m = mat3(f.vertices[1] - f.vertices[0], f.vertices[2] - f.vertices[0], -ray);
|
||||||
f.vertices[1] - f.vertices[0],
|
|
||||||
f.vertices[2] - f.vertices[0],
|
|
||||||
-ray,
|
|
||||||
);
|
|
||||||
let m = m.inverse();
|
let m = m.inverse();
|
||||||
let rel = m * (base - f.vertices[0]);
|
let rel = m * (base - f.vertices[0]);
|
||||||
Some(TraceResult {
|
Some(TraceResult {
|
||||||
|
|
|
||||||
|
|
@ -161,10 +161,7 @@ mod tests {
|
||||||
metric.inverse_at(rng.gen()),
|
metric.inverse_at(rng.gen()),
|
||||||
Mat3::from_cols_array(&[1. / 9., 0., 0., 0., 1. / 16., 0., 0., 0., 1. / 25.])
|
Mat3::from_cols_array(&[1. / 9., 0., 0., 0., 1. / 16., 0., 0., 0., 1. / 25.])
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(metric.part_derivs_at(rng.gen()), [Mat3::ZERO, Mat3::ZERO, Mat3::ZERO]);
|
||||||
metric.part_derivs_at(rng.gen()),
|
|
||||||
[Mat3::ZERO, Mat3::ZERO, Mat3::ZERO]
|
|
||||||
);
|
|
||||||
assert_eq!(metric.vec_length_at(rng.gen(), vec3(1., 0., 0.)), 3.);
|
assert_eq!(metric.vec_length_at(rng.gen(), vec3(1., 0., 0.)), 3.);
|
||||||
assert_eq!(metric.vec_length_at(rng.gen(), vec3(0., 1., 0.)), 4.);
|
assert_eq!(metric.vec_length_at(rng.gen(), vec3(0., 1., 0.)), 4.);
|
||||||
assert_eq!(metric.vec_length_at(rng.gen(), vec3(0., 0., 1.)), 5.);
|
assert_eq!(metric.vec_length_at(rng.gen(), vec3(0., 0., 1.)), 5.);
|
||||||
|
|
@ -225,12 +222,7 @@ mod tests {
|
||||||
vec3(3., 6.25, 0.)
|
vec3(3., 6.25, 0.)
|
||||||
);
|
);
|
||||||
assert_abs_diff_eq!(
|
assert_abs_diff_eq!(
|
||||||
trace_iter(
|
trace_iter(&metric, vec3(3., 5., 0.), vec3(0.5, 0.25, 0.), std::f32::consts::SQRT_2)
|
||||||
&metric,
|
|
||||||
vec3(3., 5., 0.),
|
|
||||||
vec3(0.5, 0.25, 0.),
|
|
||||||
std::f32::consts::SQRT_2
|
|
||||||
)
|
|
||||||
.nth(7)
|
.nth(7)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
vec3(7., 7., 0.),
|
vec3(7., 7., 0.),
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,7 @@ pub trait FlatCoordinateSystem<T> {
|
||||||
fn global_to_flat(&self, v: T) -> T;
|
fn global_to_flat(&self, v: T) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FlatRegion:
|
pub trait FlatRegion: FlatCoordinateSystem<Vec3> + FlatCoordinateSystem<Ray> + FlatCoordinateSystem<Location> {
|
||||||
FlatCoordinateSystem<Vec3> + FlatCoordinateSystem<Ray> + FlatCoordinateSystem<Location>
|
|
||||||
{
|
|
||||||
// Измеряет расстояние до выхода за пределы области вдоль луча ray. Луч задаётся в плоской СК.
|
// Измеряет расстояние до выхода за пределы области вдоль луча ray. Луч задаётся в плоской СК.
|
||||||
fn distance_to_boundary(&self, _ray: Ray) -> Option<f32> {
|
fn distance_to_boundary(&self, _ray: Ray) -> Option<f32> {
|
||||||
None
|
None
|
||||||
|
|
@ -22,10 +20,7 @@ pub trait FlatRegion:
|
||||||
trait MetricCS: FlatCoordinateSystem<Vec3> {
|
trait MetricCS: FlatCoordinateSystem<Vec3> {
|
||||||
fn global_metric(&self) -> &impl Metric;
|
fn global_metric(&self) -> &impl Metric;
|
||||||
fn flat_to_global_tfm_at(&self, pos: Vec3) -> Mat3 {
|
fn flat_to_global_tfm_at(&self, pos: Vec3) -> Mat3 {
|
||||||
self.global_metric()
|
self.global_metric().sqrt_at(self.flat_to_global(pos)).inverse().into()
|
||||||
.sqrt_at(self.flat_to_global(pos))
|
|
||||||
.inverse()
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
fn global_to_flat_tfm_at(&self, pos: Vec3) -> Mat3 {
|
fn global_to_flat_tfm_at(&self, pos: Vec3) -> Mat3 {
|
||||||
self.global_metric().sqrt_at(pos).into()
|
self.global_metric().sqrt_at(pos).into()
|
||||||
|
|
@ -86,11 +81,7 @@ impl FlatCoordinateSystem<Vec3> for InnerCS {
|
||||||
impl FlatRegion for InnerCS {
|
impl FlatRegion for InnerCS {
|
||||||
fn distance_to_boundary(&self, ray: Ray) -> Option<f32> {
|
fn distance_to_boundary(&self, ray: Ray) -> Option<f32> {
|
||||||
Rect {
|
Rect {
|
||||||
size: vec3(
|
size: vec3(self.0.inner_radius, self.0.internal_halflength, self.0.inner_radius),
|
||||||
self.0.inner_radius,
|
|
||||||
self.0.internal_halflength,
|
|
||||||
self.0.inner_radius,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
.trace_out_of(ray)
|
.trace_out_of(ray)
|
||||||
}
|
}
|
||||||
|
|
@ -134,8 +125,7 @@ impl FlatCoordinateSystem<Vec3> for OuterCS {
|
||||||
};
|
};
|
||||||
if inner.is_inside(pos) {
|
if inner.is_inside(pos) {
|
||||||
let Vec3 { x: u, y, z: w } = pos; // в основной СК
|
let Vec3 { x: u, y, z: w } = pos; // в основной СК
|
||||||
let v = self.0.v(y)
|
let v = self.0.v(y) + y.signum() * (self.0.external_halflength - self.0.internal_halflength);
|
||||||
+ y.signum() * (self.0.external_halflength - self.0.internal_halflength);
|
|
||||||
vec3(u, v, w) // в плоском продолжении СК Outer на область Inner
|
vec3(u, v, w) // в плоском продолжении СК Outer на область Inner
|
||||||
} else {
|
} else {
|
||||||
pos
|
pos
|
||||||
|
|
@ -146,11 +136,7 @@ impl FlatCoordinateSystem<Vec3> for OuterCS {
|
||||||
impl FlatRegion for OuterCS {
|
impl FlatRegion for OuterCS {
|
||||||
fn distance_to_boundary(&self, ray: Ray) -> Option<f32> {
|
fn distance_to_boundary(&self, ray: Ray) -> Option<f32> {
|
||||||
Rect {
|
Rect {
|
||||||
size: vec3(
|
size: vec3(self.0.outer_radius, self.0.external_halflength, self.0.outer_radius),
|
||||||
self.0.outer_radius,
|
|
||||||
self.0.external_halflength,
|
|
||||||
self.0.outer_radius,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
.trace_into(ray)
|
.trace_into(ray)
|
||||||
}
|
}
|
||||||
|
|
@ -227,20 +213,12 @@ mod tests {
|
||||||
}),
|
}),
|
||||||
Location {
|
Location {
|
||||||
pos: vec3(0., -0.5, 0.),
|
pos: vec3(0., -0.5, 0.),
|
||||||
rot: mat3(
|
rot: mat3(vec3(0., 0.25, 0.), vec3(-1. / 3., 0., 0.), vec3(0., 0., 0.2))
|
||||||
vec3(0., 0.25, 0.),
|
|
||||||
vec3(-1. / 3., 0., 0.),
|
|
||||||
vec3(0., 0., 0.2)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_flat_region(
|
fn test_flat_region(region: &impl FlatRegion, range_global: (Vec3, Vec3), range_flat: (Vec3, Vec3)) {
|
||||||
region: &impl FlatRegion,
|
|
||||||
range_global: (Vec3, Vec3),
|
|
||||||
range_flat: (Vec3, Vec3),
|
|
||||||
) {
|
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
const ε: f32 = 1e-3;
|
const ε: f32 = 1e-3;
|
||||||
macro_rules! assert_eq_at {
|
macro_rules! assert_eq_at {
|
||||||
|
|
@ -256,14 +234,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
fn check_range(
|
fn check_range(name_a: &str, a: Vec3, range_a: (Vec3, Vec3), name_b: &str, b: Vec3, range_b: (Vec3, Vec3)) {
|
||||||
name_a: &str,
|
|
||||||
a: Vec3,
|
|
||||||
range_a: (Vec3, Vec3),
|
|
||||||
name_b: &str,
|
|
||||||
b: Vec3,
|
|
||||||
range_b: (Vec3, Vec3),
|
|
||||||
) {
|
|
||||||
assert!(b.cmpge(range_b.0 - ε).all() && b.cmple(range_b.1 + ε).all(), "Assertion failed:\nAt {name_a}: {a}, from range: {range_a:?}\nGot {name_b}: {b}, which is out of range {range_b:?}");
|
assert!(b.cmpge(range_b.0 - ε).all() && b.cmple(range_b.1 + ε).all(), "Assertion failed:\nAt {name_a}: {a}, from range: {range_a:?}\nGot {name_b}: {b}, which is out of range {range_b:?}");
|
||||||
// TODO sort out when to check these conditions:
|
// TODO sort out when to check these conditions:
|
||||||
if a.x.abs_diff_eq(&range_a.0.x, ε) {
|
if a.x.abs_diff_eq(&range_a.0.x, ε) {
|
||||||
|
|
@ -284,14 +255,7 @@ mod tests {
|
||||||
for z in linspace(range_global.0.z, range_global.1.z, 20) {
|
for z in linspace(range_global.0.z, range_global.1.z, 20) {
|
||||||
let pos_global = vec3(x, y, z);
|
let pos_global = vec3(x, y, z);
|
||||||
let pos_flat = region.global_to_flat(pos_global);
|
let pos_flat = region.global_to_flat(pos_global);
|
||||||
check_range(
|
check_range("global", pos_global, range_global, "flat", pos_flat, range_flat);
|
||||||
"global",
|
|
||||||
pos_global,
|
|
||||||
range_global,
|
|
||||||
"flat",
|
|
||||||
pos_flat,
|
|
||||||
range_flat,
|
|
||||||
);
|
|
||||||
assert_eq_at!(
|
assert_eq_at!(
|
||||||
pos_global,
|
pos_global,
|
||||||
region
|
region
|
||||||
|
|
@ -321,14 +285,7 @@ mod tests {
|
||||||
for z in linspace(range_flat.0.z, range_flat.1.z, 20) {
|
for z in linspace(range_flat.0.z, range_flat.1.z, 20) {
|
||||||
let pos_flat = vec3(x, y, z);
|
let pos_flat = vec3(x, y, z);
|
||||||
let pos_global = region.flat_to_global(pos_flat);
|
let pos_global = region.flat_to_global(pos_flat);
|
||||||
check_range(
|
check_range("flat", pos_flat, range_flat, "global", pos_global, range_global);
|
||||||
"flat",
|
|
||||||
pos_flat,
|
|
||||||
range_flat,
|
|
||||||
"global",
|
|
||||||
pos_global,
|
|
||||||
range_global,
|
|
||||||
);
|
|
||||||
assert_eq_at!(
|
assert_eq_at!(
|
||||||
pos_flat,
|
pos_flat,
|
||||||
region
|
region
|
||||||
|
|
|
||||||
|
|
@ -101,24 +101,17 @@ mod test {
|
||||||
let epsilon = 1.0e-3;
|
let epsilon = 1.0e-3;
|
||||||
let margin = 1.0 / 16.0;
|
let margin = 1.0 / 16.0;
|
||||||
let mul = 1.0 + margin;
|
let mul = 1.0 + margin;
|
||||||
for x in itertools_num::linspace(-mul * testee.outer_radius, mul * testee.outer_radius, 20)
|
for x in itertools_num::linspace(-mul * testee.outer_radius, mul * testee.outer_radius, 20) {
|
||||||
{
|
for y in itertools_num::linspace(-mul * testee.external_halflength, mul * testee.external_halflength, 20) {
|
||||||
for y in itertools_num::linspace(
|
for z in itertools_num::linspace(-mul * testee.outer_radius, mul * testee.outer_radius, 20) {
|
||||||
-mul * testee.external_halflength,
|
|
||||||
mul * testee.external_halflength,
|
|
||||||
20,
|
|
||||||
) {
|
|
||||||
for z in itertools_num::linspace(
|
|
||||||
-mul * testee.outer_radius,
|
|
||||||
mul * testee.outer_radius,
|
|
||||||
20,
|
|
||||||
) {
|
|
||||||
let pos = vec3(x, y, z);
|
let pos = vec3(x, y, z);
|
||||||
let computed = testee.part_derivs_at(pos);
|
let computed = testee.part_derivs_at(pos);
|
||||||
let reference = approx.part_derivs_at(pos);
|
let reference = approx.part_derivs_at(pos);
|
||||||
let eq =
|
let eq = (0..2).all(|coord| computed[coord].abs_diff_eq(reference[coord], epsilon));
|
||||||
(0..2).all(|coord| computed[coord].abs_diff_eq(reference[coord], epsilon));
|
assert!(
|
||||||
assert!(eq, "Bad derivative computation at {pos}:\n explicit: {computed:?}\n numerical: {reference:?}\n");
|
eq,
|
||||||
|
"Bad derivative computation at {pos}:\n explicit: {computed:?}\n numerical: {reference:?}\n"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -168,16 +161,8 @@ mod test {
|
||||||
let ε = 1e-3;
|
let ε = 1e-3;
|
||||||
let off = 10.0;
|
let off = 10.0;
|
||||||
let steps = 4096;
|
let steps = 4096;
|
||||||
for ax in linspace(
|
for ax in linspace(-space.tube.inner_radius + ε, space.tube.inner_radius - ε, 20) {
|
||||||
-space.tube.inner_radius + ε,
|
for bx in linspace(-space.tube.inner_radius + ε, space.tube.inner_radius - ε, 20) {
|
||||||
space.tube.inner_radius - ε,
|
|
||||||
20,
|
|
||||||
) {
|
|
||||||
for bx in linspace(
|
|
||||||
-space.tube.inner_radius + ε,
|
|
||||||
space.tube.inner_radius - ε,
|
|
||||||
20,
|
|
||||||
) {
|
|
||||||
let a = vec3(ax, -(space.tube.external_halflength + off), 0.);
|
let a = vec3(ax, -(space.tube.external_halflength + off), 0.);
|
||||||
let b = vec3(bx, space.tube.external_halflength + off, 0.);
|
let b = vec3(bx, space.tube.external_halflength + off, 0.);
|
||||||
let δ = vec3(bx - ax, 2.0 * (space.tube.internal_halflength + off), 0.);
|
let δ = vec3(bx - ax, 2.0 * (space.tube.internal_halflength + off), 0.);
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,7 @@ impl Space {
|
||||||
/// Выполняет один шаг перемещения. Работает в любой части пространства.
|
/// Выполняет один шаг перемещения. Работает в любой части пространства.
|
||||||
/// off задаётся в локальной СК. Рекомендуется считать небольшими шагами.
|
/// off задаётся в локальной СК. Рекомендуется считать небольшими шагами.
|
||||||
pub fn move_step(&self, loc: Location, off: Vec3) -> Location {
|
pub fn move_step(&self, loc: Location, off: Vec3) -> Location {
|
||||||
let corr =
|
let corr = Mat3::IDENTITY - riemann::contract(riemann::krist(&self.tube, loc.pos), loc.rot * off);
|
||||||
Mat3::IDENTITY - riemann::contract(riemann::krist(&self.tube, loc.pos), loc.rot * off);
|
|
||||||
let p = loc.pos + corr * loc.rot * off;
|
let p = loc.pos + corr * loc.rot * off;
|
||||||
Location {
|
Location {
|
||||||
pos: p,
|
pos: p,
|
||||||
|
|
@ -94,26 +93,16 @@ impl Space {
|
||||||
fn list_objects(&self, tfm: impl Fn(Location) -> Location) -> Vec<Object> {
|
fn list_objects(&self, tfm: impl Fn(Location) -> Location) -> Vec<Object> {
|
||||||
self.objs
|
self.objs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&Object { id, loc, r }| Object {
|
.map(|&Object { id, loc, r }| Object { id, loc: tfm(loc), r })
|
||||||
id,
|
|
||||||
loc: tfm(loc),
|
|
||||||
r,
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_objects(
|
fn hit_objects(objs: &[Object], ray: Ray, limit: Option<f32>, globalize: impl Fn(Vec3) -> Vec3) -> Vec<Hit> {
|
||||||
objs: &[Object],
|
|
||||||
ray: Ray,
|
|
||||||
limit: Option<f32>,
|
|
||||||
globalize: impl Fn(Vec3) -> Vec3,
|
|
||||||
) -> Vec<Hit> {
|
|
||||||
let limit = limit.unwrap_or(f32::INFINITY);
|
let limit = limit.unwrap_or(f32::INFINITY);
|
||||||
objs.iter()
|
objs.iter()
|
||||||
.filter_map(|obj| {
|
.filter_map(|obj| {
|
||||||
let rel = ray.pos - obj.loc.pos;
|
let rel = ray.pos - obj.loc.pos;
|
||||||
let diff = rel.dot(ray.dir).powi(2)
|
let diff = rel.dot(ray.dir).powi(2) - ray.dir.length_squared() * (rel.length_squared() - obj.r.powi(2));
|
||||||
- ray.dir.length_squared() * (rel.length_squared() - obj.r.powi(2));
|
|
||||||
if diff > 0.0 {
|
if diff > 0.0 {
|
||||||
let t = (-rel.dot(ray.dir) - diff.sqrt()) / ray.dir.length_squared();
|
let t = (-rel.dot(ray.dir) - diff.sqrt()) / ray.dir.length_squared();
|
||||||
Some((obj, t))
|
Some((obj, t))
|
||||||
|
|
|
||||||
36
src/utils.rs
36
src/utils.rs
|
|
@ -43,16 +43,8 @@ mod tests {
|
||||||
mat3(vec3(1., 0., 0.), vec3(0., 1., 0.), vec3(0., 0., 1.)),
|
mat3(vec3(1., 0., 0.), vec3(0., 1., 0.), vec3(0., 0., 1.)),
|
||||||
);
|
);
|
||||||
assert_eq!(loc.pos, vec3(1., 2., 0.));
|
assert_eq!(loc.pos, vec3(1., 2., 0.));
|
||||||
assert_abs_diff_eq!(
|
assert_abs_diff_eq!(loc.rot * vec3(1., 0., 0.), vec3(1. / 3., 0., 0.), epsilon = ε);
|
||||||
loc.rot * vec3(1., 0., 0.),
|
assert_abs_diff_eq!(loc.rot * vec3(0., 1., 0.), vec3(0., 1. / 4., 0.), epsilon = ε);
|
||||||
vec3(1. / 3., 0., 0.),
|
|
||||||
epsilon = ε
|
|
||||||
);
|
|
||||||
assert_abs_diff_eq!(
|
|
||||||
loc.rot * vec3(0., 1., 0.),
|
|
||||||
vec3(0., 1. / 4., 0.),
|
|
||||||
epsilon = ε
|
|
||||||
);
|
|
||||||
|
|
||||||
let loc = put_object(
|
let loc = put_object(
|
||||||
&m,
|
&m,
|
||||||
|
|
@ -60,16 +52,8 @@ mod tests {
|
||||||
mat3(vec3(0., 1., 0.), vec3(-1., 0., 0.), vec3(0., 0., 1.)),
|
mat3(vec3(0., 1., 0.), vec3(-1., 0., 0.), vec3(0., 0., 1.)),
|
||||||
);
|
);
|
||||||
assert_eq!(loc.pos, vec3(1., 2., 0.));
|
assert_eq!(loc.pos, vec3(1., 2., 0.));
|
||||||
assert_abs_diff_eq!(
|
assert_abs_diff_eq!(loc.rot * vec3(1., 0., 0.), vec3(0., 1. / 4., 0.), epsilon = ε);
|
||||||
loc.rot * vec3(1., 0., 0.),
|
assert_abs_diff_eq!(loc.rot * vec3(0., 1., 0.), vec3(-1. / 3., 0., 0.), epsilon = ε);
|
||||||
vec3(0., 1. / 4., 0.),
|
|
||||||
epsilon = ε
|
|
||||||
);
|
|
||||||
assert_abs_diff_eq!(
|
|
||||||
loc.rot * vec3(0., 1., 0.),
|
|
||||||
vec3(-1. / 3., 0., 0.),
|
|
||||||
epsilon = ε
|
|
||||||
);
|
|
||||||
|
|
||||||
let c = 0.5 * std::f32::consts::SQRT_2;
|
let c = 0.5 * std::f32::consts::SQRT_2;
|
||||||
let loc = put_object(
|
let loc = put_object(
|
||||||
|
|
@ -78,15 +62,7 @@ mod tests {
|
||||||
mat3(vec3(c, c, 0.), vec3(-c, c, 0.), vec3(0., 0., 1.)),
|
mat3(vec3(c, c, 0.), vec3(-c, c, 0.), vec3(0., 0., 1.)),
|
||||||
);
|
);
|
||||||
assert_eq!(loc.pos, vec3(1., 2., 0.));
|
assert_eq!(loc.pos, vec3(1., 2., 0.));
|
||||||
assert_abs_diff_eq!(
|
assert_abs_diff_eq!(loc.rot * vec3(1., 0., 0.), vec3(1. / 5., 1. / 5., 0.), epsilon = ε);
|
||||||
loc.rot * vec3(1., 0., 0.),
|
assert_abs_diff_eq!(loc.rot * vec3(0., 1., 0.), vec3(-4. / 15., 3. / 20., 0.), epsilon = ε);
|
||||||
vec3(1. / 5., 1. / 5., 0.),
|
|
||||||
epsilon = ε
|
|
||||||
);
|
|
||||||
assert_abs_diff_eq!(
|
|
||||||
loc.rot * vec3(0., 1., 0.),
|
|
||||||
vec3(-4. / 15., 3. / 20., 0.),
|
|
||||||
epsilon = ε
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user