cgmath icon indicating copy to clipboard operation
cgmath copied to clipboard

cast to lower-level buffer ref

Open jimy-byerley opened this issue 5 years ago • 10 comments

Would it be possible to add a trait to downcast &[Vector<T>] to &[[T; N]] and &[T] ? I work with buffers of vectors, and I need to pass them to other libraries, that are using &[T] for compatibility. For now I only copy it element by element, but I think that copy could be avoided with a simple reference cast.

For example, something like that

impl Into<&[T]> for &[Vector3<T>] {
    fn into(self) -> &[T] {
         unsafe { std::slice::from_raw_parts(self.as_ptr() as *const [T], self.len() * 3) }
    }
}

and maybe also the inverse

impl Into<&[Vector<T>]> for &[T] {
    fn into(self) -> &[Vector<T>] {
         assert_eq!(self.len() % 3, 0);
         unsafe { std::slice::from_raw_parts(self.as_ptr() as *const [Vector3<T>], self.len() / 3) }
    }
}

I think it's possible because the Vector struct is marked repr(C) and its fields are all of the same type (so there is no alignment concerns). Plus all slices are contiguous data storages This kind of cast would get it much more simple to get from a buffer type to an other. (slices, vec, ndarray, with grouped components or not).

jimy-byerley avatar Nov 20 '19 20:11 jimy-byerley

These methods are already there, see https://docs.rs/cgmath/0.17.0/cgmath/struct.Vector4.html#impl-AsRef%3C%5BS%3B%204%5D%3E

kvark avatar Dec 12 '19 17:12 kvark

Yes, to cast cgmath::Vector to slice, but what about std::Vec<cgmath::Vector> to slice ? for arrays of cgmath vectors (I think to opengl vector buffers for example).

jimy-byerley avatar Dec 16 '19 14:12 jimy-byerley

I think solving this is out of scope for cgmath. The desire to reinterpret elements of collections is common (https://github.com/rust-lang/rfcs/pull/2756) but, as you can see from the pr, there are quite some things to consider.

That being said, I would not be surprised if there are crates out there that provide these conversions and traits which cgmath could implement. If you find any of those we could look at it.

mickvangelderen avatar Feb 15 '20 13:02 mickvangelderen

The Pod trait from bytemuck crate does this. It's quite handy for reinterpreting data for buffers, so it would be great if cgmath could support it.

vjackson725 avatar Dec 22 '20 11:12 vjackson725

@vjackson725 so you are suggesting bytemuck as an optional dependency? I suppose it could be seen similarly to how cgmath optionally supports mint. Both mint and bytemuck are ways to interop data.

kvark avatar Dec 22 '20 14:12 kvark

Did the optional bytemuck support ever land to cgmath? I have tricky situation where my struct is used in many places and is defined as such :

#[derive(Clone)]
pub struct Triangle {
    pub vertices: [Vector3<Real>; 3],
    pub normal: [Vector3<Real>; 3],
    pub uv: [Vector2<Real>; 3],
}

If I try to add the typical bytemuck derive options here (Pod and Zeroable) that would allow me to cast Vec<Triangle> types to &[u8], I get an error that Pod and Zeroable are not implemented for Vector3<f64>.

kaphula avatar Jul 24 '22 19:07 kaphula

Yes, cgmath now uses bytemuck optionally. Enable the feature "bytemuck" to use it. This looks to have been added in #541.

vjackson725 avatar Aug 13 '22 12:08 vjackson725

I'm looking to use this feature, but the referenced PR doesn't actually add bytemuck as an available feature in cargo.toml?

matt328 avatar Dec 15 '23 00:12 matt328

@matt328 Me too.

freddycansic avatar Dec 29 '23 18:12 freddycansic

It's not part of an official release yet. You'll need to pull from the master branch. For example:

cargo add cgmath --git https://github.com/rustgd/cgmath.git --features bytemuck

redmcg avatar Jan 15 '24 03:01 redmcg