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