1use slice::*;
10use slice::Slice::*;
11
12pub mod interpolation;
13pub mod shapes;
14mod slice;
15
16pub trait Vec3:
17 std::ops::Add<Self, Output = Self> +
18 std::ops::Mul<f32, Output = Self> +
19 Copy
20{
21 const ZERO: Self;
22
23 fn dot(self, other: Self) -> f32;
24 fn normalize(self) -> Self;
25 fn from_arr3(data: [f32; 3]) -> Self;
26}
27
28pub trait BaseShape<V: Vec3> {
29 fn initial_points(&self) -> Vec<V>;
30
31 fn triangles(&self) -> Box<[Triangle]>;
32
33 const EDGES: usize;
34
35 fn interpolate(&self, a: V, b: V, p: f32) -> V;
36
37
38 fn interpolate_half(&self, a: V, b: V) -> V {
39 self.interpolate(a, b, 0.5)
40 }
41
42 fn interpolate_multiple(&self, a: V, b: V, indices: &[u32], points: &mut [V]) {
43 for (percent, index) in indices.iter().enumerate() {
44 let percent = (percent + 1) as f32 / (indices.len() + 1) as f32;
45
46 points[*index as usize] = self.interpolate(a, b, percent);
47 }
48 }
49}
50
51struct Edge {
52 points: Vec<u32>,
53 done: bool,
54}
55
56impl Default for Edge {
57 fn default() -> Self {
58 Self {
59 points: Vec::new(),
60 done: true,
61 }
62 }
63}
64
65#[derive(Clone, Debug)]
66enum TriangleContents {
67 None,
68 One(u32),
69 Three { a: u32, b: u32, c: u32 },
70 Six {
71 a: u32,
72 b: u32,
73 c: u32,
74 ab: u32,
75 bc: u32,
76 ca: u32,
77 },
78 More {
79 a: u32,
80 b: u32,
81 c: u32,
82 sides: Vec<u32>,
85 my_side_length: u32,
86 contents: Box<TriangleContents>,
90 },
91}
92
93impl TriangleContents {
94 pub fn none() -> Self {
95 Self::None
96 }
97
98 fn one<V: Vec3>(ab: Slice<u32>, bc: Slice<u32>, points: &mut Vec<V>, calculate: bool, shape: &impl BaseShape<V>) -> Self {
99 assert_eq!(ab.len(), bc.len());
100 assert_eq!(ab.len(), 2);
101 let p1 = points[ab[0] as usize];
102 let p2 = points[bc[1] as usize];
103 let index = points.len() as u32;
104 if calculate {
105 points.push(shape.interpolate_half(p1, p2));
106 } else {
107 points.push(V::ZERO);
108 }
109 TriangleContents::One(index)
110 }
111
112 fn three<V: Vec3>(
113 &mut self,
114 ab: Slice<u32>,
115 bc: Slice<u32>,
116 ca: Slice<u32>,
117 points: &mut Vec<V>,
118 calculate: bool,
119 shape: &impl BaseShape<V>,
120 ) {
121 use TriangleContents::*;
122
123 assert_eq!(ab.len(), bc.len());
124 assert_eq!(ab.len(), ca.len());
125 assert_eq!(ab.len(), 3);
126
127 match self {
128 &mut One(x) => {
129 let ab = points[ab[1] as usize];
130 let bc = points[bc[1] as usize];
131 let ca = points[ca[1] as usize];
132
133 if calculate {
134 let a = shape.interpolate_half(ab, ca);
135 let b = shape.interpolate_half(bc, ab);
136 let c = shape.interpolate_half(ca, bc);
137
138 points.extend_from_slice(&[b, c]);
139 points[x as usize] = a;
140 } else {
141 points.extend_from_slice(&[V::ZERO, V::ZERO])
142 }
143
144 *self = Three {
145 a: x,
146 b: points.len() as u32 - 2,
147 c: points.len() as u32 - 1,
148 };
149 }
150 _ => panic!("Self is {:?} while it should be One", self),
151 }
152 }
153
154 fn six<V: Vec3>(
155 &mut self,
156 ab: Slice<u32>,
157 bc: Slice<u32>,
158 ca: Slice<u32>,
159 points: &mut Vec<V>,
160 calculate: bool,
161 shape: &impl BaseShape<V>,
162 ) {
163 use TriangleContents::*;
164
165 assert_eq!(ab.len(), bc.len());
166 assert_eq!(ab.len(), ca.len());
167 assert_eq!(ab.len(), 4);
168
169 match self {
170 &mut Three {
171 a: a_index,
172 b: b_index,
173 c: c_index,
174 } => {
175 let aba = points[ab[1] as usize];
176 let abb = points[ab[2] as usize];
177 let bcb = points[bc[1] as usize];
178 let bcc = points[bc[2] as usize];
179 let cac = points[ca[1] as usize];
180 let caa = points[ca[2] as usize];
181
182 if calculate {
183 let a = shape.interpolate_half(aba, caa);
184 let b = shape.interpolate_half(abb, bcb);
185 let c = shape.interpolate_half(bcc, cac);
186
187 let ab = shape.interpolate_half(a, b);
188 let bc = shape.interpolate_half(b, c);
189 let ca = shape.interpolate_half(c, a);
190
191 points[a_index as usize] = a;
192 points[b_index as usize] = b;
193 points[c_index as usize] = c;
194 points.extend_from_slice(&[ab, bc, ca]);
195 } else {
196 points.extend_from_slice(&[V::ZERO, V::ZERO, V::ZERO])
197 }
198
199 *self = Six {
200 a: a_index,
201 b: b_index,
202 c: c_index,
203 ab: points.len() as u32 - 3,
204 bc: points.len() as u32 - 2,
205 ca: points.len() as u32 - 1,
206 };
207 }
208 _ => panic!("Found {:?} whereas a Three was expected", self),
209 }
210 }
211
212 pub fn subdivide<V: Vec3>(
213 &mut self,
214 ab: Slice<u32>,
215 bc: Slice<u32>,
216 ca: Slice<u32>,
217 points: &mut Vec<V>,
218 calculate: bool,
219 shape: &impl BaseShape<V>,
220 ) {
221 use TriangleContents::*;
222 assert_eq!(ab.len(), bc.len());
223 assert_eq!(ab.len(), ca.len());
224 assert!(ab.len() >= 2);
225 match self {
226 None => *self = Self::one(ab, bc, points, calculate, shape),
227 One(_) => self.three(ab, bc, ca, points, calculate, shape),
228 Three { .. } => self.six(ab, bc, ca, points, calculate, shape),
229 &mut Six {
230 a,
231 b,
232 c,
233 ab: ab_idx,
234 bc: bc_idx,
235 ca: ca_idx,
236 } => {
237 *self = More {
238 a,
239 b,
240 c,
241 sides: vec![ab_idx, bc_idx, ca_idx],
242 my_side_length: 1,
243 contents: Box::new(Self::none()),
244 };
245 self.subdivide(ab, bc, ca, points, calculate, shape);
246 }
247 &mut More {
248 a: a_idx,
249 b: b_idx,
250 c: c_idx,
251 ref mut sides,
252 ref mut contents,
253 ref mut my_side_length,
254 } => {
255 points.extend_from_slice(&[V::ZERO, V::ZERO, V::ZERO]);
256 let len = points.len() as u32;
257 sides.extend_from_slice(&[len - 3, len - 2, len - 1]);
258 *my_side_length += 1;
259 let side_length = *my_side_length as usize;
260
261 let outer_len = ab.len();
262
263 let aba = points[ab[1] as usize];
264 let abb = points[ab[outer_len - 2] as usize];
265 let bcb = points[bc[1] as usize];
266 let bcc = points[bc[outer_len - 2] as usize];
267 let cac = points[ca[1] as usize];
268 let caa = points[ca[outer_len - 2] as usize];
269
270 if calculate {
271 points[a_idx as usize] = shape.interpolate_half(aba, caa);
272 points[b_idx as usize] = shape.interpolate_half(abb, bcb);
273 points[c_idx as usize] = shape.interpolate_half(bcc, cac);
274 }
275
276 let ab = &sides[0..side_length];
277 let bc = &sides[side_length..side_length * 2];
278 let ca = &sides[side_length * 2..];
279
280 if calculate {
281 shape.interpolate_multiple(
282 points[a_idx as usize],
283 points[b_idx as usize],
284 ab,
285 points,
286 );
287 shape.interpolate_multiple(
288 points[b_idx as usize],
289 points[c_idx as usize],
290 bc,
291 points,
292 );
293 shape.interpolate_multiple(
294 points[c_idx as usize],
295 points[a_idx as usize],
296 ca,
297 points,
298 );
299 }
300
301 contents.subdivide(Forward(ab), Forward(bc), Forward(ca), points, calculate, shape);
302 }
303 }
304 }
305
306 pub fn idx_ab(&self, idx: usize) -> u32 {
307 use TriangleContents::*;
308 match self {
309 None => panic!("Invalid Index, len is 0, but got {}", idx),
310 One(x) => {
311 if idx != 0 {
312 panic!("Invalid Index, len is 1, but got {}", idx);
313 } else {
314 *x
315 }
316 }
317 Three { a, b, .. } => *[a, b][idx],
318 Six { a, b, ab, .. } => *[a, ab, b][idx],
319 &More {
320 a,
321 b,
322 ref sides,
323 my_side_length,
324 ..
325 } => match idx {
326 0 => a,
327 x if (1..(my_side_length as usize + 1)).contains(&x) => sides[x - 1],
328 x if x == my_side_length as usize + 1 => b,
329 _ => panic!(
330 "Invalid Index, len is {}, but got {}",
331 my_side_length + 2,
332 idx
333 ),
334 },
335 }
336 }
337
338 pub fn idx_bc(&self, idx: usize) -> u32 {
339 use TriangleContents::*;
340 match self {
341 None => panic!("Invalid Index, len is 0, but got {}", idx),
342 One(x) => {
343 if idx != 0 {
344 panic!("Invalid Index, len is 1, but got {}", idx);
345 } else {
346 *x
347 }
348 }
349 Three { c, b, .. } => *[b, c][idx],
350 Six { b, c, bc, .. } => *[b, bc, c][idx],
351 &More {
352 b,
353 c,
354 ref sides,
355 my_side_length,
356 ..
357 } => match idx {
358 0 => b,
359 x if (1..(my_side_length as usize + 1)).contains(&x) => {
360 sides[my_side_length as usize + (x - 1)]
361 }
362 x if x == my_side_length as usize + 1 => c,
363 _ => panic!(
364 "Invalid Index, len is {}, but got {}",
365 my_side_length + 2,
366 idx
367 ),
368 },
369 }
370 }
371
372 pub fn idx_ca(&self, idx: usize) -> u32 {
373 use TriangleContents::*;
374 match self {
375 None => panic!("Invalid Index, len is 0, but got {}", idx),
376 One(x) => {
377 if idx != 0 {
378 panic!("Invalid Index, len is 1, but got {}", idx);
379 } else {
380 *x
381 }
382 }
383 Three { c, a, .. } => *[c, a][idx],
384 Six { c, a, ca, .. } => *[c, ca, a][idx],
385 &More {
386 c,
387 a,
388 ref sides,
389 my_side_length,
390 ..
391 } => match idx {
392 0 => c,
393 x if (1..(my_side_length as usize + 1)).contains(&x) => {
394 sides[my_side_length as usize * 2 + x - 1]
395 }
396 x if x == my_side_length as usize + 1 => a,
397 _ => panic!(
398 "Invalid Index, len is {}, but got {}",
399 my_side_length + 2,
400 idx
401 ),
402 },
403 }
404 }
405
406 pub fn add_indices(&self, buffer: &mut Vec<u32>) {
407 use TriangleContents::*;
408 match self {
409 None | One(_) => {}
410 &Three { a, b, c } => buffer.extend_from_slice(&[a, b, c]),
411 &Six {
412 a,
413 b,
414 c,
415 ab,
416 bc,
417 ca,
418 } => {
419 buffer.extend_from_slice(&[a, ab, ca]);
420 buffer.extend_from_slice(&[ab, b, bc]);
421 buffer.extend_from_slice(&[bc, c, ca]);
422
423 buffer.extend_from_slice(&[ab, bc, ca]);
424 }
425 &More {
426 a,
427 b,
428 c,
429 ref sides,
430 my_side_length,
431 ref contents,
432 } => {
433 let my_side_length = my_side_length as usize;
434 let ab = &sides[0..my_side_length];
435 let bc = &sides[my_side_length..my_side_length * 2];
436 let ca = &sides[my_side_length * 2..];
437
438 add_indices_triangular(
440 a,
441 b,
442 c,
443 Forward(ab),
444 Forward(bc),
445 Forward(ca),
446 &**contents,
447 buffer,
448 );
449 contents.add_indices(buffer);
450 }
451 }
452 }
453}
454
455#[derive(Clone, Debug)]
456pub struct Triangle {
457 pub a: u32,
458 pub b: u32,
459 pub c: u32,
460 pub ab_edge: usize,
461 pub bc_edge: usize,
462 pub ca_edge: usize,
463 pub(crate) ab_forward: bool,
464 pub(crate) bc_forward: bool,
465 pub(crate) ca_forward: bool,
466
467 pub(crate) contents: TriangleContents,
468}
469
470impl Default for Triangle {
471 fn default() -> Self {
472 Self {
473 a: 0,
474 b: 0,
475 c: 0,
476 ab_edge: 0,
477 bc_edge: 0,
478 ca_edge: 0,
479 ab_forward: false,
480 bc_forward: false,
481 ca_forward: false,
482 contents: TriangleContents::None,
483 }
484 }
485}
486
487impl Triangle {
488 pub const fn new(a: u32, b: u32, c: u32, ab_edge: usize, bc_edge: usize, ca_edge: usize) -> Self {
489 Self {
490 a,
491 b,
492 c,
493 ab_edge,
494 bc_edge,
495 ca_edge,
496
497 ab_forward: false,
498 bc_forward: false,
499 ca_forward: false,
500
501 contents: TriangleContents::None,
502 }
503 }
504
505 fn subdivide_edges<V: Vec3>(
506 &mut self,
507 edges: &mut [Edge],
508 points: &mut Vec<V>,
509 calculate: bool,
510 shape: &impl BaseShape<V>,
511 ) -> usize {
512 let mut divide = |p1: u32, p2: u32, edge_idx: usize, forward: &mut bool| {
513 if !edges[edge_idx].done {
514 edges[edge_idx].points.push(points.len() as u32);
515 points.push(V::ZERO);
516
517 if calculate {
518 shape.interpolate_multiple(
519 points[p1 as usize],
520 points[p2 as usize],
521 &edges[edge_idx].points,
522 points,
523 );
524 }
525
526 edges[edge_idx].done = true;
527 *forward = true;
528 } else {
529 *forward = false;
530 }
531 };
532
533 divide(self.a, self.b, self.ab_edge, &mut self.ab_forward);
534 divide(self.b, self.c, self.bc_edge, &mut self.bc_forward);
535 divide(self.c, self.a, self.ca_edge, &mut self.ca_forward);
536
537 edges[self.ab_edge].points.len()
538 }
539
540 fn subdivide<V: Vec3>(
541 &mut self,
542 edges: &mut [Edge],
543 points: &mut Vec<V>,
544 calculate: bool,
545 shape: &impl BaseShape<V>,
546 ) {
547 let side_length = self.subdivide_edges(edges, points, calculate, shape) + 1;
548
549 if side_length > 2 {
550 let ab = if self.ab_forward {
551 Forward(&edges[self.ab_edge].points)
552 } else {
553 Backward(&edges[self.ab_edge].points)
554 };
555 let bc = if self.bc_forward {
556 Forward(&edges[self.bc_edge].points)
557 } else {
558 Backward(&edges[self.bc_edge].points)
559 };
560 let ca = if self.ca_forward {
561 Forward(&edges[self.ca_edge].points)
562 } else {
563 Backward(&edges[self.ca_edge].points)
564 };
565 self.contents.subdivide(ab, bc, ca, points, calculate, shape);
566 }
567 }
568
569 fn add_indices(&self, buffer: &mut Vec<u32>, edges: &[Edge]) {
570 let ab = if self.ab_forward {
571 Forward(&edges[self.ab_edge].points)
572 } else {
573 Backward(&edges[self.ab_edge].points)
574 };
575 let bc = if self.bc_forward {
576 Forward(&edges[self.bc_edge].points)
577 } else {
578 Backward(&edges[self.bc_edge].points)
579 };
580 let ca = if self.ca_forward {
581 Forward(&edges[self.ca_edge].points)
582 } else {
583 Backward(&edges[self.ca_edge].points)
584 };
585
586 add_indices_triangular(self.a, self.b, self.c, ab, bc, ca, &self.contents, buffer);
587
588 self.contents.add_indices(buffer);
589 }
590}
591
592pub struct Subdivided<T, V: Vec3, S: BaseShape<V>> {
593 points: Vec<V>,
594 data: Vec<T>,
595 triangles: Box<[Triangle]>,
596 shared_edges: Box<[Edge]>,
597 subdivisions: usize,
598 shape: S,
599}
600
601impl<T, V: Vec3, S: BaseShape<V> + Default> Subdivided<T, V, S> {
602 pub fn new(subdivisions: usize, generator: impl FnMut(V) -> T) -> Self {
603 Self::new_custom_shape(subdivisions, generator, S::default())
604 }
605}
606
607impl<T, V: Vec3, S: BaseShape<V>> Subdivided<T, V, S> {
608 pub fn new_custom_shape(subdivisions: usize, generator: impl FnMut(V) -> T, shape: S) -> Self {
609 let mut this = Self {
610 points: shape.initial_points(),
611 shared_edges: {
612 let mut edges = Vec::new();
613 edges.resize_with(S::EDGES, Edge::default);
614 edges.into_boxed_slice()
615 },
616 triangles: shape.triangles(),
617 subdivisions: 1,
618 data: vec![],
619 shape,
620 };
621
622 match subdivisions {
623 0 => {}
624 1 => this.subdivide(true),
625 x => {
626 for _ in 0..x - 1 {
627 this.subdivide(false);
628 }
629
630 this.subdivide(true);
631 }
632 }
633
634 this.data = this.points.iter().copied().map(generator).collect();
635
636 this
637 }
638
639 fn subdivide(&mut self, calculate: bool) {
640 for Edge { done, .. } in &mut *self.shared_edges {
641 *done = false;
642 }
643
644 for triangle in &mut *self.triangles {
645 triangle.subdivide(&mut *self.shared_edges, &mut self.points, calculate, &self.shape);
646 }
647 }
648
649 pub fn raw_user_data(&self) -> &[T] {
650 &self.data
651 }
652
653 pub fn raw_points(&self) -> &[V] {
654 &self.points
655 }
656
657 pub fn get_indices(&self, triangle: usize, buffer: &mut Vec<u32>) {
658 self.triangles[triangle].add_indices(buffer, &self.shared_edges);
659 }
660
661 pub fn get_all_indices(&self) -> Vec<u32> {
662 let mut buffer = Vec::new();
663
664 for i in 0..self.triangles.len() {
665 self.get_indices(i, &mut buffer);
666 }
667
668 buffer
669 }
670
671 pub fn subdivisions(&self) -> usize {
672 self.subdivisions
673 }
674}
675
676fn add_indices_triangular(
679 a: u32,
680 b: u32,
681 c: u32,
682 ab: Slice<u32>,
683 bc: Slice<u32>,
684 ca: Slice<u32>,
685 contents: &TriangleContents,
686 buffer: &mut Vec<u32>,
687) {
688 let subdivisions = ab.len();
689 if subdivisions == 0 {
690 buffer.extend_from_slice(&[a, b, c]);
691 return;
692 } else if subdivisions == 1 {
693 buffer.extend_from_slice(&[a, ab[0], ca[0]]);
694 buffer.extend_from_slice(&[b, bc[0], ab[0]]);
695 buffer.extend_from_slice(&[c, ca[0], bc[0]]);
696 buffer.extend_from_slice(&[ab[0], bc[0], ca[0]]);
697 return;
698 } else if subdivisions == 2 {
699 buffer.extend_from_slice(&[a, ab[0], ca[1]]);
700 buffer.extend_from_slice(&[b, bc[0], ab[1]]);
701 buffer.extend_from_slice(&[c, ca[0], bc[1]]);
702
703 buffer.extend_from_slice(&[ab[1], contents.idx_ab(0), ab[0]]);
704 buffer.extend_from_slice(&[bc[1], contents.idx_ab(0), bc[0]]);
705 buffer.extend_from_slice(&[ca[1], contents.idx_ab(0), ca[0]]);
706
707 buffer.extend_from_slice(&[ab[0], contents.idx_ab(0), ca[1]]);
708 buffer.extend_from_slice(&[bc[0], contents.idx_ab(0), ab[1]]);
709 buffer.extend_from_slice(&[ca[0], contents.idx_ab(0), bc[1]]);
710 return;
711 }
712
713 let last_idx = ab.len() - 1;
714
715 buffer.extend_from_slice(&[a, ab[0], ca[last_idx]]);
716 buffer.extend_from_slice(&[b, bc[0], ab[last_idx]]);
717 buffer.extend_from_slice(&[c, ca[0], bc[last_idx]]);
718
719 buffer.extend_from_slice(&[ab[0], contents.idx_ab(0), ca[last_idx]]);
720 buffer.extend_from_slice(&[bc[0], contents.idx_bc(0), ab[last_idx]]);
721 buffer.extend_from_slice(&[ca[0], contents.idx_ca(0), bc[last_idx]]);
722
723 for i in 0..last_idx - 1 {
724 buffer.extend_from_slice(&[ab[i], ab[i + 1], contents.idx_ab(i)]);
727 buffer.extend_from_slice(&[ab[i + 1], contents.idx_ab(i + 1), contents.idx_ab(i)]);
728 buffer.extend_from_slice(&[bc[i], bc[i + 1], contents.idx_bc(i)]);
730 buffer.extend_from_slice(&[bc[i + 1], contents.idx_bc(i + 1), contents.idx_bc(i)]);
731 buffer.extend_from_slice(&[ca[i], ca[i + 1], contents.idx_ca(i)]);
733 buffer.extend_from_slice(&[ca[i + 1], contents.idx_ca(i + 1), contents.idx_ca(i)]);
734 }
735
736 buffer.extend_from_slice(&[
738 ab[last_idx],
739 contents.idx_ab(last_idx - 1),
740 ab[last_idx - 1],
741 ]);
742
743 buffer.extend_from_slice(&[
744 bc[last_idx],
745 contents.idx_bc(last_idx - 1),
746 bc[last_idx - 1],
747 ]);
748
749 buffer.extend_from_slice(&[
750 ca[last_idx],
751 contents.idx_ca(last_idx - 1),
752 ca[last_idx - 1],
753 ]);
754}
755
756#[cfg(test)]
757mod tests {
758 use crate::shapes::IcoSphere;
759 use crate::Slice::Forward;
760 use glam::Vec3A;
761
762 impl crate::Vec3 for glam::Vec3A {
763 const ZERO: Self = Vec3A::ZERO;
764
765 fn dot(self, other: Self) -> f32 {
766 self.dot(other)
767 }
768
769 fn normalize(self) -> Self {
770 self.normalize()
771 }
772
773 fn from_arr3([x, y, z]: [f32; 3]) -> Self {
774 Self::new(x, y, z)
775 }
776 }
777
778 const EPSILON: f32 = 0.0000002;
780
781 #[test]
782 fn slerp_one() {
783 use crate::interpolation::geometric_slerp_half;
784 let p1 = Vec3A::new(0.360492952832, 0.932761936915, 0.0);
785 let p2 = Vec3A::new(0.975897449331, 0.218229623081, 0.0);
786
787 let expected = Vec3A::new(0.757709663147, 0.652591806854, 0.0);
788
789 let result = geometric_slerp_half(p1, p2);
790
791 assert!((expected - result).length() <= EPSILON);
792
793 let p1 = Vec3A::new(-0.24953852315, 0.0, 0.968364872073);
795 let p2 = Vec3A::new(-0.948416666565, 0.0, 0.317026539239);
796
797 let expected = Vec3A::new(-0.681787771301, 0.0, 0.731550022148);
798
799 let result = geometric_slerp_half(p1, p2);
800
801 assert!((expected - result).length() <= EPSILON);
802 }
803
804 #[test]
805 fn slerp_many() {
806 use crate::interpolation::geometric_slerp_multiple;
807
808 let p1 = Vec3A::new(0.0, -0.885330189449, 0.464962854054);
809 let p2 = Vec3A::new(0.0, 0.946042343528, 0.324043028395);
810
811 let expected = Vec3A::new(0.0, 0.0767208624118, 0.997052611085);
812
813 let mut result = Vec3A::ZERO;
814 geometric_slerp_multiple(p1, p2, &[0], std::slice::from_mut(&mut result));
815
816 assert!((expected - result).length() <= EPSILON);
817
818 let p1 = Vec3A::new(0.876621956288, 0.0, 0.481179743707);
819 let p2 = Vec3A::new(-0.391617625614, 0.0, -0.920128053756);
820
821 let expected = [
822 Vec3A::new(0.999975758841, 0.0, 0.00696288230076),
823 Vec3A::new(0.883237589397, 0.0, -0.468925751774),
824 Vec3A::new(0.554436024709, 0.0, -0.83222634812),
825 Vec3A::new(0.0925155945469, 0.0, -0.995711235633),
826 ];
827
828 let mut result = [Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO];
829
830 geometric_slerp_multiple(p1, p2, &[0, 1, 2, 3], &mut result);
831
832 for (&expected, &result) in expected.iter().zip(result.iter()) {
833 assert!((expected - result).length() <= EPSILON);
834 }
835 }
836
837 #[test]
838 fn new() {
839 let x = IcoSphere::new(0, |_: Vec3A| ());
840 x.get_indices(0, &mut Vec::new());
841 }
842
843 #[test]
844 fn one() {
845 let x = IcoSphere::new(1, |_: Vec3A| ());
846 x.get_indices(0, &mut Vec::new());
847 }
848
849 #[test]
850 fn second_layer_inner() {
851 let x = IcoSphere::new(2, |_: Vec3A| ());
852 x.get_indices(0, &mut Vec::new());
853 let x = IcoSphere::new(3, |_: Vec3A| ());
854 x.get_indices(0, &mut Vec::new());
855 let x = IcoSphere::new(5, |_: Vec3A| ());
856 x.get_indices(0, &mut Vec::new());
857 let x = IcoSphere::new(6, |_: Vec3A| ());
858 x.get_indices(0, &mut Vec::new());
859 }
860
861 #[test]
862 fn indices_zero() {
863 use super::add_indices_triangular;
864 use super::TriangleContents;
865
866 let mut buffer = Vec::new();
867
868 add_indices_triangular(
869 0,
870 1,
871 2,
872 Forward(&[]),
873 Forward(&[]),
874 Forward(&[]),
875 &TriangleContents::none(),
876 &mut buffer,
877 );
878
879 assert_eq!(buffer, &[0, 1, 2]);
880 }
881
882 #[test]
883 fn indices_one() {
884 use super::add_indices_triangular;
885 use super::TriangleContents;
886
887 let mut buffer = Vec::new();
888
889 add_indices_triangular(
890 0,
891 1,
892 2,
893 Forward(&[3]),
894 Forward(&[4]),
895 Forward(&[5]),
896 &TriangleContents::none(),
897 &mut buffer,
898 );
899
900 assert_eq!(buffer, &[0, 3, 5, 1, 4, 3, 2, 5, 4, 3, 4, 5,]);
901 }
902
903 #[test]
904 fn indices_two() {
905 use super::add_indices_triangular;
906 use super::TriangleContents;
907
908 let mut buffer = Vec::new();
909
910 add_indices_triangular(
911 0,
912 3,
913 6,
914 Forward(&[1, 2]),
915 Forward(&[4, 5]),
916 Forward(&[7, 8]),
917 &TriangleContents::One(9),
918 &mut buffer,
919 );
920
921 assert_eq!(
922 buffer,
923 &[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,]
924 );
925 }
926
927 #[test]
929 fn indices_three() {
930 use super::add_indices_triangular;
931 use super::TriangleContents;
932
933 let mut buffer = Vec::new();
934
935 add_indices_triangular(
936 0,
937 4,
938 8,
939 Forward(&[1, 2, 3]),
940 Forward(&[5, 6, 7]),
941 Forward(&[9, 10, 11]),
942 &TriangleContents::Three {
943 a: 12,
944 b: 13,
945 c: 14,
946 },
947 &mut buffer,
948 );
949
950 assert_eq!(
951 buffer,
952 &[
953 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,
954 6, 13, 6, 14, 13, 9, 10, 14, 10, 12, 14, 3, 13, 2, 7, 14, 6, 11, 12, 10,
955 ][..]
956 );
957 }
958
959 #[test]
960 fn precision() {
961 let sphere = IcoSphere::new(10, |_: Vec3A| ());
962
963 for i in sphere.raw_points() {
964 assert!(i.length() - 1.0 <= EPSILON);
965 }
966 }
967}