This commit is contained in:
Robin Appelman 2023-12-12 18:34:50 +01:00
commit 922699a089
5 changed files with 60 additions and 6 deletions

View file

@ -33,6 +33,10 @@ impl Model {
&self.vvd.vertices
}
pub fn tangents(&self) -> &[[f32; 4]] {
&self.vvd.tangents
}
pub fn texture_directories(&self) -> &[String] {
&self.mdl.texture_paths
}
@ -77,6 +81,7 @@ impl Model {
.map(|((mdl, model_vertex_offset), vtx)| Mesh {
model_vertex_offset,
vertices: self.vertices(),
tangents: self.tangents(),
mdl,
vtx,
})
@ -100,6 +105,7 @@ impl<'a> SkinTable<'a> {
pub struct Mesh<'a> {
model_vertex_offset: usize,
vertices: &'a [Vertex],
tangents: &'a [[f32; 4]],
mdl: &'a mdl::Mesh,
vtx: &'a vtx::Mesh,
}
@ -128,6 +134,11 @@ impl<'a> Mesh<'a> {
self.vertex_strip_indices()
.flat_map(|strip| strip.map(|index| &self.vertices[index]))
}
pub fn tangents(&self) -> impl Iterator<Item = [f32; 4]> + '_ {
self.vertex_strip_indices()
.flat_map(|strip| strip.map(|index| self.tangents[index]))
}
}
fn read_indexes<I: Iterator<Item = usize> + 'static, T: Readable>(
@ -198,6 +209,11 @@ impl ReadableRelative for u32 {}
impl ReadableRelative for i8 {}
impl ReadableRelative for i16 {}
impl ReadableRelative for i32 {}
impl ReadableRelative for f32 {}
impl<T: ReadableRelative + Pod> ReadableRelative for [T; 1] {}
impl<T: ReadableRelative + Pod> ReadableRelative for [T; 2] {}
impl<T: ReadableRelative + Pod> ReadableRelative for [T; 3] {}
impl<T: ReadableRelative + Pod> ReadableRelative for [T; 4] {}
impl<T: ReadableRelative> ReadRelative for T {
type Header = T;

View file

@ -11,6 +11,7 @@ type Result<T> = std::result::Result<T, ModelError>;
pub struct Vvd {
pub header: VvdHeader,
pub vertices: Vec<Vertex>,
pub tangents: Vec<[f32; 4]>,
}
impl Vvd {
@ -23,10 +24,18 @@ impl Vvd {
offset: 0,
})?,
)?;
let vertices = if !header.has_fixups() {
source_vertices
let source_tangents = read_relative(
data,
header.tangent_indexes(0).ok_or(ModelError::OutOfBounds {
data: "model_lod",
offset: 0,
})?,
)?;
let (tangents, vertices) = if !header.has_fixups() {
(source_tangents, source_vertices)
} else {
let mut vertices = Vec::new();
let mut tangents = Vec::new();
for fixup in read_relative_iter::<'_, VertexFileFixup, _>(data, header.fixup_indexes())
{
let fixup = fixup?;
@ -38,9 +47,22 @@ impl Vvd {
offset: to,
}
})?);
tangents.extend_from_slice(source_tangents.get(from..to).ok_or({
ModelError::OutOfBounds {
data: "source_tangents",
offset: to,
}
})?);
}
vertices
(tangents, vertices)
};
Ok(Vvd { vertices, header })
debug_assert!(tangents.len() == vertices.len());
Ok(Vvd {
vertices,
header,
tangents,
})
}
}

View file

@ -13,7 +13,6 @@ pub struct VvdHeader {
fixup_count: i32,
fixup_index: i32,
vertex_index: i32,
#[allow(dead_code)]
tangent_index: i32,
}
@ -41,6 +40,18 @@ impl VvdHeader {
None
}
}
pub fn tangent_indexes(&self, lod: i32) -> Option<impl Iterator<Item = usize>> {
if lod < self.lod_count {
Some(index_range(
self.tangent_index,
self.lod_vertex_count[lod as usize],
size_of::<[f32; 4]>(),
))
} else {
None
}
}
}
#[derive(Debug, Clone, Zeroable, Pod, Copy)]