This commit is contained in:
Robin Appelman 2024-06-12 21:26:19 +02:00
commit cc70727690
3 changed files with 76 additions and 6 deletions

View file

@ -7,7 +7,7 @@ use std::mem::size_of;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use crate::vvd::Vertex; use crate::vvd::Vertex;
use crate::{read_relative, read_relative_iter, read_single, FixedString, ModelError, ReadRelative, Readable, Transform3x4}; use crate::{read_relative, read_relative_iter, read_single, FixedString, ModelError, ReadRelative, Readable, Transform3x4, Vector};
type Result<T> = std::result::Result<T, ModelError>; type Result<T> = std::result::Result<T, ModelError>;
@ -26,6 +26,7 @@ pub struct Mdl {
pub local_animations: Vec<AnimationDescription>, pub local_animations: Vec<AnimationDescription>,
pub pose_parameters: Vec<PoseParameterDescription>, pub pose_parameters: Vec<PoseParameterDescription>,
pub attachments: Vec<StudioAttachment>, pub attachments: Vec<StudioAttachment>,
pub hit_boxes: Vec<HitBoxSet>,
} }
impl Mdl { impl Mdl {
@ -63,6 +64,7 @@ impl Mdl {
let local_animations = read_relative(data, header.local_animation_indexes())?; let local_animations = read_relative(data, header.local_animation_indexes())?;
let pose_parameters = read_relative(data, header.local_pose_param_indexes())?; let pose_parameters = read_relative(data, header.local_pose_param_indexes())?;
let attachments = read_relative(data, header.attachment_indexes())?; let attachments = read_relative(data, header.attachment_indexes())?;
let hit_boxes = read_relative(data, header.hitbox_set_indexes())?;
Ok(Mdl { Ok(Mdl {
name, name,
@ -88,6 +90,7 @@ impl Mdl {
pose_parameters, pose_parameters,
local_animations, local_animations,
attachments, attachments,
hit_boxes,
}) })
} }
} }
@ -189,3 +192,43 @@ impl ReadRelative for StudioAttachment {
}) })
} }
} }
#[derive(Debug, Clone)]
pub struct HitBoxSet {
pub name: String,
pub boxes: Vec<BoundingBox>
}
impl ReadRelative for HitBoxSet {
type Header = HitBoxSetHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
Ok(HitBoxSet {
name: String::read(&data[header.name_index as usize..], ())?.replace('\\', "/"),
boxes: read_relative(data, header.hitbox_indexes())?
})
}
}
#[derive(Debug, Clone)]
pub struct BoundingBox {
pub name: String,
pub bone: i32,
pub group: i32,
pub min: Vector,
pub max: Vector
}
impl ReadRelative for BoundingBox {
type Header = BoundingBoxHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
Ok(BoundingBox {
name: String::read(&data[header.name_index as usize..], ())?.replace('\\', "/"),
bone: header.bone,
group: header.group,
min: header.bounding_box_min,
max: header.bounding_box_max,
})
}
}

View file

@ -31,8 +31,8 @@ pub struct StudioHeader {
bone_controller_offset: i32, bone_controller_offset: i32,
// mstudiohitboxset_t // mstudiohitboxset_t
hitbox_count: i32, hitbox_set_count: i32,
hitbox_offset: i32, hitbox_set_offset: i32,
// mstudioanimdesc_t // mstudioanimdesc_t
local_animation_count: i32, local_animation_count: i32,
@ -216,8 +216,8 @@ impl StudioHeader {
index_range(self.bone_controller_offset, self.bone_controller_count, 1) index_range(self.bone_controller_offset, self.bone_controller_count, 1)
} }
pub fn hitbox_indexes(&self) -> impl Iterator<Item = usize> { pub fn hitbox_set_indexes(&self) -> impl Iterator<Item = usize> {
index_range(self.hitbox_offset, self.hitbox_count, 1) index_range(self.hitbox_set_offset, self.hitbox_set_count, size_of::<HitBoxSetHeader>())
} }
pub fn local_animation_indexes(&self) -> impl Iterator<Item = usize> { pub fn local_animation_indexes(&self) -> impl Iterator<Item = usize> {

View file

@ -132,4 +132,31 @@ bitflags! {
} }
} }
static_assertions::const_assert_eq!(size_of::<StudioAttachmentHeader>(), 23 * 4); static_assertions::const_assert_eq!(size_of::<StudioAttachmentHeader>(), 23 * 4);
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
#[allow(dead_code)]
pub struct HitBoxSetHeader {
pub name_index: i32,
pub hitbox_count: i32,
pub hitbox_offset: i32,
}
impl HitBoxSetHeader {
pub fn hitbox_indexes(&self) -> impl Iterator<Item = usize> {
index_range(self.hitbox_offset, self.hitbox_count, size_of::<BoundingBoxHeader>())
}
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
#[allow(dead_code)]
pub struct BoundingBoxHeader {
pub bone: i32,
pub group: i32,
pub bounding_box_min: Vector,
pub bounding_box_max: Vector,
pub name_index: i32,
padding: [i32; 8],
}