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

Make the space views bigger and less cluttered #269

Merged
merged 17 commits into from
Nov 8, 2022
Next Next commit
Move view3d settings to Selection View
  • Loading branch information
emilk committed Nov 8, 2022
commit 47dae5d25ba30581b86f75156429e6ae982758c7
11 changes: 10 additions & 1 deletion crates/re_viewer/src/ui/selection_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,14 @@ fn ui_space_view(ctx: &mut ViewerContext<'_>, ui: &mut egui::Ui, space_view: &mu
ui.end_row();
});

// TODO(emilk): view settings
ui.separator();

match space_view.selected_category {
super::space_view::ViewCategory::TwoD => {}
super::space_view::ViewCategory::ThreeD => {
ui.label("3D:");
super::view_3d::show_settings_ui(ctx, ui, &mut space_view.view_state.state_3d);
}
super::space_view::ViewCategory::Tensor | super::space_view::ViewCategory::Text => {}
}
}
18 changes: 6 additions & 12 deletions crates/re_viewer/src/ui/space_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::{view_2d, view_3d, view_tensor, view_text, Scene};
// ----------------------------------------------------------------------------

#[derive(Copy, Clone, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
enum ViewCategory {
pub(crate) enum ViewCategory {
TwoD,
#[default]
ThreeD,
Expand All @@ -26,7 +26,7 @@ pub(crate) struct SpaceView {
pub view_state: ViewState,

/// In case we are a mix of 2d/3d/tensor/text, we show what?
selected_category: ViewCategory,
pub selected_category: ViewCategory,

pub obj_tree_properties: ObjectTreeProperties,
}
Expand Down Expand Up @@ -75,6 +75,7 @@ impl SpaceView {
match categories.len() {
0 => ui.label("(empty)"),
1 => {
self.selected_category = categories[0];
if has_2d {
self.view_state
.ui_2d(ctx, ui, &self.space_path, &scene.two_d)
Expand Down Expand Up @@ -179,16 +180,9 @@ impl ViewState {
let state = &mut self.state_3d;
let space_cameras = &space_cameras(spaces_info, space_info);
let coordinates = space_info.coordinates;
let space_specs = view_3d::SpaceSpecs::from_view_coordinates(coordinates);
view_3d::view_3d(
ctx,
ui,
state,
Some(space),
&space_specs,
scene,
space_cameras,
);
state.space_specs = view_3d::SpaceSpecs::from_view_coordinates(coordinates);
view_3d::view_3d(ctx, ui, state, Some(space), scene, space_cameras);
crate::misc::help_hover_button(ui).on_hover_text(view_3d::HELP_TEXT);
})
.response
}
Expand Down
2 changes: 1 addition & 1 deletion crates/re_viewer/src/ui/view_3d/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub use self::scene::{
};

mod ui;
pub(crate) use self::ui::{view_3d, SpaceSpecs, View3DState};
pub(crate) use self::ui::{show_settings_ui, view_3d, SpaceSpecs, View3DState, HELP_TEXT};

#[cfg(feature = "glow")]
mod glow_rendering;
141 changes: 67 additions & 74 deletions crates/re_viewer/src/ui/view_3d/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub(crate) struct View3DState {
show_axes: bool,

last_eye_interact_time: f64,

/// Filled in at the start of each frame
#[serde(skip)]
pub space_specs: SpaceSpecs,
}

impl Default for View3DState {
Expand All @@ -54,6 +58,7 @@ impl Default for View3DState {
spin: false,
show_axes: false,
last_eye_interact_time: f64::NEG_INFINITY,
space_specs: Default::default(),
}
}
}
Expand All @@ -64,14 +69,13 @@ impl View3DState {
ctx: &mut ViewerContext<'_>,
tracking_camera: Option<Eye>,
response: &egui::Response,
space_specs: &SpaceSpecs,
) -> &mut OrbitEye {
if response.double_clicked() {
// Reset camera
if tracking_camera.is_some() {
ctx.rec_cfg.selection = Selection::None;
}
self.interpolate_to_orbit_eye(default_eye(&self.scene_bbox, space_specs));
self.interpolate_to_orbit_eye(default_eye(&self.scene_bbox, &self.space_specs));
}

if let Some(tracking_camera) = tracking_camera {
Expand All @@ -89,7 +93,7 @@ impl View3DState {

let orbit_camera = self
.orbit_eye
.get_or_insert_with(|| default_eye(&self.scene_bbox, space_specs));
.get_or_insert_with(|| default_eye(&self.scene_bbox, &self.space_specs));

if self.spin {
orbit_camera.rotate(egui::vec2(
Expand Down Expand Up @@ -175,82 +179,64 @@ impl EyeInterpolation {
}
}

fn show_settings_ui(
pub(crate) fn show_settings_ui(
ctx: &mut ViewerContext<'_>,
ui: &mut egui::Ui,
state: &mut View3DState,
space_specs: &SpaceSpecs,
) {
ui.horizontal(|ui| {
{
let up_response = if let Some(up) = space_specs.up {
if up == Vec3::X {
ui.label("Up: +X")
} else if up == -Vec3::X {
ui.label("Up: -X")
} else if up == Vec3::Y {
ui.label("Up: +Y")
} else if up == -Vec3::Y {
ui.label("Up: -Y")
} else if up == Vec3::Z {
ui.label("Up: +Z")
} else if up == -Vec3::Z {
ui.label("Up: -Z")
} else if up != Vec3::ZERO {
ui.label(format!("Up: [{:.3} {:.3} {:.3}]", up.x, up.y, up.z))
} else {
ui.label("Up: —")
}
{
let up_response = if let Some(up) = state.space_specs.up {
if up == Vec3::X {
ui.label("Up: +X")
} else if up == -Vec3::X {
ui.label("Up: -X")
} else if up == Vec3::Y {
ui.label("Up: +Y")
} else if up == -Vec3::Y {
ui.label("Up: -Y")
} else if up == Vec3::Z {
ui.label("Up: +Z")
} else if up == -Vec3::Z {
ui.label("Up: -Z")
} else if up != Vec3::ZERO {
ui.label(format!("Up: [{:.3} {:.3} {:.3}]", up.x, up.y, up.z))
} else {
ui.label("Up: —")
};

up_response.on_hover_ui(|ui| {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0;
ui.label("Set with ");
ui.code("rerun.log_view_coordinates");
ui.label(".");
});
}
} else {
ui.label("Up: —")
};

up_response.on_hover_ui(|ui| {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0;
ui.label("Set with ");
ui.code("rerun.log_view_coordinates");
ui.label(".");
});
}
});
}

if ui
.button("Reset view")
.on_hover_text("You can also double-click the 3D view")
.clicked()
{
state.orbit_eye = Some(default_eye(&state.scene_bbox, space_specs));
state.eye_interpolation = None;
// TODO(emilk): reset tracking camera too
}
if ui
.button("Reset camera")
.on_hover_text("You can also double-click the 3D view")
.clicked()
{
state.orbit_eye = Some(default_eye(&state.scene_bbox, &state.space_specs));
state.eye_interpolation = None;
// TODO(emilk): reset tracking camera too
}

// TODO(emilk): only show if there is a camera om scene.
ui.toggle_value(&mut ctx.options.show_camera_mesh_in_3d, "📷")
.on_hover_text("Show camera mesh");

ui.toggle_value(&mut state.spin, "Spin")
.on_hover_text("Spin view");
ui.toggle_value(&mut state.show_axes, "Axes")
.on_hover_text("Show X-Y-Z axes");

crate::misc::help_hover_button(ui).on_hover_text(
"Drag to rotate.\n\
Drag with secondary mouse button to pan.\n\
Drag with middle mouse button to roll the view.\n\
Scroll to zoom.\n\
\n\
While hovering the 3D view, navigate with WSAD and QE.\n\
CTRL slows down, SHIFT speeds up.\n\
\n\
Click on a object to focus the view on it.\n\
\n\
Double-click anywhere to reset the view.",
);
});
// TODO(emilk): only show if there is a camera om scene.
ui.toggle_value(&mut ctx.options.show_camera_mesh_in_3d, "Show camera mesh");

ui.toggle_value(&mut state.spin, "Spin Camera")
.on_hover_text("Spin view");
ui.toggle_value(&mut state.show_axes, "Show Axes")
.on_hover_text("Show X-Y-Z axes");
}

#[derive(Default)]
#[derive(Clone, Default)]
pub(crate) struct SpaceSpecs {
up: Option<glam::Vec3>,
right: Option<glam::Vec3>,
Expand Down Expand Up @@ -314,27 +300,34 @@ fn click_object(

// ----------------------------------------------------------------------------

pub(crate) const HELP_TEXT: &str = "Drag to rotate.\n\
Drag with secondary mouse button to pan.\n\
Drag with middle mouse button to roll the view.\n\
Scroll to zoom.\n\
\n\
While hovering the 3D view, navigate with WSAD and QE.\n\
CTRL slows down, SHIFT speeds up.\n\
\n\
Click on a object to focus the view on it.\n\
\n\
Double-click anywhere to reset the view.";

pub(crate) fn view_3d(
ctx: &mut ViewerContext<'_>,
ui: &mut egui::Ui,
state: &mut View3DState,
space: Option<&ObjPath>,
space_specs: &SpaceSpecs,
scene: &mut Scene3D,
space_cameras: &[SpaceCamera],
) -> egui::Response {
crate::profile_function!();

state.scene_bbox = state.scene_bbox.union(scene.calc_bbox());

// TODO(emilk): show settings on top of 3D view.
// Requires some egui work to handle interaction of overlapping widgets.
show_settings_ui(ctx, ui, state, space_specs);

let (rect, response) = ui.allocate_at_least(ui.available_size(), egui::Sense::click_and_drag());

let tracking_camera = tracking_camera(ctx, space_cameras);
let orbit_eye = state.update_eye(ctx, tracking_camera, &response, space_specs);
let orbit_eye = state.update_eye(ctx, tracking_camera, &response);

let did_interact_wth_eye = orbit_eye.interact(&response);
let orbit_eye = *orbit_eye;
Expand Down