texture paths

This commit is contained in:
Robin Appelman 2023-12-09 23:28:00 +01:00
commit cd5ec8492e
8 changed files with 99 additions and 8 deletions

View file

@ -4,9 +4,12 @@ pub use raw::header::*;
pub use raw::header2::*;
use std::mem::size_of;
use crate::mdl::raw::{BodyPartHeader, Bone, MeshHeader, ModelHeader};
use crate::mdl::raw::{BodyPartHeader, Bone, MeshHeader, MeshTexture, ModelHeader};
use crate::vvd::Vertex;
use crate::{read_indexes, read_relative, FixedString, ModelError, ReadRelative, Readable};
use crate::{
read_indexes, read_relative, read_relative_iter, FixedString, ModelError, ReadRelative,
Readable,
};
type Result<T> = std::result::Result<T, ModelError>;
@ -15,11 +18,22 @@ pub struct Mdl {
pub header: StudioHeader,
pub bones: Vec<Bone>,
pub body_parts: Vec<BodyPart>,
pub textures: Vec<TextureInfo>,
pub texture_paths: Vec<String>,
}
impl Mdl {
pub fn read(data: &[u8]) -> Result<Self> {
let header = <StudioHeader as Readable>::read(data)?;
let textures = read_relative_iter(data, header.texture_indexes())
.collect::<Result<Vec<TextureInfo>>>()?;
let texture_dirs_indexes =
read_relative_iter(data, header.texture_dir_indexes()).collect::<Result<Vec<u32>>>()?;
let texture_paths = read_relative::<String, _>(
data,
texture_dirs_indexes.into_iter().map(|index| index as usize),
)?;
let bones = read_indexes(header.bone_indexes(), data).collect::<Result<_>>()?;
Ok(Mdl {
bones,
@ -34,6 +48,8 @@ impl Mdl {
BodyPart::read(data, header)
})
.collect::<Result<_>>()?,
textures,
texture_paths,
header,
})
}
@ -94,3 +110,18 @@ impl ReadRelative for Mesh {
})
}
}
#[derive(Debug, Clone)]
pub struct TextureInfo {
pub name: String,
}
impl ReadRelative for TextureInfo {
type Header = MeshTexture;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
Ok(TextureInfo {
name: String::read(&data[header.name_index as usize..], ())?,
})
}
}

View file

@ -229,11 +229,19 @@ impl StudioHeader {
}
pub fn texture_indexes(&self) -> impl Iterator<Item = usize> {
index_range(self.texture_offset, self.texture_count, 1)
index_range(
self.texture_offset,
self.texture_count,
size_of::<MeshTexture>(),
)
}
pub fn texture_dir_indexes(&self) -> impl Iterator<Item = usize> {
index_range(self.texture_dir_offset, self.texture_dir_count, 1)
index_range(
self.texture_dir_offset,
self.texture_dir_count,
size_of::<u32>(),
)
}
pub fn body_part_indexes(&self) -> impl Iterator<Item = usize> {

View file

@ -146,3 +146,18 @@ pub struct MeshVertexData {
model_vertex_data: i32,
lod_vertex_count: [i32; 8],
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
#[allow(dead_code)]
pub struct MeshTexture {
pub name_index: i32, // relative offset to this struct
pub flags: i32,
pub used: i32,
_padding: i32,
pub material_ptr: i32,
pub client_material_ptr: i32,
_padding2: [i32; 10],
}
static_assertions::const_assert_eq!(size_of::<MeshTexture>(), 16 * 4);