Skip to content

Commit

Permalink
World grid part 2/2: Integrate into Viewer (#8234)
Browse files Browse the repository at this point in the history
### Related

* Follow-up of part 1: #8230
* Fixes #872

### What

Adds new line grid property to the 3D view and enables it by default.

Furthermore...
* improves the grid shader with infinite cardinal lines while showing
only two types of "cardinalitities"
* this is simply based on log10(camera distance from plane) and then
blends between two levels of grid
* improve grid's handling of extreme zoom levels. Still some instability
on WebGL, but overall much more robust (less flickering/cutoff)
* Introduce a general `Plane3D` component which is meant for later reuse
in other contexts

The new view property is best described its fbs:
```rust
/// Configuration for the 3D line grid.
table LineGrid3D (
    "attr.rerun.scope": "blueprint"
) {
    /// Whether the grid is visible.
    ///
    /// Defaults to true.
    visible: rerun.blueprint.components.Visible ("attr.rerun.component_optional", nullable, order: 1000);

    /// Space between grid lines spacing of one line to the next in scene units.
    ///
    /// As you zoom out, successively only every tenth line is shown.
    /// This controls the closest zoom level.
    spacing: rerun.blueprint.components.GridSpacing ("attr.rerun.component_optional", nullable, order: 2000);

    /// In what plane the grid is drawn.
    ///
    /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [components.ViewCoordinates] if present.
    plane: rerun.components.Plane3D ("attr.rerun.component_optional", nullable, order: 3000);

    /// How thick the lines should be in ui units.
    ///
    /// Default is 1.0 ui unit.
    stroke_width: rerun.components.StrokeWidth ("attr.rerun.component_optional", nullable, order: 5000);

    /// Color used for the grid.
    ///
    /// Transparency via alpha channel is supported.
    /// Defaults to a slightly transparent light gray.
    color: rerun.components.Color ("attr.rerun.component_optional", nullable, order: 6000);
}

```

Properties in the viewer in default selection panel width
<img width="291" alt="image"
src="https://github.com/user-attachments/assets/8292f7bb-e2a4-42b4-9147-7bbd72fc38c7">

New plane controls expanded:
<img width="281" alt="image"
src="https://github.com/user-attachments/assets/0cc19ce7-1031-4b58-bc24-7c2699d5e25b">



Examples of the grid in action (in default settings):
<img width="1326" alt="image"
src="https://github.com/user-attachments/assets/fe167eef-29e4-478f-a6e2-d2fb82f30a91">
<img width="1563" alt="image"
src="https://github.com/user-attachments/assets/d1a878be-16b0-4c9b-873c-fcf1abcd67fd">


Bad case - grid is not fine enough and through the scene:
<img width="1154" alt="image"
src="https://github.com/user-attachments/assets/cb76355a-778d-4bd9-a724-b4d9b1dffd84">
Bad case - grid is above the scene.
<img width="1464" alt="image"
src="https://github.com/user-attachments/assets/0a150db3-f344-444a-a4a0-33c877ea38ae">

## Testing 

* [x] Metal
* [x] Vulkan
* [x] WebGPU
* [x] WebGL

##  Future work

* tweak some examples to disable the grid or change its spacing
* Extend grid to 2d scenes
  • Loading branch information
Wumpf authored Dec 6, 2024
1 parent d8fab9b commit 601afc8
Show file tree
Hide file tree
Showing 90 changed files with 2,483 additions and 86 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6499,6 +6499,7 @@ dependencies = [
"re_format",
"re_log",
"re_log_types",
"re_math",
"re_tracing",
"re_types_builder",
"re_types_core",
Expand Down
5 changes: 3 additions & 2 deletions crates/store/re_types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ ecolor = ["dep:ecolor"]
## Enable conversions to plot primitives
egui_plot = ["dep:egui_plot"]

## Add support for some math operations using [`glam`](https://crates.io/crates/glam/).
glam = ["dep:glam"]
## Add support for some math operations using [`glam`](https://crates.io/crates/glam/) and [`re_math`](https://crates.io/crates/re_math/).
glam = ["dep:glam", "dep:re_math"]

## Integration with the [`image`](https://crates.io/crates/image/) crate, plus JPEG support.
image = ["dep:ecolor", "dep:image"]
Expand Down Expand Up @@ -92,6 +92,7 @@ image = { workspace = true, optional = true, default-features = false, features
"jpeg",
] }
mint = { workspace = true, optional = true }
re_math = { workspace = true, optional = true }
serde = { workspace = true, optional = true, features = ["derive", "rc"] }


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace rerun.archetypes;
///
/// Currently, many visualizers support only a single instance transform per entity.
/// Check archetype documentations for details - if not otherwise specified, only the first instance transform is applied.
/// Some visualizers like the mesh visualizer used for [`archetype.Mesh3D`],
/// Some visualizers like the mesh visualizer used for [archetypes.Mesh3D],
/// will draw an object for every pose, a behavior also known as "instancing".
///
/// \example archetypes/instance_poses3d_combined title="Regular & instance transforms in tandem" image="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/1200w.png"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ table Pinhole (

/// Sets the view coordinates for the camera.
///
/// All common values are available as constants on the `components.ViewCoordinates` class.
/// All common values are available as constants on the [components.ViewCoordinates] class.
///
/// The default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting.
/// This means that the camera frustum will point along the positive Z axis of the parent space,
Expand Down

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,33 @@
namespace rerun.blueprint.archetypes;

/// Configuration for the 3D line grid.
table LineGrid3D (
"attr.rerun.scope": "blueprint"
) {
/// Whether the grid is visible.
///
/// Defaults to true.
visible: rerun.blueprint.components.Visible ("attr.rerun.component_optional", nullable, order: 1000);

/// Space between grid lines spacing of one line to the next in scene units.
///
/// As you zoom out, successively only every tenth line is shown.
/// This controls the closest zoom level.
spacing: rerun.blueprint.components.GridSpacing ("attr.rerun.component_optional", nullable, order: 2000);

/// In what plane the grid is drawn.
///
/// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [components.ViewCoordinates] if present.
plane: rerun.components.Plane3D ("attr.rerun.component_optional", nullable, order: 3000);

/// How thick the lines should be in ui units.
///
/// Default is 1.0 ui unit.
stroke_width: rerun.components.StrokeWidth ("attr.rerun.component_optional", nullable, order: 5000);

/// Color used for the grid.
///
/// Transparency via alpha channel is supported.
/// Defaults to a slightly transparent light gray.
color: rerun.components.Color ("attr.rerun.component_optional", nullable, order: 6000);
}

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,11 @@
namespace rerun.blueprint.components;

/// Space between grid lines of one line to the next in scene units.
table GridSpacing (
"attr.python.aliases": "float",
"attr.python.array_aliases": "npt.ArrayLike",
"attr.rerun.scope": "blueprint"
) {
/// Space between grid lines of one line to the next in scene units.
distance: rerun.datatypes.Float32 (order: 100);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ table Spatial3DView (
/// Configuration for the background of the view.
background: rerun.blueprint.archetypes.Background (order: 1000);

/// Configuration for the 3D line grid.
line_grid: rerun.blueprint.archetypes.LineGrid3D (order: 2000);

/// Configures which range on each timeline is shown by this view (unless specified differently per entity).
///
/// If not specified, the default is to show the latest state of each component.
Expand Down
1 change: 1 addition & 0 deletions crates/store/re_types/definitions/rerun/components.fbs

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

18 changes: 18 additions & 0 deletions crates/store/re_types/definitions/rerun/components/plane3d.fbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace rerun.components;

/// An infinite 3D plane represented by a unit normal vector and a distance.
///
/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`,
/// where `xyz` is the plane's normal and `d` the distance of the plane from the origin.
/// This representation is also known as the Hesse normal form.
///
/// Note: although the normal will be passed through to the
/// datastore as provided, when used in the Viewer, planes will always be normalized.
/// I.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5
struct Plane3D (
"attr.docs.unreleased",
"attr.rust.derive": "Copy, PartialEq, bytemuck::Pod, bytemuck::Zeroable",
"attr.rust.repr": "transparent"
) {
xyzd: rerun.datatypes.Plane3D (order: 100);
}
1 change: 1 addition & 0 deletions crates/store/re_types/definitions/rerun/datatypes.fbs

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

22 changes: 22 additions & 0 deletions crates/store/re_types/definitions/rerun/datatypes/plane3d.fbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace rerun.datatypes;

/// An infinite 3D plane represented by a unit normal vector and a distance.
///
/// Any point P on the plane fulfills the equation `dot(xyz, P) - d = 0`,
/// where `xyz` is the plane's normal and `d` the distance of the plane from the origin.
/// This representation is also known as the Hesse normal form.
///
/// Note: although the normal will be passed through to the
/// datastore as provided, when used in the Viewer, planes will always be normalized.
/// I.e. the plane with xyz = (2, 0, 0), d = 1 is equivalent to xyz = (1, 0, 0), d = 0.5
struct Plane3D (
"attr.docs.unreleased",
"attr.arrow.transparent",
"attr.python.array_aliases": "npt.NDArray[Any], npt.ArrayLike, Sequence[Sequence[float]]",
"attr.rust.derive": "Copy, PartialEq, PartialOrd, bytemuck::Pod, bytemuck::Zeroable",
"attr.rust.tuple_struct",
"attr.rust.repr": "C",
"attr.cpp.no_field_ctors" // Always be explicit about the values of the fields.
) {
xyzd: [float: 4] (order: 100);
}
2 changes: 1 addition & 1 deletion crates/store/re_types/src/archetypes/instance_poses3d.rs

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

4 changes: 2 additions & 2 deletions crates/store/re_types/src/archetypes/pinhole.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.

Loading

0 comments on commit 601afc8

Please sign in to comment.