rust 如何转换矢量Vec〈[f32< f32>;3]>-给定格式为Float 32,但应为Float 32 x3

7uhlpewt  于 2023-03-18  发布在  其他
关注(0)|答案(2)|浏览(151)

在bevy(0.10)中,我发现了transvoxel模块,在它当前的状态下,* 因为一些依赖性问题而不允许bevy_mesh特性被启用;因此我手动将其输出转换为bevy::Mesh
这需要的任务之一是将Vec转换为Vec〈[f32;3]〉,这样每个(xyz)坐标都在一个地方。
由于我是新的 rust ,我想知道是否有最佳实践来实现这一点。
到目前为止,我尝试了以下方法:

let mut pos2: Vec<[f32; 3]> = Vec::new(); // A vector to contain VertexFormat::Float32x3
let i = 0; 
extracted_mesh.positions.into_iter().map(|u|{
    if i % 3 == 0 {
        pos2.push([0.,0.,0.]);
}
    if let Some(pos3) = pos2.last_mut() {pos3[i % 3] = u};
});

我会说这真的很难看,但似乎做的工作。我感兴趣的是,如果有一个map(...).collect()的方式来做到这一点,因为这本身产生了一个警告:

warning: src/meshgen.rs:28: unused `std::iter::Map` that must be used
note: src/meshgen.rs:28: iterators are lazy and do nothing unless consumed
  • 截至2023年3月
ux6nzvsh

ux6nzvsh1#

如果positions是一个Vec或类似的东西,那么就有slice::chunksslice::chunks_exact,尽管它们会产生切片,所以需要将它们try_into到固定大小的数组中:

v.chunks(3).map(|c| <[_;3]>::try_from(c).unwrap()).collect::<Vec<_>>()

如果你能改变它,itertools有更好的Itertools::tuples,它可以将元素收集到你想要的大小的元组中,你只需要将它们移到一个数组中,而不会看到任何恐慌:

v.into_iter().tuples().map(|(a, b, c)| [a, b, c]).collect::<Vec<_>>()
uxhixvfz

uxhixvfz2#

如果要转换的矢量很大,并且必须避免复制数据,则可以通过转换矢量来实现:

use std::mem::ManuallyDrop;
pub fn to_arrays<const N: usize, T>(mut v: Vec<T>) -> Vec<[T; N]> {
    assert_eq!(v.len() % N, 0, "length not divisible by {N}");
    if v.capacity() % N != 0 {
        v.shrink_to_fit();
        assert_eq!(v.capacity() % N, 0, "capacity not divisible by {N} and we could not shrink to make it so");
    }
    let mut v = ManuallyDrop::new(v);
    let (ptr, len, cap) = (v.as_mut_ptr(), v.len(), v.capacity());
    // SAFETY:
    // * Global allocator is given `Vec<T> == Vec<T, Global>`
    // * an array has the same alingment as it's items
    // * len / N arrays of [T; N] have been initialized because len items have been initialized before
    // * capacity is divisible by N so the allocation is the same sisze
    unsafe { Vec::from_raw_parts(ptr.cast(), len / N, cap / N) }
}

相关问题