Skip to content

Commit

Permalink
Use bytemuck for slice cast (#36)
Browse files Browse the repository at this point in the history
Use the `bytemuck` package for slice casting to byte, instead of rolling
some manual unsafe one.

Fixes #29
  • Loading branch information
djeedai committed May 11, 2024
1 parent 249b1ee commit a4dc348
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 18 deletions.
3 changes: 2 additions & 1 deletion bin/weldr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ serde_json = "1.0"
serde_repr = "0.1"
ordered-float = "2.0"
log = "0.4"
atty = "0.2"
atty = "0.2"
bytemuck = { version = "1", features = ["derive"] }
17 changes: 10 additions & 7 deletions bin/weldr/src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Action to convert an LDraw file to another format.

use crate::{
as_u8_slice,
error::{Error, Utf8Error},
gltf, Action, App, DiskResolver, GeometryCache,
};
Expand Down Expand Up @@ -252,8 +251,9 @@ impl ConvertCommand {
gltf: &mut gltf::Gltf,
buffer: &mut Vec<u8>,
) {
// TODO: glTF is LE only; should convert on BE platforms
let vertices = &geometry_cache.vertices;
let vertices_bytes: &[u8] = unsafe { as_u8_slice(vertices) };
let vertices_bytes: &[u8] = bytemuck::cast_slice(&vertices[..]);

// TODO: Line indices?
let vertex_buffer_view_index = gltf.buffer_views.len() as u32;
Expand Down Expand Up @@ -293,16 +293,19 @@ impl ConvertCommand {
let attributes = HashMap::from([("POSITION".to_string(), gltf.accessors.len() as u32)]);
gltf.accessors.push(vertex_accessor);

// TODO: Use bytemuck instead.
let triangle_indices = &geometry_cache.triangle_indices;
let triangle_indices_bytes: &[u8] = unsafe { as_u8_slice(triangle_indices) };
// TODO: glTF is LE only; should convert on BE platforms
let triangle_indices_bytes: &[u8] =
bytemuck::cast_slice(&geometry_cache.triangle_indices[..]);

let byte_offset = buffer.len() as u32;
let byte_length = triangle_indices_bytes.len() as u32;
let index_buffer_view_index = gltf.buffer_views.len() as u32;

gltf.buffer_views.push(gltf::BufferView {
name: Some("index_buffer".to_string()),
buffer_index: 0,
byte_length: triangle_indices_bytes.len() as u32,
byte_offset: buffer.len() as u32,
byte_length,
byte_offset,
byte_stride: None,
target: Some(gltf::BufferTarget::ElementArrayBuffer as u32),
});
Expand Down
10 changes: 1 addition & 9 deletions bin/weldr/src/weldr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,14 +337,6 @@ impl GeometryCache {
}
}

/// Transform a slice of something sized into a slice of u8, for binary writing.
unsafe fn as_u8_slice<T: Sized>(p: &[T]) -> &[u8] {
::std::slice::from_raw_parts(
p.as_ptr() as *const u8,
::std::mem::size_of::<T>() * p.len(),
)
}

#[cfg(not(target_os = "windows"))]
fn is_tty() -> bool {
atty::is(atty::Stream::Stderr)
Expand Down Expand Up @@ -400,7 +392,7 @@ mod tests {
fn test_as_u8_slice() {
assert_eq!(12, std::mem::size_of::<Vec3>());
let v = vec![Vec3::new(1.0, 2.0, 4.0), Vec3::new(1.0, 2.0, 4.0)];
let b: &[u8] = unsafe { as_u8_slice(&v[..]) };
let b: &[u8] = bytemuck::cast_slice(&v[..]);
assert_eq!(24, b.len());
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ path = "src/lib.rs"

[dependencies]
nom = "7.1.3"
glam = "0.23.0"
glam = { version = "0.23.0", features = ["bytemuck"] }
log = "0.4"
base64 = "0.21.0"

0 comments on commit a4dc348

Please sign in to comment.