diff --git a/src/accessor/util.rs b/src/accessor/util.rs index 996e7301..b6d8c872 100644 --- a/src/accessor/util.rs +++ b/src/accessor/util.rs @@ -94,6 +94,11 @@ pub struct SparseIter<'a, T: Item> { /// This can be `None` if the base buffer view is not set. In this case the base values are all zero. base: Option>, + /// Number of values in the base accessor + /// + /// Valid even when `base` is not set. + base_count: usize, + /// Sparse indices iterator. indices: iter::Peekable>, @@ -110,11 +115,13 @@ impl<'a, T: Item> SparseIter<'a, T> { /// Here `base` is allowed to be `None` when the base buffer view is not explicitly specified. pub fn new( base: Option>, + base_count: usize, indices: SparseIndicesIter<'a>, values: ItemIter<'a, T>, ) -> Self { SparseIter { base, + base_count, indices: indices.peekable(), values, counter: 0, @@ -125,11 +132,17 @@ impl<'a, T: Item> SparseIter<'a, T> { impl<'a, T: Item> Iterator for SparseIter<'a, T> { type Item = T; fn next(&mut self) -> Option { - let mut next_value = self - .base - .as_mut() - .map(|iter| iter.next()) - .unwrap_or_else(|| Some(T::zero()))?; + let mut next_value = if let Some(base) = self.base.as_mut() { + // If accessor.bufferView is set we let base decide when we have reached the end + // of the iteration sequence. + base.next()? + } else if (self.counter as usize) < self.base_count { + // Else, we continue iterating until we have generated the number of items + // specified by accessor.count + T::zero() + } else { + return None; + }; let next_sparse_index = self.indices.peek(); if let Some(index) = next_sparse_index { @@ -145,11 +158,8 @@ impl<'a, T: Item> Iterator for SparseIter<'a, T> { } fn size_hint(&self) -> (usize, Option) { - if let Some(base) = self.base.as_ref() { - base.size_hint() - } else { - self.values.size_hint() - } + let hint = self.base_count - (self.counter as usize).min(self.base_count); + (hint, Some(hint)) } } @@ -303,6 +313,7 @@ impl<'a, 's, T: Item> Iter<'s, T> { } else { None }; + let base_count = accessor.count(); let indices = sparse.indices(); let values = sparse.values(); @@ -344,7 +355,7 @@ impl<'a, 's, T: Item> Iter<'s, T> { }; Some(Iter::Sparse(SparseIter::new( - base_iter, index_iter, value_iter, + base_iter, base_count, index_iter, value_iter, ))) } None => {