Skip to content

Make the near clipping plane editable in 2D views #8348

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

Merged
merged 15 commits into from
Dec 9, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ table VisualBounds2D (
///
/// Use this to control pan & zoom of the view.
range: rerun.blueprint.components.VisualBounds2D ("attr.rerun.component_required", order: 1000);

/// Controls the distance to the near clipping plane
clipping_plane: rerun.blueprint.components.ClippingPlane ("attr.rerun.component_optional", order: 2000);
Copy link
Member

Choose a reason for hiding this comment

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

maybe better to call the field near_clip_plane - near for descriptiveness, clip for brevity (and the type then ClipPlane)

(?)

}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace rerun.blueprint.components;

// ---

/// Distance to the near clipping plane in used for `Spatial2DView`.
struct ClippingPlane (
"attr.rerun.scope": "blueprint",
"attr.rust.derive": "Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable",
"attr.rust.repr": "transparent",
"attr.docs.unreleased"
) {
/// Z distance to the near clipping plane
clipping_plane: rerun.datatypes.Float32 (order: 100);
}
42 changes: 34 additions & 8 deletions crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

116 changes: 116 additions & 0 deletions crates/store/re_types/src/blueprint/components/clipping_plane.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/rust/api.rs
// Based on "crates/store/re_types/definitions/rerun/blueprint/components/clipping_plane.fbs".

#![allow(unused_imports)]
#![allow(unused_parens)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::cloned_instead_of_copied)]
#![allow(clippy::map_flatten)]
#![allow(clippy::needless_question_mark)]
#![allow(clippy::new_without_default)]
#![allow(clippy::redundant_closure)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::too_many_lines)]

use ::re_types_core::external::arrow2;
use ::re_types_core::ComponentName;
use ::re_types_core::SerializationResult;
use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch};
use ::re_types_core::{DeserializationError, DeserializationResult};

/// **Component**: Distance to the near clipping plane in used for `Spatial2DView`.
#[derive(Clone, Debug, Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
#[repr(transparent)]
pub struct ClippingPlane(
/// Z distance to the near clipping plane
pub crate::datatypes::Float32,
);

impl ::re_types_core::SizeBytes for ClippingPlane {
#[inline]
fn heap_size_bytes(&self) -> u64 {
self.0.heap_size_bytes()
}

#[inline]
fn is_pod() -> bool {
<crate::datatypes::Float32>::is_pod()
}
}

impl<T: Into<crate::datatypes::Float32>> From<T> for ClippingPlane {
fn from(v: T) -> Self {
Self(v.into())
}
}

impl std::borrow::Borrow<crate::datatypes::Float32> for ClippingPlane {
#[inline]
fn borrow(&self) -> &crate::datatypes::Float32 {
&self.0
}
}

impl std::ops::Deref for ClippingPlane {
type Target = crate::datatypes::Float32;

#[inline]
fn deref(&self) -> &crate::datatypes::Float32 {
&self.0
}
}

impl std::ops::DerefMut for ClippingPlane {
#[inline]
fn deref_mut(&mut self) -> &mut crate::datatypes::Float32 {
&mut self.0
}
}

::re_types_core::macros::impl_into_cow!(ClippingPlane);

impl ::re_types_core::Loggable for ClippingPlane {
#[inline]
fn arrow_datatype() -> arrow::datatypes::DataType {
crate::datatypes::Float32::arrow_datatype()
}

fn to_arrow_opt<'a>(
data: impl IntoIterator<Item = Option<impl Into<::std::borrow::Cow<'a, Self>>>>,
) -> SerializationResult<arrow::array::ArrayRef>
where
Self: Clone + 'a,
{
crate::datatypes::Float32::to_arrow_opt(data.into_iter().map(|datum| {
datum.map(|datum| match datum.into() {
::std::borrow::Cow::Borrowed(datum) => ::std::borrow::Cow::Borrowed(&datum.0),
::std::borrow::Cow::Owned(datum) => ::std::borrow::Cow::Owned(datum.0),
})
}))
}

fn from_arrow2_opt(
arrow_data: &dyn arrow2::array::Array,
) -> DeserializationResult<Vec<Option<Self>>>
where
Self: Sized,
{
crate::datatypes::Float32::from_arrow2_opt(arrow_data)
.map(|v| v.into_iter().map(|v| v.map(Self)).collect())
}

#[inline]
fn from_arrow2(arrow_data: &dyn arrow2::array::Array) -> DeserializationResult<Vec<Self>>
where
Self: Sized,
{
crate::datatypes::Float32::from_arrow2(arrow_data).map(bytemuck::cast_vec)
}
}

