hexasphere/
lib.rs

1//!
2//! Library for subdividing shapes made of triangles.
3//!
4//! This library defines [`Subdivided<T, S>`](Subdivided). This struct
5//! allows one to define a base shape using `S` and the
6//! [`BaseShape`] trait, and to subdivide it using the
7//! interpolation functions defined as part of `S`.
8//!
9//! Shapes define the starting vertices and triangles, as well as
10//! the type of interpolation used and thus the smooth shape that is approximated.
11//! These provided shapes generate **spheres**:
12//!
13//! - [`shapes::CubeSphere`] (cube)
14//! - [`shapes::IcoSphere`] (icosahedron)
15//! - [`shapes::NormIcoSphere`] (icosahedron)
16//! - [`shapes::TetraSphere`] (tetrahedron)
17//!
18//! Two flat shapes are also provided:
19//!
20//! - [`shapes::SquarePlane`]
21//! - [`shapes::TrianglePlane`]
22//!
23//! ## Example usage
24//!
25//! ```rust
26//! use hexasphere::shapes::IcoSphere;
27//!
28//! // Create a new sphere with 20 subdivisions
29//! // an no data associated with the vertices.
30//! let sphere = IcoSphere::new(20, |_| ());
31//!
32//! let points = sphere.raw_points();
33//! for p in points {
34//!     println!("{:?} is a point on the sphere!", p);
35//! }
36//! let indices = sphere.get_all_indices();
37//! for triangle in indices.chunks(3) {
38//!     println!(
39//!         "[{}, {}, {}] is a triangle on the resulting shape",
40//!         triangle[0],
41//!         triangle[1],
42//!         triangle[2],
43//!     );
44//! }
45//! ```
46//!
47//! # Features
48//! - `adjacency` allows the user to create neighbour maps from
49//!   the indices provided by the `Subdivided` struct.
50//!
51#![cfg_attr(not(feature = "std"), no_std)]
52
53#[cfg(all(not(feature = "std"), not(feature = "libm")))]
54compile_error!("`libm` feature is required to be enabled in no-std environment");
55
56use glam::Vec3A;
57
58#[doc(hidden)]
59#[macro_use]
60extern crate alloc;
61
62use alloc::boxed::Box;
63use alloc::vec::Vec;
64
65use slice::Slice::*;
66use slice::*;
67
68#[cfg(feature = "adjacency")]
69pub use adjacency::*;
70
71pub mod interpolation;
72mod math;
73pub mod shapes;
74mod slice;
75///
76/// Defines the geometry of the shape to be subdivided, and the functions
77/// used in interpolation.
78///
79/// If you want to use a different interpolation function,
80/// implement this trait for a new type, and carry over only
81/// the properties you'd like to keep:
82///
83/// ```rust
84/// # use hexasphere::BaseShape;
85/// use hexasphere::{Triangle, shapes::IcoSphereBase};
86/// use glam::Vec3A;
87/// // Uses linear interpolation instead of spherical.
88/// struct FlatIcosahedron;
89///
90/// impl BaseShape for FlatIcosahedron {
91///     // Keep the initial parameters.
92///     fn initial_points(&self) -> Vec<Vec3A> {
93///         IcoSphereBase.initial_points()
94///     }
95///
96///     fn triangles(&self) -> Box<[Triangle]> {
97///         IcoSphereBase.triangles()
98///     }
99///     const EDGES: usize = IcoSphereBase::EDGES;
100///
101///     // Swap out what you'd like to change.
102///     fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
103///         hexasphere::interpolation::lerp(a, b, p)
104///     }
105///
106///     fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
107///         hexasphere::interpolation::lerp_half(a, b)
108///     }
109///
110///     fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
111///         hexasphere::interpolation::lerp_multiple(a, b, indices, points);
112///     }
113/// }
114/// ```
115///
116/// Or, create your own shape, by changing the values for
117/// [`initial_points`], [`triangles`], and [`EDGES`]. Check
118/// the documentation for these members individually on how
119/// they should be implemented.
120///
121/// [`initial_points`]: #tymethod.initial_points
122/// [`triangles`]: #tymethod.triangles
123/// [`EDGES`]: #associatedconstant.EDGES
124///
125pub trait BaseShape {
126    ///
127    /// The vertices for all main triangles of the shape.
128    /// Check the source file for this
129    /// crate and look for the constants module at the bottom
130    /// for an example.
131    ///
132    /// Constraints on the points depend on the interpolation
133    /// function used:
134    /// - `slerp` requires normalized (magnitude 1) data.
135    /// - `lerp` doesn't care.
136    /// - `normalized_lerp` requires normalized (magnitude 1)
137    ///   data.
138    ///
139    fn initial_points(&self) -> Vec<Vec3A>;
140
141    ///
142    /// Main triangles for the shape;
143    /// that is, the triangles which exist before subdivision.
144    ///
145    /// See [`Triangle::new()`] for details.
146    ///
147    fn triangles(&self) -> Box<[Triangle]>;
148
149    ///
150    /// Number of unique edges defined in the contents of
151    /// `triangles()`. This number is 5 for a square for
152    /// example:
153    /// ```text
154    /// a - 0 - b
155    /// |     / |
156    /// 3   4   1
157    /// | /     |
158    /// d - 2 - c
159    /// ```
160    ///
161    const EDGES: usize;
162
163    ///
164    /// Basic function used for interpolation. When `p` is
165    /// `0.0`, `a` is expected. When `p` is `1.0`, `b` is
166    /// expected. There are three options already implemented
167    /// in this crate:
168    /// - [`lerp`] implements linear interpolation.
169    /// - [`geometric_slerp`] implements spherical
170    ///   interpolation. (Interpolates along an arc on a sphere)
171    /// - [`normalized_lerp`] implements cheaper
172    ///   yet less accurate spherical interpolation. The accuracy
173    ///   decreases as the angle between the two points on the unit
174    ///   sphere increases.
175    ///
176    /// [`lerp`]: ../fn.lerp.html
177    /// [`geometric_slerp`]: ../fn.geometric_slerp.html
178    /// [`normalized_lerp`]: ../fn.normalized_lerp.html
179    ///
180    fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A;
181
182    ///
183    /// If an optimization is available for the case where `p`
184    /// is `0.5`, this function should implement it. This defaults
185    /// to calling `interpolate(a, b, 0.5)` however.
186    ///
187    fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
188        self.interpolate(a, b, 0.5)
189    }
190
191    ///
192    /// If an optimization is available for the case where `p`
193    /// varies but `a` and `b` don't, this function should implement
194    /// it.
195    ///
196    /// ### Parameters
197    /// - `a`: start.
198    /// - `b`: end.
199    /// - `indices`: list of indices to index into `points`. `points`
200    ///   at the index should contain the result. The index (n) of an
201    ///   index should correspond with the nth point in a distribution
202    ///   of `indices.len()` points between (exclusive) `a` and `b`.
203    /// - `points`: list of points where the results of the calculation
204    ///   should end up. To be indexed by values in `indices`.
205    ///
206    fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
207        for (percent, index) in indices.iter().enumerate() {
208            let percent = (percent + 1) as f32 / (indices.len() + 1) as f32;
209
210            points[*index as usize] = self.interpolate(a, b, percent);
211        }
212    }
213}
214
215///
216/// Implemented in the case where the triangles on the shape
217/// are both equilateral and identifiable from their normal.
218///
219/// This is only used in the cases of spherical shapes.
220///
221#[cfg(feature = "shape-extras")]
222pub trait EquilateralBaseShape: BaseShape {
223    ///
224    /// Normals for each of the triangles provided by
225    /// [`BaseShape::triangles`].
226    ///
227    fn triangle_normals() -> &'static [Vec3A];
228    ///
229    /// Minimum value for the dot product which one could use
230    /// to determine that triangle being the closest.
231    ///
232    /// If the dot product between a vector and a triangle
233    /// normal is greater than this, then that vector is
234    /// guaranteed to be within that triangle.
235    ///
236    /// This is also the cosine of the angle of the cone
237    /// whose circular edge lies on a triangle.
238    ///
239    fn triangle_min_dot() -> f32;
240}
241
242///
243/// The edge between two main triangles.
244///
245#[derive(Debug, Clone)]
246struct Edge {
247    ///
248    /// Indices of the points between the endpoints.
249    ///
250    points: Vec<u32>,
251    ///
252    /// Whether this edge has already been processed
253    /// or not for point generation.
254    ///
255    done: bool,
256}
257
258impl Default for Edge {
259    fn default() -> Self {
260        Self {
261            points: Vec::new(),
262            done: true,
263        }
264    }
265}
266
267impl Edge {
268    pub fn subdivide_n_times(&mut self, n: usize, points: &mut usize) {
269        for _ in 0..n {
270            self.points.push(*points as _);
271            *points += 1;
272        }
273    }
274}
275
276///
277/// Contents of one of the main triangular faces.
278///
279/// This is *not* the entire face, it is the points which do
280/// not include the exterior edges and vertices since those are
281/// shared.
282///
283#[derive(Clone, Debug)]
284enum TriangleContents {
285    ///
286    /// Nothing inside the triangle: subdivisions 0 and 1
287    ///
288    None,
289    ///
290    /// One point inside the triangle: subdivision 2
291    ///
292    One(u32),
293    ///
294    /// Three points inside the triangle: subdivision 3
295    ///
296    Three { a: u32, b: u32, c: u32 },
297    ///
298    /// Six points inside the triangle: subdivision 4
299    ///
300    Six {
301        a: u32,
302        b: u32,
303        c: u32,
304        ab: u32,
305        bc: u32,
306        ca: u32,
307    },
308    ///
309    /// More than six points inside the triangle: subdivision > 4
310    ///
311    More {
312        a: u32,
313        b: u32,
314        c: u32,
315        // Separated into three `my_side_length` segments
316        // to save on extra allocations.
317        sides: Vec<u32>,
318        my_side_length: u32,
319        ///
320        /// Contents of the inner triangle.
321        ///
322        // Implementing this as a `Vec<TriangleContents>` would
323        // probably be a perf. improvement someday, however not
324        // something worth implementing right now.
325        contents: Box<TriangleContents>,
326    },
327}
328
329impl TriangleContents {
330    ///
331    /// Creates a `None` variant.
332    ///
333    pub fn none() -> Self {
334        Self::None
335    }
336
337    ///
338    /// Creates a `One` by interpolating two values.
339    ///
340    fn one(points: &mut usize) -> Self {
341        let index = *points as u32;
342        *points += 1;
343        TriangleContents::One(index)
344    }
345
346    fn calculate_one(
347        &self,
348        ab: Slice<u32>,
349        bc: Slice<u32>,
350        points: &mut [Vec3A],
351        shape: &impl BaseShape,
352    ) {
353        assert_eq!(ab.len(), bc.len());
354        assert_eq!(ab.len(), 2);
355        match self {
356            TriangleContents::One(idx) => {
357                let p1 = points[ab[0] as usize];
358                let p2 = points[bc[1] as usize];
359
360                points[*idx as usize] = shape.interpolate_half(p1, p2);
361            }
362            _ => panic!("Did not find One variant."),
363        }
364    }
365
366    ///
367    /// Creates a `Three` variant from a `One` variant.
368    ///
369    fn three(&mut self, points: &mut usize) {
370        use TriangleContents::*;
371
372        match self {
373            &mut One(x) => {
374                *points += 2;
375
376                *self = Three {
377                    a: x,
378                    b: *points as u32 - 2,
379                    c: *points as u32 - 1,
380                };
381            }
382            _ => panic!("Self is {:?} while it should be One", self),
383        }
384    }
385
386    fn calculate_three(
387        &self,
388        ab: Slice<u32>,
389        bc: Slice<u32>,
390        ca: Slice<u32>,
391        points: &mut [Vec3A],
392        shape: &impl BaseShape,
393    ) {
394        assert_eq!(ab.len(), bc.len());
395        assert_eq!(ab.len(), ca.len());
396        assert_eq!(ab.len(), 3);
397
398        match self {
399            &TriangleContents::Three { a, b, c } => {
400                let ab = points[ab[1] as usize];
401                let bc = points[bc[1] as usize];
402                let ca = points[ca[1] as usize];
403
404                let a_val = shape.interpolate_half(ab, ca);
405                let b_val = shape.interpolate_half(bc, ab);
406                let c_val = shape.interpolate_half(ca, bc);
407
408                points[a as usize] = a_val;
409                points[b as usize] = b_val;
410                points[c as usize] = c_val;
411            }
412            _ => panic!("Did not find Three variant."),
413        }
414    }
415
416    ///
417    /// Creates a `Six` variant from a `Three` variant.
418    ///
419    fn six(&mut self, points: &mut usize) {
420        use TriangleContents::*;
421
422        match self {
423            &mut Three {
424                a: a_index,
425                b: b_index,
426                c: c_index,
427            } => {
428                *points += 3;
429
430                *self = Six {
431                    a: a_index,
432                    b: b_index,
433                    c: c_index,
434                    ab: *points as u32 - 3,
435                    bc: *points as u32 - 2,
436                    ca: *points as u32 - 1,
437                };
438            }
439            _ => panic!("Found {:?} whereas a Three was expected", self),
440        }
441    }
442
443    fn calculate_six(
444        &self,
445        ab: Slice<u32>,
446        bc: Slice<u32>,
447        ca: Slice<u32>,
448        points: &mut [Vec3A],
449        shape: &impl BaseShape,
450    ) {
451        assert_eq!(ab.len(), bc.len());
452        assert_eq!(ab.len(), ca.len());
453        assert_eq!(ab.len(), 4);
454
455        use TriangleContents::*;
456
457        match self {
458            &Six {
459                a: a_index,
460                b: b_index,
461                c: c_index,
462                ab: ab_index,
463                bc: bc_index,
464                ca: ca_index,
465            } => {
466                let aba = points[ab[1] as usize];
467                let abb = points[ab[2] as usize];
468                let bcb = points[bc[1] as usize];
469                let bcc = points[bc[2] as usize];
470                let cac = points[ca[1] as usize];
471                let caa = points[ca[2] as usize];
472
473                let a = shape.interpolate_half(aba, caa);
474                let b = shape.interpolate_half(abb, bcb);
475                let c = shape.interpolate_half(bcc, cac);
476
477                let ab = shape.interpolate_half(a, b);
478                let bc = shape.interpolate_half(b, c);
479                let ca = shape.interpolate_half(c, a);
480
481                points[a_index as usize] = a;
482                points[b_index as usize] = b;
483                points[c_index as usize] = c;
484                points[ab_index as usize] = ab;
485                points[bc_index as usize] = bc;
486                points[ca_index as usize] = ca;
487            }
488            _ => panic!("Found {:?} whereas a Three was expected", self),
489        }
490    }
491
492    ///
493    /// Subdivides this given the surrounding points.
494    ///
495    fn subdivide(&mut self, points: &mut usize) {
496        use TriangleContents::*;
497
498        match self {
499            None => *self = Self::one(points),
500            One(_) => self.three(points),
501            Three { .. } => self.six(points),
502            &mut Six {
503                a,
504                b,
505                c,
506                ab: ab_idx,
507                bc: bc_idx,
508                ca: ca_idx,
509            } => {
510                *self = More {
511                    a,
512                    b,
513                    c,
514                    sides: vec![ab_idx, bc_idx, ca_idx],
515                    my_side_length: 1,
516                    contents: Box::new(Self::none()),
517                };
518                self.subdivide(points);
519            }
520            More {
521                sides,
522                contents,
523                my_side_length,
524                ..
525            } => {
526                *points += 3;
527                let len = *points as u32;
528                sides.extend_from_slice(&[len - 3, len - 2, len - 1]);
529                *my_side_length += 1;
530
531                contents.subdivide(points);
532            }
533        }
534    }
535
536    pub fn calculate(
537        &mut self,
538        ab: Slice<u32>,
539        bc: Slice<u32>,
540        ca: Slice<u32>,
541        points: &mut [Vec3A],
542        shape: &impl BaseShape,
543    ) {
544        assert_eq!(ab.len(), bc.len());
545        assert_eq!(ab.len(), ca.len());
546        assert!(ab.len() >= 2);
547
548        use TriangleContents::*;
549
550        match self {
551            None => panic!(),
552            One(_) => self.calculate_one(ab, bc, points, shape),
553            Three { .. } => self.calculate_three(ab, bc, ca, points, shape),
554            Six { .. } => self.calculate_six(ab, bc, ca, points, shape),
555            &mut More {
556                a: a_idx,
557                b: b_idx,
558                c: c_idx,
559                ref mut sides,
560                ref mut contents,
561                ref mut my_side_length,
562            } => {
563                let side_length = *my_side_length as usize;
564
565                let outer_len = ab.len();
566
567                let aba = points[ab[1] as usize];
568                let abb = points[ab[outer_len - 2] as usize];
569                let bcb = points[bc[1] as usize];
570                let bcc = points[bc[outer_len - 2] as usize];
571                let cac = points[ca[1] as usize];
572                let caa = points[ca[outer_len - 2] as usize];
573
574                points[a_idx as usize] = shape.interpolate_half(aba, caa);
575                points[b_idx as usize] = shape.interpolate_half(abb, bcb);
576                points[c_idx as usize] = shape.interpolate_half(bcc, cac);
577
578                let ab = &sides[0..side_length];
579                let bc = &sides[side_length..side_length * 2];
580                let ca = &sides[side_length * 2..];
581
582                shape.interpolate_multiple(
583                    points[a_idx as usize],
584                    points[b_idx as usize],
585                    ab,
586                    points,
587                );
588                shape.interpolate_multiple(
589                    points[b_idx as usize],
590                    points[c_idx as usize],
591                    bc,
592                    points,
593                );
594                shape.interpolate_multiple(
595                    points[c_idx as usize],
596                    points[a_idx as usize],
597                    ca,
598                    points,
599                );
600
601                contents.calculate(Forward(ab), Forward(bc), Forward(ca), points, shape);
602            }
603        }
604    }
605
606    ///
607    /// Indexes the AB edge.
608    ///
609    /// This is inclusive of A and B.
610    ///
611    pub fn idx_ab(&self, idx: usize) -> u32 {
612        use TriangleContents::*;
613        match self {
614            None => panic!("Invalid Index, len is 0, but got {}", idx),
615            One(x) => {
616                if idx != 0 {
617                    panic!("Invalid Index, len is 1, but got {}", idx);
618                } else {
619                    *x
620                }
621            }
622            Three { a, b, .. } => *[a, b][idx],
623            Six { a, b, ab, .. } => *[a, ab, b][idx],
624            &More {
625                a,
626                b,
627                ref sides,
628                my_side_length,
629                ..
630            } => match idx {
631                0 => a,
632                x if (1..(my_side_length as usize + 1)).contains(&x) => sides[x - 1],
633                x if x == my_side_length as usize + 1 => b,
634                _ => panic!(
635                    "Invalid Index, len is {}, but got {}",
636                    my_side_length + 2,
637                    idx
638                ),
639            },
640        }
641    }
642
643    ///
644    /// Indexes the BC edge.
645    ///
646    /// This is inclusive of B and C.
647    ///
648    pub fn idx_bc(&self, idx: usize) -> u32 {
649        use TriangleContents::*;
650        match self {
651            None => panic!("Invalid Index, len is 0, but got {}", idx),
652            One(x) => {
653                if idx != 0 {
654                    panic!("Invalid Index, len is 1, but got {}", idx);
655                } else {
656                    *x
657                }
658            }
659            Three { c, b, .. } => *[b, c][idx],
660            Six { b, c, bc, .. } => *[b, bc, c][idx],
661            &More {
662                b,
663                c,
664                ref sides,
665                my_side_length,
666                ..
667            } => match idx {
668                0 => b,
669                x if (1..(my_side_length as usize + 1)).contains(&x) => {
670                    sides[my_side_length as usize + (x - 1)]
671                }
672                x if x == my_side_length as usize + 1 => c,
673                _ => panic!(
674                    "Invalid Index, len is {}, but got {}",
675                    my_side_length + 2,
676                    idx
677                ),
678            },
679        }
680    }
681
682    ///
683    /// Indexes the CA edge.
684    ///
685    /// This is inclusive of C and A.
686    ///
687    pub fn idx_ca(&self, idx: usize) -> u32 {
688        use TriangleContents::*;
689        match self {
690            None => panic!("Invalid Index, len is 0, but got {}", idx),
691            One(x) => {
692                if idx != 0 {
693                    panic!("Invalid Index, len is 1, but got {}", idx);
694                } else {
695                    *x
696                }
697            }
698            Three { c, a, .. } => *[c, a][idx],
699            Six { c, a, ca, .. } => *[c, ca, a][idx],
700            &More {
701                c,
702                a,
703                ref sides,
704                my_side_length,
705                ..
706            } => match idx {
707                0 => c,
708                x if (1..(my_side_length as usize + 1)).contains(&x) => {
709                    sides[my_side_length as usize * 2 + x - 1]
710                }
711                x if x == my_side_length as usize + 1 => a,
712                _ => panic!(
713                    "Invalid Index, len is {}, but got {}",
714                    my_side_length + 2,
715                    idx
716                ),
717            },
718        }
719    }
720
721    ///
722    /// Adds the indices in this portion of the triangle
723    /// to the specified buffer in order.
724    ///
725    pub fn add_indices(&self, buffer: &mut Vec<u32>) {
726        use TriangleContents::*;
727        match self {
728            None | One(_) => {}
729            &Three { a, b, c } => buffer.extend_from_slice(&[a, b, c]),
730            &Six {
731                a,
732                b,
733                c,
734                ab,
735                bc,
736                ca,
737            } => {
738                buffer.extend_from_slice(&[a, ab, ca]);
739                buffer.extend_from_slice(&[ab, b, bc]);
740                buffer.extend_from_slice(&[bc, c, ca]);
741
742                buffer.extend_from_slice(&[ab, bc, ca]);
743            }
744            &More {
745                a,
746                b,
747                c,
748                ref sides,
749                my_side_length,
750                ref contents,
751            } => {
752                let my_side_length = my_side_length as usize;
753                let ab = &sides[0..my_side_length];
754                let bc = &sides[my_side_length..my_side_length * 2];
755                let ca = &sides[my_side_length * 2..];
756
757                // Contents are always stored forward.
758                add_indices_triangular(
759                    a,
760                    b,
761                    c,
762                    Forward(ab),
763                    Forward(bc),
764                    Forward(ca),
765                    contents,
766                    buffer,
767                );
768                contents.add_indices(buffer);
769            }
770        }
771    }
772
773    ///
774    /// Adds the indices for a wireframe of the triangles
775    /// in this portion of the triangle to the specified
776    /// buffer in order.
777    ///
778    pub fn add_line_indices(
779        &self,
780        buffer: &mut Vec<u32>,
781        delta: u32,
782        mut breaks: impl FnMut(&mut Vec<u32>),
783    ) {
784        use TriangleContents::*;
785        match self {
786            None | One(_) | Three { .. } => {}
787            Six { ab, bc, ca, .. } => {
788                let ab = core::slice::from_ref(ab);
789                let bc = core::slice::from_ref(bc);
790                let ca = core::slice::from_ref(ca);
791                // buffer.extend_from_slice(&[ab + delta, bc + delta, ca + delta]);
792                add_line_indices_triangular(
793                    delta,
794                    Forward(ab),
795                    Forward(bc),
796                    Forward(ca),
797                    &TriangleContents::None,
798                    buffer,
799                );
800                breaks(buffer);
801            }
802            &More {
803                ref sides,
804                my_side_length,
805                ref contents,
806                ..
807            } => {
808                let my_side_length = my_side_length as usize;
809                let ab = &sides[0..my_side_length];
810                let bc = &sides[my_side_length..my_side_length * 2];
811                let ca = &sides[my_side_length * 2..];
812
813                // Contents are always stored forward.
814                add_line_indices_triangular(
815                    delta,
816                    Forward(ab),
817                    Forward(bc),
818                    Forward(ca),
819                    contents,
820                    buffer,
821                );
822                breaks(buffer);
823                contents.add_line_indices(buffer, delta, breaks);
824            }
825        }
826    }
827}
828
829#[derive(Clone, Debug)]
830///
831/// A main triangle on the base shape of a subdivided shape.
832///
833/// Main triangles are those which are part of the definition of the base shape,
834/// rather than created by subdivision.
835///
836/// The specification of the library expects `a`, `b`, and `c`
837/// to be in a counter-clockwise winding.
838///
839pub struct Triangle {
840    pub a: u32,
841    pub b: u32,
842    pub c: u32,
843    pub ab_edge: usize,
844    pub bc_edge: usize,
845    pub ca_edge: usize,
846    pub(crate) ab_forward: bool,
847    pub(crate) bc_forward: bool,
848    pub(crate) ca_forward: bool,
849
850    pub(crate) contents: TriangleContents,
851}
852
853impl Default for Triangle {
854    fn default() -> Self {
855        Self {
856            a: 0,
857            b: 0,
858            c: 0,
859            ab_edge: 0,
860            bc_edge: 0,
861            ca_edge: 0,
862            ab_forward: false,
863            bc_forward: false,
864            ca_forward: false,
865            contents: TriangleContents::None,
866        }
867    }
868}
869
870impl Triangle {
871    ///
872    /// Creates a new `Triangle` given the necessary data.
873    ///
874    /// - The fields `a`, `b`, and `c` are the indices into
875    ///   [`BaseShape::initial_points()`] which are the vertices
876    ///   of this triangle.
877    ///   Note that this crate assumes
878    ///   points are in a counter-clockwise ordering.
879    /// - The fields `ab_edge`, `bc_edge`, `ca_edge` mark the
880    ///   index of the edge which `a`/`b`, `b`/`c`, and `c`/`a`
881    ///   border respectively. While theoretically you could give
882    ///   each triangle its own edge, sharing edges between triangles
883    ///   saves on memory footprint and performance.
884    ///
885    ///   There is no explicit list of edges; they are defined by how
886    ///   they are used here. However, the total number of edges must
887    ///   be specified in [`BaseShape::EDGES`], and all edge indices
888    ///   from 0 to `EDGES - 1` must be used.
889    ///
890    pub const fn new(
891        a: u32,
892        b: u32,
893        c: u32,
894        ab_edge: usize,
895        bc_edge: usize,
896        ca_edge: usize,
897    ) -> Self {
898        Self {
899            a,
900            b,
901            c,
902            ab_edge,
903            bc_edge,
904            ca_edge,
905
906            ab_forward: false,
907            bc_forward: false,
908            ca_forward: false,
909
910            contents: TriangleContents::None,
911        }
912    }
913
914    fn calculate_edges(
915        &mut self,
916        edges: &mut [Edge],
917        points: &mut [Vec3A],
918        shape: &impl BaseShape,
919    ) -> usize {
920        let mut divide = |p1: u32, p2: u32, edge_idx: usize, forward: &mut bool| {
921            if !edges[edge_idx].done {
922                shape.interpolate_multiple(
923                    points[p1 as usize],
924                    points[p2 as usize],
925                    &edges[edge_idx].points,
926                    points,
927                );
928
929                edges[edge_idx].done = true;
930                *forward = true;
931            } else {
932                *forward = false;
933            }
934        };
935
936        divide(self.a, self.b, self.ab_edge, &mut self.ab_forward);
937        divide(self.b, self.c, self.bc_edge, &mut self.bc_forward);
938        divide(self.c, self.a, self.ca_edge, &mut self.ca_forward);
939
940        edges[self.ab_edge].points.len()
941    }
942
943    ///
944    /// Subdivides the edges and contents of this triangle.
945    ///
946    /// If `calculate` is set to `false`, then the points are
947    /// simply added to the buffer and the indices recorded,
948    /// but no calculations are performed.
949    ///
950    fn subdivide(&mut self, points: &mut usize, subdivision_level: usize) {
951        if subdivision_level >= 1 {
952            self.contents.subdivide(points);
953        }
954    }
955
956    fn calculate(&mut self, edges: &mut [Edge], points: &mut [Vec3A], shape: &impl BaseShape) {
957        let side_length = self.calculate_edges(edges, points, shape) + 1;
958
959        if side_length > 2 {
960            let ab = if self.ab_forward {
961                Forward(&edges[self.ab_edge].points)
962            } else {
963                Backward(&edges[self.ab_edge].points)
964            };
965            let bc = if self.bc_forward {
966                Forward(&edges[self.bc_edge].points)
967            } else {
968                Backward(&edges[self.bc_edge].points)
969            };
970            let ca = if self.ca_forward {
971                Forward(&edges[self.ca_edge].points)
972            } else {
973                Backward(&edges[self.ca_edge].points)
974            };
975            self.contents.calculate(ab, bc, ca, points, shape);
976        }
977    }
978
979    ///
980    /// Appends the indices of all the subtriangles onto the
981    /// specified buffer.
982    ///
983    fn add_indices(&self, buffer: &mut Vec<u32>, edges: &[Edge]) {
984        let ab = if self.ab_forward {
985            Forward(&edges[self.ab_edge].points)
986        } else {
987            Backward(&edges[self.ab_edge].points)
988        };
989        let bc = if self.bc_forward {
990            Forward(&edges[self.bc_edge].points)
991        } else {
992            Backward(&edges[self.bc_edge].points)
993        };
994        let ca = if self.ca_forward {
995            Forward(&edges[self.ca_edge].points)
996        } else {
997            Backward(&edges[self.ca_edge].points)
998        };
999
1000        add_indices_triangular(self.a, self.b, self.c, ab, bc, ca, &self.contents, buffer);
1001
1002        self.contents.add_indices(buffer);
1003    }
1004
1005    ///
1006    /// Appends the indices of all the subtriangles' wireframes
1007    /// onto the specified buffer.
1008    ///
1009    fn add_line_indices(
1010        &self,
1011        buffer: &mut Vec<u32>,
1012        edges: &[Edge],
1013        delta: u32,
1014        mut breaks: impl FnMut(&mut Vec<u32>),
1015    ) {
1016        let ab = if self.ab_forward {
1017            Forward(&edges[self.ab_edge].points)
1018        } else {
1019            Backward(&edges[self.ab_edge].points)
1020        };
1021        let bc = if self.bc_forward {
1022            Forward(&edges[self.bc_edge].points)
1023        } else {
1024            Backward(&edges[self.bc_edge].points)
1025        };
1026        let ca = if self.ca_forward {
1027            Forward(&edges[self.ca_edge].points)
1028        } else {
1029            Backward(&edges[self.ca_edge].points)
1030        };
1031
1032        add_line_indices_triangular(delta, ab, bc, ca, &self.contents, buffer);
1033
1034        breaks(buffer);
1035
1036        self.contents.add_line_indices(buffer, delta, breaks);
1037    }
1038}
1039
1040///
1041/// A subdivided shape generated from some [`BaseShape`] and a subdivision level.
1042///
1043/// The subdivided shape is defined, as is conventional in most 3D graphics systems,
1044/// as a list of vertices, and a list of indices into the vertex list which connect
1045/// the vertices into primitive shapes. [`Subdivided`] can provide triangle-list indices
1046/// indices for solid surface rendering, and line-strip indices for wireframe rendering.
1047///
1048/// All main triangles specified by `S` in [`BaseShape`]
1049/// are expected to be in counter clockwise winding.
1050///
1051/// Points are preferably stored with coordinates less
1052/// than or equal to `1.0`. This is why all default shapes
1053/// lie on the unit sphere.
1054///
1055#[derive(Clone)]
1056pub struct Subdivided<T, S: BaseShape> {
1057    points: Vec<Vec3A>,
1058    data: Vec<T>,
1059    triangles: Box<[Triangle]>,
1060    shared_edges: Box<[Edge]>,
1061    subdivisions: usize,
1062    shape: S,
1063}
1064
1065impl<T, S: BaseShape> Subdivided<T, S> {
1066    /// Creates the base shape from `S` and subdivides it.
1067    ///
1068    /// This is equivalent to
1069    /// `Subdivided::new_custom_shape(subdivisions, generator, S::default())`
1070    /// and is convenient when `S` implements [`Default`].
1071    pub fn new(subdivisions: usize, generator: impl FnMut(Vec3A) -> T) -> Self
1072    where
1073        S: Default,
1074    {
1075        Self::new_custom_shape(subdivisions, generator, S::default())
1076    }
1077    ///
1078    /// Creates the base shape from `S` and subdivides it.
1079    ///
1080    /// - `subdivisions` specifies the number of auxiliary points that will be created
1081    ///   along the edges the vertices of the base shape. For example, if `subdivisions`
1082    ///   is 0, then the base shape is unaltered; if `subdivisions` is 3, then each edge
1083    ///   of the base shape will have 3 added points, forming 4 triangle edges.
1084    ///
1085    /// - `generator` is a function run for each vertex once all the subdivisions are
1086    ///   applied, and its values are stored in an internal `Vec`,
1087    ///   accessible from [`Self::raw_data()`].
1088    ///
1089    pub fn new_custom_shape(
1090        subdivisions: usize,
1091        generator: impl FnMut(Vec3A) -> T,
1092        shape: S,
1093    ) -> Self {
1094        let mut this = Self {
1095            points: shape.initial_points(),
1096            shared_edges: {
1097                let mut edges = Vec::new();
1098                edges.resize_with(S::EDGES, Edge::default);
1099                edges.into_boxed_slice()
1100            },
1101            triangles: shape.triangles(),
1102            subdivisions: 1,
1103            data: vec![],
1104            shape,
1105        };
1106
1107        let mut new_points = this.points.len();
1108
1109        for edge in &mut *this.shared_edges {
1110            edge.subdivide_n_times(subdivisions, &mut new_points);
1111            edge.done = false;
1112        }
1113
1114        for triangle in &mut *this.triangles {
1115            for i in 0..subdivisions {
1116                triangle.subdivide(&mut new_points, i);
1117            }
1118        }
1119
1120        let diff = new_points - this.points.len();
1121        this.points.extend(core::iter::repeat_n(Vec3A::ZERO, diff));
1122
1123        for triangle in &mut *this.triangles {
1124            triangle.calculate(&mut this.shared_edges, &mut this.points, &this.shape);
1125        }
1126
1127        this.data = this.points.iter().copied().map(generator).collect();
1128
1129        this.subdivisions = subdivisions;
1130
1131        this
1132    }
1133
1134    ///
1135    /// Increases the current subdivision count by `amount`.
1136    ///
1137    /// After calling this, you must call [`Self::calculate_values()`]
1138    /// to compute new vertex data.
1139    ///
1140    pub fn subdivide(&mut self, amount: usize) {
1141        let mut new_points = self.points.len();
1142
1143        let subdivision_level = self.shared_edges[0].points.len();
1144
1145        for edge in &mut *self.shared_edges {
1146            edge.subdivide_n_times(amount, &mut new_points);
1147            edge.done = false;
1148        }
1149
1150        for triangle in &mut *self.triangles {
1151            for _ in 0..amount {
1152                triangle.subdivide(&mut new_points, subdivision_level);
1153            }
1154        }
1155
1156        let diff = new_points - self.points.len();
1157        self.points.extend(core::iter::repeat_n(Vec3A::ZERO, diff));
1158
1159        self.subdivisions += amount;
1160    }
1161
1162    ///
1163    /// Recalculate data after [`Self::subdivide()`].
1164    ///
1165    pub fn calculate_values(&mut self, generator: impl FnMut(Vec3A) -> T) {
1166        for triangle in &mut *self.triangles {
1167            triangle.calculate(&mut self.shared_edges, &mut self.points, &self.shape);
1168        }
1169
1170        self.data = self.points.iter().copied().map(generator).collect();
1171    }
1172
1173    ///
1174    /// The vertex positions created by the subdivision process.
1175    ///
1176    pub fn raw_points(&self) -> &[Vec3A] {
1177        &self.points
1178    }
1179
1180    ///
1181    /// Appends the indices for the subdivided form of the specified
1182    /// main triangle into `buffer`.
1183    ///
1184    /// The specified `triangle` is a main triangle on the base
1185    /// shape. The range of this should be limited to the number
1186    /// of triangles in the base shape.
1187    ///
1188    /// Alternatively, use [`Self::get_all_indices`] to get all the
1189    /// indices.
1190    ///
1191    /// Each element put into `buffer` is an index into [`Self::raw_data`]
1192    /// or [`Self::raw_points`] specifying the position of a triangle vertex.
1193    /// The first three elements specify the three vertices of a triangle
1194    /// to be drawn, and the next three elements specify another triangle,
1195    /// and so on.
1196    ///
1197    pub fn get_indices(&self, triangle: usize, buffer: &mut Vec<u32>) {
1198        self.triangles[triangle].add_indices(buffer, &self.shared_edges);
1199    }
1200
1201    ///
1202    /// Gets the indices for the triangles making up the subdivided shape.
1203    ///
1204    /// Each element of the returned [`Vec`] is an index into [`Self::raw_data`]
1205    /// or [`Self::raw_points`] specifying the position of a triangle vertex.
1206    /// The first three elements specify the three vertices of a triangle
1207    /// to be drawn, and the next three elements specify another triangle,
1208    /// and so on.
1209    ///
1210    /// Together, these triangles cover the entire surface of the shape.
1211    ///
1212    pub fn get_all_indices(&self) -> Vec<u32> {
1213        let mut buffer = Vec::new();
1214
1215        for i in 0..self.triangles.len() {
1216            self.get_indices(i, &mut buffer);
1217        }
1218
1219        buffer
1220    }
1221
1222    ///
1223    /// Appends indices for the wireframe of the subdivided form of
1224    /// the specified main triangle to `buffer`.
1225    ///
1226    /// This is equivalent to [`Self::get_all_line_indices`] except that it
1227    /// selects a single main triangle from the base shape. See its documentation
1228    /// for the format of the result, and how to use `delta` and `breaks`.
1229    ///
1230    pub fn get_line_indices(
1231        &self,
1232        buffer: &mut Vec<u32>,
1233        triangle: usize,
1234        delta: usize,
1235        breaks: impl FnMut(&mut Vec<u32>),
1236    ) {
1237        self.triangles[triangle].add_line_indices(buffer, &self.shared_edges, delta as u32, breaks);
1238    }
1239
1240    ///
1241    /// Appends indices for the wireframe of the subdivided form of
1242    /// the specified main triangle edge to `buffer`.
1243    ///
1244    /// The valid range of `edge` is `0..(S::EDGES)`.
1245    /// See [`Self::get_line_indices`] for more on `delta`.
1246    ///
1247    #[deprecated = "Flawed. Use `get_major_edges_line_indices()` instead."]
1248    pub fn get_major_edge_line_indices(&self, edge: usize, buffer: &mut Vec<u32>, delta: usize) {
1249        buffer.extend(
1250            self.shared_edges[edge]
1251                .points
1252                .iter()
1253                .map(|x| x + delta as u32),
1254        );
1255    }
1256
1257    ///
1258    /// Appends indices for the wireframe of the subdivided form of
1259    /// the base shape's main triangles' edges to `buffer`.
1260    ///
1261    /// Compared to [`Self::get_all_line_indices`], this does not return edges of any of the
1262    /// triangles which were created by subdivision — only edges of the original triangles.
1263    /// See that method's documentation for how to use `delta` and `breaks`.
1264    ///
1265    pub fn get_major_edges_line_indices(
1266        &self,
1267        buffer: &mut Vec<u32>,
1268        delta: u32,
1269        mut breaks: impl FnMut(&mut Vec<u32>),
1270    ) {
1271        for triangle in &*self.triangles {
1272            for (p1, p2, edge, forward) in [
1273                (
1274                    triangle.a,
1275                    triangle.b,
1276                    triangle.ab_edge,
1277                    triangle.ab_forward,
1278                ),
1279                (
1280                    triangle.b,
1281                    triangle.c,
1282                    triangle.bc_edge,
1283                    triangle.bc_forward,
1284                ),
1285                (
1286                    triangle.c,
1287                    triangle.a,
1288                    triangle.ca_edge,
1289                    triangle.ca_forward,
1290                ),
1291            ] {
1292                if !forward {
1293                    continue;
1294                }
1295
1296                buffer.push(p1 + delta);
1297                buffer.extend(self.shared_edges[edge].points.iter().map(|x| x + delta));
1298                buffer.push(p2 + delta);
1299
1300                breaks(buffer);
1301            }
1302        }
1303    }
1304
1305    ///
1306    /// Returns a vector of indices for the wireframe of the subdivided mesh.
1307    ///
1308    /// Each element in the returned [`Vec`] is an index into [`Self::raw_data`]
1309    /// or [`Self::raw_points`] specifying the position of a triangle vertex.
1310    /// The indices are formatted as "line strips"; that is, each vertex
1311    /// should be connected to the previous by a line, except where a break is
1312    /// specified.
1313    ///
1314    /// The `breaks` function is run every time there is a necessary break in
1315    /// the line strip. Use this to, for example, swap out the buffer using
1316    /// [`std::mem::take`], or push a special break-marking index into the buffer.
1317    ///
1318    /// `delta` is added to all of the indices pushed into the buffer, and
1319    /// is generally intended to be used together with `breaks` to allow a
1320    /// marker index at zero.
1321    /// This marker index might be used to refer to a vertex with position
1322    /// set to NaN, or parsed in some other way by the graphics API the indices
1323    /// are fed to.
1324    ///
1325    pub fn get_all_line_indices(
1326        &self,
1327        delta: usize,
1328        mut breaks: impl FnMut(&mut Vec<u32>),
1329    ) -> Vec<u32> {
1330        let mut buffer = Vec::new();
1331
1332        // Pushes all of the subdivision-created lines that are *not* part of `self.shared_edges`.
1333        for i in 0..self.triangles.len() {
1334            self.get_line_indices(&mut buffer, i, delta, &mut breaks);
1335            breaks(&mut buffer);
1336        }
1337
1338        let delta = delta as u32;
1339        self.get_major_edges_line_indices(&mut buffer, delta, &mut breaks);
1340
1341        buffer
1342    }
1343
1344    ///
1345    /// Returns the number of subdivisions applied when this shape
1346    /// was created.
1347    ///
1348    pub fn subdivisions(&self) -> usize {
1349        self.subdivisions
1350    }
1351
1352    ///
1353    /// Returns the custom data for each vertex created by the generator function.
1354    ///
1355    /// The length of this slice is equal to the number of vertices in the subdivided shape.
1356    ///
1357    pub fn raw_data(&self) -> &[T] {
1358        &self.data
1359    }
1360
1361    ///
1362    /// Returns mutable access to the custom data created by the generator function.
1363    ///
1364    /// The length of this slice is equal to the number of vertices in the subdivided shape.
1365    ///
1366    pub fn raw_data_mut(&mut self) -> &mut [T] {
1367        &mut self.data
1368    }
1369
1370    ///
1371    /// Calculate the number of indices which each main
1372    /// triangle will add to the vertex buffer.
1373    ///
1374    /// # Equation
1375    ///
1376    /// ```text
1377    /// (subdivisions + 1)²
1378    /// ```
1379    ///
1380    pub fn indices_per_main_triangle(&self) -> usize {
1381        (self.subdivisions + 1) * (self.subdivisions + 1)
1382    }
1383
1384    ///
1385    /// Calculate the number of vertices contained within
1386    /// each main triangle including the vertices which are
1387    /// shared with another main triangle.
1388    ///
1389    /// # Equation
1390    ///
1391    /// ```text
1392    /// (subdivisions + 1) * (subdivisions + 2) / 2
1393    /// ```
1394    ///
1395    pub fn vertices_per_main_triangle_shared(&self) -> usize {
1396        (self.subdivisions + 1) * (self.subdivisions + 2) / 2
1397    }
1398
1399    ///
1400    /// Calculate the number of vertices contained within each
1401    /// main triangle excluding the ones that are shared with
1402    /// other main triangles.
1403    ///
1404    /// # Equation
1405    ///
1406    /// ```text
1407    /// {
1408    /// { subdivisions < 2  : 0
1409    /// {
1410    /// { subdivisions >= 2 : (subdivisions - 1) * subdivisions / 2
1411    /// {
1412    /// ```
1413    ///
1414    pub fn vertices_per_main_triangle_unique(&self) -> usize {
1415        if self.subdivisions < 2 {
1416            return 0;
1417        }
1418        (self.subdivisions - 1) * self.subdivisions / 2
1419    }
1420
1421    ///
1422    /// Calculate the number of vertices along the edges
1423    /// of the main triangles and the vertices of the main
1424    /// triangles.
1425    ///
1426    /// # Equation
1427    ///
1428    /// ```text
1429    /// subdivisions * EDGES + INITIAL_POINTS
1430    /// ```
1431    ///
1432    pub fn shared_vertices(&self) -> usize {
1433        self.subdivisions * S::EDGES + self.shape.initial_points().len()
1434    }
1435
1436    ///
1437    /// Linear distance between two points on this shape.
1438    ///
1439    pub fn linear_distance(&self, p1: u32, p2: u32, radius: f32) -> f32 {
1440        (self.points[p1 as usize] - self.points[p2 as usize]).length() * radius
1441    }
1442
1443    ///
1444    /// Returns the base triangles used by the library internally.
1445    ///
1446    /// This typically won't be useful to most people, except for
1447    /// when you want to know how many base triangles the shape
1448    /// had originally.
1449    ///
1450    pub fn main_triangles(&self) -> &[Triangle] {
1451        &self.triangles
1452    }
1453}
1454
1455#[cfg(feature = "shape-extras")]
1456impl<T, S: BaseShape + EquilateralBaseShape> Subdivided<T, S> {
1457    ///
1458    /// Closest "main" triangle.
1459    ///
1460    /// Undefined results if the point is one of the vertices
1461    /// on the original base shape.
1462    ///
1463    pub fn main_triangle_intersect(point: Vec3A) -> usize {
1464        let point = point.normalize();
1465        let mut nearest = 0;
1466        let mut near_factor = point.dot(S::triangle_normals()[0]);
1467
1468        if near_factor > S::triangle_min_dot() {
1469            return 0;
1470        }
1471
1472        for (index, normal) in S::triangle_normals().iter().enumerate().skip(1) {
1473            let factor = normal.dot(point);
1474            if factor > near_factor {
1475                if factor > S::triangle_min_dot() {
1476                    return index;
1477                }
1478                nearest = index;
1479                near_factor = factor;
1480            }
1481        }
1482
1483        nearest
1484    }
1485
1486    ///
1487    /// Distance between two points on this sphere (assuming this
1488    /// is a sphere).
1489    ///
1490    pub fn spherical_distance(&self, p1: u32, p2: u32, radius: f32) -> f32 {
1491        self.points[p1 as usize]
1492            .dot(self.points[p2 as usize])
1493            .acos()
1494            * radius
1495    }
1496}
1497
1498///
1499/// Adds the indices of the triangles in this "layer" of the triangle to
1500/// the buffer.
1501///
1502// The logic in this function has been worked out mostly on pen and paper
1503// and therefore it is difficult to read.
1504fn add_indices_triangular(
1505    a: u32,
1506    b: u32,
1507    c: u32,
1508    ab: Slice<u32>,
1509    bc: Slice<u32>,
1510    ca: Slice<u32>,
1511    contents: &TriangleContents,
1512    buffer: &mut Vec<u32>,
1513) {
1514    let subdivisions = ab.len();
1515    if subdivisions == 0 {
1516        buffer.extend_from_slice(&[a, b, c]);
1517        return;
1518    } else if subdivisions == 1 {
1519        buffer.extend_from_slice(&[a, ab[0], ca[0]]);
1520        buffer.extend_from_slice(&[b, bc[0], ab[0]]);
1521        buffer.extend_from_slice(&[c, ca[0], bc[0]]);
1522        buffer.extend_from_slice(&[ab[0], bc[0], ca[0]]);
1523        return;
1524    } else if subdivisions == 2 {
1525        buffer.extend_from_slice(&[a, ab[0], ca[1]]);
1526        buffer.extend_from_slice(&[b, bc[0], ab[1]]);
1527        buffer.extend_from_slice(&[c, ca[0], bc[1]]);
1528
1529        buffer.extend_from_slice(&[ab[1], contents.idx_ab(0), ab[0]]);
1530        buffer.extend_from_slice(&[bc[1], contents.idx_ab(0), bc[0]]);
1531        buffer.extend_from_slice(&[ca[1], contents.idx_ab(0), ca[0]]);
1532
1533        buffer.extend_from_slice(&[ab[0], contents.idx_ab(0), ca[1]]);
1534        buffer.extend_from_slice(&[bc[0], contents.idx_ab(0), ab[1]]);
1535        buffer.extend_from_slice(&[ca[0], contents.idx_ab(0), bc[1]]);
1536        return;
1537    }
1538
1539    let last_idx = ab.len() - 1;
1540
1541    buffer.extend_from_slice(&[a, ab[0], ca[last_idx]]);
1542    buffer.extend_from_slice(&[b, bc[0], ab[last_idx]]);
1543    buffer.extend_from_slice(&[c, ca[0], bc[last_idx]]);
1544
1545    buffer.extend_from_slice(&[ab[0], contents.idx_ab(0), ca[last_idx]]);
1546    buffer.extend_from_slice(&[bc[0], contents.idx_bc(0), ab[last_idx]]);
1547    buffer.extend_from_slice(&[ca[0], contents.idx_ca(0), bc[last_idx]]);
1548
1549    for i in 0..last_idx - 1 {
1550        // Exclude special case: last_idx - 1.
1551        // AB
1552        buffer.extend_from_slice(&[ab[i], ab[i + 1], contents.idx_ab(i)]);
1553        buffer.extend_from_slice(&[ab[i + 1], contents.idx_ab(i + 1), contents.idx_ab(i)]);
1554        // BC
1555        buffer.extend_from_slice(&[bc[i], bc[i + 1], contents.idx_bc(i)]);
1556        buffer.extend_from_slice(&[bc[i + 1], contents.idx_bc(i + 1), contents.idx_bc(i)]);
1557        // CA
1558        buffer.extend_from_slice(&[ca[i], ca[i + 1], contents.idx_ca(i)]);
1559        buffer.extend_from_slice(&[ca[i + 1], contents.idx_ca(i + 1), contents.idx_ca(i)]);
1560    }
1561
1562    // Deal with special case: last_idx - 1
1563    buffer.extend_from_slice(&[
1564        ab[last_idx],
1565        contents.idx_ab(last_idx - 1),
1566        ab[last_idx - 1],
1567    ]);
1568
1569    buffer.extend_from_slice(&[
1570        bc[last_idx],
1571        contents.idx_bc(last_idx - 1),
1572        bc[last_idx - 1],
1573    ]);
1574
1575    buffer.extend_from_slice(&[
1576        ca[last_idx],
1577        contents.idx_ca(last_idx - 1),
1578        ca[last_idx - 1],
1579    ]);
1580}
1581
1582/// Adds the indices of the triangles in this "layer" of the triangle to
1583/// the buffer in line strip format.
1584///
1585/// Does the zig-zag between the current one and the contents,
1586/// and also the ring of the contents. (Since the outermost
1587/// ring is dealt with separately by `get_major_edge_line_indices`.
1588///
1589/// This is used to create a wireframe look.
1590///
1591// Like the previous function, this logic has been worked out mostly on
1592// pen and paper and it is therefore difficult to read.
1593fn add_line_indices_triangular(
1594    delta: u32,
1595    ab: Slice<u32>,
1596    bc: Slice<u32>,
1597    ca: Slice<u32>,
1598    contents: &TriangleContents,
1599    buffer: &mut Vec<u32>,
1600) {
1601    // if the number of points on our edge is zero, we have
1602    // no interior, and no zigzag
1603    if ab.len() == 0 {
1604        return;
1605    }
1606
1607    // if the number of points on our edge is one, there is no
1608    // interior, and there is only the zigzag
1609    if ab.len() == 1 {
1610        #[rustfmt::skip]
1611        buffer.extend_from_slice(&[
1612            ab[0] + delta,
1613            bc[0] + delta,
1614            ca[0] + delta,
1615            ab[0] + delta,
1616        ]);
1617        return;
1618    }
1619
1620    // if the number of points on our edge is two, then `contents`
1621    // is a single point and we get a three leaf clover
1622    if ab.len() == 2 {
1623        let inner = contents.idx_ab(0);
1624        buffer.extend_from_slice(&[
1625            inner + delta,
1626            ab[1] + delta,
1627            bc[0] + delta,
1628            inner + delta,
1629            bc[1] + delta,
1630            ca[0] + delta,
1631            inner + delta,
1632            ca[1] + delta,
1633            ab[0] + delta,
1634            inner + delta,
1635        ]);
1636        return;
1637    }
1638
1639    buffer.reserve((ab.len() - 1) * 9);
1640
1641    // Add the inner loop
1642    for i in 0..ab.len() - 2 {
1643        buffer.push(contents.idx_ab(i) + delta);
1644    }
1645
1646    for i in 0..bc.len() - 2 {
1647        buffer.push(contents.idx_bc(i) + delta);
1648    }
1649
1650    for i in 0..ca.len() - 2 {
1651        buffer.push(contents.idx_ca(i) + delta);
1652    }
1653
1654    // close the inner loop
1655    buffer.push(contents.idx_ab(0) + delta);
1656
1657    // do zigzag
1658    buffer.push(ab[0] + delta);
1659
1660    for i in (1..ca.len()).rev() {
1661        buffer.push(ca[i] + delta);
1662        buffer.push(contents.idx_ca(i - 1) + delta);
1663    }
1664
1665    buffer.push(ca[0] + delta);
1666
1667    for i in (1..bc.len()).rev() {
1668        buffer.push(bc[i] + delta);
1669        buffer.push(contents.idx_bc(i - 1) + delta);
1670    }
1671
1672    buffer.push(bc[0] + delta);
1673
1674    for i in (1..ab.len()).rev() {
1675        buffer.push(ab[i] + delta);
1676        buffer.push(contents.idx_ab(i - 1) + delta);
1677    }
1678
1679    buffer.push(ab[0] + delta);
1680}
1681
1682#[cfg(feature = "adjacency")]
1683///
1684/// Implements neighbour tracking.
1685///
1686mod adjacency {
1687    use alloc::vec::Vec;
1688    use tinyvec::ArrayVec;
1689
1690    #[derive(Copy, Clone, Eq, PartialEq, Debug)]
1691    pub(crate) enum RehexState {
1692        Empty,
1693        Clear,
1694        TwoTwo,
1695        ThreeTwo,
1696        TwoTwoTwo,
1697        Complete,
1698    }
1699
1700    /// Tracks the neighbours adjacent to each vertex by only using index data.
1701    ///
1702    /// The result preserves winding: the resulting array is wound around the
1703    /// center vertex in the same way that the source triangles were wound.
1704    pub struct AdjacencyBuilder {
1705        pub(crate) state: Vec<RehexState>,
1706        pub result: Vec<ArrayVec<[usize; 6]>>,
1707    }
1708
1709    impl AdjacencyBuilder {
1710        pub fn new(points_len: usize) -> Self {
1711            let state = core::iter::repeat(RehexState::Empty)
1712                .take(points_len)
1713                .collect::<Vec<_>>();
1714            let result = core::iter::repeat(ArrayVec::new())
1715                .take(points_len)
1716                .collect::<Vec<_>>();
1717            Self { state, result }
1718        }
1719
1720        pub fn add_indices(&mut self, indices: &[u32]) {
1721            for chunk in indices.chunks_exact(3) {
1722                let &[a, b, c] = chunk else { unreachable!() };
1723
1724                self.add_triangle(a, b, c);
1725                self.add_triangle(c, a, b);
1726                self.add_triangle(b, c, a);
1727            }
1728        }
1729
1730        pub fn finish(self) -> Vec<ArrayVec<[usize; 6]>> {
1731            self.result
1732        }
1733
1734        fn add_triangle(&mut self, a: u32, b: u32, c: u32) {
1735            let (a, b, c) = (a as usize, b as usize, c as usize);
1736            let state = &mut self.state[a];
1737            if let RehexState::Complete = state {
1738                return;
1739            }
1740
1741            let result = &mut self.result[a];
1742
1743            match state {
1744                RehexState::Empty => {
1745                    result.extend([b, c]);
1746                    *state = RehexState::Clear;
1747                }
1748                RehexState::Clear => {
1749                    if result[result.len() - 1] == b {
1750                        if result[0] == c {
1751                            *state = RehexState::Complete;
1752                        } else {
1753                            result.push(c);
1754                            if result.len() == 6 {
1755                                *state = RehexState::Complete;
1756                            }
1757                        }
1758                    } else if result[0] == c {
1759                        result.insert(0, b);
1760                        if result.len() == 6 {
1761                            *state = RehexState::Complete;
1762                        }
1763                    } else {
1764                        *state = match result.len() {
1765                            2 => RehexState::TwoTwo,
1766                            3 => RehexState::ThreeTwo,
1767                            4 => RehexState::Complete,
1768                            _ => unreachable!(),
1769                        };
1770                        result.extend([b, c]);
1771                    }
1772                }
1773                RehexState::TwoTwo => {
1774                    if result[1] == b {
1775                        if result[2] == c {
1776                            *state = RehexState::Clear;
1777                        } else {
1778                            result.insert(2, c);
1779                            *state = RehexState::ThreeTwo;
1780                        }
1781                    } else if result[0] == c {
1782                        if result[3] == b {
1783                            let temp = result[2];
1784                            result.pop();
1785                            result.pop();
1786                            result.insert(0, temp);
1787                            result.insert(1, b);
1788                            *state = RehexState::Clear;
1789                        } else {
1790                            result.insert(0, b);
1791                            *state = RehexState::ThreeTwo;
1792                        }
1793                    } else if result[2] == c {
1794                        result.insert(0, b);
1795                        let t2 = result.swap_remove(2);
1796                        let t1 = result.swap_remove(1);
1797                        result.push(t1);
1798                        result.push(t2);
1799                        *state = RehexState::ThreeTwo;
1800                    } else {
1801                        result.extend([b, c]);
1802                        *state = RehexState::TwoTwoTwo;
1803                    }
1804                }
1805                RehexState::ThreeTwo => {
1806                    if result[2] == b {
1807                        if result[3] == c {
1808                            *state = RehexState::Clear;
1809                        } else {
1810                            result.insert(3, c);
1811                            *state = RehexState::Complete;
1812                        }
1813                    } else {
1814                        if result[4] == b {
1815                            result.pop();
1816                            let temp = result.pop().unwrap();
1817                            result.insert(0, b);
1818                            result.insert(0, temp);
1819                            *state = RehexState::Clear;
1820                        } else {
1821                            result.insert(0, b);
1822                            *state = RehexState::Complete;
1823                        }
1824                    }
1825                }
1826                RehexState::TwoTwoTwo => {
1827                    if (result[1] != b || result[2] != c)
1828                        && (result[3] != b || result[4] != c)
1829                        && (result[5] != b || result[0] != c)
1830                    {
1831                        let t2 = result.swap_remove(3);
1832                        let t1 = result.swap_remove(2);
1833                        result.extend([t1, t2]);
1834                    }
1835                    *state = RehexState::Complete;
1836                }
1837                RehexState::Complete => unreachable!(),
1838            }
1839        }
1840    }
1841}
1842
1843#[cfg(test)]
1844mod tests {
1845    use crate::shapes::{IcoSphere, SquarePlane};
1846    use crate::Slice::Forward;
1847    use alloc::vec::Vec;
1848    use glam::Vec3A;
1849
1850    // Starting points aren't _quite_ precise enough to use `f32::EPSILON`.
1851    const EPSILON: f32 = 0.0000002;
1852
1853    #[test]
1854    fn slerp_one() {
1855        use crate::interpolation::geometric_slerp_half;
1856        let p1 = Vec3A::new(0.360492952832, 0.932761936915, 0.0);
1857        let p2 = Vec3A::new(0.975897449331, 0.218229623081, 0.0);
1858
1859        let expected = Vec3A::new(0.757709663147, 0.652591806854, 0.0);
1860
1861        let result = geometric_slerp_half(p1, p2);
1862
1863        assert!((expected - result).length() <= EPSILON);
1864
1865        // Another test case
1866        let p1 = Vec3A::new(-0.24953852315, 0.0, 0.968364872073);
1867        let p2 = Vec3A::new(-0.948416666565, 0.0, 0.317026539239);
1868
1869        let expected = Vec3A::new(-0.681787771301, 0.0, 0.731550022148);
1870
1871        let result = geometric_slerp_half(p1, p2);
1872
1873        assert!((expected - result).length() <= EPSILON);
1874    }
1875
1876    #[test]
1877    fn slerp_many() {
1878        use crate::interpolation::geometric_slerp_multiple;
1879
1880        let p1 = Vec3A::new(0.0, -0.885330189449, 0.464962854054);
1881        let p2 = Vec3A::new(0.0, 0.946042343528, 0.324043028395);
1882
1883        let expected = Vec3A::new(0.0, 0.0767208624118, 0.997052611085);
1884
1885        let mut result = Vec3A::ZERO;
1886        geometric_slerp_multiple(p1, p2, &[0], core::slice::from_mut(&mut result));
1887
1888        assert!((expected - result).length() <= EPSILON);
1889
1890        let p1 = Vec3A::new(0.876621956288, 0.0, 0.481179743707);
1891        let p2 = Vec3A::new(-0.391617625614, 0.0, -0.920128053756);
1892
1893        let expected = [
1894            Vec3A::new(0.999975758841, 0.0, 0.00696288230076),
1895            Vec3A::new(0.883237589397, 0.0, -0.468925751774),
1896            Vec3A::new(0.554436024709, 0.0, -0.83222634812),
1897            Vec3A::new(0.0925155945469, 0.0, -0.995711235633),
1898        ];
1899
1900        let mut result = [Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO];
1901
1902        geometric_slerp_multiple(p1, p2, &[0, 1, 2, 3], &mut result);
1903
1904        for (&expected, &result) in expected.iter().zip(result.iter()) {
1905            assert!((expected - result).length() <= EPSILON);
1906        }
1907    }
1908
1909    #[test]
1910    fn new() {
1911        let x = IcoSphere::new(0, |_| ());
1912        x.get_indices(0, &mut Vec::new());
1913    }
1914
1915    #[test]
1916    fn clone() {
1917        let _x = IcoSphere::new(6, |_| ()).clone();
1918    }
1919
1920    #[test]
1921    fn one() {
1922        let x = IcoSphere::new(1, |_| ());
1923        x.get_indices(0, &mut Vec::new());
1924    }
1925
1926    #[test]
1927    fn second_layer_inner() {
1928        let x = IcoSphere::new(2, |_| ());
1929        x.get_indices(0, &mut Vec::new());
1930        let x = IcoSphere::new(3, |_| ());
1931        x.get_indices(0, &mut Vec::new());
1932        let x = IcoSphere::new(5, |_| ());
1933        x.get_indices(0, &mut Vec::new());
1934        let x = IcoSphere::new(6, |_| ());
1935        x.get_indices(0, &mut Vec::new());
1936    }
1937
1938    #[test]
1939    fn indices_zero() {
1940        use super::add_indices_triangular;
1941        use super::TriangleContents;
1942
1943        let mut buffer = Vec::new();
1944
1945        add_indices_triangular(
1946            0,
1947            1,
1948            2,
1949            Forward(&[]),
1950            Forward(&[]),
1951            Forward(&[]),
1952            &TriangleContents::none(),
1953            &mut buffer,
1954        );
1955
1956        assert_eq!(buffer, &[0, 1, 2]);
1957    }
1958
1959    #[test]
1960    fn indices_one() {
1961        use super::add_indices_triangular;
1962        use super::TriangleContents;
1963
1964        let mut buffer = Vec::new();
1965
1966        add_indices_triangular(
1967            0,
1968            1,
1969            2,
1970            Forward(&[3]),
1971            Forward(&[4]),
1972            Forward(&[5]),
1973            &TriangleContents::none(),
1974            &mut buffer,
1975        );
1976
1977        assert_eq!(buffer, &[0, 3, 5, 1, 4, 3, 2, 5, 4, 3, 4, 5,]);
1978    }
1979
1980    #[test]
1981    fn indices_two() {
1982        use super::add_indices_triangular;
1983        use super::TriangleContents;
1984
1985        let mut buffer = Vec::new();
1986
1987        add_indices_triangular(
1988            0,
1989            3,
1990            6,
1991            Forward(&[1, 2]),
1992            Forward(&[4, 5]),
1993            Forward(&[7, 8]),
1994            &TriangleContents::One(9),
1995            &mut buffer,
1996        );
1997
1998        assert_eq!(
1999            buffer,
2000            &[0, 1, 8, 3, 4, 2, 6, 7, 5, 2, 9, 1, 5, 9, 4, 8, 9, 7, 1, 9, 8, 4, 9, 2, 7, 9, 5,]
2001        );
2002    }
2003
2004    // Really, we're testing for the rest.
2005    #[test]
2006    fn indices_three() {
2007        use super::add_indices_triangular;
2008        use super::TriangleContents;
2009
2010        let mut buffer = Vec::new();
2011
2012        add_indices_triangular(
2013            0,
2014            4,
2015            8,
2016            Forward(&[1, 2, 3]),
2017            Forward(&[5, 6, 7]),
2018            Forward(&[9, 10, 11]),
2019            &TriangleContents::Three {
2020                a: 12,
2021                b: 13,
2022                c: 14,
2023            },
2024            &mut buffer,
2025        );
2026
2027        assert_eq!(
2028            buffer,
2029            &[
2030                0, 1, 11, 4, 5, 3, 8, 9, 7, 1, 12, 11, 5, 13, 3, 9, 14, 7, 1, 2, 12, 2, 13, 12, 5,
2031                6, 13, 6, 14, 13, 9, 10, 14, 10, 12, 14, 3, 13, 2, 7, 14, 6, 11, 12, 10,
2032            ][..]
2033        );
2034    }
2035
2036    #[test]
2037    fn precision() {
2038        let sphere = IcoSphere::new(10, |_| ());
2039
2040        for i in sphere.raw_points() {
2041            assert!(i.length() - 1.0 <= EPSILON);
2042        }
2043    }
2044
2045    #[test]
2046    fn line_one() {
2047        use super::add_line_indices_triangular;
2048        use super::TriangleContents;
2049
2050        let mut buffer = Vec::new();
2051
2052        add_line_indices_triangular(
2053            0,
2054            Forward(&[0]),
2055            Forward(&[1]),
2056            Forward(&[2]),
2057            &TriangleContents::none(),
2058            &mut buffer,
2059        );
2060
2061        assert_eq!(buffer, &[0, 1, 2, 0]);
2062    }
2063
2064    #[test]
2065    fn line_two() {
2066        use super::add_line_indices_triangular;
2067        use super::TriangleContents;
2068
2069        let mut buffer = Vec::new();
2070
2071        add_line_indices_triangular(
2072            0,
2073            Forward(&[0, 1]),
2074            Forward(&[2, 3]),
2075            Forward(&[4, 5]),
2076            &TriangleContents::One(6),
2077            &mut buffer,
2078        );
2079
2080        assert_eq!(buffer, &[6, 1, 2, 6, 3, 4, 6, 5, 0, 6]);
2081    }
2082
2083    #[test]
2084    fn line_three() {
2085        use super::add_line_indices_triangular;
2086        use super::TriangleContents;
2087
2088        let mut buffer = Vec::new();
2089
2090        add_line_indices_triangular(
2091            0,
2092            Forward(&[0, 1, 2]),
2093            Forward(&[3, 4, 5]),
2094            Forward(&[6, 7, 8]),
2095            &TriangleContents::Three { a: 9, b: 10, c: 11 },
2096            &mut buffer,
2097        );
2098
2099        assert_eq!(
2100            buffer,
2101            &[9, 10, 11, 9, 0, 8, 9, 7, 11, 6, 5, 11, 4, 10, 3, 2, 10, 1, 9, 0]
2102        );
2103    }
2104
2105    #[test]
2106    fn getting_major_edges() {
2107        // Use the square shape because it has few and simple vertices.
2108        let square = SquarePlane::new(1, |_| ());
2109
2110        let mut buffer = Vec::new();
2111        square.get_major_edges_line_indices(&mut buffer, 1, |v| v.push(0));
2112
2113        assert_eq!(
2114            buffer,
2115            vec![
2116                // Note: this is a list of five edges because the square is two triangles,
2117                // so there is a diagonal edge which counts as a major edge.
2118                // Each one has 2 original vertices and 1 interpolated vertex.
2119                1, 6, 2, 0, //
2120                2, 7, 3, 0, //
2121                3, 5, 1, 0, //
2122                3, 8, 4, 0, //
2123                4, 9, 1, 0, //
2124            ]
2125        );
2126    }
2127
2128    #[test]
2129    fn subdivisions() {
2130        let subdivisions = 64;
2131        let sphere = IcoSphere::new(subdivisions, |_| {});
2132
2133        assert_eq!(subdivisions, sphere.subdivisions());
2134    }
2135
2136    #[cfg(feature = "adjacency")]
2137    mod adjacency {
2138        use alloc::vec::Vec;
2139
2140        use crate::adjacency::RehexState;
2141        use crate::{adjacency::AdjacencyBuilder, shapes::IcoSphere};
2142
2143        #[test]
2144        fn creation() {
2145            let sphere = IcoSphere::new(5, |_| ());
2146
2147            let mut indices = Vec::new();
2148
2149            for i in 0..20 {
2150                sphere.get_indices(i, &mut indices);
2151            }
2152
2153            let mut builder = AdjacencyBuilder::new(sphere.raw_points().len());
2154            builder.add_indices(&indices);
2155            builder
2156                .state
2157                .iter()
2158                .for_each(|&state| assert_eq!(state, RehexState::Complete));
2159        }
2160    }
2161}