Skip to content

Commit

Permalink
multi line edit for plane
Browse files Browse the repository at this point in the history
  • Loading branch information
Wumpf committed Dec 3, 2024
1 parent 294d408 commit d884bd3
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 36 deletions.
1 change: 1 addition & 0 deletions crates/store/re_types/src/components/plane3d_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ impl Plane3D {
/// Create a new plane from a normal and distance.
///
/// The plane will not be normalized upon creation.
#[inline]
pub fn new(normal: impl Into<crate::datatypes::Vec3D>, d: f32) -> Self {
Self(crate::datatypes::Plane3D::new(normal, d))
}
Expand Down
3 changes: 3 additions & 0 deletions crates/store/re_types/src/datatypes/plane3d_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,21 @@ impl Plane3D {
pub const XY: Self = Self([0.0, 0.0, 1.0, 0.0]);

/// The normal of the plane (unnormalized if the plane is unnormalized).
#[inline]
pub const fn normal(&self) -> super::Vec3D {
super::Vec3D([self.0[0], self.0[1], self.0[2]])
}

/// The distance of the plane from the origin (in multiples of the normal if the normal is unnormalized).
#[inline]
pub const fn distance(&self) -> f32 {
self.0[3]
}

/// Create a new plane from a normal and distance.
///
/// The plane will not be normalized upon creation.
#[inline]
pub fn new(normal: impl Into<crate::datatypes::Vec3D>, d: f32) -> Self {
let normal = normal.into();
Self([normal.0[0], normal.0[1], normal.0[2], d])
Expand Down
30 changes: 26 additions & 4 deletions crates/viewer/re_component_ui/src/datatype_uis/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,31 @@ pub fn edit_or_view_vec3d(
MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value),
MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(value),
};
edit_or_view_vec3d_raw(ui, &mut value)
edit_or_view_vec3d_raw_immutable(ui, &mut value)
}

// TODO(#6743): Since overrides are not yet taken into account, editing this value has no effect.
//MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value[i]),
fn edit_or_view_vec3d_raw_immutable(
ui: &mut egui::Ui,
value: &mut MaybeMutRef<'_, datatypes::Vec3D>,
) -> egui::Response {
edit_or_view_vector_component_immutable(ui, value, 0)
| edit_or_view_vector_component_immutable(ui, value, 1)
| edit_or_view_vector_component_immutable(ui, value, 2)
}

fn edit_or_view_vector_component_immutable(
ui: &mut egui::Ui,
value: &mut MaybeMutRef<'_, datatypes::Vec3D>,
i: usize,
) -> egui::Response {
let mut value: MaybeMutRef<'_, f32> = match value {
MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value[i]),

MaybeMutRef::MutRef(value) => MaybeMutRef::Ref(&value[i]),
};
edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX)
}

pub fn edit_or_view_vec3d_raw(
Expand All @@ -31,9 +55,7 @@ fn edit_or_view_vector_component(
) -> egui::Response {
let mut value: MaybeMutRef<'_, f32> = match value {
MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value[i]),
// TODO(#6743): Since overrides are not yet taken into account, editing this value has no effect.
//MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value[i]),
MaybeMutRef::MutRef(value) => MaybeMutRef::Ref(&value[i]),
MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value[i]),
};
edit_f32_float_raw(ui, &mut value, f32::MIN..=f32::MAX)
}
3 changes: 2 additions & 1 deletion crates/viewer/re_component_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry

registry.add_singleline_edit_or_view(zoom_level::edit_zoom_level);

// TODO: add ui for plane
registry.add_singleline_edit_or_view(plane3d::edit_or_view_plane3d);
registry.add_multiline_edit_or_view(plane3d::multiline_edit_or_view_plane3d);

registry
}
172 changes: 146 additions & 26 deletions crates/viewer/re_component_ui/src/plane3d.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,162 @@
use re_types::datatypes;
use re_types::{components, external::glam};
use re_ui::UiExt as _;
use re_viewer_context::MaybeMutRef;

use crate::datatype_uis::{edit_f32_float_raw, edit_or_view_vec3d_raw};
use crate::{
datatype_uis::{edit_f32_float_raw, edit_or_view_vec3d_raw},
response_utils::response_with_changes_of_inner,
};

#[derive(PartialEq, Eq, Copy, Clone)]
enum AxisDirection {
PosX,
PosY,
PosZ,
NegX,
NegY,
NegZ,
}

impl AxisDirection {
const VARIANTS: [Self; 6] = [
Self::PosX,
Self::PosY,
Self::PosZ,
Self::NegX,
Self::NegY,
Self::NegZ,
];
}

impl std::fmt::Display for AxisDirection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::PosX => write!(f, "+X"),
Self::PosY => write!(f, "+Y"),
Self::PosZ => write!(f, "+Z"),
Self::NegX => write!(f, "-X"),
Self::NegY => write!(f, "-Y"),
Self::NegZ => write!(f, "-Z"),
}
}
}

impl TryFrom<glam::Vec3> for AxisDirection {
type Error = ();

fn try_from(value: glam::Vec3) -> Result<Self, Self::Error> {
match value {
glam::Vec3::X => Ok(Self::PosX),
glam::Vec3::Y => Ok(Self::PosY),
glam::Vec3::Z => Ok(Self::PosZ),
glam::Vec3::NEG_X => Ok(Self::NegX),
glam::Vec3::NEG_Y => Ok(Self::NegY),
glam::Vec3::NEG_Z => Ok(Self::NegZ),
_ => Err(()),
}
}
}

