Compare commits
7 Commits
32a2995e7b
...
3ab86973cc
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ab86973cc | |||
| 33906f51b3 | |||
| c1b7d5ea00 | |||
| db50127cf5 | |||
| 553823b65f | |||
| a29c17e295 | |||
| 01331350e4 |
|
|
@ -3,7 +3,8 @@ name = "refraction"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
[lints.rust]
|
||||||
|
mixed_script_confusables = "allow"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
panic = 'abort'
|
panic = 'abort'
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,7 @@ pub fn main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn draw_cross(gc: &mut Vec<Draw>, pos: Vec2, r: f32) {
|
fn draw_cross(gc: &mut Vec<Draw>, pos: Vec2, r: f32) {
|
||||||
gc.move_to(pos.x - r, pos.y - r);
|
gc.move_to(pos.x - r, pos.y - r);
|
||||||
gc.line_to(pos.x + r, pos.y + r);
|
gc.line_to(pos.x + r, pos.y + r);
|
||||||
|
|
@ -215,8 +216,8 @@ fn draw_track(gc: &mut Vec<Draw>, space: &Space, start: Vec2, dir: Vec2) {
|
||||||
};
|
};
|
||||||
draw(&loc);
|
draw(&loc);
|
||||||
for _ in 0..1000 {
|
for _ in 0..1000 {
|
||||||
let N = (STEP / DT).floor() as i32;
|
let n = (STEP / DT).floor() as i32;
|
||||||
for _ in 0..N {
|
for _ in 0..n {
|
||||||
loc = space.move_step(loc, v * DT);
|
loc = space.move_step(loc, v * DT);
|
||||||
}
|
}
|
||||||
draw(&loc);
|
draw(&loc);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
use glam::*;
|
use glam::*;
|
||||||
use refraction::mesh_loader::load_mesh;
|
use refraction::mesh_loader::load_mesh;
|
||||||
use refraction::mesh_tracer::{trace_to_mesh, Mesh};
|
use refraction::mesh_tracer::{trace_to_mesh, Mesh};
|
||||||
|
use show_image::event::{ElementState, VirtualKeyCode, WindowEvent};
|
||||||
use show_image::{exit, ImageInfo, ImageView, WindowOptions};
|
use show_image::{exit, ImageInfo, ImageView, WindowOptions};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
|
||||||
|
|
||||||
const W: i32 = 320;
|
const W: i32 = 320;
|
||||||
const H: i32 = 240;
|
const H: i32 = 240;
|
||||||
|
|
@ -109,6 +111,10 @@ fn test_projs() {
|
||||||
check(ortho, 9., 1., 8.);
|
check(ortho, 9., 1., 8.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add_event_handler wants 'static + Send. Let it be so.
|
||||||
|
static PROJ_INDEX: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
static PROJS: [fn(dist: f32, off: Vec2) -> (Vec3, Vec3); 2] = [persp, ortho];
|
||||||
|
|
||||||
#[show_image::main]
|
#[show_image::main]
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
|
|
@ -121,10 +127,20 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let mut f = BufReader::new(f);
|
let mut f = BufReader::new(f);
|
||||||
load_mesh(&mut f)?
|
load_mesh(&mut f)?
|
||||||
};
|
};
|
||||||
let proj = persp;
|
|
||||||
let window = show_image::create_window("Raytracing", WindowOptions::default())?;
|
let window = show_image::create_window("Raytracing", WindowOptions::default())?;
|
||||||
|
window.add_event_handler(|_wnd, ev, _ctl| {
|
||||||
|
if let WindowEvent::KeyboardInput(ev) = ev {
|
||||||
|
if ev.input.state != ElementState::Pressed {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(VirtualKeyCode::Tab) = ev.input.key_code {
|
||||||
|
PROJ_INDEX.store((PROJ_INDEX.load(Relaxed) + 1) % PROJS.len(), Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})?;
|
||||||
loop {
|
loop {
|
||||||
for phi in 0..360 {
|
for phi in 0..360 {
|
||||||
|
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,
|
(135.0 + phi as f32) * PI / 180.0,
|
||||||
-30.0 * PI / 180.0,
|
-30.0 * PI / 180.0,
|
||||||
|
|
|
||||||
|
|
@ -99,8 +99,8 @@ static KEYS_MOVE: &'static [(PhysicalKey, Vec3)] = &[
|
||||||
(PhysicalKey::Code(KeyCode::KeyS), vec3(-1., 0., 0.)),
|
(PhysicalKey::Code(KeyCode::KeyS), vec3(-1., 0., 0.)),
|
||||||
(PhysicalKey::Code(KeyCode::KeyA), vec3(0., 1., 0.)),
|
(PhysicalKey::Code(KeyCode::KeyA), vec3(0., 1., 0.)),
|
||||||
(PhysicalKey::Code(KeyCode::KeyD), vec3(0., -1., 0.)),
|
(PhysicalKey::Code(KeyCode::KeyD), vec3(0., -1., 0.)),
|
||||||
(PhysicalKey::Code(KeyCode::Space), vec3(0., 0., 1.)),
|
(PhysicalKey::Code(KeyCode::KeyE), vec3(0., 0., 1.)),
|
||||||
(PhysicalKey::Code(KeyCode::ShiftLeft), vec3(0., 0., -1.)),
|
(PhysicalKey::Code(KeyCode::KeyQ), vec3(0., 0., -1.)),
|
||||||
];
|
];
|
||||||
|
|
||||||
static KEYS_ROTATE: &'static [(PhysicalKey, Vec3)] = &[
|
static KEYS_ROTATE: &'static [(PhysicalKey, Vec3)] = &[
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ trait Renderable {
|
||||||
|
|
||||||
impl Renderable for Tube {
|
impl Renderable for Tube {
|
||||||
fn render(&self) -> Vec<Line> {
|
fn render(&self) -> Vec<Line> {
|
||||||
let lines = 17;
|
let lines = 4;
|
||||||
let step = 2. * std::f32::consts::PI / lines as f32;
|
let step = 2. * std::f32::consts::PI / lines as f32;
|
||||||
let r = 0.5 * (self.outer_radius + self.inner_radius);
|
let r = 0.5 * (self.outer_radius + self.inner_radius);
|
||||||
let w = 0.5 * (self.outer_radius - self.inner_radius);
|
let w = 0.5 * (self.outer_radius - self.inner_radius);
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ impl QuadraticAccelerator {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use approx::{abs_diff_eq, assert_abs_diff_eq, AbsDiffEq};
|
use approx::{abs_diff_eq, assert_abs_diff_eq};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|
|
||||||
16
src/mathx.rs
16
src/mathx.rs
|
|
@ -142,6 +142,22 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn make_vec2(f: impl Fn(usize) -> f32) -> Vec2 {
|
||||||
|
Vec2::from_array(std::array::from_fn(|i| f(i)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_mat2(f: impl Fn(usize, usize) -> f32) -> Mat2 {
|
||||||
|
Mat2::from_cols_array_2d(&std::array::from_fn(|i| std::array::from_fn(|j| f(i, j))))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_vec3(f: impl Fn(usize) -> f32) -> Vec3 {
|
||||||
|
Vec3::from_array(std::array::from_fn(|i| f(i)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_mat3(f: impl Fn(usize, usize) -> f32) -> Mat3 {
|
||||||
|
Mat3::from_cols_array_2d(&std::array::from_fn(|i| std::array::from_fn(|j| f(i, j))))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use std::io;
|
||||||
struct ObjVertex {
|
struct ObjVertex {
|
||||||
vertex: usize,
|
vertex: usize,
|
||||||
normal: usize,
|
normal: usize,
|
||||||
tex_coord: usize,
|
// tex_coord: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
@ -42,7 +42,7 @@ impl ObjMesh {
|
||||||
assert_eq!(tokens.len(), 3);
|
assert_eq!(tokens.len(), 3);
|
||||||
ObjVertex {
|
ObjVertex {
|
||||||
vertex: tokens[0],
|
vertex: tokens[0],
|
||||||
tex_coord: tokens[1],
|
// tex_coord: tokens[1],
|
||||||
normal: tokens[2],
|
normal: tokens[2],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::mathx::Decomp3;
|
use crate::mathx::{make_mat3, Decomp3};
|
||||||
use glam::*;
|
use glam::*;
|
||||||
|
|
||||||
pub type Tens3 = [Mat3; 3];
|
pub type Tens3 = [Mat3; 3];
|
||||||
|
|
@ -86,14 +86,6 @@ pub fn contract2(t: Tens3, v: Vec3) -> Vec3 {
|
||||||
contract(t, v) * v
|
contract(t, v) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_vec3(f: impl Fn(usize) -> f32) -> Vec3 {
|
|
||||||
Vec3::from_array(std::array::from_fn(|i| f(i)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_mat3(f: impl Fn(usize, usize) -> f32) -> Mat3 {
|
|
||||||
Mat3::from_cols_array_2d(&std::array::from_fn(|i| std::array::from_fn(|j| f(i, j))))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_tens3(f: impl Fn(usize, usize, usize) -> f32) -> Tens3 {
|
fn make_tens3(f: impl Fn(usize, usize, usize) -> f32) -> Tens3 {
|
||||||
std::array::from_fn(|i| make_mat3(|j, k| f(i, j, k)))
|
std::array::from_fn(|i| make_mat3(|j, k| f(i, j, k)))
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +137,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use approx::assert_abs_diff_eq;
|
use approx::assert_abs_diff_eq;
|
||||||
|
|
||||||
use glam::{mat3, vec3, Mat3};
|
use glam::{vec3, Mat3};
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,8 @@ mod test {
|
||||||
for bx in [0.0, ε, 1.0, 7.0, 30.0 - ε] {
|
for bx in [0.0, ε, 1.0, 7.0, 30.0 - ε] {
|
||||||
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.);
|
||||||
let dir = Δ / (steps as f32);
|
let dir = δ / (steps as f32);
|
||||||
let traced = space.trace_iter(Ray { pos: a, dir }).nth(steps).unwrap();
|
let traced = space.trace_iter(Ray { pos: a, dir }).nth(steps).unwrap();
|
||||||
assert_abs_diff_eq!(traced.pos.x, b.x, epsilon = 1.0e-2);
|
assert_abs_diff_eq!(traced.pos.x, b.x, epsilon = 1.0e-2);
|
||||||
assert_abs_diff_eq!(traced.pos.y, b.y, epsilon = 1.0e1);
|
assert_abs_diff_eq!(traced.pos.y, b.y, epsilon = 1.0e1);
|
||||||
|
|
@ -180,8 +180,8 @@ mod test {
|
||||||
) {
|
) {
|
||||||
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.);
|
||||||
let dir = Δ / (steps as f32);
|
let dir = δ / (steps as f32);
|
||||||
let traced = space.trace_iter(Ray { pos: a, dir }).nth(steps).unwrap();
|
let traced = space.trace_iter(Ray { pos: a, dir }).nth(steps).unwrap();
|
||||||
assert_abs_diff_eq!(traced.pos.x, b.x, epsilon = 1.0e-2);
|
assert_abs_diff_eq!(traced.pos.x, b.x, epsilon = 1.0e-2);
|
||||||
assert_abs_diff_eq!(traced.pos.y, b.y, epsilon = 1.0e0);
|
assert_abs_diff_eq!(traced.pos.y, b.y, epsilon = 1.0e0);
|
||||||
|
|
@ -208,8 +208,8 @@ mod test {
|
||||||
for x in [space.tube.inner_radius - ε, space.tube.inner_radius + ε] {
|
for x in [space.tube.inner_radius - ε, space.tube.inner_radius + ε] {
|
||||||
let a = vec3(x, -(space.tube.external_halflength + off), 0.);
|
let a = vec3(x, -(space.tube.external_halflength + off), 0.);
|
||||||
let b = vec3(x, space.tube.external_halflength + off, 0.);
|
let b = vec3(x, space.tube.external_halflength + off, 0.);
|
||||||
let Δ = vec3(0.0, 2.0 * (space.tube.internal_halflength + off), 0.);
|
let δ = vec3(0.0, 2.0 * (space.tube.internal_halflength + off), 0.);
|
||||||
let dir = Δ / (steps as f32);
|
let dir = δ / (steps as f32);
|
||||||
let traced = space.trace_iter(Ray { pos: a, dir }).nth(steps).unwrap();
|
let traced = space.trace_iter(Ray { pos: a, dir }).nth(steps).unwrap();
|
||||||
assert_abs_diff_eq!(traced.pos.x, b.x, epsilon = 1.0e-1);
|
assert_abs_diff_eq!(traced.pos.x, b.x, epsilon = 1.0e-1);
|
||||||
assert_abs_diff_eq!(traced.pos.y, b.y, epsilon = 1.0e0);
|
assert_abs_diff_eq!(traced.pos.y, b.y, epsilon = 1.0e0);
|
||||||
|
|
@ -235,8 +235,8 @@ mod test {
|
||||||
for x in [space.tube.outer_radius + ε, space.tube.outer_radius - ε] {
|
for x in [space.tube.outer_radius + ε, space.tube.outer_radius - ε] {
|
||||||
let a = vec3(x, -(space.tube.external_halflength + off), 0.);
|
let a = vec3(x, -(space.tube.external_halflength + off), 0.);
|
||||||
let b = vec3(x, space.tube.external_halflength + off, 0.);
|
let b = vec3(x, space.tube.external_halflength + off, 0.);
|
||||||
let Δ = vec3(0.0, 2.0 * (space.tube.external_halflength + off), 0.);
|
let δ = vec3(0.0, 2.0 * (space.tube.external_halflength + off), 0.);
|
||||||
let dir = Δ / (steps as f32);
|
let dir = δ / (steps as f32);
|
||||||
let traced = space.trace_iter(Ray { pos: a, dir }).nth(steps).unwrap();
|
let traced = space.trace_iter(Ray { pos: a, dir }).nth(steps).unwrap();
|
||||||
assert_abs_diff_eq!(traced.pos.x, b.x, epsilon = 2.0e0);
|
assert_abs_diff_eq!(traced.pos.x, b.x, epsilon = 2.0e0);
|
||||||
assert_abs_diff_eq!(traced.pos.y, b.y, epsilon = 1.0e0);
|
assert_abs_diff_eq!(traced.pos.y, b.y, epsilon = 1.0e0);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use glam::{bool, f32, vec3, Mat3, Vec3};
|
use glam::{bool, f32, Mat3, Vec3};
|
||||||
|
|
||||||
use crate::ifaces::{DebugTraceable, RayPath, Traceable};
|
use crate::ifaces::{DebugTraceable, RayPath, Traceable};
|
||||||
use coords::{FlatCoordinateSystem, InnerCS, OuterCS};
|
use coords::{FlatCoordinateSystem, InnerCS, OuterCS};
|
||||||
|
|
@ -91,13 +91,6 @@ impl Space {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trace_boundary(&self, ray: Ray) -> Ray {
|
|
||||||
assert_eq!(self.which_subspace(ray.pos), Boundary);
|
|
||||||
self.trace_iter(ray)
|
|
||||||
.find(|&ray| self.which_subspace(ray.pos) != Boundary)
|
|
||||||
.expect("Can't get outta the wall!")
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
||||||
|
|
@ -236,7 +229,7 @@ impl DebugTraceable for Space {
|
||||||
let Some(ray_outta_flat) = ret.end else {
|
let Some(ray_outta_flat) = ret.end else {
|
||||||
return (hits, RayPath { points });
|
return (hits, RayPath { points });
|
||||||
};
|
};
|
||||||
points.extend(self.line(ray_into_flat.pos, ray_outta_flat.pos, 10.0));
|
points.extend(self.line(ray_into_flat.pos, ray_outta_flat.pos, 1.0));
|
||||||
ray = ray_outta_flat;
|
ray = ray_outta_flat;
|
||||||
}
|
}
|
||||||
panic!("tracing didn't terminate");
|
panic!("tracing didn't terminate");
|
||||||
|
|
@ -284,6 +277,9 @@ impl Rect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
use glam::vec3;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rect() {
|
fn test_rect() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user