Skip to content

Commit

Permalink
Use an octahedron as the subdivision shape for ProcMeshKey::Sphere. (
Browse files Browse the repository at this point in the history
…#7014)

### What

Instead of an icosahedron, use an octahedron. The edges of the
octahedron become axis-aligned great circles around the subdivided mesh,
which makes more sense for ellipsoid visualization since the axes and
their perpendicular planes are significant.

![Screenshot 2024-07-29 at 15 13
53](https://github.com/user-attachments/assets/4c4d90f8-f590-4949-8e84-1102ab2c17e3)

This will make it easy to also choose to draw *only* the axis-aligned
great circles (once
OptimisticPeach/hexasphere#26 is available),
making this a step towards implementing #6962.

### 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)
* [ ] I have tested the web demo (if applicable):
* Using examples from latest `main` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/7014?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/7014?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/7014)
- [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`.
  • Loading branch information
kpreid authored Jul 30, 2024
1 parent 8231e84 commit ff26b3a
Showing 1 changed file with 66 additions and 3 deletions.
69 changes: 66 additions & 3 deletions crates/viewer/re_space_view_spatial/src/proc_mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use std::sync::Arc;

use ahash::HashSet;
use glam::{uvec3, vec3, Vec3};
use glam::{uvec3, vec3, Vec3, Vec3A};
use itertools::Itertools as _;
use smallvec::smallvec;

Expand Down Expand Up @@ -167,7 +167,8 @@ fn generate_wireframe(key: &ProcMeshKey, render_ctx: &RenderContext) -> Wirefram
}
}
ProcMeshKey::Sphere { subdivisions } => {
let subdiv = hexasphere::shapes::IcoSphere::new(subdivisions, |_| ());
let subdiv: hexasphere::Subdivided<(), OctahedronBase> =
hexasphere::Subdivided::new(subdivisions, |_| ());

let sphere_points = subdiv.raw_points();

Expand Down Expand Up @@ -296,7 +297,8 @@ fn generate_solid(
}
}
ProcMeshKey::Sphere { subdivisions } => {
let subdiv = hexasphere::shapes::IcoSphere::new(subdivisions, |_| ());
let subdiv: hexasphere::Subdivided<(), OctahedronBase> =
hexasphere::Subdivided::new(subdivisions, |_| ());

let vertex_positions: Vec<Vec3> =
subdiv.raw_points().iter().map(|&p| p.into()).collect();
Expand Down Expand Up @@ -358,3 +360,64 @@ fn materials_for_uncolored_mesh(
albedo_factor: re_renderer::Rgba::BLACK,
}]
}

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

/// Base shape for [`hexasphere`]'s subdivision algorithm which is an octahedron
/// that is subdivided into a sphere mesh.
/// The value of this shape for us is that it has “equatorial” edges which are
/// perpendicular to the axes of the ellipsoid, which thus align with the quantities
/// the user actually specified (length on each axis), and can be usefully visualized
/// by themselves separately from the subdivision mesh.
///
/// TODO(kpreid): This would also make sense to contribute back to `hexasphere` itself.
#[derive(Clone, Copy, Debug, Default)]
struct OctahedronBase;

impl hexasphere::BaseShape for OctahedronBase {
fn initial_points(&self) -> Vec<Vec3A> {
vec![
Vec3A::NEG_X,
Vec3A::NEG_Y,
Vec3A::NEG_Z,
Vec3A::X,
Vec3A::Y,
Vec3A::Z,
]
}

fn triangles(&self) -> Box<[hexasphere::Triangle]> {
use hexasphere::Triangle;
const TRIANGLES: [Triangle; 8] = [
Triangle::new(0, 2, 1, 1, 4, 0), // -X-Y-Z face
Triangle::new(0, 1, 5, 0, 6, 3), // -X-Y+Z face
Triangle::new(0, 4, 2, 2, 5, 1), // -X+Y-Z face
Triangle::new(0, 5, 4, 3, 7, 2), // -X+Y+Z face
Triangle::new(3, 1, 2, 8, 4, 9), // +X-Y-Z face
Triangle::new(3, 5, 1, 11, 6, 8), // +X-Y+Z face
Triangle::new(3, 2, 4, 9, 5, 10), // +X+Y-Z face
Triangle::new(3, 4, 5, 10, 7, 11), // +X+Y+Z face
];
Box::new(TRIANGLES)
}

/// The octahedron has 12 edges, which we are arbitrarily numbering as follows:
///
/// 0. -X to -Y
/// 1. -X to -Z
/// 2. -X to +Y
/// 3. -X to +Z
/// 4. -Z to -Y
/// 5. -Z to +Y
/// 6. +Z to -Y
/// 7. +Z to +Y
/// 8. +X to -Y
/// 9. +X to -Z
/// 10. +X to +Y
/// 11. +X to +Z
const EDGES: usize = 12;

fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
hexasphere::interpolation::geometric_slerp(a, b, p)
}
}

0 comments on commit ff26b3a

Please sign in to comment.