1#![cfg_attr(not(feature = "std"), no_std)]
54
55use glam::Vec3A;
56
57#[doc(hidden)]
58#[macro_use]
59extern crate alloc;
60
61use alloc::boxed::Box;
62use alloc::vec::Vec;
63
64use slice::Slice::*;
65use slice::*;
66
67#[cfg(feature = "adjacency")]
68pub use adjacency::*;
69
70pub mod interpolation;
71mod math;
72pub mod shapes;
73mod slice;
74pub trait BaseShape {
125 fn initial_points(&self) -> Vec<Vec3A>;
139
140 fn triangles(&self) -> Box<[Triangle]>;
147
148 const EDGES: usize;
161
162 fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A;
180
181 fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
187 self.interpolate(a, b, 0.5)
188 }
189
190 fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
206 for (percent, index) in indices.iter().enumerate() {
207 let percent = (percent + 1) as f32 / (indices.len() + 1) as f32;
208
209 points[*index as usize] = self.interpolate(a, b, percent);
210 }
211 }
212}
213
214#[cfg(feature = "shape-extras")]
221pub trait EquilateralBaseShape: BaseShape {
222 fn triangle_normals() -> &'static [Vec3A];
227 fn triangle_min_dot() -> f32;
239}
240
241#[derive(Debug, Clone)]
245struct Edge {
246 points: Vec<u32>,
250 done: bool,
255}
256
257impl Default for Edge {
258 fn default() -> Self {
259 Self {
260 points: Vec::new(),
261 done: true,
262 }
263 }
264}
265
266impl Edge {
267 pub fn subdivide_n_times(&mut self, n: usize, points: &mut usize) {
268 for _ in 0..n {
269 self.points.push(*points as _);
270 *points += 1;
271 }
272 }
273}
274
275#[derive(Clone, Debug)]
283enum TriangleContents {
284 None,
288 One(u32),
292 Three { a: u32, b: u32, c: u32 },
296 Six {
300 a: u32,
301 b: u32,
302 c: u32,
303 ab: u32,
304 bc: u32,
305 ca: u32,
306 },
307 More {
311 a: u32,
312 b: u32,
313 c: u32,
314 sides: Vec<u32>,
317 my_side_length: u32,
318 contents: Box<TriangleContents>,
325 },
326}
327
328impl TriangleContents {
329 pub fn none() -> Self {
333 Self::None
334 }
335
336 fn one(points: &mut usize) -> Self {
340 let index = *points as u32;
341 *points += 1;
342 TriangleContents::One(index)
343 }
344
345 fn calculate_one(
346 &self,
347 ab: Slice<u32>,
348 bc: Slice<u32>,
349 points: &mut [Vec3A],
350 shape: &impl BaseShape,
351 ) {
352 assert_eq!(ab.len(), bc.len());
353 assert_eq!(ab.len(), 2);
354 match self {
355 TriangleContents::One(idx) => {
356 let p1 = points[ab[0] as usize];
357 let p2 = points[bc[1] as usize];
358
359 points[*idx as usize] = shape.interpolate_half(p1, p2);
360 }
361 _ => panic!("Did not find One variant."),
362 }
363 }
364
365 fn three(&mut self, points: &mut usize) {
369 use TriangleContents::*;
370
371 match self {
372 &mut One(x) => {
373 *points += 2;
374
375 *self = Three {
376 a: x,
377 b: *points as u32 - 2,
378 c: *points as u32 - 1,
379 };
380 }
381 _ => panic!("Self is {:?} while it should be One", self),
382 }
383 }
384
385 fn calculate_three(
386 &self,
387 ab: Slice<u32>,
388 bc: Slice<u32>,
389 ca: Slice<u32>,
390 points: &mut [Vec3A],
391 shape: &impl BaseShape,
392 ) {
393 assert_eq!(ab.len(), bc.len());
394 assert_eq!(ab.len(), ca.len());
395 assert_eq!(ab.len(), 3);
396
397 match self {
398 &TriangleContents::Three { a, b, c } => {
399 let ab = points[ab[1] as usize];
400 let bc = points[bc[1] as usize];
401 let ca = points[ca[1] as usize];
402
403 let a_val = shape.interpolate_half(ab, ca);
404 let b_val = shape.interpolate_half(bc, ab);
405 let c_val = shape.interpolate_half(ca, bc);
406
407 points[a as usize] = a_val;
408 points[b as usize] = b_val;
409 points[c as usize] = c_val;
410 }
411 _ => panic!("Did not find Three variant."),
412 }
413 }
414
415 fn six(&mut self, points: &mut usize) {
419 use TriangleContents::*;
420
421 match self {
422 &mut Three {
423 a: a_index,
424 b: b_index,
425 c: c_index,
426 } => {
427 *points += 3;
428
429 *self = Six {
430 a: a_index,
431 b: b_index,
432 c: c_index,
433 ab: *points as u32 - 3,
434 bc: *points as u32 - 2,
435 ca: *points as u32 - 1,
436 };
437 }
438 _ => panic!("Found {:?} whereas a Three was expected", self),
439 }
440 }
441
442 fn calculate_six(
443 &self,
444 ab: Slice<u32>,
445 bc: Slice<u32>,
446 ca: Slice<u32>,
447 points: &mut [Vec3A],
448 shape: &impl BaseShape,
449 ) {
450 assert_eq!(ab.len(), bc.len());
451 assert_eq!(ab.len(), ca.len());
452 assert_eq!(ab.len(), 4);
453
454 use TriangleContents::*;
455
456 match self {
457 &Six {
458 a: a_index,
459 b: b_index,
460 c: c_index,
461 ab: ab_index,
462 bc: bc_index,
463 ca: ca_index,
464 } => {
465 let aba = points[ab[1] as usize];
466 let abb = points[ab[2] as usize];
467 let bcb = points[bc[1] as usize];
468 let bcc = points[bc[2] as usize];
469 let cac = points[ca[1] as usize];
470 let caa = points[ca[2] as usize];
471
472 let a = shape.interpolate_half(aba, caa);
473 let b = shape.interpolate_half(abb, bcb);
474 let c = shape.interpolate_half(bcc, cac);
475
476 let ab = shape.interpolate_half(a, b);
477 let bc = shape.interpolate_half(b, c);
478 let ca = shape.interpolate_half(c, a);
479
480 points[a_index as usize] = a;
481 points[b_index as usize] = b;
482 points[c_index as usize] = c;
483 points[ab_index as usize] = ab;
484 points[bc_index as usize] = bc;
485 points[ca_index as usize] = ca;
486 }
487 _ => panic!("Found {:?} whereas a Three was expected", self),
488 }
489 }
490
491 fn subdivide(&mut self, points: &mut usize) {
495 use TriangleContents::*;
496
497 match self {
498 None => *self = Self::one(points),
499 One(_) => self.three(points),
500 Three { .. } => self.six(points),
501 &mut Six {
502 a,
503 b,
504 c,
505 ab: ab_idx,
506 bc: bc_idx,
507 ca: ca_idx,
508 } => {
509 *self = More {
510 a,
511 b,
512 c,
513 sides: vec![ab_idx, bc_idx, ca_idx],
514 my_side_length: 1,
515 contents: Box::new(Self::none()),
516 };
517 self.subdivide(points);
518 }
519 More {
520 sides,
521 contents,
522 my_side_length,
523 ..
524 } => {
525 *points += 3;
526 let len = *points as u32;
527 sides.extend_from_slice(&[len - 3, len - 2, len - 1]);
528 *my_side_length += 1;
529
530 contents.subdivide(points);
531 }
532 }
533 }
534
535 pub fn calculate(
536 &mut self,
537 ab: Slice<u32>,
538 bc: Slice<u32>,
539 ca: Slice<u32>,
540 points: &mut [Vec3A],
541 shape: &impl BaseShape,
542 ) {
543 assert_eq!(ab.len(), bc.len());
544 assert_eq!(ab.len(), ca.len());
545 assert!(ab.len() >= 2);
546
547 use TriangleContents::*;
548
549 match self {
550 None => panic!(),
551 One(_) => self.calculate_one(ab, bc, points, shape),
552 Three { .. } => self.calculate_three(ab, bc, ca, points, shape),
553 Six { .. } => self.calculate_six(ab, bc, ca, points, shape),
554 &mut More {
555 a: a_idx,
556 b: b_idx,
557 c: c_idx,
558 ref mut sides,
559 ref mut contents,
560 ref mut my_side_length,
561 } => {
562 let side_length = *my_side_length as usize;
563
564 let outer_len = ab.len();
565
566 let aba = points[ab[1] as usize];
567 let abb = points[ab[outer_len - 2] as usize];
568 let bcb = points[bc[1] as usize];
569 let bcc = points[bc[outer_len - 2] as usize];
570 let cac = points[ca[1] as usize];
571 let caa = points[ca[outer_len - 2] as usize];
572
573 points[a_idx as usize] = shape.interpolate_half(aba, caa);
574 points[b_idx as usize] = shape.interpolate_half(abb, bcb);
575 points[c_idx as usize] = shape.interpolate_half(bcc, cac);
576
577 let ab = &sides[0..side_length];
578 let bc = &sides[side_length..side_length * 2];
579 let ca = &sides[side_length * 2..];
580
581 shape.interpolate_multiple(
582 points[a_idx as usize],
583 points[b_idx as usize],
584 ab,
585 points,
586 );
587 shape.interpolate_multiple(
588 points[b_idx as usize],
589 points[c_idx as usize],
590 bc,
591 points,
592 );
593 shape.interpolate_multiple(
594 points[c_idx as usize],
595 points[a_idx as usize],
596 ca,
597 points,
598 );
599
600 contents.calculate(Forward(ab), Forward(bc), Forward(ca), points, shape);
601 }
602 }
603 }
604
605 pub fn idx_ab(&self, idx: usize) -> u32 {
611 use TriangleContents::*;
612 match self {
613 None => panic!("Invalid Index, len is 0, but got {}", idx),
614 One(x) => {
615 if idx != 0 {
616 panic!("Invalid Index, len is 1, but got {}", idx);
617 } else {
618 *x
619 }
620 }
621 Three { a, b, .. } => *[a, b][idx],
622 Six { a, b, ab, .. } => *[a, ab, b][idx],
623 &More {
624 a,
625 b,
626 ref sides,
627 my_side_length,
628 ..
629 } => match idx {
630 0 => a,
631 x if (1..(my_side_length as usize + 1)).contains(&x) => sides[x - 1],
632 x if x == my_side_length as usize + 1 => b,
633 _ => panic!(
634 "Invalid Index, len is {}, but got {}",
635 my_side_length + 2,
636 idx
637 ),
638 },
639 }
640 }
641
642 pub fn idx_bc(&self, idx: usize) -> u32 {
648 use TriangleContents::*;
649 match self {
650 None => panic!("Invalid Index, len is 0, but got {}", idx),
651 One(x) => {
652 if idx != 0 {
653 panic!("Invalid Index, len is 1, but got {}", idx);
654 } else {
655 *x
656 }
657 }
658 Three { c, b, .. } => *[b, c][idx],
659 Six { b, c, bc, .. } => *[b, bc, c][idx],
660 &More {
661 b,
662 c,
663 ref sides,
664 my_side_length,
665 ..
666 } => match idx {
667 0 => b,
668 x if (1..(my_side_length as usize + 1)).contains(&x) => {
669 sides[my_side_length as usize + (x - 1)]
670 }
671 x if x == my_side_length as usize + 1 => c,
672 _ => panic!(
673 "Invalid Index, len is {}, but got {}",
674 my_side_length + 2,
675 idx
676 ),
677 },
678 }
679 }
680
681 pub fn idx_ca(&self, idx: usize) -> u32 {
687 use TriangleContents::*;
688 match self {
689 None => panic!("Invalid Index, len is 0, but got {}", idx),
690 One(x) => {
691 if idx != 0 {
692 panic!("Invalid Index, len is 1, but got {}", idx);
693 } else {
694 *x
695 }
696 }
697 Three { c, a, .. } => *[c, a][idx],
698 Six { c, a, ca, .. } => *[c, ca, a][idx],
699 &More {
700 c,
701 a,
702 ref sides,
703 my_side_length,
704 ..
705 } => match idx {
706 0 => c,
707 x if (1..(my_side_length as usize + 1)).contains(&x) => {
708 sides[my_side_length as usize * 2 + x - 1]
709 }
710 x if x == my_side_length as usize + 1 => a,
711 _ => panic!(
712 "Invalid Index, len is {}, but got {}",
713 my_side_length + 2,
714 idx
715 ),
716 },
717 }
718 }
719
720 pub fn add_indices(&self, buffer: &mut Vec<u32>) {
725 use TriangleContents::*;
726 match self {
727 None | One(_) => {}
728 &Three { a, b, c } => buffer.extend_from_slice(&[a, b, c]),
729 &Six {
730 a,
731 b,
732 c,
733 ab,
734 bc,
735 ca,
736 } => {
737 buffer.extend_from_slice(&[a, ab, ca]);
738 buffer.extend_from_slice(&[ab, b, bc]);
739 buffer.extend_from_slice(&[bc, c, ca]);
740
741 buffer.extend_from_slice(&[ab, bc, ca]);
742 }
743 &More {
744 a,
745 b,
746 c,
747 ref sides,
748 my_side_length,
749 ref contents,
750 } => {
751 let my_side_length = my_side_length as usize;
752 let ab = &sides[0..my_side_length];
753 let bc = &sides[my_side_length..my_side_length * 2];
754 let ca = &sides[my_side_length * 2..];
755
756 add_indices_triangular(
758 a,
759 b,
760 c,
761 Forward(ab),
762 Forward(bc),
763 Forward(ca),
764 &**contents,
765 buffer,
766 );
767 contents.add_indices(buffer);
768 }
769 }
770 }
771
772 pub fn add_line_indices(
778 &self,
779 buffer: &mut Vec<u32>,
780 delta: u32,
781 mut breaks: impl FnMut(&mut Vec<u32>),
782 ) {
783 use TriangleContents::*;
784 match self {
785 None | One(_) | Three { .. } => {}
786 Six { ab, bc, ca, .. } => {
787 let ab = core::slice::from_ref(ab);
788 let bc = core::slice::from_ref(bc);
789 let ca = core::slice::from_ref(ca);
790 add_line_indices_triangular(
792 delta,
793 Forward(ab),
794 Forward(bc),
795 Forward(ca),
796 &TriangleContents::None,
797 buffer,
798 );
799 breaks(buffer);
800 }
801 &More {
802 ref sides,
803 my_side_length,
804 ref contents,
805 ..
806 } => {
807 let my_side_length = my_side_length as usize;
808 let ab = &sides[0..my_side_length];
809 let bc = &sides[my_side_length..my_side_length * 2];
810 let ca = &sides[my_side_length * 2..];
811
812 add_line_indices_triangular(
814 delta,
815 Forward(ab),
816 Forward(bc),
817 Forward(ca),
818 &**contents,
819 buffer,
820 );
821 breaks(buffer);
822 contents.add_line_indices(buffer, delta, breaks);
823 }
824 }
825 }
826}
827
828#[derive(Clone, Debug)]
829pub struct Triangle {
839 pub a: u32,
840 pub b: u32,
841 pub c: u32,
842 pub ab_edge: usize,
843 pub bc_edge: usize,
844 pub ca_edge: usize,
845 pub(crate) ab_forward: bool,
846 pub(crate) bc_forward: bool,
847 pub(crate) ca_forward: bool,
848
849 pub(crate) contents: TriangleContents,
850}
851
852impl Default for Triangle {
853 fn default() -> Self {
854 Self {
855 a: 0,
856 b: 0,
857 c: 0,
858 ab_edge: 0,
859 bc_edge: 0,
860 ca_edge: 0,
861 ab_forward: false,
862 bc_forward: false,
863 ca_forward: false,
864 contents: TriangleContents::None,
865 }
866 }
867}
868
869impl Triangle {
870 pub const fn new(
890 a: u32,
891 b: u32,
892 c: u32,
893 ab_edge: usize,
894 bc_edge: usize,
895 ca_edge: usize,
896 ) -> Self {
897 Self {
898 a,
899 b,
900 c,
901 ab_edge,
902 bc_edge,
903 ca_edge,
904
905 ab_forward: false,
906 bc_forward: false,
907 ca_forward: false,
908
909 contents: TriangleContents::None,
910 }
911 }
912
913 fn calculate_edges(
914 &mut self,
915 edges: &mut [Edge],
916 points: &mut [Vec3A],
917 shape: &impl BaseShape,
918 ) -> usize {
919 let mut divide = |p1: u32, p2: u32, edge_idx: usize, forward: &mut bool| {
920 if !edges[edge_idx].done {
921 shape.interpolate_multiple(
922 points[p1 as usize],
923 points[p2 as usize],
924 &edges[edge_idx].points,
925 points,
926 );
927
928 edges[edge_idx].done = true;
929 *forward = true;
930 } else {
931 *forward = false;
932 }
933 };
934
935 divide(self.a, self.b, self.ab_edge, &mut self.ab_forward);
936 divide(self.b, self.c, self.bc_edge, &mut self.bc_forward);
937 divide(self.c, self.a, self.ca_edge, &mut self.ca_forward);
938
939 edges[self.ab_edge].points.len()
940 }
941
942 fn subdivide(&mut self, points: &mut usize, subdivision_level: usize) {
950 if subdivision_level >= 1 {
951 self.contents.subdivide(points);
952 }
953 }
954
955 fn calculate(&mut self, edges: &mut [Edge], points: &mut [Vec3A], shape: &impl BaseShape) {
956 let side_length = self.calculate_edges(edges, points, shape) + 1;
957
958 if side_length > 2 {
959 let ab = if self.ab_forward {
960 Forward(&edges[self.ab_edge].points)
961 } else {
962 Backward(&edges[self.ab_edge].points)
963 };
964 let bc = if self.bc_forward {
965 Forward(&edges[self.bc_edge].points)
966 } else {
967 Backward(&edges[self.bc_edge].points)
968 };
969 let ca = if self.ca_forward {
970 Forward(&edges[self.ca_edge].points)
971 } else {
972 Backward(&edges[self.ca_edge].points)
973 };
974 self.contents.calculate(ab, bc, ca, points, shape);
975 }
976 }
977
978 fn add_indices(&self, buffer: &mut Vec<u32>, edges: &[Edge]) {
983 let ab = if self.ab_forward {
984 Forward(&edges[self.ab_edge].points)
985 } else {
986 Backward(&edges[self.ab_edge].points)
987 };
988 let bc = if self.bc_forward {
989 Forward(&edges[self.bc_edge].points)
990 } else {
991 Backward(&edges[self.bc_edge].points)
992 };
993 let ca = if self.ca_forward {
994 Forward(&edges[self.ca_edge].points)
995 } else {
996 Backward(&edges[self.ca_edge].points)
997 };
998
999 add_indices_triangular(self.a, self.b, self.c, ab, bc, ca, &self.contents, buffer);
1000
1001 self.contents.add_indices(buffer);
1002 }
1003
1004 fn add_line_indices(
1009 &self,
1010 buffer: &mut Vec<u32>,
1011 edges: &[Edge],
1012 delta: u32,
1013 mut breaks: impl FnMut(&mut Vec<u32>),
1014 ) {
1015 let ab = if self.ab_forward {
1016 Forward(&edges[self.ab_edge].points)
1017 } else {
1018 Backward(&edges[self.ab_edge].points)
1019 };
1020 let bc = if self.bc_forward {
1021 Forward(&edges[self.bc_edge].points)
1022 } else {
1023 Backward(&edges[self.bc_edge].points)
1024 };
1025 let ca = if self.ca_forward {
1026 Forward(&edges[self.ca_edge].points)
1027 } else {
1028 Backward(&edges[self.ca_edge].points)
1029 };
1030
1031 add_line_indices_triangular(delta, ab, bc, ca, &self.contents, buffer);
1032
1033 breaks(buffer);
1034
1035 self.contents.add_line_indices(buffer, delta, breaks);
1036 }
1037}
1038
1039#[derive(Clone)]
1055pub struct Subdivided<T, S: BaseShape> {
1056 points: Vec<Vec3A>,
1057 data: Vec<T>,
1058 triangles: Box<[Triangle]>,
1059 shared_edges: Box<[Edge]>,
1060 subdivisions: usize,
1061 shape: S,
1062}
1063
1064impl<T, S: BaseShape> Subdivided<T, S> {
1065 pub fn new(subdivisions: usize, generator: impl FnMut(Vec3A) -> T) -> Self
1071 where
1072 S: Default,
1073 {
1074 Self::new_custom_shape(subdivisions, generator, S::default())
1075 }
1076 pub fn new_custom_shape(
1089 subdivisions: usize,
1090 generator: impl FnMut(Vec3A) -> T,
1091 shape: S,
1092 ) -> Self {
1093 let mut this = Self {
1094 points: shape.initial_points(),
1095 shared_edges: {
1096 let mut edges = Vec::new();
1097 edges.resize_with(S::EDGES, Edge::default);
1098 edges.into_boxed_slice()
1099 },
1100 triangles: shape.triangles(),
1101 subdivisions: 1,
1102 data: vec![],
1103 shape,
1104 };
1105
1106 let mut new_points = this.points.len();
1107
1108 for edge in &mut *this.shared_edges {
1109 edge.subdivide_n_times(subdivisions, &mut new_points);
1110 edge.done = false;
1111 }
1112
1113 for triangle in &mut *this.triangles {
1114 for i in 0..subdivisions {
1115 triangle.subdivide(&mut new_points, i);
1116 }
1117 }
1118
1119 let diff = new_points - this.points.len();
1120 this.points
1121 .extend(core::iter::repeat(Vec3A::ZERO).take(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
1156 .extend(core::iter::repeat(Vec3A::ZERO).take(diff));
1157 }
1158
1159 pub fn calculate_values(&mut self, generator: impl FnMut(Vec3A) -> T) {
1163 for triangle in &mut *self.triangles {
1164 triangle.calculate(&mut *self.shared_edges, &mut self.points, &self.shape);
1165 }
1166
1167 self.data = self.points.iter().copied().map(generator).collect();
1168 }
1169
1170 pub fn raw_points(&self) -> &[Vec3A] {
1174 &self.points
1175 }
1176
1177 pub fn get_indices(&self, triangle: usize, buffer: &mut Vec<u32>) {
1195 self.triangles[triangle].add_indices(buffer, &self.shared_edges);
1196 }
1197
1198 pub fn get_all_indices(&self) -> Vec<u32> {
1210 let mut buffer = Vec::new();
1211
1212 for i in 0..self.triangles.len() {
1213 self.get_indices(i, &mut buffer);
1214 }
1215
1216 buffer
1217 }
1218
1219 pub fn get_line_indices(
1228 &self,
1229 buffer: &mut Vec<u32>,
1230 triangle: usize,
1231 delta: usize,
1232 breaks: impl FnMut(&mut Vec<u32>),
1233 ) {
1234 self.triangles[triangle].add_line_indices(buffer, &self.shared_edges, delta as u32, breaks);
1235 }
1236
1237 #[deprecated = "Flawed. Use `get_major_edges_line_indices()` instead."]
1245 pub fn get_major_edge_line_indices(&self, edge: usize, buffer: &mut Vec<u32>, delta: usize) {
1246 buffer.extend(
1247 self.shared_edges[edge]
1248 .points
1249 .iter()
1250 .map(|x| x + delta as u32),
1251 );
1252 }
1253
1254 pub fn get_major_edges_line_indices(
1263 &self,
1264 buffer: &mut Vec<u32>,
1265 delta: u32,
1266 mut breaks: impl FnMut(&mut Vec<u32>),
1267 ) {
1268 for triangle in &*self.triangles {
1269 for (p1, p2, edge, forward) in [
1270 (
1271 triangle.a,
1272 triangle.b,
1273 triangle.ab_edge,
1274 triangle.ab_forward,
1275 ),
1276 (
1277 triangle.b,
1278 triangle.c,
1279 triangle.bc_edge,
1280 triangle.bc_forward,
1281 ),
1282 (
1283 triangle.c,
1284 triangle.a,
1285 triangle.ca_edge,
1286 triangle.ca_forward,
1287 ),
1288 ] {
1289 if !forward {
1290 continue;
1291 }
1292
1293 buffer.push(p1 + delta);
1294 buffer.extend(self.shared_edges[edge].points.iter().map(|x| x + delta));
1295 buffer.push(p2 + delta);
1296
1297 breaks(buffer);
1298 }
1299 }
1300 }
1301
1302 pub fn get_all_line_indices(
1323 &self,
1324 delta: usize,
1325 mut breaks: impl FnMut(&mut Vec<u32>),
1326 ) -> Vec<u32> {
1327 let mut buffer = Vec::new();
1328
1329 for i in 0..self.triangles.len() {
1331 self.get_line_indices(&mut buffer, i, delta, &mut breaks);
1332 breaks(&mut buffer);
1333 }
1334
1335 let delta = delta as u32;
1336 self.get_major_edges_line_indices(&mut buffer, delta, &mut breaks);
1337
1338 buffer
1339 }
1340
1341 pub fn subdivisions(&self) -> usize {
1346 self.subdivisions
1347 }
1348
1349 pub fn raw_data(&self) -> &[T] {
1355 &self.data
1356 }
1357
1358 pub fn raw_data_mut(&mut self) -> &mut [T] {
1364 &mut self.data
1365 }
1366
1367 pub fn indices_per_main_triangle(&self) -> usize {
1378 (self.subdivisions + 1) * (self.subdivisions + 1)
1379 }
1380
1381 pub fn vertices_per_main_triangle_shared(&self) -> usize {
1393 (self.subdivisions + 1) * (self.subdivisions + 2) / 2
1394 }
1395
1396 pub fn vertices_per_main_triangle_unique(&self) -> usize {
1412 if self.subdivisions < 2 {
1413 return 0;
1414 }
1415 (self.subdivisions - 1) * self.subdivisions / 2
1416 }
1417
1418 pub fn shared_vertices(&self) -> usize {
1430 self.subdivisions * S::EDGES + self.shape.initial_points().len()
1431 }
1432
1433 pub fn linear_distance(&self, p1: u32, p2: u32, radius: f32) -> f32 {
1437 (self.points[p1 as usize] - self.points[p2 as usize]).length() * radius
1438 }
1439}
1440
1441#[cfg(feature = "shape-extras")]
1442impl<T, S: BaseShape + EquilateralBaseShape> Subdivided<T, S> {
1443 pub fn main_triangle_intersect(point: Vec3A) -> usize {
1450 let point = point.normalize();
1451 let mut nearest = 0;
1452 let mut near_factor = point.dot(S::triangle_normals()[0]);
1453
1454 if near_factor > S::triangle_min_dot() {
1455 return 0;
1456 }
1457
1458 for (index, normal) in S::triangle_normals().iter().enumerate().skip(1) {
1459 let factor = normal.dot(point);
1460 if factor > near_factor {
1461 if factor > S::triangle_min_dot() {
1462 return index;
1463 }
1464 nearest = index;
1465 near_factor = factor;
1466 }
1467 }
1468
1469 nearest
1470 }
1471
1472 pub fn spherical_distance(&self, p1: u32, p2: u32, radius: f32) -> f32 {
1477 self.points[p1 as usize]
1478 .dot(self.points[p2 as usize])
1479 .acos()
1480 * radius
1481 }
1482}
1483
1484fn add_indices_triangular(
1491 a: u32,
1492 b: u32,
1493 c: u32,
1494 ab: Slice<u32>,
1495 bc: Slice<u32>,
1496 ca: Slice<u32>,
1497 contents: &TriangleContents,
1498 buffer: &mut Vec<u32>,
1499) {
1500 let subdivisions = ab.len();
1501 if subdivisions == 0 {
1502 buffer.extend_from_slice(&[a, b, c]);
1503 return;
1504 } else if subdivisions == 1 {
1505 buffer.extend_from_slice(&[a, ab[0], ca[0]]);
1506 buffer.extend_from_slice(&[b, bc[0], ab[0]]);
1507 buffer.extend_from_slice(&[c, ca[0], bc[0]]);
1508 buffer.extend_from_slice(&[ab[0], bc[0], ca[0]]);
1509 return;
1510 } else if subdivisions == 2 {
1511 buffer.extend_from_slice(&[a, ab[0], ca[1]]);
1512 buffer.extend_from_slice(&[b, bc[0], ab[1]]);
1513 buffer.extend_from_slice(&[c, ca[0], bc[1]]);
1514
1515 buffer.extend_from_slice(&[ab[1], contents.idx_ab(0), ab[0]]);
1516 buffer.extend_from_slice(&[bc[1], contents.idx_ab(0), bc[0]]);
1517 buffer.extend_from_slice(&[ca[1], contents.idx_ab(0), ca[0]]);
1518
1519 buffer.extend_from_slice(&[ab[0], contents.idx_ab(0), ca[1]]);
1520 buffer.extend_from_slice(&[bc[0], contents.idx_ab(0), ab[1]]);
1521 buffer.extend_from_slice(&[ca[0], contents.idx_ab(0), bc[1]]);
1522 return;
1523 }
1524
1525 let last_idx = ab.len() - 1;
1526
1527 buffer.extend_from_slice(&[a, ab[0], ca[last_idx]]);
1528 buffer.extend_from_slice(&[b, bc[0], ab[last_idx]]);
1529 buffer.extend_from_slice(&[c, ca[0], bc[last_idx]]);
1530
1531 buffer.extend_from_slice(&[ab[0], contents.idx_ab(0), ca[last_idx]]);
1532 buffer.extend_from_slice(&[bc[0], contents.idx_bc(0), ab[last_idx]]);
1533 buffer.extend_from_slice(&[ca[0], contents.idx_ca(0), bc[last_idx]]);
1534
1535 for i in 0..last_idx - 1 {
1536 buffer.extend_from_slice(&[ab[i], ab[i + 1], contents.idx_ab(i)]);
1539 buffer.extend_from_slice(&[ab[i + 1], contents.idx_ab(i + 1), contents.idx_ab(i)]);
1540 buffer.extend_from_slice(&[bc[i], bc[i + 1], contents.idx_bc(i)]);
1542 buffer.extend_from_slice(&[bc[i + 1], contents.idx_bc(i + 1), contents.idx_bc(i)]);
1543 buffer.extend_from_slice(&[ca[i], ca[i + 1], contents.idx_ca(i)]);
1545 buffer.extend_from_slice(&[ca[i + 1], contents.idx_ca(i + 1), contents.idx_ca(i)]);
1546 }
1547
1548 buffer.extend_from_slice(&[
1550 ab[last_idx],
1551 contents.idx_ab(last_idx - 1),
1552 ab[last_idx - 1],
1553 ]);
1554
1555 buffer.extend_from_slice(&[
1556 bc[last_idx],
1557 contents.idx_bc(last_idx - 1),
1558 bc[last_idx - 1],
1559 ]);
1560
1561 buffer.extend_from_slice(&[
1562 ca[last_idx],
1563 contents.idx_ca(last_idx - 1),
1564 ca[last_idx - 1],
1565 ]);
1566}
1567
1568fn add_line_indices_triangular(
1580 delta: u32,
1581 ab: Slice<u32>,
1582 bc: Slice<u32>,
1583 ca: Slice<u32>,
1584 contents: &TriangleContents,
1585 buffer: &mut Vec<u32>,
1586) {
1587 if ab.len() == 0 {
1590 return;
1591 }
1592
1593 if ab.len() == 1 {
1596 #[rustfmt::skip]
1597 buffer.extend_from_slice(&[
1598 ab[0] + delta,
1599 bc[0] + delta,
1600 ca[0] + delta,
1601 ab[0] + delta,
1602 ]);
1603 return;
1604 }
1605
1606 if ab.len() == 2 {
1609 let inner = contents.idx_ab(0);
1610 buffer.extend_from_slice(&[
1611 inner + delta,
1612 ab[1] + delta,
1613 bc[0] + delta,
1614 inner + delta,
1615 bc[1] + delta,
1616 ca[0] + delta,
1617 inner + delta,
1618 ca[1] + delta,
1619 ab[0] + delta,
1620 inner + delta,
1621 ]);
1622 return;
1623 }
1624
1625 buffer.reserve((ab.len() - 1) * 9);
1626
1627 for i in 0..ab.len() - 2 {
1629 buffer.push(contents.idx_ab(i) + delta);
1630 }
1631
1632 for i in 0..bc.len() - 2 {
1633 buffer.push(contents.idx_bc(i) + delta);
1634 }
1635
1636 for i in 0..ca.len() - 2 {
1637 buffer.push(contents.idx_ca(i) + delta);
1638 }
1639
1640 buffer.push(contents.idx_ab(0) + delta);
1642
1643 buffer.push(ab[0] + delta);
1645
1646 for i in (1..ca.len()).rev() {
1647 buffer.push(ca[i] + delta);
1648 buffer.push(contents.idx_ca(i - 1) + delta);
1649 }
1650
1651 buffer.push(ca[0] + delta);
1652
1653 for i in (1..bc.len()).rev() {
1654 buffer.push(bc[i] + delta);
1655 buffer.push(contents.idx_bc(i - 1) + delta);
1656 }
1657
1658 buffer.push(bc[0] + delta);
1659
1660 for i in (1..ab.len()).rev() {
1661 buffer.push(ab[i] + delta);
1662 buffer.push(contents.idx_ab(i - 1) + delta);
1663 }
1664
1665 buffer.push(ab[0] + delta);
1666}
1667
1668#[cfg(feature = "adjacency")]
1669mod adjacency {
1673 use alloc::vec::Vec;
1674 use tinyvec::ArrayVec;
1675
1676 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
1677 pub(crate) enum RehexState {
1678 Empty,
1679 Clear,
1680 TwoTwo,
1681 ThreeTwo,
1682 TwoTwoTwo,
1683 Complete,
1684 }
1685
1686 pub struct AdjacencyBuilder {
1691 pub(crate) state: Vec<RehexState>,
1692 pub result: Vec<ArrayVec<[usize; 6]>>,
1693 }
1694
1695 impl AdjacencyBuilder {
1696 pub fn new(points_len: usize) -> Self {
1697 let state = core::iter::repeat(RehexState::Empty)
1698 .take(points_len)
1699 .collect::<Vec<_>>();
1700 let result = core::iter::repeat(ArrayVec::new())
1701 .take(points_len)
1702 .collect::<Vec<_>>();
1703 Self { state, result }
1704 }
1705
1706 pub fn add_indices(&mut self, indices: &[u32]) {
1707 for chunk in indices.chunks_exact(3) {
1708 let &[a, b, c] = chunk else { unreachable!() };
1709
1710 self.add_triangle(a, b, c);
1711 self.add_triangle(c, a, b);
1712 self.add_triangle(b, c, a);
1713 }
1714 }
1715
1716 pub fn finish(self) -> Vec<ArrayVec<[usize; 6]>> {
1717 self.result
1718 }
1719
1720 fn add_triangle(&mut self, a: u32, b: u32, c: u32) {
1721 let (a, b, c) = (a as usize, b as usize, c as usize);
1722 let state = &mut self.state[a];
1723 if let RehexState::Complete = state {
1724 return;
1725 }
1726
1727 let result = &mut self.result[a];
1728
1729 match state {
1730 RehexState::Empty => {
1731 result.extend([b, c]);
1732 *state = RehexState::Clear;
1733 }
1734 RehexState::Clear => {
1735 if result[result.len() - 1] == b {
1736 if result[0] == c {
1737 *state = RehexState::Complete;
1738 } else {
1739 result.push(c);
1740 if result.len() == 6 {
1741 *state = RehexState::Complete;
1742 }
1743 }
1744 } else if result[0] == c {
1745 result.insert(0, b);
1746 if result.len() == 6 {
1747 *state = RehexState::Complete;
1748 }
1749 } else {
1750 *state = match result.len() {
1751 2 => RehexState::TwoTwo,
1752 3 => RehexState::ThreeTwo,
1753 4 => RehexState::Complete,
1754 _ => unreachable!(),
1755 };
1756 result.extend([b, c]);
1757 }
1758 }
1759 RehexState::TwoTwo => {
1760 if result[1] == b {
1761 if result[2] == c {
1762 *state = RehexState::Clear;
1763 } else {
1764 result.insert(2, c);
1765 *state = RehexState::ThreeTwo;
1766 }
1767 } else if result[0] == c {
1768 if result[3] == b {
1769 let temp = result[2];
1770 result.pop();
1771 result.pop();
1772 result.insert(0, temp);
1773 result.insert(1, b);
1774 *state = RehexState::Clear;
1775 } else {
1776 result.insert(0, b);
1777 *state = RehexState::ThreeTwo;
1778 }
1779 } else if result[2] == c {
1780 result.insert(0, b);
1781 let t2 = result.swap_remove(2);
1782 let t1 = result.swap_remove(1);
1783 result.push(t1);
1784 result.push(t2);
1785 *state = RehexState::ThreeTwo;
1786 } else {
1787 result.extend([b, c]);
1788 *state = RehexState::TwoTwoTwo;
1789 }
1790 }
1791 RehexState::ThreeTwo => {
1792 if result[2] == b {
1793 if result[3] == c {
1794 *state = RehexState::Clear;
1795 } else {
1796 result.insert(3, c);
1797 *state = RehexState::Complete;
1798 }
1799 } else {
1800 if result[4] == b {
1801 result.pop();
1802 let temp = result.pop().unwrap();
1803 result.insert(0, b);
1804 result.insert(0, temp);
1805 *state = RehexState::Clear;
1806 } else {
1807 result.insert(0, b);
1808 *state = RehexState::Complete;
1809 }
1810 }
1811 }
1812 RehexState::TwoTwoTwo => {
1813 if (result[1] != b || result[2] != c)
1814 && (result[3] != b || result[4] != c)
1815 && (result[5] != b || result[0] != c)
1816 {
1817 let t2 = result.swap_remove(3);
1818 let t1 = result.swap_remove(2);
1819 result.extend([t1, t2]);
1820 }
1821 *state = RehexState::Complete;
1822 }
1823 RehexState::Complete => unreachable!(),
1824 }
1825 }
1826 }
1827}
1828
1829#[cfg(test)]
1830mod tests {
1831 use crate::shapes::{IcoSphere, SquarePlane};
1832 use crate::Slice::Forward;
1833 use alloc::vec::Vec;
1834 use glam::Vec3A;
1835
1836 const EPSILON: f32 = 0.0000002;
1838
1839 #[test]
1840 fn slerp_one() {
1841 use crate::interpolation::geometric_slerp_half;
1842 let p1 = Vec3A::new(0.360492952832, 0.932761936915, 0.0);
1843 let p2 = Vec3A::new(0.975897449331, 0.218229623081, 0.0);
1844
1845 let expected = Vec3A::new(0.757709663147, 0.652591806854, 0.0);
1846
1847 let result = geometric_slerp_half(p1, p2);
1848
1849 assert!((expected - result).length() <= EPSILON);
1850
1851 let p1 = Vec3A::new(-0.24953852315, 0.0, 0.968364872073);
1853 let p2 = Vec3A::new(-0.948416666565, 0.0, 0.317026539239);
1854
1855 let expected = Vec3A::new(-0.681787771301, 0.0, 0.731550022148);
1856
1857 let result = geometric_slerp_half(p1, p2);
1858
1859 assert!((expected - result).length() <= EPSILON);
1860 }
1861
1862 #[test]
1863 fn slerp_many() {
1864 use crate::interpolation::geometric_slerp_multiple;
1865
1866 let p1 = Vec3A::new(0.0, -0.885330189449, 0.464962854054);
1867 let p2 = Vec3A::new(0.0, 0.946042343528, 0.324043028395);
1868
1869 let expected = Vec3A::new(0.0, 0.0767208624118, 0.997052611085);
1870
1871 let mut result = Vec3A::ZERO;
1872 geometric_slerp_multiple(p1, p2, &[0], core::slice::from_mut(&mut result));
1873
1874 assert!((expected - result).length() <= EPSILON);
1875
1876 let p1 = Vec3A::new(0.876621956288, 0.0, 0.481179743707);
1877 let p2 = Vec3A::new(-0.391617625614, 0.0, -0.920128053756);
1878
1879 let expected = [
1880 Vec3A::new(0.999975758841, 0.0, 0.00696288230076),
1881 Vec3A::new(0.883237589397, 0.0, -0.468925751774),
1882 Vec3A::new(0.554436024709, 0.0, -0.83222634812),
1883 Vec3A::new(0.0925155945469, 0.0, -0.995711235633),
1884 ];
1885
1886 let mut result = [Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO];
1887
1888 geometric_slerp_multiple(p1, p2, &[0, 1, 2, 3], &mut result);
1889
1890 for (&expected, &result) in expected.iter().zip(result.iter()) {
1891 assert!((expected - result).length() <= EPSILON);
1892 }
1893 }
1894
1895 #[test]
1896 fn new() {
1897 let x = IcoSphere::new(0, |_| ());
1898 x.get_indices(0, &mut Vec::new());
1899 }
1900
1901 #[test]
1902 fn clone() {
1903 let _x = IcoSphere::new(6, |_| ()).clone();
1904 }
1905
1906 #[test]
1907 fn one() {
1908 let x = IcoSphere::new(1, |_| ());
1909 x.get_indices(0, &mut Vec::new());
1910 }
1911
1912 #[test]
1913 fn second_layer_inner() {
1914 let x = IcoSphere::new(2, |_| ());
1915 x.get_indices(0, &mut Vec::new());
1916 let x = IcoSphere::new(3, |_| ());
1917 x.get_indices(0, &mut Vec::new());
1918 let x = IcoSphere::new(5, |_| ());
1919 x.get_indices(0, &mut Vec::new());
1920 let x = IcoSphere::new(6, |_| ());
1921 x.get_indices(0, &mut Vec::new());
1922 }
1923
1924 #[test]
1925 fn indices_zero() {
1926 use super::add_indices_triangular;
1927 use super::TriangleContents;
1928
1929 let mut buffer = Vec::new();
1930
1931 add_indices_triangular(
1932 0,
1933 1,
1934 2,
1935 Forward(&[]),
1936 Forward(&[]),
1937 Forward(&[]),
1938 &TriangleContents::none(),
1939 &mut buffer,
1940 );
1941
1942 assert_eq!(buffer, &[0, 1, 2]);
1943 }
1944
1945 #[test]
1946 fn indices_one() {
1947 use super::add_indices_triangular;
1948 use super::TriangleContents;
1949
1950 let mut buffer = Vec::new();
1951
1952 add_indices_triangular(
1953 0,
1954 1,
1955 2,
1956 Forward(&[3]),
1957 Forward(&[4]),
1958 Forward(&[5]),
1959 &TriangleContents::none(),
1960 &mut buffer,
1961 );
1962
1963 assert_eq!(buffer, &[0, 3, 5, 1, 4, 3, 2, 5, 4, 3, 4, 5,]);
1964 }
1965
1966 #[test]
1967 fn indices_two() {
1968 use super::add_indices_triangular;
1969 use super::TriangleContents;
1970
1971 let mut buffer = Vec::new();
1972
1973 add_indices_triangular(
1974 0,
1975 3,
1976 6,
1977 Forward(&[1, 2]),
1978 Forward(&[4, 5]),
1979 Forward(&[7, 8]),
1980 &TriangleContents::One(9),
1981 &mut buffer,
1982 );
1983
1984 assert_eq!(
1985 buffer,
1986 &[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,]
1987 );
1988 }
1989
1990 #[test]
1992 fn indices_three() {
1993 use super::add_indices_triangular;
1994 use super::TriangleContents;
1995
1996 let mut buffer = Vec::new();
1997
1998 add_indices_triangular(
1999 0,
2000 4,
2001 8,
2002 Forward(&[1, 2, 3]),
2003 Forward(&[5, 6, 7]),
2004 Forward(&[9, 10, 11]),
2005 &TriangleContents::Three {
2006 a: 12,
2007 b: 13,
2008 c: 14,
2009 },
2010 &mut buffer,
2011 );
2012
2013 assert_eq!(
2014 buffer,
2015 &[
2016 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,
2017 6, 13, 6, 14, 13, 9, 10, 14, 10, 12, 14, 3, 13, 2, 7, 14, 6, 11, 12, 10,
2018 ][..]
2019 );
2020 }
2021
2022 #[test]
2023 fn precision() {
2024 let sphere = IcoSphere::new(10, |_| ());
2025
2026 for i in sphere.raw_points() {
2027 assert!(i.length() - 1.0 <= EPSILON);
2028 }
2029 }
2030
2031 #[test]
2032 fn line_one() {
2033 use super::add_line_indices_triangular;
2034 use super::TriangleContents;
2035
2036 let mut buffer = Vec::new();
2037
2038 add_line_indices_triangular(
2039 0,
2040 Forward(&[0]),
2041 Forward(&[1]),
2042 Forward(&[2]),
2043 &TriangleContents::none(),
2044 &mut buffer,
2045 );
2046
2047 assert_eq!(buffer, &[0, 1, 2, 0]);
2048 }
2049
2050 #[test]
2051 fn line_two() {
2052 use super::add_line_indices_triangular;
2053 use super::TriangleContents;
2054
2055 let mut buffer = Vec::new();
2056
2057 add_line_indices_triangular(
2058 0,
2059 Forward(&[0, 1]),
2060 Forward(&[2, 3]),
2061 Forward(&[4, 5]),
2062 &TriangleContents::One(6),
2063 &mut buffer,
2064 );
2065
2066 assert_eq!(buffer, &[6, 1, 2, 6, 3, 4, 6, 5, 0, 6]);
2067 }
2068
2069 #[test]
2070 fn line_three() {
2071 use super::add_line_indices_triangular;
2072 use super::TriangleContents;
2073
2074 let mut buffer = Vec::new();
2075
2076 add_line_indices_triangular(
2077 0,
2078 Forward(&[0, 1, 2]),
2079 Forward(&[3, 4, 5]),
2080 Forward(&[6, 7, 8]),
2081 &TriangleContents::Three { a: 9, b: 10, c: 11 },
2082 &mut buffer,
2083 );
2084
2085 assert_eq!(
2086 buffer,
2087 &[9, 10, 11, 9, 0, 8, 9, 7, 11, 6, 5, 11, 4, 10, 3, 2, 10, 1, 9, 0]
2088 );
2089 }
2090
2091 #[test]
2092 fn getting_major_edges() {
2093 let square = SquarePlane::new(1, |_| ());
2095
2096 let mut buffer = Vec::new();
2097 square.get_major_edges_line_indices(&mut buffer, 1, |v| v.push(0));
2098
2099 assert_eq!(
2100 buffer,
2101 vec![
2102 1, 6, 2, 0, 2, 7, 3, 0, 3, 5, 1, 0, 3, 8, 4, 0, 4, 9, 1, 0, ]
2111 );
2112 }
2113
2114 #[cfg(feature = "adjacency")]
2115 mod adjacency {
2116 use alloc::vec::Vec;
2117
2118 use crate::adjacency::RehexState;
2119 use crate::{adjacency::AdjacencyBuilder, shapes::IcoSphere};
2120
2121 #[test]
2122 fn creation() {
2123 let sphere = IcoSphere::new(5, |_| ());
2124
2125 let mut indices = Vec::new();
2126
2127 for i in 0..20 {
2128 sphere.get_indices(i, &mut indices);
2129 }
2130
2131 let mut builder = AdjacencyBuilder::new(sphere.raw_points().len());
2132 builder.add_indices(&indices);
2133 builder
2134 .state
2135 .iter()
2136 .for_each(|&state| assert_eq!(state, RehexState::Complete));
2137 }
2138 }
2139}