pub trait BaseShape {
const EDGES: usize;
// Required methods
fn initial_points(&self) -> Vec<Vec3A>;
fn triangles(&self) -> Box<[Triangle]>;
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A;
// Provided methods
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A { ... }
fn interpolate_multiple(
&self,
a: Vec3A,
b: Vec3A,
indices: &[u32],
points: &mut [Vec3A],
) { ... }
}
Expand description
Defines the geometry of the shape to be subdivided, and the functions used in interpolation.
If you want to use a different interpolation function, implement this trait for a new type, and carry over only the properties you’d like to keep:
use hexasphere::{Triangle, shapes::IcoSphereBase};
use glam::Vec3A;
// Uses linear interpolation instead of spherical.
struct FlatIcosahedron;
impl BaseShape for FlatIcosahedron {
// Keep the initial parameters.
fn initial_points(&self) -> Vec<Vec3A> {
IcoSphereBase.initial_points()
}
fn triangles(&self) -> Box<[Triangle]> {
IcoSphereBase.triangles()
}
const EDGES: usize = IcoSphereBase::EDGES;
// Swap out what you'd like to change.
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
hexasphere::interpolation::lerp(a, b, p)
}
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
hexasphere::interpolation::lerp_half(a, b)
}
fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
hexasphere::interpolation::lerp_multiple(a, b, indices, points);
}
}
Or, create your own shape, by changing the values for
initial_points
, triangles
, and EDGES
. Check
the documentation for these members individually on how
they should be implemented.
Required Associated Constants§
Required Methods§
Sourcefn initial_points(&self) -> Vec<Vec3A>
fn initial_points(&self) -> Vec<Vec3A>
The vertices for all main triangles of the shape. Check the source file for this crate and look for the constants module at the bottom for an example.
Constraints on the points depend on the interpolation function used:
slerp
requires normalized (magnitude 1) data.lerp
doesn’t care.normalized_lerp
requires normalized (magnitude 1) data.
Sourcefn triangles(&self) -> Box<[Triangle]>
fn triangles(&self) -> Box<[Triangle]>
Main triangles for the shape; that is, the triangles which exist before subdivision.
See Triangle::new()
for details.
Sourcefn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A
Basic function used for interpolation. When p
is
0.0
, a
is expected. When p
is 1.0
, b
is
expected. There are three options already implemented
in this crate:
lerp
implements linear interpolation.geometric_slerp
implements spherical interpolation. (Interpolates along an arc on a sphere)normalized_lerp
implements cheaper yet less accurate spherical interpolation. The accuracy decreases as the angle between the two points on the unit sphere increases.
Provided Methods§
Sourcefn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A
If an optimization is available for the case where p
is 0.5
, this function should implement it. This defaults
to calling interpolate(a, b, 0.5)
however.
Sourcefn interpolate_multiple(
&self,
a: Vec3A,
b: Vec3A,
indices: &[u32],
points: &mut [Vec3A],
)
fn interpolate_multiple( &self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A], )
If an optimization is available for the case where p
varies but a
and b
don’t, this function should implement
it.
§Parameters
a
: start.b
: end.indices
: list of indices to index intopoints
.points
at the index should contain the result. The index (n) of an index should correspond with the nth point in a distribution ofindices.len()
points between (exclusive)a
andb
.points
: list of points where the results of the calculation should end up. To be indexed by values inindices
.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.