Skip to content

Commit

Permalink
Add Capsules3D archetype. (#7574)
Browse files Browse the repository at this point in the history
### What
* Part of #1361

Adds the archetype `Capsules3D`, component `Length`, and a matching
visualizer.

Capsules are defined by their length and radius, and then transformed in
the usual fashion to set their orientation. There is also a constructor
for joining a pair of endpoints.

<img width="483" alt="image"
src="https://github.com/user-attachments/assets/28bd3104-0c14-41c0-aeb4-6e15b4547b0f">

Missing parts that should make it into this PR before it leaves draft:

* Needs an example image — I assume I don't have the permissions to
upload one.

Further work not included in this PR, that will add complications:

* C++ and Python have no `from_endpoints` constructors, because there
wasn’t the quaternion math handy. Should we add an equivalent to
`glam::Quat::from_rotation_arc()` to the minimal Rerun quaternion types?
* There is no wireframe mesh support (expressed as having no `FillMode`
component). This is because it was recommended that I use `re_math`’s
capsules, but `re_math` has no support for generating wireframes. In the
long run, we will want to support tapered capsules and cylinders and a
new or substantially revised mesh generator to handle these cases will
be needed anyway.
* The support for setting the length of a capsule is a horrible kludge
which is hard on the mesh cache — each length:radius ratio is cached
separately. The idea I have for fixing this is adding “bone” support —
the ability for selected vertices to be displaced by an externally
controlled offset. This allows taking a single capsule mesh and
stretching it without distorting the endcaps. (Tapered capsules will
require multiple meshes to account for the angle at which the cone meets
the endcap, but those can be fairly well approximated by a finite set of
meshes.)

### Checklist
* [X] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [X] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using examples from latest `main` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/7574?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/7574?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [X] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [X] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!
* [X] If have noted any breaking changes to the log API in
`CHANGELOG.md` and the migration guide

- [PR Build Summary](https://build.rerun.io/pr/7574)
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)

To run all checks from `main`, comment on the PR with `@rerun-bot
full-check`.

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
  • Loading branch information
kpreid and emilk authored Oct 29, 2024
1 parent 1e38ae2 commit 6599f87
Show file tree
Hide file tree
Showing 58 changed files with 2,250 additions and 41 deletions.
6 changes: 4 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4631,9 +4631,9 @@ dependencies = [

[[package]]
name = "ordered-float"
version = "4.2.0"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e"
checksum = "83e7ccb95e240b7c9506a3d544f10d935e142cc90b0a1d56954fb44d89ad6b97"
dependencies = [
"num-traits",
]
Expand Down Expand Up @@ -6217,6 +6217,7 @@ dependencies = [
"mimalloc",
"nohash-hasher",
"once_cell",
"ordered-float",
"re_arrow2",
"re_chunk_store",
"re_data_ui",
Expand All @@ -6237,6 +6238,7 @@ dependencies = [
"re_viewport_blueprint",
"serde",
"smallvec",
"thiserror",
"vec1",
"web-time",
]
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ num-derive = "0.4"
num-traits = "0.2"
numpy = "0.22"
once_cell = "1.17" # No lazy_static - use `std::sync::OnceLock` or `once_cell` instead
ordered-float = "4.2"
ordered-float = "4.3.0"
parking_lot = "0.12"
paste = "1.0"
pathdiff = "0.2"
Expand Down
1 change: 1 addition & 0 deletions crates/store/re_types/definitions/rerun/archetypes.fbs

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

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

// ---

/// 3D capsules; cylinders with hemispherical caps.
///
/// Capsules are defined by two endpoints (the centers of their end cap spheres), which are located
/// at (0, 0, 0) and (0, 0, length), that is, extending along the positive direction of the Z axis.
/// Capsules in other orientations may be produced by applying a rotation to the entity or
/// instances.
///
/// \example archetypes/capsule3d_batch title="Batch of capsules" image="https://static.rerun.io/capsule3d_batch/6e6a4acafcf528359372147d7247f85d84434101/1200w.png"
//
// TODO(#1361): This archetype should eventually generalize to cylinders without caps, truncated
// cones, and tapered capsules -- all common shapes based on expanding a line segment circularly.
table Capsules3D (
"attr.rust.derive": "PartialEq",
"attr.rust.new_pub_crate",
"attr.cpp.no_field_ctors",
"attr.docs.category": "Spatial 3D",
"attr.docs.view_types": "Spatial3DView, Spatial2DView: if logged above active projection",
"attr.docs.unreleased"
) {
// --- Required ---

/// Lengths of the capsules, defined as the distance between the centers of the endcaps.
lengths: [rerun.components.Length] ("attr.rerun.component_required", order: 1000);

/// Radii of the capsules.
//
// TODO(#1361): This should eventually become two radii, to generate truncated cones and tapered capsules.
radii: [rerun.components.Radius] ("attr.rerun.component_required", order: 1100);

// --- Recommended ---

/// Optional translations of the capsules.
///
/// If not specified, one end of each capsule will be at (0, 0, 0).
/// Note that this uses a [components.PoseTranslation3D] which is also used by [archetypes.InstancePoses3D].
translations: [rerun.components.PoseTranslation3D] ("attr.rerun.component_recommended", nullable, order: 2000);

/// Rotations via axis + angle.
///
/// If no rotation is specified, the capsules align with the +Z axis of the local coordinate system.
/// Note that this uses a [components.PoseRotationAxisAngle] which is also used by [archetypes.InstancePoses3D].
rotation_axis_angles: [rerun.components.PoseRotationAxisAngle] ("attr.rerun.component_optional", nullable, order: 2100);

/// Rotations via quaternion.
///
/// If no rotation is specified, the capsules align with the +Z axis of the local coordinate system.
/// Note that this uses a [components.PoseRotationQuat] which is also used by [archetypes.InstancePoses3D].
quaternions: [rerun.components.PoseRotationQuat] ("attr.rerun.component_optional", nullable, order: 2200);

/// Optional colors for the capsules.
colors: [rerun.components.Color] ("attr.rerun.component_recommended", nullable, order: 2300);

// --- Optional ---

// TODO(#1361): Add fill_mode component, or whatever succeeds it in case a wireframe
// or other alternate rendering is wanted.

/// Optional text labels for the capsules, which will be located at their centers.
labels: [rerun.components.Text] ("attr.rerun.component_optional", nullable, order: 3100);

/// Optional choice of whether the text labels should be shown by default.
show_labels: rerun.components.ShowLabels ("attr.rerun.component_optional", nullable, order: 3200);

/// Optional class ID for the ellipsoids.
///
/// The class ID provides colors and labels if not specified explicitly.
class_ids: [rerun.components.ClassId] ("attr.rerun.component_optional", nullable, order: 3300);
}
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.

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

// ---

/// Length, or one-dimensional size.
///
/// Measured in its local coordinate system; consult the archetype in use to determine which
/// axis or part of the entity this is the length of.
struct Length (
"attr.python.aliases": "float",
"attr.python.array_aliases": "float, npt.NDArray[np.float32]",
"attr.rust.derive": "Copy, PartialEq, PartialOrd, bytemuck::Pod, bytemuck::Zeroable",
"attr.rust.repr": "transparent"
) {
length: rerun.datatypes.Float32 (order: 100);
}
1 change: 1 addition & 0 deletions crates/store/re_types/src/archetypes/.gitattributes

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

Loading

0 comments on commit 6599f87

Please sign in to comment.