Record relative ray direction on hit
This commit is contained in:
parent
d5c2e34157
commit
fdc4e22da0
|
|
@ -133,7 +133,7 @@ struct Hit {
|
|||
distance: f32,
|
||||
id: i32,
|
||||
pos: Vec2, // положение в основной СК
|
||||
rel: Vec2, // положение в локальной ортонормированной СК объекта
|
||||
rel: Ray, // в локальной ортонормированной СК объекта
|
||||
}
|
||||
|
||||
struct HitInternal<'a> {
|
||||
|
|
@ -200,8 +200,10 @@ impl Space {
|
|||
objects: hits.into_iter().filter_map(|HitInternal { object, distance }|
|
||||
if distance < dist {
|
||||
let pos = ray.forward(distance).pos;
|
||||
// NB: object.loc.rot задан относительно object.loc.pos, поэтому и ray_to_global надо делать относительно object.loc.pos, а не pos.
|
||||
let rel = object.loc.rot.inverse() * cell.ray_to_global(Ray { pos: object.loc.pos, dir: pos - object.loc.pos }).dir;
|
||||
Some(Hit { id: object.id, distance, pos: cell.pos_to_global(pos), rel })
|
||||
let dir = object.loc.rot.inverse() * cell.ray_to_global(Ray { pos: object.loc.pos, dir: ray.dir }).dir;
|
||||
Some(Hit { id: object.id, distance, pos: cell.pos_to_global(pos), rel: Ray { pos: rel, dir } })
|
||||
} else { None }
|
||||
).collect(),
|
||||
}
|
||||
|
|
@ -220,7 +222,8 @@ impl Space {
|
|||
if distance < dist {
|
||||
let pos = ray.forward(distance).pos;
|
||||
let rel = object.loc.rot.inverse() * (pos - object.loc.pos);
|
||||
Some(Hit { id: object.id, distance, pos, rel })
|
||||
let dir = object.loc.rot.inverse() * ray.dir;
|
||||
Some(Hit { id: object.id, distance, pos, rel: Ray { pos: rel, dir } })
|
||||
} else { None }
|
||||
).collect(),
|
||||
}
|
||||
|
|
@ -336,10 +339,20 @@ fn draw_ray_2(gc: &mut Vec<Draw>, space: &Space, base: Vec2, dir: Vec2) {
|
|||
for hit in ret.objects {
|
||||
let obj = space.objs[hit.id as usize];
|
||||
hits.move_to(obj.loc.pos.x, obj.loc.pos.y);
|
||||
for pt in trace_iter(&space.rect, obj.loc.pos, obj.loc.rot * hit.rel, hit.rel.length() / 100.0).take(100) {
|
||||
for pt in trace_iter(&space.rect, obj.loc.pos, obj.loc.rot * hit.rel.pos, hit.rel.pos.length() / 100.0).take(100) {
|
||||
hits.line_to(pt.x, pt.y);
|
||||
}
|
||||
hits.circle(hit.pos.x, hit.pos.y, 1.5);
|
||||
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 = trace_iter(&space.rect, obj.loc.pos, obj.loc.rot * rel2, rel2.length() / 100.0).nth(100).unwrap();
|
||||
hits.move_to(pos2.x - 1.0, pos2.y - 1.0);
|
||||
hits.line_to(pos2.x + 1.0, pos2.y + 1.0);
|
||||
hits.move_to(pos2.x - 1.0, pos2.y + 1.0);
|
||||
hits.line_to(pos2.x + 1.0, pos2.y - 1.0);
|
||||
}
|
||||
let a = ray.pos;
|
||||
ray = match ret.end {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user