impl From<AxisDirection> for glam::Vec3 {
fn from(value: AxisDirection) -> Self {
match value {
AxisDirection::PosX => Self::X,
AxisDirection::PosY => Self::Y,
AxisDirection::PosZ => Self::Z,
AxisDirection::NegX => Self::NEG_X,
AxisDirection::NegY => Self::NEG_Y,
AxisDirection::NegZ => Self::NEG_Z,
}
}
}

pub fn edit_or_view_plane3d(
_ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
value: &mut MaybeMutRef<'_, impl std::ops::DerefMut<Target = datatypes::Plane3D>>,
value: &mut MaybeMutRef<'_, components::Plane3D>,
) -> egui::Response {
let mut value: MaybeMutRef<'_, datatypes::Plane3D> = match value {
MaybeMutRef::Ref(value) => MaybeMutRef::Ref(value),
MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(value),
let distance = value.distance();

ui.label("n");
// Show simplified combobox if this is is axis aligned.
let normal_response = if let Ok(mut axis_dir) =
AxisDirection::try_from(glam::Vec3::from(value.normal()))
{
response_with_changes_of_inner(
egui::ComboBox::from_id_salt("plane_normal")
.selected_text(format!("{axis_dir}"))
.height(250.0)
.show_ui(ui, |ui| {
let mut variants = AxisDirection::VARIANTS.iter();
#[allow(clippy::unwrap_used)] // We know there's more than zero variants.
let variant = variants.next().unwrap();

let mut response =
ui.selectable_value(&mut axis_dir, *variant, variant.to_string());
for variant in variants {
response |=
ui.selectable_value(&mut axis_dir, *variant, variant.to_string());
}

if let MaybeMutRef::MutRef(value) = value {
**value = components::Plane3D::new(glam::Vec3::from(axis_dir), distance);
}
response
}),
)
} else {
// Editing for arbitrary normals takes too much space here.
edit_or_view_vec3d_raw(ui, &mut MaybeMutRef::Ref(&value.normal()))
};

ui.label("d");
let mut maybe_mut_distance = match value {
MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value.0 .0[3]),
MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.0 .0[3]),
};
edit_or_view_plane3d_impl(ui, &mut value)
let distance_response = edit_f32_float_raw(ui, &mut maybe_mut_distance, f32::MIN..=f32::MAX);

normal_response | distance_response
}

fn edit_or_view_plane3d_impl(
pub fn multiline_edit_or_view_plane3d(
_ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
value: &mut MaybeMutRef<'_, datatypes::Plane3D>,
value: &mut MaybeMutRef<'_, components::Plane3D>,
) -> egui::Response {
let mut normal = value.normal();
let mut distance = value.distance();
let (mut maybe_mut_normal, mut maybe_mutdistance) = match value {
MaybeMutRef::Ref(value) => (MaybeMutRef::Ref(&normal), MaybeMutRef::Ref(&distance)),
MaybeMutRef::MutRef(value) => (
MaybeMutRef::MutRef(&mut normal),
MaybeMutRef::MutRef(&mut distance),
),
};
let mut any_edit = false;

ui.label("n");
let normal_response = edit_or_view_vec3d_raw(ui, &mut maybe_mut_normal);
ui.label("d");
let distance_response = edit_f32_float_raw(ui, &mut maybe_mutdistance, f32::MIN..=f32::MAX);
let response_normal = ui.list_item_flat_noninteractive(
re_ui::list_item::PropertyContent::new("Normal").value_fn(|ui, _| {
let mut normal = value.normal();
let mut maybe_mut_normal = match value {
MaybeMutRef::Ref(_) => MaybeMutRef::Ref(&normal),
MaybeMutRef::MutRef(_) => MaybeMutRef::MutRef(&mut normal),
};

if let MaybeMutRef::MutRef(value) = value {
**value = datatypes::Plane3D::new(normal, distance);
}
any_edit |= edit_or_view_vec3d_raw(ui, &mut maybe_mut_normal).changed();

if let MaybeMutRef::MutRef(value) = value {
**value = components::Plane3D::new(normal, value.distance());
}
}),
);

normal_response.union(distance_response)
let response_distance = ui.list_item_flat_noninteractive(
re_ui::list_item::PropertyContent::new("Distance").value_fn(|ui, _| {
let mut maybe_mut_distance = match value {
MaybeMutRef::Ref(value) => MaybeMutRef::Ref(&value.0 .0[3]),
MaybeMutRef::MutRef(value) => MaybeMutRef::MutRef(&mut value.0 .0[3]),
};

any_edit |=
edit_f32_float_raw(ui, &mut maybe_mut_distance, f32::MIN..=f32::MAX).changed();
}),
);

let mut response = response_normal | response_distance;
if any_edit {
response.mark_changed();
}
response
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@ impl TypedComponentFallbackProvider<Plane3D> for SpatialSpaceView3D {
.state_3d
.scene_view_coordinates
.and_then(|view_coordinates| view_coordinates.up())
.map_or(DEFAULT_PLANE, |up| match up.axis {
re_types::view_coordinates::Axis3::X => Plane3D::YZ,
re_types::view_coordinates::Axis3::Y => Plane3D::ZX,
re_types::view_coordinates::Axis3::Z => Plane3D::XY,
})
.map_or(DEFAULT_PLANE, |up| Plane3D::new(up.as_vec3(), 0.0))
}
}

Expand Down

0 comments on commit d884bd3

Please sign in to comment.