Hit objects in the inner region
This commit is contained in:
parent
9ec5f17754
commit
4b511af742
|
|
@ -131,6 +131,7 @@ enum Subspace {
|
|||
struct Hit {
|
||||
distance: f32,
|
||||
id: i32,
|
||||
pos: Vec2,
|
||||
}
|
||||
|
||||
struct FlatTraceResult {
|
||||
|
|
@ -180,13 +181,19 @@ impl Space {
|
|||
std::iter::successors(Some(ray), |&ray| Some(self.trace_step(ray)))
|
||||
}
|
||||
|
||||
fn trace_inner(&self, ray: Ray) -> Ray {
|
||||
fn trace_inner(&self, ray: Ray) -> FlatTraceResult {
|
||||
assert_eq!(self.which_subspace(ray.pos), Inner);
|
||||
let cell = RectInside { rect: self.rect };
|
||||
let ray = cell.ray_to_local(ray);
|
||||
let objs = Self::trace_to_objects(self.list_objects_inner().as_slice(), ray);
|
||||
let dist = cell.to_boundary(ray).expect("Can't get outta here!");
|
||||
let ray = ray.forward(dist);
|
||||
cell.ray_to_global(ray)
|
||||
FlatTraceResult {
|
||||
end: Some(cell.ray_to_global(ray)),
|
||||
objects: objs.into_iter().filter_map(|Hit { id, distance, pos }|
|
||||
if distance < dist { Some(Hit { id, distance, pos: cell.pos_to_global(pos) }) } else { None }
|
||||
).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn trace_outer(&self, ray: Ray) -> FlatTraceResult {
|
||||
|
|
@ -234,6 +241,26 @@ impl Space {
|
|||
}).collect()
|
||||
}
|
||||
|
||||
fn list_objects_inner(&self) -> Vec<Object> {
|
||||
let cell = RectInside { rect: self.rect };
|
||||
self.objs.iter().map(|&obj| {
|
||||
match self.which_subspace(obj.loc.pos) {
|
||||
Inner | Outer => {
|
||||
// NB: не работает для частей Outer с |y| < external_halflength. Но они и не нужны.
|
||||
Object {
|
||||
id: obj.id,
|
||||
loc: Location {
|
||||
pos: cell.pos_to_local(obj.loc.pos), // в плоской СК для Inner или её продолжении на Outer
|
||||
rot: obj.loc.rot,
|
||||
},
|
||||
r: obj.r,
|
||||
}
|
||||
}
|
||||
Boundary => panic!("Object {} was destroyed by the space curvature", obj.id),
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn trace_to_objects(objs: &[Object], ray: Ray) -> Vec<Hit> {
|
||||
objs.iter()
|
||||
.filter_map(|obj| {
|
||||
|
|
@ -242,7 +269,7 @@ impl Space {
|
|||
if diff > 0.0 {
|
||||
let t = (-rel.dot(ray.dir) - diff.sqrt()) / ray.dir.length_squared();
|
||||
if t >= 0.0 {
|
||||
return Some(Hit { id: obj.id, distance: t });
|
||||
return Some(Hit { id: obj.id, distance: t, pos: ray.forward(t).pos });
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
@ -271,27 +298,22 @@ fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, base: Vec2, dir: Vec2) {
|
|||
// gc.dash_length(6.0);
|
||||
gc.new_path();
|
||||
gc.move_to(ray.pos.x, ray.pos.y);
|
||||
match sub {
|
||||
Inner => {
|
||||
ray = space.trace_inner(ray);
|
||||
}
|
||||
Outer => {
|
||||
let ret = space.trace_outer(ray);
|
||||
for hit in ret.objects {
|
||||
let r = ray.forward(hit.distance);
|
||||
hits.circle(r.pos.x, r.pos.y, 1.5);
|
||||
}
|
||||
ray = match ret.end {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
ray = ray.forward(1000.0 / DT);
|
||||
gc.line_to(ray.pos.x, ray.pos.y);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
let ret = match sub {
|
||||
Inner => space.trace_inner(ray),
|
||||
Outer => space.trace_outer(ray),
|
||||
Boundary => panic!(),
|
||||
};
|
||||
for hit in ret.objects {
|
||||
hits.circle(hit.pos.x, hit.pos.y, 1.5);
|
||||
}
|
||||
ray = match ret.end {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
ray = ray.forward(1000.0 / DT);
|
||||
gc.line_to(ray.pos.x, ray.pos.y);
|
||||
break;
|
||||
}
|
||||
};
|
||||
gc.line_to(ray.pos.x, ray.pos.y);
|
||||
gc.stroke();
|
||||
gc.new_dash_pattern();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user