Skip to content

Commit dab7510

Browse files
committed
Polymorphic samples
1 parent 4fbf656 commit dab7510

2 files changed

Lines changed: 29 additions & 19 deletions

File tree

src/chunk.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl Chunk {
133133
}
134134

135135
/// Returns a grid of resolution^2 directions contained by the chunk, in scan-line order
136-
pub fn samples(&self, resolution: u32) -> SampleIter {
136+
pub fn samples<N: RealField + Copy>(&self, resolution: u32) -> SampleIter<N> {
137137
self.coords.samples(self.resolution(), resolution)
138138
}
139139

@@ -285,19 +285,19 @@ mod test {
285285
fn sample_count() {
286286
let chunk = Chunk::root(Face::Pz);
287287
for i in 0..4 {
288-
assert_eq!(chunk.samples(i).count(), (i * i) as usize);
288+
assert_eq!(chunk.samples::<f32>(i).count(), (i * i) as usize);
289289
}
290290
}
291291

292292
#[test]
293293
fn sample_sanity() {
294294
assert_eq!(
295-
Chunk::root(Face::Pz).samples(1).next().unwrap(),
295+
Chunk::root(Face::Pz).samples::<f32>(1).next().unwrap(),
296296
na::Vector3::z_axis()
297297
);
298298

299299
let chunk = Chunk::root(Face::Pz).children()[1];
300-
assert!(chunk.samples(2).any(|x| x == na::Vector3::z_axis()));
300+
assert!(chunk.samples::<f32>(2).any(|x| x == na::Vector3::z_axis()));
301301

302302
// Every face's
303303
for face in Face::iter() {
@@ -306,7 +306,7 @@ mod test {
306306
// each have one sample at exactly the center of the face
307307
assert_eq!(
308308
chunk
309-
.samples(2)
309+
.samples::<f32>(2)
310310
.filter(|&x| x == face.basis() * na::Vector3::z_axis())
311311
.count(),
312312
1
@@ -315,7 +315,7 @@ mod test {
315315
let corner = 1.0 / 3.0f32.sqrt();
316316
assert_eq!(
317317
chunk
318-
.samples(2)
318+
.samples::<f32>(2)
319319
.filter(|&x| abs_diff_eq!(x.x.abs(), corner)
320320
&& abs_diff_eq!(x.y.abs(), corner)
321321
&& abs_diff_eq!(x.z.abs(), corner))
@@ -340,7 +340,7 @@ mod test {
340340
let neighbor = chunk.neighbors()[0];
341341
assert_eq!(
342342
children[0]
343-
.samples(5)
343+
.samples::<f32>(5)
344344
.map(|child_vert| neighbor
345345
.samples(5)
346346
.filter(|&neighbor_vert| neighbor_vert == child_vert)

src/cubemap.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::cmp::Ordering;
2+
use std::marker::PhantomData;
23
use std::ops::{Index, IndexMut, Neg};
34
use std::{alloc, fmt, mem, ptr};
45

@@ -638,12 +639,17 @@ impl Coords {
638639
/// (0.5/w, 0.5/h), and the last has position (1, 1), not (1 - 0.5/w, 1 - 0.5/h). This allows
639640
/// for seamless interpolation in the neighborhood of chunk edges/corners without needing access
640641
/// to data for neighboring chunks.
641-
pub fn samples(&self, face_resolution: u32, chunk_resolution: u32) -> SampleIter {
642+
pub fn samples<N: RealField + Copy>(
643+
&self,
644+
face_resolution: u32,
645+
chunk_resolution: u32,
646+
) -> SampleIter<N> {
642647
SampleIter {
643648
coords: *self,
644649
face_resolution,
645650
chunk_resolution,
646651
index: 0,
652+
_marker: PhantomData,
647653
}
648654
}
649655

@@ -767,29 +773,30 @@ impl<T> IndexMut<Edge> for [T] {
767773

768774
/// Iterator over sample points distributed in a regular grid across a chunk, including its edges
769775
#[derive(Debug)]
770-
pub struct SampleIter {
776+
pub struct SampleIter<N> {
771777
coords: Coords,
772778
face_resolution: u32,
773779
chunk_resolution: u32,
774780
index: u32,
781+
_marker: PhantomData<fn() -> N>,
775782
}
776783

777-
impl Iterator for SampleIter {
778-
type Item = na::Unit<na::Vector3<f32>>;
779-
fn next(&mut self) -> Option<na::Unit<na::Vector3<f32>>> {
784+
impl<N: RealField + Copy> Iterator for SampleIter<N> {
785+
type Item = na::Unit<na::Vector3<N>>;
786+
fn next(&mut self) -> Option<na::Unit<na::Vector3<N>>> {
780787
if self.index >= self.chunk_resolution * self.chunk_resolution {
781788
return None;
782789
}
783790
let max = self.chunk_resolution - 1;
784791
let coords = if max == 0 {
785-
na::Point2::new(0.5, 0.5)
792+
na::Point2::new(0.5, 0.5).cast::<N>()
786793
} else {
787-
let step = 1.0 / max as f32;
794+
let step = 1.0 / max as f64;
788795
let (x, y) = (
789796
self.index % self.chunk_resolution,
790797
self.index / self.chunk_resolution,
791798
);
792-
na::Point2::new(x as f32, y as f32) * step
799+
na::Point2::new(x as f64, y as f64).cast::<N>() * na::convert::<f64, N>(step)
793800
};
794801
let dir = self.coords.direction(self.face_resolution, &coords);
795802
self.index += 1;
@@ -803,7 +810,7 @@ impl Iterator for SampleIter {
803810
}
804811
}
805812

806-
impl ExactSizeIterator for SampleIter {
813+
impl<N: RealField + Copy> ExactSizeIterator for SampleIter<N> {
807814
fn len(&self) -> usize {
808815
let total = self.chunk_resolution * self.chunk_resolution;
809816
(total - self.index) as usize
@@ -1090,7 +1097,10 @@ mod test {
10901097
y: 0,
10911098
face: Face::Py,
10921099
};
1093-
assert_abs_diff_eq!(COORDS.samples(1, 1).next().unwrap(), na::Vector3::y_axis());
1100+
assert_abs_diff_eq!(
1101+
COORDS.samples::<f32>(1, 1).next().unwrap(),
1102+
na::Vector3::y_axis()
1103+
);
10941104
let corners = COORDS
10951105
.samples(1, 2)
10961106
.map(|x| x.into_inner())
@@ -1119,8 +1129,8 @@ mod test {
11191129
y: 0,
11201130
face: Face::Pz,
11211131
};
1122-
let left = LEFT.samples(2, 2).collect::<Vec<_>>();
1123-
let right = RIGHT.samples(2, 2).collect::<Vec<_>>();
1132+
let left = LEFT.samples::<f32>(2, 2).collect::<Vec<_>>();
1133+
let right = RIGHT.samples::<f32>(2, 2).collect::<Vec<_>>();
11241134
assert_abs_diff_eq!(left[1], right[0]);
11251135
assert_abs_diff_eq!(left[3], right[2]);
11261136
}

0 commit comments

Comments
 (0)