#[cfg(feature = "shape-extras")]
use super::EquilateralBaseShape;
use super::{interpolation, BaseShape, Subdivided, Triangle};
use glam::Vec3A;
#[derive(Default, Copy, Clone, Debug)]
pub struct IcoSphereBase;
impl BaseShape for IcoSphereBase {
#[inline]
fn initial_points(&self) -> Vec<Vec3A> {
consts::icosphere::INITIAL_POINTS.to_vec()
}
#[inline]
fn triangles(&self) -> Box<[Triangle]> {
Box::new(consts::icosphere::TRIANGLES)
}
const EDGES: usize = consts::icosphere::EDGES;
#[inline]
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
interpolation::geometric_slerp(a, b, p)
}
#[inline]
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
interpolation::geometric_slerp_half(a, b)
}
#[inline]
fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
interpolation::geometric_slerp_multiple(a, b, indices, points);
}
}
#[cfg(feature = "shape-extras")]
impl EquilateralBaseShape for IcoSphereBase {
#[inline]
fn triangle_normals() -> &'static [Vec3A] {
&consts::icosphere::TRIANGLE_NORMALS
}
#[inline]
fn triangle_min_dot() -> f32 {
consts::icosphere::MIN_NORMAL_DOT
}
}
pub type IcoSphere<T> = Subdivided<T, IcoSphereBase>;
impl<T> IcoSphere<T> {
pub fn radius_shapes(&self) -> f32 {
let subdivisions = self.subdivisions as f32 + 1.0;
const DEFAULT_ANGLE: f32 = 1.10714871779409085306;
let angle = DEFAULT_ANGLE / subdivisions;
(angle * 0.5).sin() * 2.0
}
}
#[derive(Default, Copy, Clone, Debug)]
pub struct NormIcoSphereBase;
impl BaseShape for NormIcoSphereBase {
#[inline]
fn initial_points(&self) -> Vec<Vec3A> {
consts::icosphere::INITIAL_POINTS.to_vec()
}
#[inline]
fn triangles(&self) -> Box<[Triangle]> {
Box::new(consts::icosphere::TRIANGLES)
}
const EDGES: usize = consts::icosphere::EDGES;
#[inline]
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
interpolation::normalized_lerp(a, b, p)
}
#[inline]
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
interpolation::normalized_lerp_half(a, b)
}
#[inline]
fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
interpolation::normalized_lerp_multiple(a, b, indices, points);
}
}
#[cfg(feature = "shape-extras")]
impl EquilateralBaseShape for NormIcoSphereBase {
#[inline]
fn triangle_normals() -> &'static [Vec3A] {
&consts::icosphere::TRIANGLE_NORMALS
}
#[inline]
fn triangle_min_dot() -> f32 {
consts::icosphere::MIN_NORMAL_DOT
}
}
pub type NormIcoSphere<T> = Subdivided<T, NormIcoSphereBase>;
#[derive(Default, Copy, Clone, Debug)]
pub struct TetraSphereBase;
impl BaseShape for TetraSphereBase {
#[inline]
fn initial_points(&self) -> Vec<Vec3A> {
consts::tetrasphere::INITIAL_POINTS.to_vec()
}
#[inline]
fn triangles(&self) -> Box<[Triangle]> {
Box::new(consts::tetrasphere::TRIANGLES)
}
const EDGES: usize = consts::tetrasphere::EDGES;
#[inline]
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
interpolation::geometric_slerp(a, b, p)
}
#[inline]
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
interpolation::geometric_slerp_half(a, b)
}
#[inline]
fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
interpolation::geometric_slerp_multiple(a, b, indices, points);
}
}
#[cfg(feature = "shape-extras")]
impl EquilateralBaseShape for TetraSphereBase {
#[inline]
fn triangle_normals() -> &'static [Vec3A] {
&consts::tetrasphere::TRIANGLE_NORMALS
}
#[inline]
fn triangle_min_dot() -> f32 {
consts::tetrasphere::MIN_NORMAL_DOT
}
}
pub type TetraSphere<T> = Subdivided<T, TetraSphereBase>;
#[derive(Default, Copy, Clone, Debug)]
pub struct TriangleBase;
impl BaseShape for TriangleBase {
#[inline]
fn initial_points(&self) -> Vec<Vec3A> {
consts::triangle::INITIAL_POINTS.to_vec()
}
#[inline]
fn triangles(&self) -> Box<[Triangle]> {
core::slice::from_ref(&consts::triangle::TRIANGLE)
.to_vec()
.into()
}
const EDGES: usize = consts::triangle::EDGES;
#[inline]
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
interpolation::lerp(a, b, p)
}
#[inline]
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
interpolation::lerp_half(a, b)
}
#[inline]
fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
interpolation::lerp_multiple(a, b, indices, points);
}
}
#[cfg(feature = "shape-extras")]
impl EquilateralBaseShape for TriangleBase {
#[inline]
fn triangle_normals() -> &'static [Vec3A] {
core::slice::from_ref(&consts::triangle::TRIANGLE_NORMAL)
}
#[inline]
fn triangle_min_dot() -> f32 {
-1.0
}
}
pub type TrianglePlane<T> = Subdivided<T, TriangleBase>;
#[derive(Default, Copy, Clone, Debug)]
pub struct SquareBase;
impl BaseShape for SquareBase {
#[inline]
fn initial_points(&self) -> Vec<Vec3A> {
consts::square::INITIAL_POINTS.to_vec()
}
#[inline]
fn triangles(&self) -> Box<[Triangle]> {
consts::square::TRIANGLES.to_vec().into()
}
const EDGES: usize = consts::square::EDGES;
#[inline]
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
interpolation::lerp(a, b, p)
}
#[inline]
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
interpolation::lerp_half(a, b)
}
#[inline]
fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
interpolation::lerp_multiple(a, b, indices, points);
}
}
pub type SquarePlane<T> = Subdivided<T, SquareBase>;
#[derive(Default, Copy, Clone, Debug)]
pub struct CubeBase;
impl BaseShape for CubeBase {
#[inline]
fn initial_points(&self) -> Vec<Vec3A> {
consts::cube::INITIAL_POINTS.to_vec()
}
#[inline]
fn triangles(&self) -> Box<[Triangle]> {
consts::cube::TRIANGLES.to_vec().into()
}
const EDGES: usize = consts::cube::EDGES;
#[inline]
fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
interpolation::geometric_slerp(a, b, p)
}
#[inline]
fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
interpolation::geometric_slerp_half(a, b)
}
#[inline]
fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
interpolation::geometric_slerp_multiple(a, b, indices, points);
}
}
pub type CubeSphere<T> = Subdivided<T, CubeBase>;
mod consts {
pub mod square {
use crate::{Triangle, TriangleContents};
use glam::Vec3A;
#[rustfmt::skip]
pub(crate) const INITIAL_POINTS: [Vec3A; 4] = [
Vec3A::new( 1.0, 0.0, 1.0),
Vec3A::new( 1.0, 0.0, -1.0),
Vec3A::new(-1.0, 0.0, -1.0),
Vec3A::new(-1.0, 0.0, 1.0),
];
pub const TRIANGLES: [Triangle; 2] = [
Triangle {
a: 0,
b: 1,
c: 2,
ab_edge: 1,
bc_edge: 2,
ca_edge: 0,
ab_forward: true,
bc_forward: true,
ca_forward: true,
contents: TriangleContents::None,
},
Triangle {
a: 0,
b: 2,
c: 3,
ab_edge: 0,
bc_edge: 3,
ca_edge: 4,
ab_forward: true,
bc_forward: true,
ca_forward: true,
contents: TriangleContents::None,
},
];
pub const EDGES: usize = 5;
}
pub mod triangle {
use crate::{Triangle, TriangleContents};
use constgebra::const_soft_float::soft_f32::SoftF32;
use glam::Vec3A;
pub(crate) static INITIAL_POINTS: [Vec3A; 3] = [
Vec3A::new(
SoftF32(-3.0f32).sqrt().div(SoftF32(2.0)).to_f32(),
0.0,
-0.5,
),
Vec3A::new(SoftF32(3.0f32).sqrt().div(SoftF32(2.0)).to_f32(), 0.0, -0.5),
Vec3A::new(0.0, 0.0, 1.0),
];
#[cfg(feature = "shape-extras")]
pub(crate) const TRIANGLE_NORMAL: Vec3A = Vec3A::Y;
pub const TRIANGLE: Triangle = Triangle {
a: 2,
b: 1,
c: 0,
ab_edge: 0,
bc_edge: 1,
ca_edge: 2,
ab_forward: true,
bc_forward: true,
ca_forward: true,
contents: TriangleContents::None,
};
pub const EDGES: usize = 3;
}
pub mod tetrasphere {
use crate::{Triangle, TriangleContents};
use constgebra::const_soft_float::soft_f32::SoftF32;
#[cfg(feature = "shape-extras")]
use constgebra::{const_soft_float::soft_f64::SoftF64, CVector, Operation};
use glam::Vec3A;
pub const TRIANGLES: [Triangle; 4] = [
Triangle {
a: 0,
b: 1,
c: 2,
ab_edge: 0,
bc_edge: 1,
ca_edge: 2,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 0,
b: 3,
c: 1,
ab_edge: 3,
bc_edge: 4,
ca_edge: 0,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 1,
b: 3,
c: 2,
ab_edge: 4,
bc_edge: 5,
ca_edge: 1,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 0,
b: 2,
c: 3,
ab_edge: 2,
bc_edge: 5,
ca_edge: 3,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
];
pub const EDGES: usize = 6;
#[cfg(feature = "shape-extras")]
pub(super) const fn normal<const I: usize>(
triangles: &[Triangle],
initial_points: &[Vec3A],
) -> Vec3A {
const fn f32_arr_to_f64<const N: usize>(arr: [f32; N]) -> [f64; N] {
let mut ret = [0.0_f64; N];
let mut i = 0;
while i < N {
ret[i] = arr[i] as f64;
i += 1;
}
ret
}
const fn f64_arr_to_f32<const N: usize>(arr: [f64; N]) -> [f32; N] {
let mut ret = [0.0_f32; N];
let mut i = 0;
while i < N {
ret[i] = arr[i] as f32;
i += 1;
}
ret
}
let triangle = &triangles[I];
let p1 = CVector::new_vector(f32_arr_to_f64(
initial_points[triangle.a as usize].to_array(),
));
let p2 = CVector::new_vector(f32_arr_to_f64(
initial_points[triangle.b as usize].to_array(),
));
let p3 = CVector::new_vector(f32_arr_to_f64(
initial_points[triangle.c as usize].to_array(),
));
let normal = p1.add(p2).add(p3);
let len = {
let [x, y, z] = normal.finish_vector();
let x = SoftF64(x);
let y = SoftF64(y);
let z = SoftF64(z);
x.mul(x).add(y.mul(y)).add(z.mul(z)).sqrt()
};
let normal = normal.apply_each(Operation::Div(len.0));
return Vec3A::from_array(f64_arr_to_f32(normal.finish_vector()));
}
pub(crate) const INITIAL_POINTS: [Vec3A; 4] = [
Vec3A::new(
SoftF32(8.0f32).sqrt().div(SoftF32(3.0)).to_f32(),
SoftF32(-1.0).div(SoftF32(3.0)).to_f32(),
0.0,
),
Vec3A::new(
SoftF32(-2.0f32).sqrt().div(SoftF32(3.0)).to_f32(),
SoftF32(-1.0).div(SoftF32(3.0)).to_f32(),
SoftF32(2.0f32).div(SoftF32(3.0)).sqrt().to_f32(),
),
Vec3A::new(
SoftF32(-2.0f32).sqrt().div(SoftF32(3.0)).to_f32(),
SoftF32(-1.0).div(SoftF32(3.0)).to_f32(),
SoftF32(2.0f32).div(SoftF32(3.0)).sqrt().neg().to_f32(),
),
Vec3A::new(0.0, 1.0, 0.0),
];
#[cfg(feature = "shape-extras")]
pub(crate) const MIN_NORMAL_DOT: f32 = SoftF32(7.0f32).sqrt().div(SoftF32(3.0)).to_f32();
#[cfg(feature = "shape-extras")]
pub(crate) const TRIANGLE_NORMALS: [Vec3A; 4] = [
normal::<0>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<2>(&TRIANGLES, &INITIAL_POINTS),
normal::<3>(&TRIANGLES, &INITIAL_POINTS),
];
}
pub mod cube {
use crate::{Triangle, TriangleContents};
use constgebra::const_soft_float::soft_f32::SoftF32;
use glam::Vec3A;
#[rustfmt::skip]
pub(crate) static INITIAL_POINTS: [Vec3A; 8] = {
let val = SoftF32(1.0).div(SoftF32(3.0f32).sqrt()).to_f32();
[
Vec3A::new(-val, -val, -val),
Vec3A::new( val, -val, -val),
Vec3A::new(-val, val, -val),
Vec3A::new( val, val, -val),
Vec3A::new(-val, -val, val),
Vec3A::new( val, -val, val),
Vec3A::new(-val, val, val),
Vec3A::new( val, val, val),
]
};
pub const TRIANGLES: &[Triangle; 12] = &[
Triangle {
a: 0,
b: 2,
c: 3,
ab_edge: 1,
bc_edge: 2,
ca_edge: 12,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 0,
b: 3,
c: 1,
ab_edge: 12,
bc_edge: 3,
ca_edge: 0,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 2,
b: 7,
c: 3,
ab_edge: 14,
bc_edge: 6,
ca_edge: 2,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 2,
b: 6,
c: 7,
ab_edge: 5,
bc_edge: 10,
ca_edge: 14,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 4,
b: 2,
c: 0,
ab_edge: 13,
bc_edge: 1,
ca_edge: 4,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 4,
b: 6,
c: 2,
ab_edge: 9,
bc_edge: 5,
ca_edge: 13,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 1,
b: 5,
c: 4,
ab_edge: 7,
bc_edge: 8,
ca_edge: 16,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 1,
b: 4,
c: 0,
ab_edge: 16,
bc_edge: 4,
ca_edge: 0,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 1,
b: 7,
c: 5,
ab_edge: 15,
bc_edge: 11,
ca_edge: 7,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 1,
b: 3,
c: 7,
ab_edge: 3,
bc_edge: 6,
ca_edge: 15,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 5,
b: 6,
c: 4,
ab_edge: 17,
bc_edge: 9,
ca_edge: 8,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
Triangle {
a: 5,
b: 7,
c: 6,
ab_edge: 11,
bc_edge: 10,
ca_edge: 17,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
},
];
pub const EDGES: usize = 18;
}
pub mod icosphere {
use crate::{Triangle, TriangleContents};
#[cfg(feature = "shape-extras")]
use constgebra::const_soft_float::soft_f32::SoftF32;
use glam::Vec3A;
#[cfg(feature = "shape-extras")]
use super::tetrasphere::normal;
pub(crate) const INITIAL_POINTS: [Vec3A; 12] = [
Vec3A::Y,
Vec3A::new(
0.89442719099991585541,
0.44721359549995792770,
0.00000000000000000000,
),
Vec3A::new(
0.27639320225002106390,
0.44721359549995792770,
0.85065080835203987775,
),
Vec3A::new(
-0.72360679774997882507,
0.44721359549995792770,
0.52573111211913370333,
),
Vec3A::new(
-0.72360679774997904712,
0.44721359549995792770,
-0.52573111211913348129,
),
Vec3A::new(
0.27639320225002084186,
0.44721359549995792770,
-0.85065080835203998877,
),
Vec3A::new(
0.72360679774997871405,
-0.44721359549995792770,
-0.52573111211913392538,
),
Vec3A::new(
0.72360679774997904712,
-0.44721359549995792770,
0.52573111211913337026,
),
Vec3A::new(
-0.27639320225002073084,
-0.44721359549995792770,
0.85065080835203998877,
),
Vec3A::new(
-0.89442719099991585541,
-0.44721359549995792770,
0.00000000000000000000,
),
Vec3A::new(
-0.27639320225002139697,
-0.44721359549995792770,
-0.85065080835203976672,
),
Vec3A::NEG_Y,
];
#[cfg(feature = "shape-extras")]
pub(crate) static TRIANGLE_NORMALS: [Vec3A; 20] = [
normal::<0>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<2>(&TRIANGLES, &INITIAL_POINTS),
normal::<3>(&TRIANGLES, &INITIAL_POINTS),
normal::<4>(&TRIANGLES, &INITIAL_POINTS),
normal::<5>(&TRIANGLES, &INITIAL_POINTS),
normal::<6>(&TRIANGLES, &INITIAL_POINTS),
normal::<7>(&TRIANGLES, &INITIAL_POINTS),
normal::<8>(&TRIANGLES, &INITIAL_POINTS),
normal::<9>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
normal::<1>(&TRIANGLES, &INITIAL_POINTS),
];
#[cfg(feature = "shape-extras")]
pub(crate) static MIN_NORMAL_DOT: f32 = ((SoftF32(1.0f32).div(SoftF32(30.0)))
.mul(SoftF32(25.0).add(SoftF32(5.0_f32)).sqrt()))
.sqrt()
.to_f32();
pub const TRIANGLES: [Triangle; 20] = [
Triangle {
a: 0,
b: 2,
c: 1,
ab_edge: 0,
bc_edge: 5,
ca_edge: 4,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 0,
b: 3,
c: 2,
ab_edge: 1,
bc_edge: 6,
ca_edge: 0,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 0,
b: 4,
c: 3,
ab_edge: 2,
bc_edge: 7,
ca_edge: 1,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 0,
b: 5,
c: 4,
ab_edge: 3,
bc_edge: 8,
ca_edge: 2,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 0,
b: 1,
c: 5,
ab_edge: 4,
bc_edge: 9,
ca_edge: 3,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 5,
b: 1,
c: 6,
ab_edge: 9,
bc_edge: 10,
ca_edge: 15,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 1,
b: 2,
c: 7,
ab_edge: 5,
bc_edge: 11,
ca_edge: 16,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 2,
b: 3,
c: 8,
ab_edge: 6,
bc_edge: 12,
ca_edge: 17,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 3,
b: 4,
c: 9,
ab_edge: 7,
bc_edge: 13,
ca_edge: 18,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 4,
b: 5,
c: 10,
ab_edge: 8,
bc_edge: 14,
ca_edge: 19,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 5,
b: 6,
c: 10,
ab_edge: 15,
bc_edge: 20,
ca_edge: 14,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 1,
b: 7,
c: 6,
ab_edge: 16,
bc_edge: 21,
ca_edge: 10,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 2,
b: 8,
c: 7,
ab_edge: 17,
bc_edge: 22,
ca_edge: 11,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 3,
b: 9,
c: 8,
ab_edge: 18,
bc_edge: 23,
ca_edge: 12,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 4,
b: 10,
c: 9,
ab_edge: 19,
bc_edge: 24,
ca_edge: 13,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 10,
b: 6,
c: 11,
ab_edge: 20,
bc_edge: 26,
ca_edge: 25,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 6,
b: 7,
c: 11,
ab_edge: 21,
bc_edge: 27,
ca_edge: 26,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 7,
b: 8,
c: 11,
ab_edge: 22,
bc_edge: 28,
ca_edge: 27,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 8,
b: 9,
c: 11,
ab_edge: 23,
bc_edge: 29,
ca_edge: 28,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, Triangle {
a: 9,
b: 10,
c: 11,
ab_edge: 24,
bc_edge: 25,
ca_edge: 29,
ab_forward: false,
bc_forward: false,
ca_forward: false,
contents: TriangleContents::None,
}, ];
pub const EDGES: usize = 30;
}
}