impl ::re_types_core::Component for ClippingPlane {
#[inline]
fn name() -> ComponentName {
"rerun.blueprint.components.ClippingPlane".into()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use re_types_core::datatypes::Float32;

use super::ClippingPlane;

impl Default for ClippingPlane {
#[inline]
fn default() -> Self {
// Default clipping plane set at a reasonable distance for common cameras
Self(Float32(0.1))
}
}
3 changes: 3 additions & 0 deletions crates/store/re_types/src/blueprint/components/mod.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion crates/viewer/re_component_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ use datatype_uis::{

use re_types::{
blueprint::components::{
BackgroundKind, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider, ViewFit, Visible,
BackgroundKind, ClippingPlane, Corner2D, GridSpacing, LockRangeDuringZoom, MapProvider,
ViewFit, Visible,
},
components::{
AggregationPolicy, AlbedoFactor, AxisLength, Color, DepthMeter, DrawOrder, FillMode,
Expand Down Expand Up @@ -76,6 +77,7 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry
registry.add_singleline_edit_or_view::<ImagePlaneDistance>(edit_f32_zero_to_max);
registry.add_singleline_edit_or_view::<MarkerSize>(edit_ui_points);
registry.add_singleline_edit_or_view::<StrokeWidth>(edit_ui_points);
registry.add_singleline_edit_or_view::<ClippingPlane>(edit_f32_zero_to_max);

// float min-max components:
registry.add_singleline_edit_or_view::<DrawOrder>(edit_f32_min_to_max_float);
Expand Down
30 changes: 20 additions & 10 deletions crates/viewer/re_space_view_spatial/src/ui_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ use re_types::{
};
use re_ui::{ContextExt as _, ModifiersMarkdown, MouseButtonMarkdown};
use re_viewer_context::{
gpu_bridge, ItemSpaceContext, SpaceViewId, SpaceViewSystemExecutionError, ViewQuery,
ViewerContext,
gpu_bridge, ItemSpaceContext, SpaceViewSystemExecutionError, ViewQuery, ViewerContext,
};
use re_viewport_blueprint::ViewProperty;

Expand All @@ -31,16 +30,11 @@ use crate::{
/// Pan and zoom, and return the current transform.
fn ui_from_scene(
ctx: &ViewerContext<'_>,
view_id: SpaceViewId,
response: &egui::Response,
view_class: &SpatialSpaceView2D,
view_state: &mut SpatialSpaceViewState,
bounds_property: &ViewProperty,
) -> RectTransform {
let bounds_property = ViewProperty::from_archetype::<VisualBounds2D>(
ctx.blueprint_db(),
ctx.blueprint_query,
view_id,
);
let bounds: blueprint_components::VisualBounds2D = bounds_property
.component_or_fallback(ctx, view_class, view_state)
.ok_or_log_error()
Expand Down Expand Up @@ -169,20 +163,35 @@ impl SpatialSpaceView2D {
let (response, painter) =
ui.allocate_painter(ui.available_size(), egui::Sense::click_and_drag());

let bounds_property = ViewProperty::from_archetype::<VisualBounds2D>(
ctx.blueprint_db(),
ctx.blueprint_query,
query.space_view_id,
);

// Convert ui coordinates to/from scene coordinates.
let ui_from_scene = ui_from_scene(ctx, query.space_view_id, &response, self, state);
let ui_from_scene = ui_from_scene(ctx, &response, self, state, &bounds_property);
let scene_from_ui = ui_from_scene.inverse();

let clipping_plane: blueprint_components::ClippingPlane = bounds_property
.component_or_fallback(ctx, self, state)
.ok_or_log_error()
.unwrap_or_default();

// TODO(andreas): Use the same eye & transformations as in `setup_target_config`.
let eye = Eye {
world_from_rub_view: IsoTransform::IDENTITY,
fov_y: None,
};

// Don't let clipping plane become zero
let clipping_plane = f32::max(f32::MIN_POSITIVE, *clipping_plane.0);

let scene_bounds = *scene_from_ui.to();
let Ok(target_config) = setup_target_config(
&painter,
scene_bounds,
clipping_plane,
&query.space_origin.to_string(),
query.highlights.any_outlines(),
&state.pinhole_at_origin,
Expand Down Expand Up @@ -287,6 +296,7 @@ impl SpatialSpaceView2D {
fn setup_target_config(
egui_painter: &egui::Painter,
scene_bounds: Rect,
clipping_plane: f32,
space_name: &str,
any_outlines: bool,
scene_pinhole: &Option<Pinhole>,
Expand Down Expand Up @@ -350,7 +360,7 @@ fn setup_target_config(

let projection_from_view = re_renderer::view_builder::Projection::Perspective {
vertical_fov: pinhole.fov_y().unwrap_or(Eye::DEFAULT_FOV_Y),
near_plane_distance: 0.1,
near_plane_distance: clipping_plane,
aspect_ratio: pinhole
.aspect_ratio()
.unwrap_or(scene_bounds_size.x / scene_bounds_size.y), // only happens if the pinhole lacks resolution
Expand Down
2 changes: 2 additions & 0 deletions crates/viewer/re_viewer/src/blueprint/validation_gen/mod.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading