Skip to content

Commit

Permalink
Add methods and types for reading from MeshBuilder
Browse files Browse the repository at this point in the history
MeshBuilder is a convenient way of storing mesh data on the CPU, since it supports a
wide variety of formats due to using arbitrary vertex attributes. However it does
not have any way to read the data stored inside of it.

This patch adds functionality for reading the mesh stored inside of the buffers:

* `MeshBuilder::view_attr` finds an attribute in the stored buffers by name and returns a view
  into the buffer that reads that attribute. It can also be iterated over.
* `MeshBuffer::iter_index` iterates over elements in the index buffer, or from 0..numvertices if there
  is no index buffer.
* Various getters for `MeshBuffer` and `RawVertexBuffer`
* `FromVertexBuffer` defines how to read a type from a vertex buffer and convert it from the vertex
  format its in (ex. normalizing and scaling integer values into floating-point).
  • Loading branch information
ColonelThirtyTwo committed Dec 22, 2019
1 parent cae226f commit c8eacf9
Show file tree
Hide file tree
Showing 4 changed files with 1,188 additions and 10 deletions.
34 changes: 33 additions & 1 deletion core/src/casts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Contains functions for casting
use std::{any::TypeId, borrow::Cow};
use std::{any::TypeId, borrow::Cow, mem, slice};

/// Cast vec of some arbitrary type into vec of bytes.
/// Can lead to UB if allocator changes. Use with caution.
Expand Down Expand Up @@ -59,3 +59,35 @@ pub fn identical_cast<T: 'static, U: 'static>(value: T) -> U {
std::ptr::read(ptr as *mut U)
}
}

/// Tries to cast a slice from one type to another.
///
/// Can fail and return `None` if the from slice is not sized or aligned correctly.
///
/// Safety
/// ======
///
/// Must be able to interpret `To` from the bytes in `From` safely (you could, for example, create invalid references).
pub unsafe fn cast_any_slice<From: 'static + Copy, To: 'static + Copy>(
from: &[From],
) -> Option<&[To]> {
let from_size = mem::size_of::<From>();
let from_ptr = from.as_ptr();
let from_len = from.len();
let to_size = mem::size_of::<To>();
let to_align = mem::align_of::<To>();
if from_size == 0 || to_size == 0 {
// can't cast zero-sized types
return None;
}
if (from_len * from_size) % to_size != 0 {
// invalid size
return None;
}
if from_ptr.align_offset(to_align) != 0 {
// unaligned pointer
return None;
}
let to_len = (from_len * from_size) / to_size;
Some(slice::from_raw_parts(from_ptr as *const To, to_len))
}
3 changes: 2 additions & 1 deletion mesh/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use rendy_resource as resource;

mod format;
mod mesh;
mod read;

pub use crate::{format::*, mesh::*};
pub use crate::{format::*, mesh::*, read::*};
pub use rendy_core::types::vertex::*;
Loading

0 comments on commit c8eacf9

Please sign in to comment.