diff --git a/package.json b/package.json index 52f2dc7f..f3a0e214 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "lint": "biome check .", "lint:fix": "biome check . --fix", "lint:summary": "biome check --reporter=summary", + "lint:rust": "cargo clippy --manifest-path rust/Cargo.toml", "site:build:relativeurls": "npm run build && npm run site:clean && node scripts/copy-site-files.js && mkdocs build && node scripts/rename-assets-to-static.js && node scripts/replace-urls.js", "site:build": "npm run build && npm run site:clean && node scripts/copy-site-files.js && mkdocs build && node scripts/rename-assets-to-static.js", "site:clean": "node scripts/clean-site-files.js && node scripts/clean-site.js", diff --git a/rust/build-lod/src/main.rs b/rust/build-lod/src/main.rs index 0b06ffde..7b93ec78 100644 --- a/rust/build-lod/src/main.rs +++ b/rust/build-lod/src/main.rs @@ -97,8 +97,8 @@ fn process_file_lod(filename: &str, options: &BuildLodOptions) { } fn process_file_lod_tsplat(filename: &str, options: &BuildLodOptions, splats: TS) { - let mut decoder = MultiDecoder::new(splats, None, Some(&filename)); - let mut splats = match read_file_chunks(&filename, &mut decoder) { + let mut decoder = MultiDecoder::new(splats, None, Some(filename)); + let mut splats = match read_file_chunks(filename, &mut decoder) { Ok(_) => { println!("Detected file type: {:?}", decoder.file_type.unwrap()); decoder.into_splats() diff --git a/rust/spark-lib/src/bhatt_lod.rs b/rust/spark-lib/src/bhatt_lod.rs index 74f70bb5..33bb471b 100644 --- a/rust/spark-lib/src/bhatt_lod.rs +++ b/rust/spark-lib/src/bhatt_lod.rs @@ -19,7 +19,7 @@ pub fn compute_lod_tree(splats: &mut TA, lod_base: f32, logger: splats.sort_by(|s| s.feature_size()); splats.prepare_children(); - logger(&format!("Sorted and prepared splats")); + logger("Sorted and prepared splats"); let mut is_active = Vec::with_capacity(splats.len() * 2 - 1); is_active.resize(splats.len(), true); @@ -235,7 +235,7 @@ pub fn compute_lod_tree(splats: &mut TA, lod_base: f32, logger: if next_frontier.is_empty() { break; } - limit_size = limit_size / 4.0; + limit_size /= 4.0; frontier = next_frontier; } diff --git a/rust/spark-lib/src/chunk_tree.rs b/rust/spark-lib/src/chunk_tree.rs index 9a030e98..1ac19ec5 100644 --- a/rust/spark-lib/src/chunk_tree.rs +++ b/rust/spark-lib/src/chunk_tree.rs @@ -477,7 +477,7 @@ pub fn chunk_tree_size(splats: &mut TA, root: usize, logger: im println!("octant lengths: {:?}", octants.iter().map(|o| o.len()).collect::>()); // Resort into Hilbert order - let mut octants = octants.into_iter().map(|o| Some(o)).collect::>(); + let mut octants = octants.into_iter().map(Some).collect::>(); let octants = [0, 1, 3, 2, 6, 7, 5, 4].map(|i| octants[i].take().unwrap()); for batch in octants { batches.push_back(batch); @@ -638,7 +638,7 @@ pub fn chunk_tree_morton(splats: &mut TA, root: usize, logger: println!("octant lengths: {:?}", octants.iter().map(|o| o.len()).collect::>()); // Resort into Hilbert order - let mut octants = octants.into_iter().map(|o| Some(o)).collect::>(); + let mut octants = octants.into_iter().map(Some).collect::>(); let octants = [0, 1, 3, 2, 6, 7, 5, 4].map(|i| octants[i].take().unwrap()); for batch in octants { batches.push_back(batch); diff --git a/rust/spark-lib/src/csplat.rs b/rust/spark-lib/src/csplat.rs index 6c5fdcfa..63f549f5 100644 --- a/rust/spark-lib/src/csplat.rs +++ b/rust/spark-lib/src/csplat.rs @@ -192,7 +192,7 @@ impl TsplatArray for CsplatArray { } fn prepare_children(&mut self) { - self.children.resize_with(self.len(), || SmallVec::new()); + self.children.resize_with(self.len(), SmallVec::new); } fn has_children(&self) -> bool { @@ -324,7 +324,7 @@ impl TsplatArray for CsplatArray { } fn retain) -> bool)>(&mut self, mut f: F) { - let keep: Vec = self.splats.iter_mut().map(|splat| f(CsplatRefMut { splat: splat, encoding: &self.encoding })).collect(); + let keep: Vec = self.splats.iter_mut().map(|splat| f(CsplatRefMut { splat, encoding: &self.encoding })).collect(); let mut bits = keep.iter(); self.splats.retain(|_splat| *bits.next().unwrap()); @@ -352,9 +352,9 @@ impl TsplatArray for CsplatArray { .map(|(i, splat)| { if let Some(children) = self.children.get(i) { let children: SmallVec<[usize; 4]> = children.iter().map(|&i| i as usize).collect(); - f(CsplatRefMut { splat: splat, encoding: &encoding }, &children) + f(CsplatRefMut { splat, encoding: &encoding }, &children) } else { - f(CsplatRefMut { splat: splat, encoding: &encoding }, &[]) + f(CsplatRefMut { splat, encoding: &encoding }, &[]) } }) .collect(); @@ -417,11 +417,11 @@ impl TsplatArray for CsplatArray { Self { encoding: self.encoding.clone(), max_sh_degree: self.max_sh_degree, - splats: index_map.iter().map(|&i| self.splats[i as usize].clone()).collect(), - children: if !self.children.is_empty() { index_map.iter().map(|&i| self.children[i as usize].clone()).collect() } else { Vec::new() }, - sh1: if !self.sh1.is_empty() { index_map.iter().map(|&i| self.sh1[i as usize].clone()).collect() } else { Vec::new() }, - sh2: if !self.sh2.is_empty() { index_map.iter().map(|&i| self.sh2[i as usize].clone()).collect() } else { Vec::new() }, - sh3: if !self.sh3.is_empty() { index_map.iter().map(|&i| self.sh3[i as usize].clone()).collect() } else { Vec::new() }, + splats: index_map.iter().map(|&i| self.splats[i].clone()).collect(), + children: if !self.children.is_empty() { index_map.iter().map(|&i| self.children[i].clone()).collect() } else { Vec::new() }, + sh1: if !self.sh1.is_empty() { index_map.iter().map(|&i| self.sh1[i].clone()).collect() } else { Vec::new() }, + sh2: if !self.sh2.is_empty() { index_map.iter().map(|&i| self.sh2[i].clone()).collect() } else { Vec::new() }, + sh3: if !self.sh3.is_empty() { index_map.iter().map(|&i| self.sh3[i].clone()).collect() } else { Vec::new() }, } } @@ -457,7 +457,7 @@ impl SplatReceiver for CsplatArray { self.sh3.reserve(est_lod_size); } } else { - self.children.resize_with(init.num_splats, || SmallVec::new()); + self.children.resize_with(init.num_splats, SmallVec::new); } self.splats.resize_with(init.num_splats, Default::default); @@ -623,7 +623,7 @@ impl SplatReceiver for CsplatArray { fn set_child_count(&mut self, base: usize, count: usize, child_count: &[u16]) { for i in 0..count { - let mut child_index = *self.children[base + i].get(0).unwrap_or(&0); + let mut child_index = *self.children[base + i].first().unwrap_or(&0); self.children[base + i].clear(); self.children[base + i].resize_with(child_count[i] as usize, || { let child = child_index; diff --git a/rust/spark-lib/src/decoder.rs b/rust/spark-lib/src/decoder.rs index 74c4af30..1fb5b580 100644 --- a/rust/spark-lib/src/decoder.rs +++ b/rust/spark-lib/src/decoder.rs @@ -21,23 +21,13 @@ impl dyn ChunkReceiver { pub fn into_any(self: Box) -> Box { self } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct SplatInit { pub num_splats: usize, pub max_sh_degree: usize, pub lod_tree: bool, } -impl Default for SplatInit { - fn default() -> Self { - Self { - num_splats: 0, - max_sh_degree: 0, - lod_tree: false, - } - } -} - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SplatEncoding { #[serde(rename = "rgbMin")] @@ -108,7 +98,7 @@ impl From for SetSplatEncoding { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct SplatProps<'a> { pub center: &'a [f32], pub opacity: &'a [f32], @@ -122,23 +112,6 @@ pub struct SplatProps<'a> { pub child_start: &'a [usize], } -impl<'a> Default for SplatProps<'a> { - fn default() -> Self { - Self { - center: &[], - opacity: &[], - rgb: &[], - scale: &[], - quat: &[], - sh1: &[], - sh2: &[], - sh3: &[], - child_count: &[], - child_start: &[], - } - } -} - #[allow(unused)] pub trait SplatReceiver: 'static { fn init_splats(&mut self, init: &SplatInit) -> anyhow::Result<()> { Ok(()) } @@ -239,7 +212,7 @@ impl SplatPropsArray { } } -#[derive(Debug)] +#[derive(Debug, Default)] pub struct SplatPropsMut<'a> { pub center: &'a mut [f32], pub opacity: &'a mut [f32], @@ -253,23 +226,6 @@ pub struct SplatPropsMut<'a> { pub child_start: &'a mut [usize], } -impl<'a> Default for SplatPropsMut<'a> { - fn default() -> Self { - Self { - center: &mut [], - opacity: &mut [], - rgb: &mut [], - scale: &mut [], - quat: &mut [], - sh1: &mut [], - sh2: &mut [], - sh3: &mut [], - child_count: &mut [], - child_start: &mut [], - } - } -} - #[allow(unused)] pub trait SplatGetter: 'static { // Source/format metadata (header-like) @@ -382,7 +338,7 @@ impl SplatFileType { let clean_path = clean_path .split_once('#') .map_or(clean_path, |(path, _)| path); - clean_path.split('.').last().and_then(Self::from_extension) + clean_path.split('.').next_back().and_then(Self::from_extension) } } diff --git a/rust/spark-lib/src/gsplat.rs b/rust/spark-lib/src/gsplat.rs index 0a69d468..52358401 100644 --- a/rust/spark-lib/src/gsplat.rs +++ b/rust/spark-lib/src/gsplat.rs @@ -26,9 +26,9 @@ impl Gsplat { Self { center: center.to_vec3(), opacity: f16::from_f32(opacity), - rgb: rgb.to_array().map(|v| f16::from_f32(v)), + rgb: rgb.to_array().map(f16::from_f32), ln_scales: scales.to_array().map(|v| f16::from_f32(v.ln())), - quaternion: quaternion.to_array().map(|v| f16::from_f32(v)), + quaternion: quaternion.to_array().map(f16::from_f32), } } } @@ -39,7 +39,7 @@ impl std::fmt::Debug for Gsplat { } } -impl<'a> Tsplat for &'a Gsplat { +impl Tsplat for &Gsplat { fn center(&self) -> Vec3A { self.center.to_vec3a() } @@ -65,7 +65,7 @@ impl<'a> Tsplat for &'a Gsplat { } } -impl<'a> Tsplat for &'a mut Gsplat { +impl Tsplat for &mut Gsplat { fn center(&self) -> Vec3A { self.center.to_vec3a() } @@ -91,7 +91,7 @@ impl<'a> Tsplat for &'a mut Gsplat { } } -impl<'a> TsplatMut for &'a mut Gsplat { +impl TsplatMut for &mut Gsplat { fn set_center(&mut self, center: Vec3A) { self.center = center.to_vec3(); } @@ -100,19 +100,16 @@ impl<'a> TsplatMut for &'a mut Gsplat { self.opacity = f16::from_f32(opacity); } - fn set_rgb(&mut self, rgb: Vec3A) { - self.rgb = rgb.to_array().map(|v| f16::from_f32(v)); + self.rgb = rgb.to_array().map(f16::from_f32); } - fn set_scales(&mut self, scales: Vec3A) { self.ln_scales = scales.to_array().map(|v| f16::from_f32(v.ln())); } - fn set_quaternion(&mut self, quaternion: Quat) { - self.quaternion = quaternion.to_array().map(|v| f16::from_f32(v)); + self.quaternion = quaternion.to_array().map(f16::from_f32); } } @@ -121,7 +118,7 @@ pub struct GsplatSH1(pub [[f16; 3]; 3]); impl GsplatSH1 { pub fn new(rgb3: [Vec3A; 3]) -> Self { - Self(rgb3.map(|rgb| rgb.to_array().map(|v| f16::from_f32(v)))) + Self(rgb3.map(|rgb| rgb.to_array().map(f16::from_f32))) } pub fn set_from_array(&mut self, rgb3: &[f32]) { @@ -144,7 +141,7 @@ pub struct GsplatSH2(pub [[f16; 3]; 5]); impl GsplatSH2 { pub fn new(rgb5: [Vec3A; 5]) -> Self { - Self(rgb5.map(|rgb| rgb.to_array().map(|v| f16::from_f32(v)))) + Self(rgb5.map(|rgb| rgb.to_array().map(f16::from_f32))) } pub fn set_from_array(&mut self, rgb5: &[f32]) { @@ -169,7 +166,7 @@ pub struct GsplatSH3(pub [[f16; 3]; 7]); impl GsplatSH3 { pub fn new(rgb7: [Vec3A; 7]) -> Self { - Self(rgb7.map(|rgb| rgb.to_array().map(|v| f16::from_f32(v)))) + Self(rgb7.map(|rgb| rgb.to_array().map(f16::from_f32))) } pub fn set_from_array(&mut self, rgb7: &[f32]) { @@ -282,7 +279,7 @@ impl TsplatArray for GsplatArray { } fn prepare_children(&mut self) { - self.children.resize_with(self.len(), || SmallVec::new()); + self.children.resize_with(self.len(), SmallVec::new); } fn has_children(&self) -> bool { @@ -329,7 +326,7 @@ impl TsplatArray for GsplatArray { let filter2 = (0.5 * step).powi(2); for (i, &index) in indices.iter().enumerate() { - let splat = &self.splats[index as usize]; + let splat = &self.splats[index]; let weight = weights[i]; let delta = splat.center() - center; let cov = SymMat3::new_scale_quaternion(splat.scales(), splat.quaternion()); @@ -459,7 +456,7 @@ impl TsplatArray for GsplatArray { } fn get_child_count_start(&self, index: usize) -> (usize, usize) { - (self.children[index].len(), self.children[index].first().copied().unwrap_or(0) as usize) + (self.children[index].len(), self.children[index].first().copied().unwrap_or(0)) } @@ -483,8 +480,8 @@ impl TsplatArray for GsplatArray { similarity_metric(&self.get(a), &self.get(b)) } - fn retain bool)>(&mut self, mut f: F) { - let keep: Vec = self.splats.iter_mut().map(|splat| f(splat)).collect(); + fn retain bool)>(&mut self, f: F) { + let keep: Vec = self.splats.iter_mut().map(f).collect(); let mut bits = keep.iter(); self.splats.retain(|_splat| *bits.next().unwrap()); if !self.children.is_empty() { @@ -644,8 +641,7 @@ impl GsplatArray { pub fn to_packed_array(&self, encoding: &SplatEncoding) -> (usize, Vec) { let (_, _, _, max_splats) = get_splat_tex_size(self.splats.len()); - let mut packed = Vec::new(); - packed.resize(max_splats * 4, 0); + let mut packed = vec![0; max_splats * 4]; for i in 0..self.splats.len() { let i4 = i * 4; @@ -669,16 +665,13 @@ impl GsplatArray { return Vec::new(); } let (_, _, _, max_splats) = get_splat_tex_size(self.splats.len()); - let mut sh1 = Vec::new(); - sh1.resize(max_splats * 2, 0); + let mut sh1 = vec![0; max_splats * 2]; let SplatEncoding { sh1_max, .. } = encoding; for i in 0..self.splats.len() { let i2 = i * 2; let encoded = encode_sh1(&self.sh1[i].to_array(), *sh1_max); - for w in 0..2 { - sh1[i2 + w] = encoded[w]; - } + sh1[i2..(i2 + 2)].copy_from_slice(&encoded); } sh1 } @@ -688,16 +681,13 @@ impl GsplatArray { return Vec::new(); } let (_, _, _, max_splats) = get_splat_tex_size(self.splats.len()); - let mut sh2 = Vec::new(); - sh2.resize(max_splats * 4, 0); + let mut sh2 = vec![0; max_splats * 4]; let SplatEncoding { sh2_max, .. } = encoding; for i in 0..self.splats.len() { let i4 = i * 4; let encoded = encode_sh2(&self.sh2[i].to_array(), *sh2_max); - for w in 0..4 { - sh2[i4 + w] = encoded[w]; - } + sh2[i4..(i4 + 4)].copy_from_slice(&encoded); } sh2 } @@ -707,16 +697,13 @@ impl GsplatArray { return Vec::new(); } let (_, _, _, max_splats) = get_splat_tex_size(self.splats.len()); - let mut sh3 = Vec::new(); - sh3.resize(max_splats * 4, 0); + let mut sh3 = vec![0; max_splats * 4]; let SplatEncoding { sh3_max, .. } = encoding; for i in 0..self.splats.len() { let i4 = i * 4; let encoded = encode_sh3(&self.sh3[i].to_array(), *sh3_max); - for w in 0..4 { - sh3[i4 + w] = encoded[w]; - } + sh3[i4..(i4 + 4)].copy_from_slice(&encoded); } sh3 } @@ -875,7 +862,7 @@ impl SplatReceiver for GsplatArray { fn set_child_count(&mut self, base: usize, count: usize, child_count: &[u16]) { for i in 0..count { - let mut child_index = *self.children[base + i].get(0).unwrap_or(&0); + let mut child_index = *self.children[base + i].first().unwrap_or(&0); self.children[base + i].clear(); self.children[base + i].resize_with(child_count[i] as usize, || { let child = child_index; @@ -980,7 +967,7 @@ impl SplatGetter for GsplatArray { fn get_child_start(&mut self, base: usize, count: usize, out: &mut [usize]) { for i in 0..count { let children = &self.children[base + i]; - out[i] = children.first().copied().unwrap_or(0) as usize; + out[i] = children.first().copied().unwrap_or(0); } } } diff --git a/rust/spark-lib/src/ksplat.rs b/rust/spark-lib/src/ksplat.rs index 924507b8..22437283 100644 --- a/rust/spark-lib/src/ksplat.rs +++ b/rust/spark-lib/src/ksplat.rs @@ -246,7 +246,7 @@ impl ChunkReceiver for KsplatDecoder { i / bucket_size } else { if let Some(lengths) = partially_filled_lengths { - let idx = partial_bucket_index.checked_sub(full_bucket_count).unwrap_or(0); + let idx = partial_bucket_index.saturating_sub(full_bucket_count); if idx < lengths.len() && i >= partial_bucket_base + lengths[idx] as usize { partial_bucket_index += 1; partial_bucket_base += lengths[idx] as usize; diff --git a/rust/spark-lib/src/ordering.rs b/rust/spark-lib/src/ordering.rs index c2d0b35b..7bd0f774 100644 --- a/rust/spark-lib/src/ordering.rs +++ b/rust/spark-lib/src/ordering.rs @@ -59,7 +59,7 @@ pub fn morton_coord64_to_index([x, y, z]: [u64; 3]) -> [u64; 3] { fn or_shift_u64_into_u192_le(out: &mut [u64; 3], v: u64, shift: u32) { let limb = (shift / 64) as usize; - let off = (shift % 64) as u32; + let off = shift % 64; out[limb] |= v << off; if off != 0 && limb + 1 < 3 { diff --git a/rust/spark-lib/src/ply.rs b/rust/spark-lib/src/ply.rs index a957cfa8..782f4396 100644 --- a/rust/spark-lib/src/ply.rs +++ b/rust/spark-lib/src/ply.rs @@ -461,7 +461,7 @@ fn parse_header(header: &str) -> anyhow::Result { current = Some(PlyElementBuilder::new(fields[1], fields[2].parse()?)); }, "property" => { - if fields.get(1).map(|s| *s) == Some("list") { + if fields.get(1).copied() == Some("list") { return Err(anyhow!("PLY list properties are not supported")); } if fields.len() != 3 { @@ -590,7 +590,7 @@ impl SuperSplatState { fn new(parsed: ParsedHeader) -> anyhow::Result { let chunk_desc = parsed.chunk.ok_or(anyhow!("Missing chunk element for SuperSplat PLY"))?; let vertex_desc = parsed.vertex; - let expected_chunks = (vertex_desc.count + SUPER_CHUNK_SIZE - 1) / SUPER_CHUNK_SIZE; + let expected_chunks = vertex_desc.count.div_ceil(SUPER_CHUNK_SIZE); if chunk_desc.count < expected_chunks { return Err(anyhow!( "Not enough chunk records: have {}, need at least {}", @@ -1058,7 +1058,7 @@ impl PointCloudDecoderState { *properties.get("green").ok_or(anyhow!("Missing green property"))?, *properties.get("blue").ok_or(anyhow!("Missing blue property"))?, ]; - let alpha = properties.get("alpha").map(|p| *p); + let alpha = properties.get("alpha").copied(); Ok(Self { num_splats, @@ -1403,8 +1403,8 @@ impl PlyEncoder { _ => 0.0, } }; - for idx in 0..num_f_rest { - let d = if stride > 0 { idx / stride } else { 0 }; + for idx in 0usize..num_f_rest { + let d = idx.checked_div(stride).unwrap_or(0); let in_channel = if stride > 0 { idx % stride } else { 0 }; if in_channel < 3 { let k = in_channel; // degree 1 (3 coeffs) diff --git a/rust/spark-lib/src/rad.rs b/rust/spark-lib/src/rad.rs index 813495ef..20e7046c 100644 --- a/rust/spark-lib/src/rad.rs +++ b/rust/spark-lib/src/rad.rs @@ -524,7 +524,7 @@ impl RadEncoder { let num_splats = self.getter.num_splats(); let max_sh = self.getter.max_sh_degree().min(self.max_sh); - let encoding = self.encoding.clone().or_else(|| self.getter.get_encoding()).unwrap_or(SplatEncoding::default()); + let encoding = self.encoding.clone().or_else(|| self.getter.get_encoding()).unwrap_or_default(); let mut buffer = Vec::new(); let buffer_dim = if max_sh == 0 { 4 } else if max_sh == 1 { 9 } else if max_sh == 2 { 15 } else { 21 }; @@ -570,7 +570,7 @@ impl RadEncoder { max_sh: Some(max_sh), lod_tree: if self.getter.has_lod_tree() { Some(true) } else { None }, chunk_size: Some(CHUNK_SIZE), - all_chunk_bytes: all_chunk_bytes, + all_chunk_bytes, chunks: chunk_ranges, splat_encoding: None, sh_code_count: self.sh_clusters.as_ref().map(|c| c.num_clusters as u32), @@ -609,11 +609,11 @@ impl RadEncoder { self.getter.get_center(base, count, &mut buffer[..count * 3]); let (enc, bytes) = match self.center_encoding { - RadCenterEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(&buffer, 3, count)), - RadCenterEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(&buffer, 3, count)), + RadCenterEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(buffer, 3, count)), + RadCenterEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(buffer, 3, count)), RadCenterEncoding::Auto | - RadCenterEncoding::F32LeBytes => (RadChunkPropertyEncoding::F32LeBytes, encode_f32_lebytes(&buffer, 3, count)), - RadCenterEncoding::F16LeBytes => (RadChunkPropertyEncoding::F16LeBytes, encode_f16_lebytes(&buffer, 3, count)), + RadCenterEncoding::F32LeBytes => (RadChunkPropertyEncoding::F32LeBytes, encode_f32_lebytes(buffer, 3, count)), + RadCenterEncoding::F16LeBytes => (RadChunkPropertyEncoding::F16LeBytes, encode_f16_lebytes(buffer, 3, count)), }; let meta = RadChunkProperty { property: RadChunkPropertyName::Center, @@ -632,10 +632,10 @@ impl RadEncoder { let max_alpha = if self.getter.has_lod_tree() { 2.0 } else { 1.0 }; let (enc, bytes, min, max) = match self.alpha_encoding { - RadAlphaEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(&buffer, 1, count), None, None), + RadAlphaEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(buffer, 1, count), None, None), RadAlphaEncoding::Auto | - RadAlphaEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(&buffer, 1, count), None, None), - RadAlphaEncoding::R8 => (RadChunkPropertyEncoding::R8, encode_r8(&buffer, 1, count, 0.0, max_alpha), Some(0.0), Some(max_alpha)), + RadAlphaEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(buffer, 1, count), None, None), + RadAlphaEncoding::R8 => (RadChunkPropertyEncoding::R8, encode_r8(buffer, 1, count, 0.0, max_alpha), Some(0.0), Some(max_alpha)), }; let meta = RadChunkProperty { property: RadChunkPropertyName::Alpha, @@ -655,11 +655,11 @@ impl RadEncoder { self.getter.get_rgb(base, count, &mut buffer[..count * 3]); let (enc, bytes, min, max) = match self.rgb_encoding { - RadRgbEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(&buffer, 3, count), None, None), - RadRgbEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(&buffer, 3, count), None, None), - RadRgbEncoding::R8 => (RadChunkPropertyEncoding::R8, encode_r8(&buffer, 3, count, encoding.rgb_min, encoding.rgb_max), Some(encoding.rgb_min), Some(encoding.rgb_max)), + RadRgbEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(buffer, 3, count), None, None), + RadRgbEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(buffer, 3, count), None, None), + RadRgbEncoding::R8 => (RadChunkPropertyEncoding::R8, encode_r8(buffer, 3, count, encoding.rgb_min, encoding.rgb_max), Some(encoding.rgb_min), Some(encoding.rgb_max)), RadRgbEncoding::Auto | - RadRgbEncoding::R8Delta => (RadChunkPropertyEncoding::R8Delta, encode_r8_delta(&buffer, 3, count, encoding.rgb_min, encoding.rgb_max), Some(encoding.rgb_min), Some(encoding.rgb_max)), + RadRgbEncoding::R8Delta => (RadChunkPropertyEncoding::R8Delta, encode_r8_delta(buffer, 3, count, encoding.rgb_min, encoding.rgb_max), Some(encoding.rgb_min), Some(encoding.rgb_max)), }; let meta = RadChunkProperty { property: RadChunkPropertyName::Rgb, @@ -679,10 +679,10 @@ impl RadEncoder { self.getter.get_scale(base, count, &mut buffer[..count * 3]); let (enc, bytes, min, max) = match self.scales_encoding { - RadScalesEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(&buffer, 3, count), None, None), + RadScalesEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(buffer, 3, count), None, None), RadScalesEncoding::Auto | - RadScalesEncoding::Ln0R8 => (RadChunkPropertyEncoding::Ln0R8, encode_ln_0r8(&buffer, 3, count, -30.0, encoding.ln_scale_min, encoding.ln_scale_max), Some(encoding.ln_scale_min), Some(encoding.ln_scale_max)), - RadScalesEncoding::LnF16 => (RadChunkPropertyEncoding::LnF16, encode_ln_f16(&buffer, 3, count), None, None), + RadScalesEncoding::Ln0R8 => (RadChunkPropertyEncoding::Ln0R8, encode_ln_0r8(buffer, 3, count, -30.0, encoding.ln_scale_min, encoding.ln_scale_max), Some(encoding.ln_scale_min), Some(encoding.ln_scale_max)), + RadScalesEncoding::LnF16 => (RadChunkPropertyEncoding::LnF16, encode_ln_f16(buffer, 3, count), None, None), }; let meta = RadChunkProperty { property: RadChunkPropertyName::Scales, @@ -702,7 +702,7 @@ impl RadEncoder { self.getter.get_quat(base, count, &mut buffer[..count * 4]); if self.orientation_encoding == RadOrientationEncoding::Oct88R8 || self.orientation_encoding == RadOrientationEncoding::Auto { - let bytes = encode_quat_oct88r8(&buffer, count); + let bytes = encode_quat_oct88r8(buffer, count); let meta = RadChunkProperty { property: RadChunkPropertyName::Orientation, encoding: RadChunkPropertyEncoding::Oct88R8, @@ -717,8 +717,8 @@ impl RadEncoder { } } let (enc, bytes) = match self.orientation_encoding { - RadOrientationEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(&buffer, 3, count)), - RadOrientationEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(&buffer, 3, count)), + RadOrientationEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(buffer, 3, count)), + RadOrientationEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(buffer, 3, count)), _ => unreachable!(), }; let meta = RadChunkProperty { @@ -771,11 +771,11 @@ impl RadEncoder { } let (encoding, bytes, min, max) = match self.sh_encoding { - RadShEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(&buffer, elements, count), None, None), - RadShEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(&buffer, elements, count), None, None), + RadShEncoding::F32 => (RadChunkPropertyEncoding::F32, encode_f32(buffer, elements, count), None, None), + RadShEncoding::F16 => (RadChunkPropertyEncoding::F16, encode_f16(buffer, elements, count), None, None), RadShEncoding::Auto | - RadShEncoding::S8 => (RadChunkPropertyEncoding::S8, encode_s8(&buffer, elements, count, sh_max), Some(-sh_max), Some(sh_max)), - RadShEncoding::S8Delta => (RadChunkPropertyEncoding::S8Delta, encode_s8_delta(&buffer, elements, count, sh_max), Some(-sh_max), Some(sh_max)), + RadShEncoding::S8 => (RadChunkPropertyEncoding::S8, encode_s8(buffer, elements, count, sh_max), Some(-sh_max), Some(sh_max)), + RadShEncoding::S8Delta => (RadChunkPropertyEncoding::S8Delta, encode_s8_delta(buffer, elements, count, sh_max), Some(-sh_max), Some(sh_max)), }; let meta = RadChunkProperty { property, @@ -796,13 +796,11 @@ impl RadEncoder { if buffer.len() < count { buffer.resize(count, 0); } - for i in 0..count { - buffer[i] = clusters.labels[base + i]; - } + buffer[..count].copy_from_slice(&clusters.labels[base..(base + count)]); let (encoding, bytes) = match self.sh_label_encoding { - RadShLabelEncoding::U16 => (RadChunkPropertyEncoding::U16, encode_usize_as_u16(&buffer, 1, count)), - RadShLabelEncoding::U32 => (RadChunkPropertyEncoding::U32, encode_usize_as_u32(&buffer, 1, count)), + RadShLabelEncoding::U16 => (RadChunkPropertyEncoding::U16, encode_usize_as_u16(buffer, 1, count)), + RadShLabelEncoding::U32 => (RadChunkPropertyEncoding::U32, encode_usize_as_u32(buffer, 1, count)), _ => unreachable!(), }; let meta = RadChunkProperty { @@ -820,7 +818,7 @@ impl RadEncoder { } self.getter.get_child_count(base, count, &mut buffer[..count]); - let bytes = encode_u16(&buffer, 1, count); + let bytes = encode_u16(buffer, 1, count); let meta = RadChunkProperty { property: RadChunkPropertyName::ChildCount, encoding: RadChunkPropertyEncoding::U16, @@ -836,7 +834,7 @@ impl RadEncoder { } self.getter.get_child_start(base, count, &mut buffer[..count]); - let bytes = encode_usize_as_u32(&buffer, 1, count); + let bytes = encode_usize_as_u32(buffer, 1, count); let meta = RadChunkProperty { property: RadChunkPropertyName::ChildStart, encoding: RadChunkPropertyEncoding::U32, @@ -948,7 +946,7 @@ fn write_pad(writer: &mut W, size: usize) -> anyhow::Result<()> { let pad = pad8(size); if pad != 0 { let zero_pad = [0u8; 8]; - writer.write_all(&zero_pad[..pad as usize])?; + writer.write_all(&zero_pad[..pad])?; } Ok(()) } @@ -1798,7 +1796,7 @@ impl RadDecoder { self.buffer.drain(..available as usize); self.offset += available; - return Ok(self.offset >= self.chunk_end); + Ok(self.offset >= self.chunk_end) } fn skip_remaining(&mut self) -> anyhow::Result<()> { diff --git a/rust/spark-lib/src/sh_clustering.rs b/rust/spark-lib/src/sh_clustering.rs index d5d826a4..411d7bf7 100644 --- a/rust/spark-lib/src/sh_clustering.rs +++ b/rust/spark-lib/src/sh_clustering.rs @@ -65,7 +65,7 @@ pub fn compute_sh_clusters( let last_iteration = iteration == num_iterations; fnc.set_clusters(dims, &clusters)?; - logger(&format!("sh_clustering: Initialized centroids")); + logger("sh_clustering: Initialized centroids"); cluster_weight.fill(0.0); cluster_count.fill(0); diff --git a/rust/spark-lib/src/splat_encode.rs b/rust/spark-lib/src/splat_encode.rs index 3a0d58d6..d7e3e2b5 100644 --- a/rust/spark-lib/src/splat_encode.rs +++ b/rust/spark-lib/src/splat_encode.rs @@ -160,7 +160,7 @@ pub fn encode_ext_splat_rgb(ext_b: &mut [u32], rgb: [f32; 3]) { pub fn decode_ext_splat_rgb(ext_b: &[u32]) -> [f32; 3] { [ext_b[0] as u16, (ext_b[0] >> 16) as u16, ext_b[1] as u16] - .map(|x| f16::from_bits(x as u16).to_f32()) + .map(|x| f16::from_bits(x).to_f32()) } pub fn encode_ext_splat_rgba(ext_a: &mut [u32], ext_b: &mut [u32], rgba: [f32; 4]) { @@ -180,7 +180,7 @@ pub fn encode_ext_splat_scale(ext_b: &mut [u32], scale: [f32; 3]) { pub fn decode_ext_splat_scale(ext_b: &[u32]) -> [f32; 3] { [(ext_b[1] >> 16) as u16, ext_b[2] as u16, (ext_b[2] >> 16) as u16] - .map(|x| f16::from_bits(x as u16).to_f32().exp()) + .map(|x| f16::from_bits(x).to_f32().exp()) } pub fn encode_ext_splat_quat(ext_b: &mut [u32], quat_xyzw: [f32; 4]) { @@ -488,11 +488,11 @@ pub fn encode_lod_tree(buffer: &mut [u32], center: &[f32], opacity: f32, scale: buffer[0] = (center[0].to_bits() as u32) | ((center[1].to_bits() as u32) << 16); buffer[1] = (center[2].to_bits() as u32) | ((size.to_bits() as u32) << 16); buffer[2] = child_count as u32; - buffer[3] = child_start as u32; + buffer[3] = child_start; } pub fn decode_lod_tree_children(buffer: &[u32]) -> (u16, u32) { let child_count = (buffer[2] & 0xffff) as u16; - let child_start = buffer[3] as u32; + let child_start = buffer[3]; (child_count, child_start) } diff --git a/rust/spark-lib/src/spz.rs b/rust/spark-lib/src/spz.rs index 1e60d943..3d23778d 100644 --- a/rust/spark-lib/src/spz.rs +++ b/rust/spark-lib/src/spz.rs @@ -78,7 +78,7 @@ impl SpzDecoder { let _reserved = self.buffer[15]; self.buffer.drain(..16); - let state = SpzDecoderState::new(version as u32, num_splats, sh_degree, fractional_bits, flags)?; + let state = SpzDecoderState::new(version, num_splats, sh_degree, fractional_bits, flags)?; self.state = Some(state); self.splats.init_splats(&SplatInit { diff --git a/rust/spark-lib/src/tiny_lod.rs b/rust/spark-lib/src/tiny_lod.rs index 48bdda81..178077c9 100644 --- a/rust/spark-lib/src/tiny_lod.rs +++ b/rust/spark-lib/src/tiny_lod.rs @@ -127,7 +127,7 @@ pub fn compute_lod_tree(splats: &mut SA, lod_base: f32, merge_f let grid_range = (grid_min_max[1] - grid_min_max[0]).max_element(); if grid_range <= 1 { - logger(&format!("Grid range is 1, making root")); + logger("Grid range is 1, making root"); make_root = true; } } diff --git a/rust/spark-rs/src/decoder.rs b/rust/spark-rs/src/decoder.rs index 4ffc28de..b32e7050 100644 --- a/rust/spark-rs/src/decoder.rs +++ b/rust/spark-rs/src/decoder.rs @@ -7,7 +7,7 @@ use spark_lib::decoder::ChunkReceiver; const MAX_BUFFER_SIZE: usize = 1048576; thread_local! { - static BUFFER: RefCell> = RefCell::new(Vec::new()); + static BUFFER: RefCell> = const { RefCell::new(Vec::new()) }; } #[wasm_bindgen] diff --git a/rust/spark-rs/src/ext_splats.rs b/rust/spark-rs/src/ext_splats.rs index eed4da9f..f675d5fe 100644 --- a/rust/spark-rs/src/ext_splats.rs +++ b/rust/spark-rs/src/ext_splats.rs @@ -226,14 +226,10 @@ impl ExtSplatsData { let scales = splat.scales(); let quat = splat.quaternion().to_array(); - for d in 0..3 { - batch_center[i3 + d] = center[d]; - batch_rgb[i3 + d] = rgb[d]; - batch_scale[i3 + d] = scales[d]; - } - for d in 0..4 { - batch_quat[i4 + d] = quat[d]; - } + batch_center[i3..(i3 + 3)].copy_from_slice(¢er.to_array()); + batch_rgb[i3..(i3 + 3)].copy_from_slice(&rgb.to_array()); + batch_scale[i3..(i3 + 3)].copy_from_slice(&scales.to_array()); + batch_quat[i4..(i4 + 4)].copy_from_slice(&quat); batch_opacity[i] = splat.opacity(); @@ -270,9 +266,7 @@ impl ExtSplatsData { for i in 0..count { let i9 = i * 9; let values = splats.get_sh1(base + i); - for d in 0..9 { - batch[i9 + d] = values[d]; - } + batch[i9..i9 + 9].copy_from_slice(&values) } receiver.set_sh1(base, count, &batch); base += count; @@ -287,9 +281,7 @@ impl ExtSplatsData { for i in 0..count { let i15 = i * 15; let values = splats.get_sh2(base + i); - for d in 0..15 { - batch[i15 + d] = values[d]; - } + batch[i15..i15 + 15].copy_from_slice(&values); } receiver.set_sh2(base, count, &batch); base += count; @@ -304,9 +296,7 @@ impl ExtSplatsData { for i in 0..count { let i21 = i * 21; let values = splats.get_sh3(base + i); - for d in 0..21 { - batch[i21 + d] = values[d]; - } + batch[i21..i21 + 21].copy_from_slice(&values); } receiver.set_sh3(base, count, &batch); base += count; @@ -440,8 +430,8 @@ impl SplatReceiver for ExtSplatsData { self.child_counts = None; } - std::mem::swap(&mut self.buffer_a, &mut Vec::new()); - std::mem::swap(&mut self.buffer_b, &mut Vec::new()); + self.buffer_a = Vec::new(); + self.buffer_b = Vec::new(); Ok(()) } @@ -772,9 +762,7 @@ impl SplatReceiver for ExtSplatsData { let label = sh_labels[i] as usize; let i4 = i * 4; let l4 = label * 4; - for k in 0..4 { - buffer_a[i4 + k] = self.sh1_codes[l4 + k]; - } + buffer_a[i4..i4 + 4].copy_from_slice(&self.sh1_codes[l4..l4 + 4]) } if self.max_sh_degree == 1 { @@ -807,9 +795,7 @@ impl SplatReceiver for ExtSplatsData { let label = sh_labels[i] as usize; let i4 = i * 4; let l4 = label * 4; - for k in 0..4 { - buffer_a[i4 + k] = self.sh3_codes[0][l4 + k]; - } + buffer_a[i4..i4 + 4].copy_from_slice(&self.sh3_codes[0][l4..l4 + 4]); for k in 4..7 { buffer_b[i4 + (k - 4)] = self.sh3_codes[1][l4 + (k - 4)]; } @@ -827,9 +813,7 @@ impl SplatReceiver for ExtSplatsData { self.child_counts = Some(vec![0; self.num_splats]); } let counts = self.child_counts.as_mut().unwrap(); - for i in 0..count { - counts[base + i] = child_count[i]; - } + counts[base..base + count].copy_from_slice(&child_count[..count]) } fn set_child_start(&mut self, base: usize, count: usize, child_start: &[usize]) { @@ -860,9 +844,7 @@ impl SplatGetter for ExtSplatsData { let buffer_b = &self.buffer_b[i4..i4 + 4]; if !out.center.is_empty() { let center = decode_ext_splat_center(buffer_a); - for d in 0..3 { - out.center[i3 + d] = center[d]; - } + out.center[i3..i3 + 3].copy_from_slice(¢er); } if !out.opacity.is_empty() { let opacity = decode_ext_splat_opacity(buffer_a); @@ -870,21 +852,15 @@ impl SplatGetter for ExtSplatsData { } if !out.rgb.is_empty() { let rgb = decode_ext_splat_rgb(buffer_b); - for d in 0..3 { - out.rgb[i3 + d] = rgb[d]; - } + out.rgb[i3..i3 + 3].copy_from_slice(&rgb); } if !out.scale.is_empty() { let scale = decode_ext_splat_scale(buffer_b); - for d in 0..3 { - out.scale[i3 + d] = scale[d]; - } + out.scale[i3..i3 + 3].copy_from_slice(&scale); } if !out.quat.is_empty() { let quat = decode_ext_splat_quat(buffer_b); - for d in 0..4 { - out.quat[i4 + d] = quat[d]; - } + out.quat[i4..i4 + 4].copy_from_slice(&quat); } } diff --git a/rust/spark-rs/src/lib.rs b/rust/spark-rs/src/lib.rs index 68d11d53..481b91a5 100644 --- a/rust/spark-rs/src/lib.rs +++ b/rust/spark-rs/src/lib.rs @@ -56,14 +56,14 @@ pub fn sort_splats( let active_splats = match sort_internal(buffers, num_splats as usize) { Ok(active_splats) => active_splats, Err(err) => { - wasm_bindgen::throw_str(&format!("{}", err)); + wasm_bindgen::throw_str(&err.to_string()); } }; if active_splats > 0 { // Copy out ordering result let subarray = &buffers.ordering[..active_splats as usize]; - ordering.subarray(0, active_splats).copy_from(&subarray); + ordering.subarray(0, active_splats).copy_from(subarray); } active_splats }); @@ -85,14 +85,14 @@ pub fn sort32_splats( let active_splats = match sort32_internal(buffers, max_splats, num_splats as usize) { Ok(active_splats) => active_splats, Err(err) => { - wasm_bindgen::throw_str(&format!("{}", err)); + wasm_bindgen::throw_str(&err.to_string()); } }; if active_splats > 0 { // Copy out ordering result let subarray = &buffers.ordering[..active_splats as usize]; - ordering.subarray(0, active_splats).copy_from(&subarray); + ordering.subarray(0, active_splats).copy_from(subarray); } active_splats }); @@ -517,14 +517,14 @@ thread_local! { #[wasm_bindgen] pub fn get_raycast_buffer() -> Uint32Array { RAYCAST_BUFFERS.with_borrow_mut(|(buffer, _, _)| { - unsafe { Uint32Array::view(&buffer) } + unsafe { Uint32Array::view(buffer) } }) } #[wasm_bindgen] pub fn get_raycast_buffer2() -> Uint32Array { RAYCAST_BUFFERS.with_borrow_mut(|(_, buffer, _)| { - unsafe { Uint32Array::view(&buffer) } + unsafe { Uint32Array::view(buffer) } }) } @@ -552,7 +552,7 @@ pub fn raycast_packed_buffer( min_opacity, near, far, &encoding, ); - unsafe { Float32Array::view(&distances) } + unsafe { Float32Array::view(distances) } }) } @@ -573,7 +573,7 @@ pub fn raycast_ext_buffers( min_opacity, near, far, ); - unsafe { Float32Array::view(&distances) } + unsafe { Float32Array::view(distances) } }) } @@ -593,7 +593,7 @@ pub fn raycast_packed_splats( ..Default::default() }; - _ = RAYCAST_BUFFERS.with_borrow_mut(|(buffer, _, _)| { + RAYCAST_BUFFERS.with_borrow_mut(|(buffer, _, _)| { let mut base = 0; while base < num_splats { let chunk_size = (RAYCAST_BUFFER_COUNT as u32).min(num_splats - base); diff --git a/rust/spark-rs/src/lod_tree.rs b/rust/spark-rs/src/lod_tree.rs index c7121057..4f4e153c 100644 --- a/rust/spark-rs/src/lod_tree.rs +++ b/rust/spark-rs/src/lod_tree.rs @@ -106,7 +106,7 @@ impl LodSplat { #[allow(dead_code)] fn new(center: Vec3, size: f32, child_start: u32, child_count: u16) -> Self { - let center = center.to_array().map(|x| f16::from_f32(x)); + let center = center.to_array().map(f16::from_f32); let size = f16::from_f32(size); Self::new_f16(center, size, child_start, child_count) } @@ -200,7 +200,7 @@ fn set_lod_tree_data(state: &mut LodState, lod_id: u32, page_base: u32, _chunk_b while index < count { let chunk = (count - index).min(MAX_SPLAT_CHUNK as u32); let buffer = &mut state.buffer[0..(chunk * 4) as usize]; - lod_tree_data.subarray((index * 4) as u32, ((index + chunk) * 4) as u32).copy_to(buffer); + lod_tree_data.subarray(index * 4, (index + chunk) * 4).copy_to(buffer); for i in 0..chunk { let i4 = i * 4; @@ -264,8 +264,8 @@ pub fn init_lod_tree(num_splats: u32, lod_tree: Uint32Array) -> Result = (0..pages).map(|chunk| chunk as u32).collect(); + let page_to_chunk = (0..pages).collect(); + let chunk_to_page: Vec = (0..pages).collect(); state.lod_trees.insert(lod_id, LodTree { splats, page_to_chunk, chunk_to_page }); state.next_id += 1; @@ -546,8 +546,7 @@ pub fn traverse_lod_trees( output.push((inst_index, paged_index)); } - let mut instance_counts = Vec::new(); - instance_counts.resize(num_instances, 0); + let mut instance_counts = vec![0; num_instances]; for &(inst_index, _) in output.iter() { instance_counts[inst_index as usize] += 1; } @@ -568,7 +567,7 @@ pub fn traverse_lod_trees( let rows = instance_output.len().div_ceil(16384); let capacity = rows * 16384; let output = Uint32Array::new_with_length(capacity as u32); - output.subarray(0, instance_output.len() as u32).copy_from(&instance_output); + output.subarray(0, instance_output.len() as u32).copy_from(instance_output); let result = Object::new(); let lod_id = instances[inst_index].0; @@ -691,7 +690,7 @@ pub fn dynamic_traverse_lod_trees( outputs.push((instance_output, frontier)); let chunk_max = lod_chunk_max.entry(*lod_id).or_default(); - if 0 >= chunk_max.len() { + if chunk_max.is_empty() { chunk_max.resize(1, 0.0); } chunk_max[0] = f32::INFINITY; @@ -705,12 +704,12 @@ pub fn dynamic_traverse_lod_trees( let mut current_scale = pixel_scale_limit * 100.0; loop { - let iterator = instances.iter().zip(outputs).enumerate(); + let iterator = instances.iter().zip(outputs); outputs = Vec::with_capacity(num_instances); let mut output_count = 0; - for (_inst_index, (instance, (mut instance_output, mut stack))) in iterator { + for (instance, (mut instance_output, mut stack)) in iterator { let (lod_id, splats, _, chunk_to_page, ..) = instance; let chunk_max = lod_chunk_max.entry(*lod_id).or_default(); let mut frontier = Vec::with_capacity(stack.len()); diff --git a/rust/spark-rs/src/packed_splats.rs b/rust/spark-rs/src/packed_splats.rs index 68c368a1..36fef9f6 100644 --- a/rust/spark-rs/src/packed_splats.rs +++ b/rust/spark-rs/src/packed_splats.rs @@ -216,14 +216,10 @@ impl PackedSplatsData { let scales = splat.scales(); let quat = splat.quaternion().to_array(); - for d in 0..3 { - batch_center[i3 + d] = center[d]; - batch_rgb[i3 + d] = rgb[d]; - batch_scale[i3 + d] = scales[d]; - } - for d in 0..4 { - batch_quat[i4 + d] = quat[d]; - } + batch_center[i3..(i3 + 3)].copy_from_slice(¢er.to_array()); + batch_rgb[i3..(i3 + 3)].copy_from_slice(&rgb.to_array()); + batch_scale[i3..(i3 + 3)].copy_from_slice(&scales.to_array()); + batch_quat[i4..(i4 + 4)].copy_from_slice(&quat); batch_opacity[i] = splat.opacity(); @@ -260,9 +256,7 @@ impl PackedSplatsData { for i in 0..count { let i9 = i * 9; let values = splats.get_sh1(base + i); - for d in 0..9 { - batch[i9 + d] = values[d]; - } + batch[i9..(i9 + 9)].copy_from_slice(&values); } receiver.set_sh1(base, count, &batch); base += count; @@ -277,9 +271,7 @@ impl PackedSplatsData { for i in 0..count { let i15 = i * 15; let values = splats.get_sh2(base + i); - for d in 0..15 { - batch[i15 + d] = values[d]; - } + batch[i15..(i15 + 15)].copy_from_slice(&values); } receiver.set_sh2(base, count, &batch); base += count; @@ -294,9 +286,7 @@ impl PackedSplatsData { for i in 0..count { let i21 = i * 21; let values = splats.get_sh3(base + i); - for d in 0..21 { - batch[i21 + d] = values[d]; - } + batch[i21..(i21 + 21)].copy_from_slice(&values); } receiver.set_sh3(base, count, &batch); base += count; @@ -707,13 +697,11 @@ impl SplatReceiver for PackedSplatsData { let label = sh_labels[i] as usize; let i4 = i * 4; let l4 = label * 4; - for k in 0..4 { - buffer[i4 + k] = self.sh2_codes[l4 + k]; - } + buffer[i4..i4 + 4].copy_from_slice(&self.sh2_codes[l4..l4 + 4]); } packed_sh2.subarray((base * 4) as u32, ((base + count) * 4) as u32).copy_from(buffer); - + if self.max_sh_degree == 2 { return; } @@ -724,9 +712,7 @@ impl SplatReceiver for PackedSplatsData { let label = sh_labels[i] as usize; let i4 = i * 4; let l4 = label * 4; - for k in 0..4 { - buffer[i4 + k] = self.sh3_codes[l4 + k]; - } + buffer[i4..i4 + 4].copy_from_slice(&self.sh3_codes[l4..l4 + 4]); } packed_sh3.subarray((base * 4) as u32, ((base + count) * 4) as u32).copy_from(buffer); } @@ -739,9 +725,7 @@ impl SplatReceiver for PackedSplatsData { self.child_counts = Some(vec![0; self.num_splats]); } let counts = self.child_counts.as_mut().unwrap(); - for i in 0..count { - counts[base + i] = child_count[i]; - } + counts[base..base + count].copy_from_slice(&child_count[..count]); } fn set_child_start(&mut self, base: usize, count: usize, child_start: &[usize]) { @@ -771,9 +755,7 @@ impl SplatGetter for PackedSplatsData { let elements = &self.buffer[i4..i4 + 4]; if !out.center.is_empty() { let center = decode_packed_splat_center(elements); - for d in 0..3 { - out.center[i3 + d] = center[d]; - } + out.center[i3..i3 + 3].copy_from_slice(¢er); } if !out.opacity.is_empty() { let opacity = decode_packed_splat_opacity(elements, &self.encoding); @@ -781,21 +763,15 @@ impl SplatGetter for PackedSplatsData { } if !out.rgb.is_empty() { let rgb = decode_packed_splat_rgb(elements, &self.encoding); - for d in 0..3 { - out.rgb[i3 + d] = rgb[d]; - } + out.rgb[i3..i3 + 3].copy_from_slice(&rgb); } if !out.scale.is_empty() { let scale = decode_packed_splat_scale(elements, &self.encoding); - for d in 0..3 { - out.scale[i3 + d] = scale[d]; - } + out.scale[i3..i3 + 3].copy_from_slice(&scale); } if !out.quat.is_empty() { let quat = decode_packed_splat_quat(elements); - for d in 0..4 { - out.quat[i4 + d] = quat[d]; - } + out.quat[i4..i4 + 4].copy_from_slice(&quat); } } @@ -899,7 +875,7 @@ impl SplatGetter for PackedSplatsData { let [i2, i9] = [i * 2, i * 9]; let words = [self.buffer[i2], self.buffer[i2 + 1]]; let decoded = decode_sh1_internal_words(words, sh1_scale); - for k in 0..9 { out[i9 + k] = decoded[k]; } + out[i9..i9 + 9].copy_from_slice(&decoded); } } @@ -917,7 +893,7 @@ impl SplatGetter for PackedSplatsData { let [i4, i15] = [i * 4, i * 15]; let words = [self.buffer[i4], self.buffer[i4 + 1], self.buffer[i4 + 2], self.buffer[i4 + 3]]; let decoded = decode_sh2_internal_words(words, sh2_scale); - for k in 0..15 { out[i15 + k] = decoded[k]; } + out[i15..i15 + 15].copy_from_slice(&decoded); } } @@ -935,7 +911,7 @@ impl SplatGetter for PackedSplatsData { let [i4, i21] = [i * 4, i * 21]; let words = [self.buffer[i4], self.buffer[i4 + 1], self.buffer[i4 + 2], self.buffer[i4 + 3]]; let decoded = decode_sh3_internal_words(words, sh3_scale); - for k in 0..21 { out[i21 + k] = decoded[k]; } + out[i21..i21 + 21].copy_from_slice(&decoded); } }