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 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>;
@ -26,6 +26,7 @@ pub struct Mdl {
pub local_animations: Vec<AnimationDescription>,
pub pose_parameters: Vec<PoseParameterDescription>,
pub attachments: Vec<StudioAttachment>,
pub hit_boxes: Vec<HitBoxSet>,
}
impl Mdl {
@ -63,6 +64,7 @@ impl Mdl {
let local_animations = read_relative(data, header.local_animation_indexes())?;
let pose_parameters = read_relative(data, header.local_pose_param_indexes())?;
let attachments = read_relative(data, header.attachment_indexes())?;
let hit_boxes = read_relative(data, header.hitbox_set_indexes())?;
Ok(Mdl {
name,
@ -88,6 +90,7 @@ impl Mdl {
pose_parameters,
local_animations,
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,
// mstudiohitboxset_t
hitbox_count: i32,
hitbox_offset: i32,
hitbox_set_count: i32,
hitbox_set_offset: i32,
// mstudioanimdesc_t
local_animation_count: i32,
@ -216,8 +216,8 @@ impl StudioHeader {
index_range(self.bone_controller_offset, self.bone_controller_count, 1)
}
pub fn hitbox_indexes(&self) -> impl Iterator<Item = usize> {
index_range(self.hitbox_offset, self.hitbox_count, 1)
pub fn hitbox_set_indexes(&self) -> impl Iterator<Item = usize> {
index_range(self.hitbox_set_offset, self.hitbox_set_count, size_of::<HitBoxSetHeader>())
}
pub fn local_animation_indexes(&self) -> impl Iterator<Item = usize> {

View file

@ -133,3 +133,30 @@ bitflags! {
}
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],
}