1#![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;
75pub trait BaseShape {
126 fn initial_points(&self) -> Vec<Vec3A>;
140
141 fn triangles(&self) -> Box<[Triangle]>;
148
149 const EDGES: usize;
162
163 fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A;
181
182 fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
188 self.interpolate(a, b, 0.5)
189 }
190
191 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#[cfg(feature = "shape-extras")]
222pub trait EquilateralBaseShape: BaseShape {
223 fn triangle_normals() -> &'static [Vec3A];
228 fn triangle_min_dot() -> f32;
240}
241
242#[derive(Debug, Clone)]
246struct Edge {
247 points: Vec<u32>,
251 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#[derive(Clone, Debug)]
284enum TriangleContents {
285 None,
289 One(u32),
293 Three { a: u32, b: u32, c: u32 },
297 Six {
301 a: u32,
302 b: u32,
303 c: u32,
304 ab: u32,
305 bc: u32,
306 ca: u32,
307 },
308 More {
312 a: u32,
313 b: u32,
314 c: u32,
315 sides: Vec<u32>,
318 my_side_length: u32,
319 contents: Box<TriangleContents>,
326 },
327}
328
329impl TriangleContents {
330 pub fn none() -> Self {
334 Self::None
335 }
336
337 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 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 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 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 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 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 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 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 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 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 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 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)]
830pub 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 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 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 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 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#[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 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 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
1130 }
1131
1132 pub fn subdivide(&mut self, amount: usize) {
1139 let mut new_points = self.points.len();
1140
1141 let subdivision_level = self.shared_edges[0].points.len();
1142
1143 for edge in &mut *self.shared_edges {
1144 edge.subdivide_n_times(amount, &mut new_points);
1145 edge.done = false;
1146 }
1147
1148 for triangle in &mut *self.triangles {
1149 for _ in 0..amount {
1150 triangle.subdivide(&mut new_points, subdivision_level);
1151 }
1152 }
1153
1154 let diff = new_points - self.points.len();
1155 self.points.extend(core::iter::repeat_n(Vec3A::ZERO, diff));
1156 }
1157
1158 pub fn calculate_values(&mut self, generator: impl FnMut(Vec3A) -> T) {
1162 for triangle in &mut *self.triangles {
1163 triangle.calculate(&mut self.shared_edges, &mut self.points, &self.shape);
1164 }
1165
1166 self.data = self.points.iter().copied().map(generator).collect();
1167 }
1168
1169 pub fn raw_points(&self) -> &[Vec3A] {
1173 &self.points
1174 }
1175
1176 pub fn get_indices(&self, triangle: usize, buffer: &mut Vec<u32>) {
1194 self.triangles[triangle].add_indices(buffer, &self.shared_edges);
1195 }
1196
1197 pub fn get_all_indices(&self) -> Vec<u32> {
1209 let mut buffer = Vec::new();
1210
1211 for i in 0..self.triangles.len() {
1212 self.get_indices(i, &mut buffer);
1213 }
1214
1215 buffer
1216 }
1217
1218 pub fn get_line_indices(
1227 &self,
1228 buffer: &mut Vec<u32>,
1229 triangle: usize,
1230 delta: usize,
1231 breaks: impl FnMut(&mut Vec<u32>),
1232 ) {
1233 self.triangles[triangle].add_line_indices(buffer, &self.shared_edges, delta as u32, breaks);
1234 }
1235
1236 #[deprecated = "Flawed. Use `get_major_edges_line_indices()` instead."]
1244 pub fn get_major_edge_line_indices(&self, edge: usize, buffer: &mut Vec<u32>, delta: usize) {
1245 buffer.extend(
1246 self.shared_edges[edge]
1247 .points
1248 .iter()
1249 .map(|x| x + delta as u32),
1250 );
1251 }
1252
1253 pub fn get_major_edges_line_indices(
1262 &self,
1263 buffer: &mut Vec<u32>,
1264 delta: u32,
1265 mut breaks: impl FnMut(&mut Vec<u32>),
1266 ) {
1267 for triangle in &*self.triangles {
1268 for (p1, p2, edge, forward) in [
1269 (
1270 triangle.a,
1271 triangle.b,
1272 triangle.ab_edge,
1273 triangle.ab_forward,
1274 ),
1275 (
1276 triangle.b,
1277 triangle.c,
1278 triangle.bc_edge,
1279 triangle.bc_forward,
1280 ),
1281 (
1282 triangle.c,
1283 triangle.a,
1284 triangle.ca_edge,
1285 triangle.ca_forward,
1286 ),
1287 ] {
1288 if !forward {
1289 continue;
1290 }
1291
1292 buffer.push(p1 + delta);
1293 buffer.extend(self.shared_edges[edge].points.iter().map(|x| x + delta));
1294 buffer.push(p2 + delta);
1295
1296 breaks(buffer);
1297 }
1298 }
1299 }
1300
1301 pub fn get_all_line_indices(
1322 &self,
1323 delta: usize,
1324 mut breaks: impl FnMut(&mut Vec<u32>),
1325 ) -> Vec<u32> {
1326 let mut buffer = Vec::new();
1327
1328 for i in 0..self.triangles.len() {
1330 self.get_line_indices(&mut buffer, i, delta, &mut breaks);
1331 breaks(&mut buffer);
1332 }
1333
1334 let delta = delta as u32;
1335 self.get_major_edges_line_indices(&mut buffer, delta, &mut breaks);
1336
1337 buffer
1338 }
1339
1340 pub fn subdivisions(&self) -> usize {
1345 self.subdivisions
1346 }
1347
1348 pub fn raw_data(&self) -> &[T] {
1354 &self.data
1355 }
1356
1357 pub fn raw_data_mut(&mut self) -> &mut [T] {
1363 &mut self.data
1364 }
1365
1366 pub fn indices_per_main_triangle(&self) -> usize {
1377 (self.subdivisions + 1) * (self.subdivisions + 1)
1378 }
1379
1380 pub fn vertices_per_main_triangle_shared(&self) -> usize {
1392 (self.subdivisions + 1) * (self.subdivisions + 2) / 2
1393 }
1394
1395 pub fn vertices_per_main_triangle_unique(&self) -> usize {
1411 if self.subdivisions < 2 {
1412 return 0;
1413 }
1414 (self.subdivisions - 1) * self.subdivisions / 2
1415 }
1416
1417 pub fn shared_vertices(&self) -> usize {
1429 self.subdivisions * S::EDGES + self.shape.initial_points().len()
1430 }
1431
1432 pub fn linear_distance(&self, p1: u32, p2: u32, radius: f32) -> f32 {
1436 (self.points[p1 as usize] - self.points[p2 as usize]).length() * radius
1437 }
1438}
1439
1440#[cfg(feature = "shape-extras")]
1441impl<T, S: BaseShape + EquilateralBaseShape> Subdivided<T, S> {
1442 pub fn main_triangle_intersect(point: Vec3A) -> usize {
1449 let point = point.normalize();
1450 let mut nearest = 0;
1451 let mut near_factor = point.dot(S::triangle_normals()[0]);
1452
1453 if near_factor > S::triangle_min_dot() {
1454 return 0;
1455 }
1456
1457 for (index, normal) in S::triangle_normals().iter().enumerate().skip(1) {
1458 let factor = normal.dot(point);
1459 if factor > near_factor {
1460 if factor > S::triangle_min_dot() {
1461 return index;
1462 }
1463 nearest = index;
1464 near_factor = factor;
1465 }
1466 }
1467
1468 nearest
1469 }
1470
1471 pub fn spherical_distance(&self, p1: u32, p2: u32, radius: f32) -> f32 {
1476 self.points[p1 as usize]
1477 .dot(self.points[p2 as usize])
1478 .acos()
1479 * radius
1480 }
1481}
1482
1483fn add_indices_triangular(
1490 a: u32,
1491 b: u32,
1492 c: u32,
1493 ab: Slice<u32>,
1494 bc: Slice<u32>,
1495 ca: Slice<u32>,
1496 contents: &TriangleContents,
1497 buffer: &mut Vec<u32>,
1498) {
1499 let subdivisions = ab.len();
1500 if subdivisions == 0 {
1501 buffer.extend_from_slice(&[a, b, c]);
1502 return;
1503 } else if subdivisions == 1 {
1504 buffer.extend_from_slice(&[a, ab[0], ca[0]]);
1505 buffer.extend_from_slice(&[b, bc[0], ab[0]]);
1506 buffer.extend_from_slice(&[c, ca[0], bc[0]]);
1507 buffer.extend_from_slice(&[ab[0], bc[0], ca[0]]);
1508 return;
1509 } else if subdivisions == 2 {
1510 buffer.extend_from_slice(&[a, ab[0], ca[1]]);
1511 buffer.extend_from_slice(&[b, bc[0], ab[1]]);
1512 buffer.extend_from_slice(&[c, ca[0], bc[1]]);
1513
1514 buffer.extend_from_slice(&[ab[1], contents.idx_ab(0), ab[0]]);
1515 buffer.extend_from_slice(&[bc[1], contents.idx_ab(0), bc[0]]);
1516 buffer.extend_from_slice(&[ca[1], contents.idx_ab(0), ca[0]]);
1517
1518 buffer.extend_from_slice(&[ab[0], contents.idx_ab(0), ca[1]]);
1519 buffer.extend_from_slice(&[bc[0], contents.idx_ab(0), ab[1]]);
1520 buffer.extend_from_slice(&[ca[0], contents.idx_ab(0), bc[1]]);
1521 return;
1522 }
1523
1524 let last_idx = ab.len() - 1;
1525
1526 buffer.extend_from_slice(&[a, ab[0], ca[last_idx]]);
1527 buffer.extend_from_slice(&[b, bc[0], ab[last_idx]]);
1528 buffer.extend_from_slice(&[c, ca[0], bc[last_idx]]);
1529
1530 buffer.extend_from_slice(&[ab[0], contents.idx_ab(0), ca[last_idx]]);
1531 buffer.extend_from_slice(&[bc[0], contents.idx_bc(0), ab[last_idx]]);
1532 buffer.extend_from_slice(&[ca[0], contents.idx_ca(0), bc[last_idx]]);
1533
1534 for i in 0..last_idx - 1 {
1535 buffer.extend_from_slice(&[ab[i], ab[i + 1], contents.idx_ab(i)]);
1538 buffer.extend_from_slice(&[ab[i + 1], contents.idx_ab(i + 1), contents.idx_ab(i)]);
1539 buffer.extend_from_slice(&[bc[i], bc[i + 1], contents.idx_bc(i)]);
1541 buffer.extend_from_slice(&[bc[i + 1], contents.idx_bc(i + 1), contents.idx_bc(i)]);
1542 buffer.extend_from_slice(&[ca[i], ca[i + 1], contents.idx_ca(i)]);
1544 buffer.extend_from_slice(&[ca[i + 1], contents.idx_ca(i + 1), contents.idx_ca(i)]);
1545 }
1546
1547 buffer.extend_from_slice(&[
1549 ab[last_idx],
1550 contents.idx_ab(last_idx - 1),
1551 ab[last_idx - 1],
1552 ]);
1553
1554 buffer.extend_from_slice(&[
1555 bc[last_idx],
1556 contents.idx_bc(last_idx - 1),
1557 bc[last_idx - 1],
1558 ]);
1559
1560 buffer.extend_from_slice(&[
1561 ca[last_idx],
1562 contents.idx_ca(last_idx - 1),
1563 ca[last_idx - 1],
1564 ]);
1565}
1566
1567fn add_line_indices_triangular(
1579 delta: u32,
1580 ab: Slice<u32>,
1581 bc: Slice<u32>,
1582 ca: Slice<u32>,
1583 contents: &TriangleContents,
1584 buffer: &mut Vec<u32>,
1585) {
1586 if ab.len() == 0 {
1589 return;
1590 }
1591
1592 if ab.len() == 1 {
1595 #[rustfmt::skip]
1596 buffer.extend_from_slice(&[
1597 ab[0] + delta,
1598 bc[0] + delta,
1599 ca[0] + delta,
1600 ab[0] + delta,
1601 ]);
1602 return;
1603 }
1604
1605 if ab.len() == 2 {
1608 let inner = contents.idx_ab(0);
1609 buffer.extend_from_slice(&[
1610 inner + delta,
1611 ab[1] + delta,
1612 bc[0] + delta,
1613 inner + delta,
1614 bc[1] + delta,
1615 ca[0] + delta,
1616 inner + delta,
1617 ca[1] + delta,
1618 ab[0] + delta,
1619 inner + delta,
1620 ]);
1621 return;
1622 }
1623
1624 buffer.reserve((ab.len() - 1) * 9);
1625
1626 for i in 0..ab.len() - 2 {
1628 buffer.push(contents.idx_ab(i) + delta);
1629 }
1630
1631 for i in 0..bc.len() - 2 {
1632 buffer.push(contents.idx_bc(i) + delta);
1633 }
1634
1635 for i in 0..ca.len() - 2 {
1636 buffer.push(contents.idx_ca(i) + delta);
1637 }
1638
1639 buffer.push(contents.idx_ab(0) + delta);
1641
1642 buffer.push(ab[0] + delta);
1644
1645 for i in (1..ca.len()).rev() {
1646 buffer.push(ca[i] + delta);
1647 buffer.push(contents.idx_ca(i - 1) + delta);
1648 }
1649
1650 buffer.push(ca[0] + delta);
1651
1652 for i in (1..bc.len()).rev() {
1653 buffer.push(bc[i] + delta);
1654 buffer.push(contents.idx_bc(i - 1) + delta);
1655 }
1656
1657 buffer.push(bc[0] + delta);
1658
1659 for i in (1..ab.len()).rev() {
1660 buffer.push(ab[i] + delta);
1661 buffer.push(contents.idx_ab(i - 1) + delta);
1662 }
1663
1664 buffer.push(ab[0] + delta);
1665}
1666
1667#[cfg(feature = "adjacency")]
1668mod adjacency {
1672 use alloc::vec::Vec;
1673 use tinyvec::ArrayVec;
1674
1675 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
1676 pub(crate) enum RehexState {
1677 Empty,
1678 Clear,
1679 TwoTwo,
1680 ThreeTwo,
1681 TwoTwoTwo,
1682 Complete,
1683 }
1684
1685 pub struct AdjacencyBuilder {
1690 pub(crate) state: Vec<RehexState>,
1691 pub result: Vec<ArrayVec<[usize; 6]>>,
1692 }
1693
1694 impl AdjacencyBuilder {
1695 pub fn new(points_len: usize) -> Self {
1696 let state = core::iter::repeat(RehexState::Empty)
1697 .take(points_len)
1698 .collect::<Vec<_>>();
1699 let result = core::iter::repeat(ArrayVec::new())
1700 .take(points_len)
1701 .collect::<Vec<_>>();
1702 Self { state, result }
1703 }
1704
1705 pub fn add_indices(&mut self, indices: &[u32]) {
1706 for chunk in indices.chunks_exact(3) {
1707 let &[a, b, c] = chunk else { unreachable!() };
1708
1709 self.add_triangle(a, b, c);
1710 self.add_triangle(c, a, b);
1711 self.add_triangle(b, c, a);
1712 }
1713 }
1714
1715 pub fn finish(self) -> Vec<ArrayVec<[usize; 6]>> {
1716 self.result
1717 }
1718
1719 fn add_triangle(&mut self, a: u32, b: u32, c: u32) {
1720 let (a, b, c) = (a as usize, b as usize, c as usize);
1721 let state = &mut self.state[a];
1722 if let RehexState::Complete = state {
1723 return;
1724 }
1725
1726 let result = &mut self.result[a];
1727
1728 match state {
1729 RehexState::Empty => {
1730 result.extend([b, c]);
1731 *state = RehexState::Clear;
1732 }
1733 RehexState::Clear => {
1734 if result[result.len() - 1] == b {
1735 if result[0] == c {
1736 *state = RehexState::Complete;
1737 } else {
1738 result.push(c);
1739 if result.len() == 6 {
1740 *state = RehexState::Complete;
1741 }
1742 }
1743 } else if result[0] == c {
1744 result.insert(0, b);
1745 if result.len() == 6 {
1746 *state = RehexState::Complete;
1747 }
1748 } else {
1749 *state = match result.len() {
1750 2 => RehexState::TwoTwo,
1751 3 => RehexState::ThreeTwo,
1752 4 => RehexState::Complete,
1753 _ => unreachable!(),
1754 };
1755 result.extend([b, c]);
1756 }
1757 }
1758 RehexState::TwoTwo => {
1759 if result[1] == b {
1760 if result[2] == c {
1761 *state = RehexState::Clear;
1762 } else {
1763 result.insert(2, c);
1764 *state = RehexState::ThreeTwo;
1765 }
1766 } else if result[0] == c {
1767 if result[3] == b {
1768 let temp = result[2];
1769 result.pop();
1770 result.pop();
1771 result.insert(0, temp);
1772 result.insert(1, b);
1773 *state = RehexState::Clear;
1774 } else {
1775 result.insert(0, b);
1776 *state = RehexState::ThreeTwo;
1777 }
1778 } else if result[2] == c {
1779 result.insert(0, b);
1780 let t2 = result.swap_remove(2);
1781 let t1 = result.swap_remove(1);
1782 result.push(t1);
1783 result.push(t2);
1784 *state = RehexState::ThreeTwo;
1785 } else {
1786 result.extend([b, c]);
1787 *state = RehexState::TwoTwoTwo;
1788 }
1789 }
1790 RehexState::ThreeTwo => {
1791 if result[2] == b {
1792 if result[3] == c {
1793 *state = RehexState::Clear;
1794 } else {
1795 result.insert(3, c);
1796 *state = RehexState::Complete;
1797 }
1798 } else {
1799 if result[4] == b {
1800 result.pop();
1801 let temp = result.pop().unwrap();
1802 result.insert(0, b);
1803 result.insert(0, temp);
1804 *state = RehexState::Clear;
1805 } else {
1806 result.insert(0, b);
1807 *state = RehexState::Complete;
1808 }
1809 }
1810 }
1811 RehexState::TwoTwoTwo => {
1812 if (result[1] != b || result[2] != c)
1813 && (result[3] != b || result[4] != c)
1814 && (result[5] != b || result[0] != c)
1815 {
1816 let t2 = result.swap_remove(3);
1817 let t1 = result.swap_remove(2);
1818 result.extend([t1, t2]);
1819 }
1820 *state = RehexState::Complete;
1821 }
1822 RehexState::Complete => unreachable!(),
1823 }
1824 }
1825 }
1826}
1827
1828#[cfg(test)]
1829mod tests {
1830 use crate::shapes::{IcoSphere, SquarePlane};
1831 use crate::Slice::Forward;
1832 use alloc::vec::Vec;
1833 use glam::Vec3A;
1834
1835 const EPSILON: f32 = 0.0000002;
1837
1838 #[test]
1839 fn slerp_one() {
1840 use crate::interpolation::geometric_slerp_half;
1841 let p1 = Vec3A::new(0.360492952832, 0.932761936915, 0.0);
1842 let p2 = Vec3A::new(0.975897449331, 0.218229623081, 0.0);
1843
1844 let expected = Vec3A::new(0.757709663147, 0.652591806854, 0.0);
1845
1846 let result = geometric_slerp_half(p1, p2);
1847
1848 assert!((expected - result).length() <= EPSILON);
1849
1850 let p1 = Vec3A::new(-0.24953852315, 0.0, 0.968364872073);
1852 let p2 = Vec3A::new(-0.948416666565, 0.0, 0.317026539239);
1853
1854 let expected = Vec3A::new(-0.681787771301, 0.0, 0.731550022148);
1855
1856 let result = geometric_slerp_half(p1, p2);
1857
1858 assert!((expected - result).length() <= EPSILON);
1859 }
1860
1861 #[test]
1862 fn slerp_many() {
1863 use crate::interpolation::geometric_slerp_multiple;
1864
1865 let p1 = Vec3A::new(0.0, -0.885330189449, 0.464962854054);
1866 let p2 = Vec3A::new(0.0, 0.946042343528, 0.324043028395);
1867
1868 let expected = Vec3A::new(0.0, 0.0767208624118, 0.997052611085);
1869
1870 let mut result = Vec3A::ZERO;
1871 geometric_slerp_multiple(p1, p2, &[0], core::slice::from_mut(&mut result));
1872
1873 assert!((expected - result).length() <= EPSILON);
1874
1875 let p1 = Vec3A::new(0.876621956288, 0.0, 0.481179743707);
1876 let p2 = Vec3A::new(-0.391617625614, 0.0, -0.920128053756);
1877
1878 let expected = [
1879 Vec3A::new(0.999975758841, 0.0, 0.00696288230076),
1880 Vec3A::new(0.883237589397, 0.0, -0.468925751774),
1881 Vec3A::new(0.554436024709, 0.0, -0.83222634812),
1882 Vec3A::new(0.0925155945469, 0.0, -0.995711235633),
1883 ];
1884
1885 let mut result = [Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO];
1886
1887 geometric_slerp_multiple(p1, p2, &[0, 1, 2, 3], &mut result);
1888
1889 for (&expected, &result) in expected.iter().zip(result.iter()) {
1890 assert!((expected - result).length() <= EPSILON);
1891 }
1892 }
1893
1894 #[test]
1895 fn new() {
1896 let x = IcoSphere::new(0, |_| ());
1897 x.get_indices(0, &mut Vec::new());
1898 }
1899
1900 #[test]
1901 fn clone() {
1902 let _x = IcoSphere::new(6, |_| ()).clone();
1903 }
1904
1905 #[test]
1906 fn one() {
1907 let x = IcoSphere::new(1, |_| ());
1908 x.get_indices(0, &mut Vec::new());
1909 }
1910
1911 #[test]
1912 fn second_layer_inner() {
1913 let x = IcoSphere::new(2, |_| ());
1914 x.get_indices(0, &mut Vec::new());
1915 let x = IcoSphere::new(3, |_| ());
1916 x.get_indices(0, &mut Vec::new());
1917 let x = IcoSphere::new(5, |_| ());
1918 x.get_indices(0, &mut Vec::new());
1919 let x = IcoSphere::new(6, |_| ());
1920 x.get_indices(0, &mut Vec::new());
1921 }
1922
1923 #[test]
1924 fn indices_zero() {
1925 use super::add_indices_triangular;
1926 use super::TriangleContents;
1927
1928 let mut buffer = Vec::new();
1929
1930 add_indices_triangular(
1931 0,
1932 1,
1933 2,
1934 Forward(&[]),
1935 Forward(&[]),
1936 Forward(&[]),
1937 &TriangleContents::none(),
1938 &mut buffer,
1939 );
1940
1941 assert_eq!(buffer, &[0, 1, 2]);
1942 }
1943
1944 #[test]
1945 fn indices_one() {
1946 use super::add_indices_triangular;
1947 use super::TriangleContents;
1948
1949 let mut buffer = Vec::new();
1950
1951 add_indices_triangular(
1952 0,
1953 1,
1954 2,
1955 Forward(&[3]),
1956 Forward(&[4]),
1957 Forward(&[5]),
1958 &TriangleContents::none(),
1959 &mut buffer,
1960 );
1961
1962 assert_eq!(buffer, &[0, 3, 5, 1, 4, 3, 2, 5, 4, 3, 4, 5,]);
1963 }
1964
1965 #[test]
1966 fn indices_two() {
1967 use super::add_indices_triangular;
1968 use super::TriangleContents;
1969
1970 let mut buffer = Vec::new();
1971
1972 add_indices_triangular(
1973 0,
1974 3,
1975 6,
1976 Forward(&[1, 2]),
1977 Forward(&[4, 5]),
1978 Forward(&[7, 8]),
1979 &TriangleContents::One(9),
1980 &mut buffer,
1981 );
1982
1983 assert_eq!(
1984 buffer,
1985 &[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,]
1986 );
1987 }
1988
1989 #[test]
1991 fn indices_three() {
1992 use super::add_indices_triangular;
1993 use super::TriangleContents;
1994
1995 let mut buffer = Vec::new();
1996
1997 add_indices_triangular(
1998 0,
1999 4,
2000 8,
2001 Forward(&[1, 2, 3]),
2002 Forward(&[5, 6, 7]),
2003 Forward(&[9, 10, 11]),
2004 &TriangleContents::Three {
2005 a: 12,
2006 b: 13,
2007 c: 14,
2008 },
2009 &mut buffer,
2010 );
2011
2012 assert_eq!(
2013 buffer,
2014 &[
2015 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,
2016 6, 13, 6, 14, 13, 9, 10, 14, 10, 12, 14, 3, 13, 2, 7, 14, 6, 11, 12, 10,
2017 ][..]
2018 );
2019 }
2020
2021 #[test]
2022 fn precision() {
2023 let sphere = IcoSphere::new(10, |_| ());
2024
2025 for i in sphere.raw_points() {
2026 assert!(i.length() - 1.0 <= EPSILON);
2027 }
2028 }
2029
2030 #[test]
2031 fn line_one() {
2032 use super::add_line_indices_triangular;
2033 use super::TriangleContents;
2034
2035 let mut buffer = Vec::new();
2036
2037 add_line_indices_triangular(
2038 0,
2039 Forward(&[0]),
2040 Forward(&[1]),
2041 Forward(&[2]),
2042 &TriangleContents::none(),
2043 &mut buffer,
2044 );
2045
2046 assert_eq!(buffer, &[0, 1, 2, 0]);
2047 }
2048
2049 #[test]
2050 fn line_two() {
2051 use super::add_line_indices_triangular;
2052 use super::TriangleContents;
2053
2054 let mut buffer = Vec::new();
2055
2056 add_line_indices_triangular(
2057 0,
2058 Forward(&[0, 1]),
2059 Forward(&[2, 3]),
2060 Forward(&[4, 5]),
2061 &TriangleContents::One(6),
2062 &mut buffer,
2063 );
2064
2065 assert_eq!(buffer, &[6, 1, 2, 6, 3, 4, 6, 5, 0, 6]);
2066 }
2067
2068 #[test]
2069 fn line_three() {
2070 use super::add_line_indices_triangular;
2071 use super::TriangleContents;
2072
2073 let mut buffer = Vec::new();
2074
2075 add_line_indices_triangular(
2076 0,
2077 Forward(&[0, 1, 2]),
2078 Forward(&[3, 4, 5]),
2079 Forward(&[6, 7, 8]),
2080 &TriangleContents::Three { a: 9, b: 10, c: 11 },
2081 &mut buffer,
2082 );
2083
2084 assert_eq!(
2085 buffer,
2086 &[9, 10, 11, 9, 0, 8, 9, 7, 11, 6, 5, 11, 4, 10, 3, 2, 10, 1, 9, 0]
2087 );
2088 }
2089
2090 #[test]
2091 fn getting_major_edges() {
2092 let square = SquarePlane::new(1, |_| ());
2094
2095 let mut buffer = Vec::new();
2096 square.get_major_edges_line_indices(&mut buffer, 1, |v| v.push(0));
2097
2098 assert_eq!(
2099 buffer,
2100 vec![
2101 1, 6, 2, 0, 2, 7, 3, 0, 3, 5, 1, 0, 3, 8, 4, 0, 4, 9, 1, 0, ]
2110 );
2111 }
2112
2113 #[cfg(feature = "adjacency")]
2114 mod adjacency {
2115 use alloc::vec::Vec;
2116
2117 use crate::adjacency::RehexState;
2118 use crate::{adjacency::AdjacencyBuilder, shapes::IcoSphere};
2119
2120 #[test]
2121 fn creation() {
2122 let sphere = IcoSphere::new(5, |_| ());
2123
2124 let mut indices = Vec::new();
2125
2126 for i in 0..20 {
2127 sphere.get_indices(i, &mut indices);
2128 }
2129
2130 let mut builder = AdjacencyBuilder::new(sphere.raw_points().len());
2131 builder.add_indices(&indices);
2132 builder
2133 .state
2134 .iter()
2135 .for_each(|&state| assert_eq!(state, RehexState::Complete));
2136 }
2137 }
2138}