Split ray tracing and trace display
This commit is contained in:
parent
88da1aa582
commit
e9993182bf
|
|
@ -4,6 +4,7 @@ use flo_canvas::*;
|
||||||
use flo_draw::*;
|
use flo_draw::*;
|
||||||
use glam::*;
|
use glam::*;
|
||||||
|
|
||||||
|
use crate::ifaces::DebugTraceable;
|
||||||
use crate::types::FlatTraceResult;
|
use crate::types::FlatTraceResult;
|
||||||
use refraction::mathx::MatExt;
|
use refraction::mathx::MatExt;
|
||||||
use riemann::{trace_iter, Metric};
|
use riemann::{trace_iter, Metric};
|
||||||
|
|
@ -196,74 +197,27 @@ fn draw_cross(gc: &mut Vec<Draw>, pos: Vec2, r: f32) {
|
||||||
gc.line_to(pos.x + r, pos.y - r);
|
gc.line_to(pos.x + r, pos.y - r);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, base: Vec2, dir: Vec2) {
|
fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, camera: Location, dir: Vec2) {
|
||||||
fn trace_to_flat(gc: &mut Vec<Draw>, space: &Space, ray: Ray) -> (Ray, FlatTraceResult) {
|
let pos = vec2(0., 0.);
|
||||||
for ray in space.trace_iter(ray).skip(1) {
|
let (hits, path) = space.trace_dbg(camera, Ray { pos, dir });
|
||||||
gc.line_to(ray.pos.x, ray.pos.y);
|
|
||||||
match space.which_subspace(ray.pos) {
|
|
||||||
Inner => return (ray, space.trace_inner(ray)),
|
|
||||||
Outer => return (ray, space.trace_outer(ray)),
|
|
||||||
Boundary => continue,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
unreachable!("Space::trace_iter terminated!")
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut hits = Vec::<Draw>::new();
|
|
||||||
gc.new_path();
|
gc.new_path();
|
||||||
gc.move_to(base.x, base.y);
|
gc.move_to(pos.x, pos.y);
|
||||||
let mut ray = Ray {
|
for pt in &path.points[1..] {
|
||||||
pos: base,
|
gc.line_to(pt.x, pt.y);
|
||||||
dir: space.tube.normalize_vec_at(base, dir) * DT,
|
|
||||||
};
|
|
||||||
for _ in 0..100 {
|
|
||||||
let ret;
|
|
||||||
(ray, ret) = trace_to_flat(gc, space, ray);
|
|
||||||
gc.stroke();
|
|
||||||
gc.new_dash_pattern();
|
|
||||||
// gc.dash_length(6.0);
|
|
||||||
gc.new_path();
|
|
||||||
gc.move_to(ray.pos.x, ray.pos.y);
|
|
||||||
for hit in ret.objects {
|
|
||||||
let obj = space.objs[hit.id as usize];
|
|
||||||
let apx_hit_pos = rel_to_abs(&space.tube, &obj.loc, hit.rel.pos, 128);
|
|
||||||
// assert_abs_diff_eq!(apx_hit_pos, hit.pos, epsilon=1.0);
|
|
||||||
let Ray { pos: rel, dir } = hit.rel;
|
|
||||||
let diff = rel.dot(dir).powi(2)
|
|
||||||
- dir.length_squared() * (rel.length_squared() - obj.r.powi(2));
|
|
||||||
assert!(diff >= 0.0);
|
|
||||||
let t = (-rel.dot(dir) + diff.sqrt()) / dir.length_squared();
|
|
||||||
let rel2 = hit.rel.forward(t).pos;
|
|
||||||
let pos2 = rel_to_abs(&space.tube, &obj.loc, rel2, 128);
|
|
||||||
draw_cross(&mut hits, pos2, 1.0);
|
|
||||||
}
|
}
|
||||||
let a = ray.pos;
|
let end_pos = *path
|
||||||
if let Some(r) = ret.end {
|
.points
|
||||||
ray = r
|
.last()
|
||||||
} else {
|
.expect("the starting point is always in the path");
|
||||||
ray = ray.forward(1000.0 / DT);
|
let dir_pos = end_pos + 1000.0 * path.end_dir;
|
||||||
gc.line_to(ray.pos.x, ray.pos.y);
|
gc.line_to(dir_pos.x, dir_pos.y);
|
||||||
break;
|
|
||||||
}
|
|
||||||
for p in space.line(a, ray.pos, 10.0) {
|
|
||||||
gc.line_to(p.x, p.y);
|
|
||||||
}
|
|
||||||
gc.stroke();
|
|
||||||
gc.new_dash_pattern();
|
|
||||||
gc.new_path();
|
|
||||||
gc.move_to(ray.pos.x, ray.pos.y);
|
|
||||||
}
|
|
||||||
gc.stroke();
|
|
||||||
gc.new_path();
|
|
||||||
gc.new_dash_pattern();
|
|
||||||
gc.append(&mut hits);
|
|
||||||
gc.stroke();
|
gc.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_fan_2(gc: &mut Vec<Draw>, space: &Space, camera: Location, spread: f32) {
|
fn draw_fan_2(gc: &mut Vec<Draw>, space: &Space, camera: Location, spread: f32) {
|
||||||
for y in itertools_num::linspace(-spread, spread, 101) {
|
for y in itertools_num::linspace(-spread, spread, 101) {
|
||||||
let ray_dir = vec2(1., y);
|
draw_ray_2(gc, space, camera, vec2(1., y));
|
||||||
draw_ray_2(gc, space, camera.pos, camera.rot * ray_dir);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
use glam::{bool, f32, vec2, Mat2, Vec2};
|
use glam::{bool, f32, vec2, Mat2, Vec2};
|
||||||
|
|
||||||
|
use crate::ifaces::{DebugTraceable, RayPath, Traceable};
|
||||||
use coords::{FlatCoordinateSystem, InnerCS, OuterCS};
|
use coords::{FlatCoordinateSystem, InnerCS, OuterCS};
|
||||||
use metric::Tube;
|
use metric::Tube;
|
||||||
use Subspace::{Boundary, Inner, Outer};
|
use Subspace::{Boundary, Inner, Outer};
|
||||||
|
|
||||||
use crate::riemann;
|
use crate::riemann::Metric;
|
||||||
use crate::tube::coords::FlatRegion;
|
use crate::tube::coords::FlatRegion;
|
||||||
use crate::types::{FlatTraceResult, Hit, Location, Object, Ray};
|
use crate::types::{FlatTraceResult, Hit, Location, Object, Ray};
|
||||||
|
use crate::{riemann, DT};
|
||||||
|
|
||||||
mod coords;
|
mod coords;
|
||||||
pub mod metric;
|
pub mod metric;
|
||||||
|
|
@ -153,6 +155,55 @@ impl Space {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Traceable for Space {
|
||||||
|
fn trace(&self, camera: Location, ray: Ray) -> Vec<Hit> {
|
||||||
|
self.trace_dbg(camera, ray).0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugTraceable for Space {
|
||||||
|
fn trace_dbg(&self, camera: Location, ray: Ray) -> (Vec<Hit>, RayPath) {
|
||||||
|
let mut points = vec![];
|
||||||
|
let mut hits = vec![];
|
||||||
|
let mut ray = Ray {
|
||||||
|
pos: camera.pos,
|
||||||
|
dir: camera.rot * ray.dir,
|
||||||
|
}; // TODO account for ray.pos
|
||||||
|
ray.dir = self.tube.normalize_vec_at(ray.pos, ray.dir) * DT;
|
||||||
|
|
||||||
|
let trace_to_flat = |points: &mut Vec<Vec2>, ray| {
|
||||||
|
for ray in self.trace_iter(ray).skip(1) {
|
||||||
|
points.push(ray.pos);
|
||||||
|
let hitter = match self.which_subspace(ray.pos) {
|
||||||
|
Inner => Self::trace_inner,
|
||||||
|
Outer => Self::trace_outer,
|
||||||
|
Boundary => continue,
|
||||||
|
};
|
||||||
|
return (ray, hitter(self, ray));
|
||||||
|
}
|
||||||
|
unreachable!("Space::trace_iter terminated!")
|
||||||
|
};
|
||||||
|
|
||||||
|
points.push(ray.pos);
|
||||||
|
for _ in 0..100 {
|
||||||
|
let (ray_into_flat, ret) = trace_to_flat(&mut points, ray);
|
||||||
|
hits.extend(ret.objects); // TODO fix distance
|
||||||
|
let Some(ray_outta_flat) = ret.end else {
|
||||||
|
return (
|
||||||
|
hits,
|
||||||
|
RayPath {
|
||||||
|
points,
|
||||||
|
end_dir: ray_into_flat.dir.normalize(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
points.extend(self.line(ray_into_flat.pos, ray_outta_flat.pos, 10.0));
|
||||||
|
ray = ray_outta_flat;
|
||||||
|
}
|
||||||
|
panic!("tracing didn't terminate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Rect {
|
struct Rect {
|
||||||
pub size: Vec2,
|
pub size: Vec2,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user