♻️ Moving more of the old API atop ZC
parent
f86fdc0c4f
commit
2714518770
153
src/lib.rs
153
src/lib.rs
|
@ -12,6 +12,7 @@ pub mod zero_copy;
|
||||||
pub use crate::names::consts;
|
pub use crate::names::consts;
|
||||||
pub use crate::names::types;
|
pub use crate::names::types;
|
||||||
pub use zero_copy::Error;
|
pub use zero_copy::Error;
|
||||||
|
use zero_copy::usize_from;
|
||||||
|
|
||||||
#[derive (Debug, Default)]
|
#[derive (Debug, Default)]
|
||||||
pub struct Mesh {
|
pub struct Mesh {
|
||||||
|
@ -38,8 +39,8 @@ pub struct VertexArray {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive (Debug)]
|
#[derive (Debug)]
|
||||||
pub struct Model <'a> {
|
pub struct Model <'data> {
|
||||||
data: &'a [u8],
|
zc: zero_copy::Model <'data>,
|
||||||
|
|
||||||
pub header: Header,
|
pub header: Header,
|
||||||
text: Vec <u8>,
|
text: Vec <u8>,
|
||||||
|
@ -60,23 +61,17 @@ impl Header {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mesh {
|
impl Mesh {
|
||||||
pub fn from_slice (input: &[u8]) -> Result <Mesh, Error> {
|
pub fn from_zc (zc: &zero_copy::Mesh) -> Mesh {
|
||||||
let mut mesh = Mesh::default ();
|
use crate::names::consts::*;
|
||||||
|
|
||||||
let mut rdr = Cursor::new (input);
|
Mesh {
|
||||||
|
name: zc.field (MESH_NAME),
|
||||||
for field in [
|
material: zc.field (MESH_MATERIAL),
|
||||||
&mut mesh.name,
|
first_vertex: zc.field (MESH_FIRST_VERTEX),
|
||||||
&mut mesh.material,
|
num_vertexes: zc.field (MESH_NUM_VERTEXES),
|
||||||
&mut mesh.first_vertex,
|
first_triangle: zc.field (MESH_FIRST_TRIANGLE),
|
||||||
&mut mesh.num_vertexes,
|
num_triangles: zc.field (MESH_NUM_TRIANGLES),
|
||||||
&mut mesh.first_triangle,
|
|
||||||
&mut mesh.num_triangles,
|
|
||||||
].iter_mut () {
|
|
||||||
**field = rdr.read_u32::<LittleEndian> ().map_err (|_| Error::ParseMeshFailed)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok (mesh)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +93,18 @@ impl VertexArray {
|
||||||
|
|
||||||
Ok (va)
|
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> {
|
impl <'a> Model <'a> {
|
||||||
|
@ -107,48 +114,21 @@ impl <'a> Model <'a> {
|
||||||
let header = Header::from_zc (&zc);
|
let header = Header::from_zc (&zc);
|
||||||
|
|
||||||
let text = {
|
let text = {
|
||||||
let offset: usize = header.fields [consts::OFS_TEXT].try_into ().unwrap ();
|
let offset = usize_from (zc.header_field (consts::OFS_TEXT));
|
||||||
let num: usize = header.fields [consts::NUM_TEXT].try_into ().unwrap ();
|
let num = usize_from (zc.header_field (consts::NUM_TEXT));
|
||||||
Vec::from (&data [offset..offset + num])
|
Vec::from (&data [offset..offset + num])
|
||||||
};
|
};
|
||||||
|
|
||||||
let meshes = {
|
let meshes = zc.meshes ().map (|zc_mesh| {
|
||||||
let num: usize = header.fields [consts::NUM_MESHES].try_into ().unwrap ();
|
Mesh::from_zc (&zc_mesh)
|
||||||
let mut meshes = Vec::with_capacity (num);
|
}).collect ();
|
||||||
let mesh_size = 6 * 4;
|
|
||||||
let meshes_offset: usize = header.fields [consts::OFS_MESHES].try_into ().unwrap ();
|
|
||||||
|
|
||||||
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 vertexarrays = zc.vertexarrays ().map (|zc_va| {
|
||||||
let num: usize = header.fields [consts::NUM_VERTEXARRAYS].try_into ().unwrap ();
|
VertexArray::from_zc (&zc_va)
|
||||||
let mut vertexarrays = Vec::with_capacity (num);
|
}).collect ();
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok (Model {
|
Ok (Model {
|
||||||
data,
|
zc,
|
||||||
|
|
||||||
header,
|
header,
|
||||||
text,
|
text,
|
||||||
|
@ -157,19 +137,8 @@ impl <'a> Model <'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_vertex_slice (&self,
|
pub fn get_vertex_slice (&self, idx: usize) -> &[u8] {
|
||||||
vertexarray_index: usize
|
self.zc.vertexarray (idx).get_vertex_slice ()
|
||||||
) -> &[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_index_slice (&self, mesh_index: usize) -> &[u8] {
|
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 ();
|
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] {
|
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 ();
|
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
|
// 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?
|
// There should be an easy way to do this with CString?
|
||||||
let mut nul_index = None;
|
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 {
|
if *c == 0 {
|
||||||
nul_index = Some (j);
|
nul_index = Some (j);
|
||||||
break;
|
break;
|
||||||
|
@ -215,7 +184,51 @@ impl <'a> Model <'a> {
|
||||||
}
|
}
|
||||||
let nul_index = nul_index.unwrap ();
|
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 ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,13 @@ use std::mem::size_of;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
|
|
||||||
|
#[derive (Debug)]
|
||||||
pub struct Model <'data> {
|
pub struct Model <'data> {
|
||||||
pub data: &'data [u8],
|
pub data: &'data [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VertexArray <'data> {
|
pub struct VertexArray <'model: 'data, 'data> {
|
||||||
pub model: &'data Model <'data>,
|
pub model: &'model Model <'data>,
|
||||||
ofs: usize,
|
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
|
// If you are using IQM models on an 8-bit or 16-bit microcontroller
|
||||||
// you're smarter than me anyway
|
// you're smarter than me anyway
|
||||||
|
|
||||||
fn usize_from (x: u32) -> usize {
|
pub fn usize_from (x: u32) -> usize {
|
||||||
usize::try_from (x).unwrap ()
|
usize::try_from (x).unwrap ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,10 +68,15 @@ impl <'data> Iterator for HeaderFields <'data> {
|
||||||
self.idx += 1;
|
self.idx += 1;
|
||||||
Some (result)
|
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> {
|
impl <'data> Iterator for VertexArrays <'data> {
|
||||||
type Item = VertexArray <'data>;
|
type Item = VertexArray <'data, 'data>;
|
||||||
|
|
||||||
fn next (&mut self) -> Option <Self::Item> {
|
fn next (&mut self) -> Option <Self::Item> {
|
||||||
if self.idx >= usize_from (self.model.header_field (crate::names::consts::NUM_VERTEXARRAYS)) {
|
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;
|
self.idx += 1;
|
||||||
Some (result)
|
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> {
|
impl <'data> Iterator for Meshes <'data> {
|
||||||
|
@ -97,6 +108,10 @@ impl <'data> Iterator for Meshes <'data> {
|
||||||
self.idx += 1;
|
self.idx += 1;
|
||||||
Some (result)
|
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> {
|
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 {
|
pub fn field (&self, idx: usize) -> u32 {
|
||||||
LittleEndian::read_u32 (&self.model.data [self.ofs + idx * size_of::<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::*;
|
use names::consts::*;
|
||||||
|
|
||||||
let stride = size_of::<f32> () * usize_from (self.field (VA_SIZE));
|
let stride = size_of::<f32> () * usize_from (self.field (VA_SIZE));
|
||||||
|
|
Loading…
Reference in New Issue