♻️ Moving more of the old API atop ZC

master
_ 2020-05-25 23:01:30 +00:00
parent f86fdc0c4f
commit 2714518770
2 changed files with 104 additions and 76 deletions

View File

@ -12,6 +12,7 @@ pub mod zero_copy;
pub use crate::names::consts;
pub use crate::names::types;
pub use zero_copy::Error;
use zero_copy::usize_from;
#[derive (Debug, Default)]
pub struct Mesh {
@ -38,8 +39,8 @@ pub struct VertexArray {
}
#[derive (Debug)]
pub struct Model <'a> {
data: &'a [u8],
pub struct Model <'data> {
zc: zero_copy::Model <'data>,
pub header: Header,
text: Vec <u8>,
@ -60,23 +61,17 @@ impl Header {
}
impl Mesh {
pub fn from_slice (input: &[u8]) -> Result <Mesh, Error> {
let mut mesh = Mesh::default ();
pub fn from_zc (zc: &zero_copy::Mesh) -> Mesh {
use crate::names::consts::*;
let mut rdr = Cursor::new (input);
for field in [
&mut mesh.name,
&mut mesh.material,
&mut mesh.first_vertex,
&mut mesh.num_vertexes,
&mut mesh.first_triangle,
&mut mesh.num_triangles,
].iter_mut () {
**field = rdr.read_u32::<LittleEndian> ().map_err (|_| Error::ParseMeshFailed)?;
Mesh {
name: zc.field (MESH_NAME),
material: zc.field (MESH_MATERIAL),
first_vertex: zc.field (MESH_FIRST_VERTEX),
num_vertexes: zc.field (MESH_NUM_VERTEXES),
first_triangle: zc.field (MESH_FIRST_TRIANGLE),
num_triangles: zc.field (MESH_NUM_TRIANGLES),
}
Ok (mesh)
}
}
@ -98,6 +93,18 @@ impl VertexArray {
Ok (va)
}
pub fn from_zc (zc: &zero_copy::VertexArray) -> VertexArray {
use crate::names::consts::*;
VertexArray {
va_type: zc.field (VA_TYPE),
va_flags: zc.field (VA_FLAGS),
va_format: zc.field (VA_FORMAT),
va_size: zc.field (VA_SIZE),
va_offset: zc.field (VA_OFFSET),
}
}
}
impl <'a> Model <'a> {
@ -107,48 +114,21 @@ impl <'a> Model <'a> {
let header = Header::from_zc (&zc);
let text = {
let offset: usize = header.fields [consts::OFS_TEXT].try_into ().unwrap ();
let num: usize = header.fields [consts::NUM_TEXT].try_into ().unwrap ();
let offset = usize_from (zc.header_field (consts::OFS_TEXT));
let num = usize_from (zc.header_field (consts::NUM_TEXT));
Vec::from (&data [offset..offset + num])
};
let meshes = {
let num: usize = header.fields [consts::NUM_MESHES].try_into ().unwrap ();
let mut meshes = Vec::with_capacity (num);
let mesh_size = 6 * 4;
let meshes_offset: usize = header.fields [consts::OFS_MESHES].try_into ().unwrap ();
let meshes = zc.meshes ().map (|zc_mesh| {
Mesh::from_zc (&zc_mesh)
}).collect ();
for i in 0..num {
let offset = meshes_offset + i * mesh_size;
let mesh_slice = &data [offset..offset + mesh_size];
let mesh = Mesh::from_slice (mesh_slice)?;
meshes.push (mesh);
}
meshes
};
let vertexarrays = {
let num: usize = header.fields [consts::NUM_VERTEXARRAYS].try_into ().unwrap ();
let mut vertexarrays = Vec::with_capacity (num);
let vertexarray_size = 5 * 4;
let vertexarrays_offset: usize = header.fields [consts::OFS_VERTEXARRAYS].try_into ().unwrap ();
for i in 0..num {
let offset = vertexarrays_offset + i * vertexarray_size;
let vertexarray_slice = &data [offset..offset + vertexarray_size];
let vertexarray = VertexArray::from_slice (vertexarray_slice)?;
vertexarrays.push (vertexarray);
}
vertexarrays
};
let vertexarrays = zc.vertexarrays ().map (|zc_va| {
VertexArray::from_zc (&zc_va)
}).collect ();
Ok (Model {
data,
zc,
header,
text,
@ -157,19 +137,8 @@ impl <'a> Model <'a> {
})
}
pub fn get_vertex_slice (&self,
vertexarray_index: usize
) -> &[u8]
{
let vertexarray = &self.vertexarrays [vertexarray_index];
let bytes_per_float = 4;
let stride = bytes_per_float * vertexarray.va_size;
//assert_eq! (stride, 12);
let offset: usize = (vertexarray.va_offset).try_into ().unwrap ();
let num_bytes: usize = (stride * self.header.fields [consts::NUM_VERTEXES]).try_into ().unwrap ();
&self.data [offset..offset + num_bytes]
pub fn get_vertex_slice (&self, idx: usize) -> &[u8] {
self.zc.vertexarray (idx).get_vertex_slice ()
}
pub fn get_index_slice (&self, mesh_index: usize) -> &[u8] {
@ -182,7 +151,7 @@ impl <'a> Model <'a> {
let num_bytes: usize = (stride * mesh.num_triangles).try_into ().unwrap ();
&self.data [offset..offset + num_bytes]
&self.zc.data [offset..offset + num_bytes]
}
pub fn get_all_indexes (&self) -> &[u8] {
@ -194,7 +163,7 @@ impl <'a> Model <'a> {
let num_bytes: usize = (stride * self.header.fields [consts::NUM_TRIANGLES]).try_into ().unwrap ();
&self.data [offset..offset + num_bytes]
&self.zc.data [offset..offset + num_bytes]
}
// I don't think IQM makes any guarantees about UTF-8
@ -207,7 +176,7 @@ impl <'a> Model <'a> {
// There should be an easy way to do this with CString?
let mut nul_index = None;
for (j, c) in self.data [ofs..].iter ().enumerate () {
for (j, c) in self.zc.data [ofs..].iter ().enumerate () {
if *c == 0 {
nul_index = Some (j);
break;
@ -215,7 +184,51 @@ impl <'a> Model <'a> {
}
let nul_index = nul_index.unwrap ();
&self.data [ofs..ofs + nul_index]
&self.zc.data [ofs..ofs + nul_index]
}
}
#[cfg (test)]
mod borrow_test {
struct Model <'data> {
data: &'data [u8],
}
struct VertexArray <'model: 'data, 'data> {
model: &'model Model <'data>,
}
impl <'data> Model <'data> {
pub fn va (&self) -> VertexArray {
VertexArray {
model: self,
}
}
pub fn slice (&'data self) -> &'data [u8] {
let va = self.va ();
va.slice ()
}
}
impl <'model: 'data, 'data> VertexArray <'model, 'data> {
pub fn slice (&self) -> &'data [u8] {
self.model.data
}
}
#[test]
fn nothing () {
let data = [1, 1, 2, 3, 5, 8];
let model = Model {
data: &data,
};
let va = model.va ();
let slice = model.va ().slice ();
let slice = model.slice ();
}
}

View File

@ -3,12 +3,13 @@ use std::mem::size_of;
use byteorder::{ByteOrder, LittleEndian};
#[derive (Debug)]
pub struct Model <'data> {
pub data: &'data [u8],
}
pub struct VertexArray <'data> {
pub model: &'data Model <'data>,
pub struct VertexArray <'model: 'data, 'data> {
pub model: &'model Model <'data>,
ofs: usize,
}
@ -50,7 +51,7 @@ pub const HEADER_FIELD_COUNT: usize = 27;
// If you are using IQM models on an 8-bit or 16-bit microcontroller
// you're smarter than me anyway
fn usize_from (x: u32) -> usize {
pub fn usize_from (x: u32) -> usize {
usize::try_from (x).unwrap ()
}
@ -67,10 +68,15 @@ impl <'data> Iterator for HeaderFields <'data> {
self.idx += 1;
Some (result)
}
fn size_hint (&self) -> (usize, Option <usize>) {
let x = HEADER_FIELD_COUNT - self.idx;
(x, Some (x))
}
}
impl <'data> Iterator for VertexArrays <'data> {
type Item = VertexArray <'data>;
type Item = VertexArray <'data, 'data>;
fn next (&mut self) -> Option <Self::Item> {
if self.idx >= usize_from (self.model.header_field (crate::names::consts::NUM_VERTEXARRAYS)) {
@ -82,6 +88,11 @@ impl <'data> Iterator for VertexArrays <'data> {
self.idx += 1;
Some (result)
}
fn size_hint (&self) -> (usize, Option <usize>) {
let x = usize_from (self.model.header_field (crate::names::consts::NUM_VERTEXARRAYS)) - self.idx;
(x, Some (x))
}
}
impl <'data> Iterator for Meshes <'data> {
@ -97,6 +108,10 @@ impl <'data> Iterator for Meshes <'data> {
self.idx += 1;
Some (result)
}
fn size_hint (&self) -> (usize, Option <usize>) {
let x = usize_from (self.model.header_field (crate::names::consts::NUM_MESHES)) - self.idx;
(x, Some (x))
}
}
impl <'data> Model <'data> {
@ -170,12 +185,12 @@ impl <'data> Model <'data> {
}
}
impl <'data> VertexArray <'data> {
impl <'model: 'data, 'data> VertexArray <'model, 'data> {
pub fn field (&self, idx: usize) -> u32 {
LittleEndian::read_u32 (&self.model.data [self.ofs + idx * size_of::<u32>()..])
}
pub fn get_vertex_slice (&self) -> &[u8] {
pub fn get_vertex_slice (&self) -> &'data [u8] {
use names::consts::*;
let stride = size_of::<f32> () * usize_from (self.field (VA_SIZE));