mirror of
https://codeberg.org/icewind/vmdl.git
synced 2026-06-03 16:44:11 +02:00
implement lod fixups
This commit is contained in:
parent
3113c03fbd
commit
28d8f5dee5
3 changed files with 41 additions and 31 deletions
20
src/lib.rs
20
src/lib.rs
|
|
@ -108,15 +108,14 @@ fn index_range(index: i32, count: i32, size: usize) -> impl Iterator<Item = usiz
|
|||
.map(move |i| index as usize + i)
|
||||
}
|
||||
|
||||
fn read_relative<T: ReadRelative, I: Iterator<Item = usize>>(
|
||||
data: &[u8],
|
||||
fn read_relative_iter<'a, T: ReadRelative, I: 'a + Iterator<Item = usize>>(
|
||||
data: &'a [u8],
|
||||
indexes: I,
|
||||
) -> Result<Vec<T>, ModelError>
|
||||
) -> impl Iterator<Item = Result<T, ModelError>> + 'a
|
||||
where
|
||||
<<T as ReadRelative>::Header as BinRead>::Args: Default,
|
||||
{
|
||||
indexes
|
||||
.map(|index| {
|
||||
indexes.map(|index| {
|
||||
let data = data.get(index..).ok_or_else(|| ModelError::OutOfBounds {
|
||||
data: type_name::<T>(),
|
||||
offset: index,
|
||||
|
|
@ -125,7 +124,16 @@ where
|
|||
let header = reader.read_le()?;
|
||||
T::read(data, header)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn read_relative<T: ReadRelative, I: Iterator<Item = usize>>(
|
||||
data: &[u8],
|
||||
indexes: I,
|
||||
) -> Result<Vec<T>, ModelError>
|
||||
where
|
||||
<<T as ReadRelative>::Header as BinRead>::Args: Default,
|
||||
{
|
||||
read_relative_iter(data, indexes).collect()
|
||||
}
|
||||
|
||||
trait ReadRelative: Sized {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
mod raw;
|
||||
|
||||
use crate::vvd::raw::VvdHeader;
|
||||
use crate::ModelError;
|
||||
use crate::vvd::raw::{VertexFileFixup, VvdHeader};
|
||||
use crate::{read_relative, read_relative_iter, ModelError};
|
||||
use binrw::BinReaderExt;
|
||||
pub use raw::{BoneWeight, Tangent, Vertex};
|
||||
use std::io::Cursor;
|
||||
|
|
@ -18,20 +18,21 @@ impl Vvd {
|
|||
pub fn read(data: &[u8]) -> Result<Self> {
|
||||
let mut reader = Cursor::new(data);
|
||||
let header: VvdHeader = reader.read_le()?;
|
||||
Ok(Vvd {
|
||||
vertices: header
|
||||
.vertex_indexes(0)
|
||||
.unwrap()
|
||||
.map(|index| {
|
||||
let data = data.get(index..).ok_or_else(|| ModelError::OutOfBounds {
|
||||
data: "Vertex",
|
||||
offset: index,
|
||||
})?;
|
||||
let mut reader = Cursor::new(data);
|
||||
Ok(reader.read_le()?)
|
||||
})
|
||||
.collect::<Result<_>>()?,
|
||||
header,
|
||||
})
|
||||
let source_vertices = read_relative(data, header.vertex_indexes(0).unwrap())?;
|
||||
let vertices = if !header.has_fixups() {
|
||||
source_vertices
|
||||
} else {
|
||||
let mut vertices = Vec::new();
|
||||
for fixup in read_relative_iter::<'_, VertexFileFixup, _>(data, header.fixup_indexes())
|
||||
{
|
||||
let fixup = fixup?;
|
||||
vertices.extend_from_slice(
|
||||
&source_vertices[fixup.source_vertex_id as usize
|
||||
..(fixup.source_vertex_id + fixup.vertex_count) as usize],
|
||||
);
|
||||
}
|
||||
vertices
|
||||
};
|
||||
Ok(Vvd { vertices, header })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ impl VvdHeader {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn vertex_indexes(&self, lod: i32) -> Option<impl Iterator<Item = usize>> {
|
||||
if lod > 0 && lod > self.fixup_count {
|
||||
todo!("lod fixup not supported")
|
||||
pub fn has_fixups(&self) -> bool {
|
||||
self.fixup_count > 0
|
||||
}
|
||||
|
||||
pub fn vertex_indexes(&self, lod: i32) -> Option<impl Iterator<Item = usize>> {
|
||||
if lod < self.lod_count {
|
||||
Some(index_range(
|
||||
self.vertex_index,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue