mirror of
https://codeberg.org/icewind/vmdl.git
synced 2026-06-03 16:44:11 +02:00
tangents
This commit is contained in:
parent
9e2ca40d29
commit
922699a089
5 changed files with 60 additions and 6 deletions
|
|
@ -11,7 +11,7 @@ static_assertions = "1.1.0"
|
||||||
bitflags = "1.3.2"
|
bitflags = "1.3.2"
|
||||||
itertools = "0.12.0"
|
itertools = "0.12.0"
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
bytemuck = { version = "1.12.3", features = ["derive"] }
|
bytemuck = { version = "1.14.0", features = ["derive"] }
|
||||||
cgmath = "0.18.0"
|
cgmath = "0.18.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
@ -33,3 +33,6 @@ harness = false
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "iai"
|
name = "iai"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 2
|
||||||
|
|
@ -295,12 +295,14 @@ fn model_to_model(model: &Model, loader: &Loader, skin: usize) -> CpuModel {
|
||||||
y: vertex.texture_coordinates[1],
|
y: vertex.texture_coordinates[1],
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
let tangents: Vec<Vec4> = mesh.tangents().map(|tangent| tangent.into()).collect();
|
||||||
|
|
||||||
CpuMesh {
|
CpuMesh {
|
||||||
positions: Positions::F32(positions),
|
positions: Positions::F32(positions),
|
||||||
normals: Some(normals),
|
normals: Some(normals),
|
||||||
uvs: Some(uvs),
|
uvs: Some(uvs),
|
||||||
material_name: Some(texture.into()),
|
material_name: Some(texture.into()),
|
||||||
|
tangents: Some(tangents),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
16
src/lib.rs
16
src/lib.rs
|
|
@ -33,6 +33,10 @@ impl Model {
|
||||||
&self.vvd.vertices
|
&self.vvd.vertices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tangents(&self) -> &[[f32; 4]] {
|
||||||
|
&self.vvd.tangents
|
||||||
|
}
|
||||||
|
|
||||||
pub fn texture_directories(&self) -> &[String] {
|
pub fn texture_directories(&self) -> &[String] {
|
||||||
&self.mdl.texture_paths
|
&self.mdl.texture_paths
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +81,7 @@ impl Model {
|
||||||
.map(|((mdl, model_vertex_offset), vtx)| Mesh {
|
.map(|((mdl, model_vertex_offset), vtx)| Mesh {
|
||||||
model_vertex_offset,
|
model_vertex_offset,
|
||||||
vertices: self.vertices(),
|
vertices: self.vertices(),
|
||||||
|
tangents: self.tangents(),
|
||||||
mdl,
|
mdl,
|
||||||
vtx,
|
vtx,
|
||||||
})
|
})
|
||||||
|
|
@ -100,6 +105,7 @@ impl<'a> SkinTable<'a> {
|
||||||
pub struct Mesh<'a> {
|
pub struct Mesh<'a> {
|
||||||
model_vertex_offset: usize,
|
model_vertex_offset: usize,
|
||||||
vertices: &'a [Vertex],
|
vertices: &'a [Vertex],
|
||||||
|
tangents: &'a [[f32; 4]],
|
||||||
mdl: &'a mdl::Mesh,
|
mdl: &'a mdl::Mesh,
|
||||||
vtx: &'a vtx::Mesh,
|
vtx: &'a vtx::Mesh,
|
||||||
}
|
}
|
||||||
|
|
@ -128,6 +134,11 @@ impl<'a> Mesh<'a> {
|
||||||
self.vertex_strip_indices()
|
self.vertex_strip_indices()
|
||||||
.flat_map(|strip| strip.map(|index| &self.vertices[index]))
|
.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>(
|
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 i8 {}
|
||||||
impl ReadableRelative for i16 {}
|
impl ReadableRelative for i16 {}
|
||||||
impl ReadableRelative for i32 {}
|
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 {
|
impl<T: ReadableRelative> ReadRelative for T {
|
||||||
type Header = T;
|
type Header = T;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ type Result<T> = std::result::Result<T, ModelError>;
|
||||||
pub struct Vvd {
|
pub struct Vvd {
|
||||||
pub header: VvdHeader,
|
pub header: VvdHeader,
|
||||||
pub vertices: Vec<Vertex>,
|
pub vertices: Vec<Vertex>,
|
||||||
|
pub tangents: Vec<[f32; 4]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vvd {
|
impl Vvd {
|
||||||
|
|
@ -23,10 +24,18 @@ impl Vvd {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
let vertices = if !header.has_fixups() {
|
let source_tangents = read_relative(
|
||||||
source_vertices
|
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 {
|
} else {
|
||||||
let mut vertices = Vec::new();
|
let mut vertices = Vec::new();
|
||||||
|
let mut tangents = Vec::new();
|
||||||
for fixup in read_relative_iter::<'_, VertexFileFixup, _>(data, header.fixup_indexes())
|
for fixup in read_relative_iter::<'_, VertexFileFixup, _>(data, header.fixup_indexes())
|
||||||
{
|
{
|
||||||
let fixup = fixup?;
|
let fixup = fixup?;
|
||||||
|
|
@ -38,9 +47,22 @@ impl Vvd {
|
||||||
offset: to,
|
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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ pub struct VvdHeader {
|
||||||
fixup_count: i32,
|
fixup_count: i32,
|
||||||
fixup_index: i32,
|
fixup_index: i32,
|
||||||
vertex_index: i32,
|
vertex_index: i32,
|
||||||
#[allow(dead_code)]
|
|
||||||
tangent_index: i32,
|
tangent_index: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,6 +40,18 @@ impl VvdHeader {
|
||||||
None
|
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)]
|
#[derive(Debug, Clone, Zeroable, Pod, Copy)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue