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
30
src/lib.rs
30
src/lib.rs
|
|
@ -108,6 +108,24 @@ fn index_range(index: i32, count: i32, size: usize) -> impl Iterator<Item = usiz
|
||||||
.map(move |i| index as usize + i)
|
.map(move |i| index as usize + i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_relative_iter<'a, T: ReadRelative, I: 'a + Iterator<Item = usize>>(
|
||||||
|
data: &'a [u8],
|
||||||
|
indexes: I,
|
||||||
|
) -> impl Iterator<Item = Result<T, ModelError>> + 'a
|
||||||
|
where
|
||||||
|
<<T as ReadRelative>::Header as BinRead>::Args: Default,
|
||||||
|
{
|
||||||
|
indexes.map(|index| {
|
||||||
|
let data = data.get(index..).ok_or_else(|| ModelError::OutOfBounds {
|
||||||
|
data: type_name::<T>(),
|
||||||
|
offset: index,
|
||||||
|
})?;
|
||||||
|
let mut reader = Cursor::new(data);
|
||||||
|
let header = reader.read_le()?;
|
||||||
|
T::read(data, header)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn read_relative<T: ReadRelative, I: Iterator<Item = usize>>(
|
fn read_relative<T: ReadRelative, I: Iterator<Item = usize>>(
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
indexes: I,
|
indexes: I,
|
||||||
|
|
@ -115,17 +133,7 @@ fn read_relative<T: ReadRelative, I: Iterator<Item = usize>>(
|
||||||
where
|
where
|
||||||
<<T as ReadRelative>::Header as BinRead>::Args: Default,
|
<<T as ReadRelative>::Header as BinRead>::Args: Default,
|
||||||
{
|
{
|
||||||
indexes
|
read_relative_iter(data, indexes).collect()
|
||||||
.map(|index| {
|
|
||||||
let data = data.get(index..).ok_or_else(|| ModelError::OutOfBounds {
|
|
||||||
data: type_name::<T>(),
|
|
||||||
offset: index,
|
|
||||||
})?;
|
|
||||||
let mut reader = Cursor::new(data);
|
|
||||||
let header = reader.read_le()?;
|
|
||||||
T::read(data, header)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ReadRelative: Sized {
|
trait ReadRelative: Sized {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
mod raw;
|
mod raw;
|
||||||
|
|
||||||
use crate::vvd::raw::VvdHeader;
|
use crate::vvd::raw::{VertexFileFixup, VvdHeader};
|
||||||
use crate::ModelError;
|
use crate::{read_relative, read_relative_iter, ModelError};
|
||||||
use binrw::BinReaderExt;
|
use binrw::BinReaderExt;
|
||||||
pub use raw::{BoneWeight, Tangent, Vertex};
|
pub use raw::{BoneWeight, Tangent, Vertex};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
@ -18,20 +18,21 @@ impl Vvd {
|
||||||
pub fn read(data: &[u8]) -> Result<Self> {
|
pub fn read(data: &[u8]) -> Result<Self> {
|
||||||
let mut reader = Cursor::new(data);
|
let mut reader = Cursor::new(data);
|
||||||
let header: VvdHeader = reader.read_le()?;
|
let header: VvdHeader = reader.read_le()?;
|
||||||
Ok(Vvd {
|
let source_vertices = read_relative(data, header.vertex_indexes(0).unwrap())?;
|
||||||
vertices: header
|
let vertices = if !header.has_fixups() {
|
||||||
.vertex_indexes(0)
|
source_vertices
|
||||||
.unwrap()
|
} else {
|
||||||
.map(|index| {
|
let mut vertices = Vec::new();
|
||||||
let data = data.get(index..).ok_or_else(|| ModelError::OutOfBounds {
|
for fixup in read_relative_iter::<'_, VertexFileFixup, _>(data, header.fixup_indexes())
|
||||||
data: "Vertex",
|
{
|
||||||
offset: index,
|
let fixup = fixup?;
|
||||||
})?;
|
vertices.extend_from_slice(
|
||||||
let mut reader = Cursor::new(data);
|
&source_vertices[fixup.source_vertex_id as usize
|
||||||
Ok(reader.read_le()?)
|
..(fixup.source_vertex_id + fixup.vertex_count) as usize],
|
||||||
})
|
);
|
||||||
.collect::<Result<_>>()?,
|
}
|
||||||
header,
|
vertices
|
||||||
})
|
};
|
||||||
|
Ok(Vvd { vertices, header })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,11 @@ impl VvdHeader {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_fixups(&self) -> bool {
|
||||||
|
self.fixup_count > 0
|
||||||
|
}
|
||||||
|
|
||||||
pub fn vertex_indexes(&self, lod: i32) -> Option<impl Iterator<Item = usize>> {
|
pub fn vertex_indexes(&self, lod: i32) -> Option<impl Iterator<Item = usize>> {
|
||||||
if lod > 0 && lod > self.fixup_count {
|
|
||||||
todo!("lod fixup not supported")
|
|
||||||
}
|
|
||||||
if lod < self.lod_count {
|
if lod < self.lod_count {
|
||||||
Some(index_range(
|
Some(index_range(
|
||||||
self.vertex_index,
|
self.vertex_index,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue