(indexes: &mut [MapIndex], items: &PalF)
| 113 | |
| 114 | #[inline(never)] |
| 115 | fn vp_create_node(indexes: &mut [MapIndex], items: &PalF) -> Node { |
| 116 | debug_assert!(!indexes.is_empty()); |
| 117 | let palette = items.as_slice(); |
| 118 | |
| 119 | if indexes.len() <= 1 { |
| 120 | let idx = indexes.first().map(|i| i.idx).unwrap_or_default(); |
| 121 | return Node { |
| 122 | vantage_point: palette.get(usize::from(idx)).copied().unwrap_or_default(), |
| 123 | idx, |
| 124 | inner: NodeInner::Leaf { len: 0, idxs: [0; LEAF_MAX_SIZE], colors: Box::new([f_pixel::default(); LEAF_MAX_SIZE]) }, |
| 125 | }; |
| 126 | } |
| 127 | |
| 128 | let most_popular_item = indexes.iter().enumerate().max_by_key(move |(_, idx)| { |
| 129 | OrdFloat::new(items.pop_as_slice().get(usize::from(idx.idx)) |
| 130 | .map(|p| p.popularity()).unwrap_or_default()) |
| 131 | }).map(|(n, _)| n).unwrap_or_default(); |
| 132 | indexes.swap(most_popular_item, 0); |
| 133 | let (ref_, indexes) = indexes.split_first_mut().unwrap(); |
| 134 | |
| 135 | let vantage_point = palette.get(usize::from(ref_.idx)).copied().unwrap_or_default(); |
| 136 | indexes.sort_by_cached_key(move |i| { |
| 137 | OrdFloat::new(palette.get(usize::from(i.idx)) |
| 138 | .map(|px| vantage_point.diff(px)).unwrap_or_default()) |
| 139 | }); |
| 140 | |
| 141 | let num_indexes = indexes.len(); |
| 142 | |
| 143 | let inner = if num_indexes <= LEAF_MAX_SIZE { |
| 144 | let mut colors = [f_pixel::default(); LEAF_MAX_SIZE]; |
| 145 | let mut idxs = [Default::default(); LEAF_MAX_SIZE]; |
| 146 | |
| 147 | indexes.iter().zip(colors.iter_mut().zip(idxs.iter_mut())).for_each(|(i, (color, idx))| { |
| 148 | if let Some(c) = palette.get(usize::from(i.idx)) { |
| 149 | *idx = i.idx; |
| 150 | *color = *c; |
| 151 | } |
| 152 | }); |
| 153 | NodeInner::Leaf { |
| 154 | len: num_indexes as _, |
| 155 | idxs, |
| 156 | colors: Box::new(colors), |
| 157 | } |
| 158 | } else { |
| 159 | let half_index = num_indexes / 2; |
| 160 | let (near, far) = indexes.split_at_mut(half_index); |
| 161 | debug_assert!(!near.is_empty()); |
| 162 | debug_assert!(!far.is_empty()); |
| 163 | let radius_squared = palette.get(usize::from(far[0].idx)) |
| 164 | .map(|px| vantage_point.diff(px)).unwrap_or_default(); |
| 165 | let radius = radius_squared.sqrt(); |
| 166 | NodeInner::Nodes { |
| 167 | radius, radius_squared, |
| 168 | near: Box::new(vp_create_node(near, items)), |
| 169 | far: Box::new(vp_create_node(far, items)), |
| 170 | } |
| 171 | }; |
| 172 |
no test coverage detected