skin mapping wip

This commit is contained in:
Robin Appelman 2023-12-10 01:18:55 +01:00
commit ca8c16dca1
5 changed files with 36 additions and 11 deletions

View file

@ -24,7 +24,7 @@ fn main() -> Result<(), vmdl::ModelError> {
.flat_map(|model| model.meshes.iter()) .flat_map(|model| model.meshes.iter())
.map(|mesh| mesh.material) .map(|mesh| mesh.material)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
dbg!(mdl.textures, models, mdl.texture_paths); dbg!(mdl.textures, models, mdl.skin_table);
// let model = Model::from_parts(mdl, vtx, vvd); // let model = Model::from_parts(mdl, vtx, vvd);
// for strip in model.vertex_strips() { // for strip in model.vertex_strips() {

View file

@ -276,10 +276,14 @@ fn model_to_model(model: &Model, loader: &Loader) -> CpuModel {
let uvs: Vec<Vec2> = model let uvs: Vec<Vec2> = model
.vertices() .vertices()
.iter() .iter()
.map(|vertex| vertex.texture_coordinates.into()) .map(|vertex| Vec2 {
x: vertex.texture_coordinates[0],
y: vertex.texture_coordinates[1],
})
.collect(); .collect();
let texture_names = model.textures(); let texture_names = model.textures();
let skin = dbg!(&model.skin_tables()[1]);
let geometries = model let geometries = model
.meshes() .meshes()
@ -289,18 +293,17 @@ fn model_to_model(model: &Model, loader: &Loader) -> CpuModel {
.flat_map(|strip| strip.map(|index| index as u32)) .flat_map(|strip| strip.map(|index| index as u32))
.collect(), .collect(),
); );
let texture_index = skin[mesh.material_index() as usize] as usize;
CpuMesh { CpuMesh {
positions: Positions::F32(positions.clone()), positions: Positions::F32(positions.clone()),
normals: Some(normals.clone()), normals: Some(normals.clone()),
uvs: Some(uvs.clone()), uvs: Some(uvs.clone()),
material_name: Some( material_name: Some(dbg!(texture_names
texture_names .get(texture_index)
.get(mesh.material_index() as usize)
.expect("texture out of bounds") .expect("texture out of bounds")
.name .name
.clone(), .clone())),
),
indices, indices,
..Default::default() ..Default::default()
} }

View file

@ -46,6 +46,10 @@ impl Model {
&self.mdl.textures &self.mdl.textures
} }
pub fn skin_tables(&self) -> &[Vec<u16>] {
&self.mdl.skin_table
}
pub fn meshes(&self) -> impl Iterator<Item = Mesh> { pub fn meshes(&self) -> impl Iterator<Item = Mesh> {
let mdl_meshes = self let mdl_meshes = self
.mdl .mdl

View file

@ -20,6 +20,7 @@ pub struct Mdl {
pub body_parts: Vec<BodyPart>, pub body_parts: Vec<BodyPart>,
pub textures: Vec<TextureInfo>, pub textures: Vec<TextureInfo>,
pub texture_paths: Vec<String>, pub texture_paths: Vec<String>,
pub skin_table: Vec<Vec<u16>>,
} }
impl Mdl { impl Mdl {
@ -36,6 +37,14 @@ impl Mdl {
.map(|path| path.map(|path| path.replace('\\', "/"))) .map(|path| path.map(|path| path.replace('\\', "/")))
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
let raw_skin_table = read_relative::<u16, _>(data, header.skin_reference_indexes())?;
let skin_table = raw_skin_table
.chunks(header.skin_reference_count as usize)
.map(|chunk| chunk.into())
.collect();
dbg!(raw_skin_table);
let bones = read_indexes(header.bone_indexes(), data).collect::<Result<_>>()?; let bones = read_indexes(header.bone_indexes(), data).collect::<Result<_>>()?;
Ok(Mdl { Ok(Mdl {
bones, bones,
@ -52,6 +61,7 @@ impl Mdl {
.collect::<Result<_>>()?, .collect::<Result<_>>()?,
textures, textures,
texture_paths, texture_paths,
skin_table,
header, header,
}) })
} }

View file

@ -60,8 +60,8 @@ pub struct StudioHeader {
// Each skin-family assigns a texture-id to a skin location // Each skin-family assigns a texture-id to a skin location
pub skin_reference_count: i32, pub skin_reference_count: i32,
pub skin_r_family_count: i32, pub skin_family_count: i32,
pub skin_reference_index: i32, pub skin_reference_offset: i32,
// mstudiobodyparts_t // mstudiobodyparts_t
body_part_count: i32, body_part_count: i32,
@ -244,6 +244,14 @@ impl StudioHeader {
) )
} }
pub fn skin_reference_indexes(&self) -> impl Iterator<Item = usize> {
index_range(
self.skin_reference_offset,
self.skin_reference_count * self.skin_family_count,
size_of::<u16>(),
)
}
pub fn body_part_indexes(&self) -> impl Iterator<Item = usize> { pub fn body_part_indexes(&self) -> impl Iterator<Item = usize> {
index_range( index_range(
self.body_part_offset, self.body_part_offset,