Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nicer frustum ray #1019

Merged
merged 2 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions crates/re_viewer/src/ui/view_spatial/scene/scene_part/cameras.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,17 @@ impl CamerasPart {
return;
};

// Actual primitives are generated later.
// Currently, we need information about viewport to display it correctly.
// TODO(andreas): Would be great if we add all the lines etc. right away!
// Let's attempt this as part of
// https://github.com/rerun-io/rerun/issues/681 (Improve camera frustum length heuristic & editability)
// and https://github.com/rerun-io/rerun/issues/686 (Replace camera mesh with expressive camera gizmo (extension of current frustum)
let frustum_length = props.pinhole_image_plane_distance(&pinhole);

scene.space_cameras.push(SpaceCamera3D {
entity_path: entity_path.clone(),
instance_path_hash,
view_coordinates,
world_from_camera,
pinhole: Some(pinhole),
picture_plane_distance: Some(frustum_length),
});

let frustum_length = props.pinhole_image_plane_distance(&pinhole);

// TODO(andreas): FOV fallback doesn't make much sense. What does pinhole without fov mean?
let fov_y = pinhole.fov_y().unwrap_or(std::f32::consts::FRAC_PI_2);
let fy = (fov_y * 0.5).tan() * frustum_length;
Expand Down
3 changes: 3 additions & 0 deletions crates/re_viewer/src/ui/view_spatial/space_camera_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub struct SpaceCamera3D {
// Optional projection-related things:
/// The projection transform of a child-entity.
pub pinhole: Option<re_log_types::Pinhole>,

/// Optional distance of a picture plane from the camera.
pub picture_plane_distance: Option<f32>,
}

impl SpaceCamera3D {
Expand Down
61 changes: 29 additions & 32 deletions crates/re_viewer/src/ui/view_spatial/ui_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,45 +602,42 @@ fn show_projections_from_2d_space(
scene_bbox_accum: &BoundingBox,
) {
if let HoveredSpace::TwoD { space_2d, pos } = ctx.selection_state().hovered_space() {
let mut point_batch = scene
.primitives
.points
.batch("projection from 2d hit points");
let mut line_batch = scene.primitives.line_strips.batch("picking ray");

for cam in &scene.space_cameras {
if &cam.entity_path == space_2d {
if let Some(ray) = cam.unproject_as_ray(glam::vec2(pos.x, pos.y)) {
// TODO(emilk): better visualization of a ray
let mut hit_pos = None;
if pos.z.is_finite() && pos.z > 0.0 {
if let Some(world_from_image) = cam.world_from_image() {
let pos = world_from_image
.transform_point3(glam::vec3(pos.x, pos.y, 1.0) * pos.z);
hit_pos = Some(pos);
}
}
let length = if let Some(hit_pos) = hit_pos {
hit_pos.distance(cam.position())
// Render a thick line to the actual z value if any and a weaker one as an extension
// If we don't have a z value, we only render the thick one.
let thick_ray_length = if pos.z.is_finite() && pos.z > 0.0 {
Some(pos.z)
} else {
4.0 * scene_bbox_accum.half_size().length() // should be long enough
cam.picture_plane_distance
};

let origin = ray.point_along(0.0);
let end = ray.point_along(length);
let radius = Size::new_points(1.5);

scene
.primitives
.line_strips
.batch("ray")
.add_segment(origin, end)
.radius(radius);

if let Some(pos) = hit_pos {
// Show where the ray hits the depth map:
point_batch
.add_point(pos)
.radius(radius * 3.0)
.color(egui::Color32::WHITE);
// No harm in making this ray _very_ long. (Infinite messes with things though!)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as long as it is not counted into scene_bbox_accum 😬

(btw, I think the frustum box is perhaps counted to scene_bbox_accum, which messes up auto-camera-centering after having a large frustum distance)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, frustum box is counted :/
and indeed this one is not because it comes after scene build up
not fond or the way we do the bounding box overall

let fallback_ray_end = ray.point_along(scene_bbox_accum.size().length() * 10.0);

if let Some(line_length) = thick_ray_length {
let main_ray_end = ray.point_along(line_length);
line_batch
.add_segment(origin, main_ray_end)
.color(egui::Color32::WHITE)
.flags(re_renderer::renderer::LineStripFlags::NO_COLOR_GRADIENT)
.radius(Size::new_points(1.0));
line_batch
.add_segment(main_ray_end, fallback_ray_end)
.color(egui::Color32::DARK_GRAY)
// TODO(andreas): Make this dashed.
.flags(re_renderer::renderer::LineStripFlags::NO_COLOR_GRADIENT)
.radius(Size::new_points(0.5));
} else {
line_batch
.add_segment(origin, fallback_ray_end)
.color(egui::Color32::WHITE)
.flags(re_renderer::renderer::LineStripFlags::NO_COLOR_GRADIENT)
.radius(Size::new_points(1.0));
}
}
}
Expand Down