misc animation stuff

This commit is contained in:
Robin Appelman 2024-12-31 00:11:38 +01:00
commit ac236685ce
5 changed files with 61 additions and 46 deletions

View file

@ -293,7 +293,7 @@ fn index_range(index: i32, count: i32, size: usize) -> impl Iterator<Item = usiz
.map(move |i| index as usize + i)
}
fn read_relative_iter<'a, T: ReadRelative, I: 'a + Iterator<Item = usize>>(
fn read_relative_iter<'a, T: ReadRelative<'a>, I: 'a + Iterator<Item = usize>>(
data: &'a [u8],
indexes: I,
) -> impl Iterator<Item = Result<T, ModelError>> + 'a {
@ -307,14 +307,17 @@ fn read_relative_iter<'a, T: ReadRelative, I: 'a + Iterator<Item = usize>>(
})
}
fn read_relative<T: ReadRelative, I: Iterator<Item = usize>>(
data: &[u8],
fn read_relative<'a, T: ReadRelative<'a>, I: Iterator<Item = usize> + 'a>(
data: &'a [u8],
indexes: I,
) -> Result<Vec<T>, ModelError> {
read_relative_iter(data, indexes).collect()
}
fn read_single<T: ReadRelative, I: TryInto<usize>>(data: &[u8], index: I) -> Result<T, ModelError> {
fn read_single<'a, T: ReadRelative<'a>, I: TryInto<usize>>(
data: &'a [u8],
index: I,
) -> Result<T, ModelError> {
let index = index.try_into().map_err(|_| ModelError::OutOfBounds {
data: type_name::<T>(),
offset: usize::MAX_VALUE,
@ -340,10 +343,10 @@ impl<T: Pod> Readable for T {
}
}
trait ReadRelative: Sized {
trait ReadRelative<'a>: Sized {
type Header: Readable;
fn read(data: &[u8], header: Self::Header) -> Result<Self, ModelError>;
fn read(data: &'a [u8], header: Self::Header) -> Result<Self, ModelError>;
}
trait ReadableRelative: Readable {}
@ -360,7 +363,7 @@ 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;
fn read(_data: &[u8], header: Self::Header) -> Result<Self, ModelError> {
@ -368,7 +371,7 @@ impl<T: ReadableRelative> ReadRelative for T {
}
}
impl ReadRelative for String {
impl ReadRelative<'_> for String {
type Header = ();
fn read(data: &[u8], _header: Self::Header) -> Result<Self, ModelError> {

View file

@ -129,7 +129,7 @@ pub struct BodyPart {
pub models: Vec<Model>,
}
impl ReadRelative for BodyPart {
impl ReadRelative<'_> for BodyPart {
type Header = BodyPartHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -150,7 +150,7 @@ pub struct Model {
pub vertex_offset: i32,
}
impl ReadRelative for Model {
impl ReadRelative<'_> for Model {
type Header = ModelHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -170,7 +170,7 @@ pub struct Mesh {
pub vertex_offset: i32,
}
impl ReadRelative for Mesh {
impl ReadRelative<'_> for Mesh {
type Header = MeshHeader;
fn read(_data: &[u8], header: Self::Header) -> Result<Self> {
@ -188,7 +188,7 @@ pub struct TextureInfo {
pub search_paths: Vec<String>,
}
impl ReadRelative for TextureInfo {
impl ReadRelative<'_> for TextureInfo {
type Header = MeshTexture;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -212,7 +212,7 @@ pub struct StudioAttachment {
pub local: Transform3x4,
}
impl ReadRelative for StudioAttachment {
impl ReadRelative<'_> for StudioAttachment {
type Header = StudioAttachmentHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -235,7 +235,7 @@ pub struct HitBoxSet {
pub boxes: Vec<BoundingBox>,
}
impl ReadRelative for HitBoxSet {
impl ReadRelative<'_> for HitBoxSet {
type Header = HitBoxSetHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -259,7 +259,7 @@ pub struct BoundingBox {
pub max: Vector,
}
impl ReadRelative for BoundingBox {
impl ReadRelative<'_> for BoundingBox {
type Header = BoundingBoxHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {

View file

@ -31,7 +31,7 @@ pub struct PoseParameterDescription {
pub loop_range: f32,
}
impl ReadRelative for PoseParameterDescription {
impl ReadRelative<'_> for PoseParameterDescription {
type Header = PoseParameterDescriptionHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self, ModelError> {
@ -90,7 +90,7 @@ pub struct AnimationDescription {
pub animations: Vec<Animation>,
}
impl ReadRelative for AnimationDescription {
impl ReadRelative<'_> for AnimationDescription {
type Header = AnimationDescriptionHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self, ModelError> {
@ -166,6 +166,9 @@ struct ValueHeader {
valid: u8,
total: u8,
}
static_assertions::const_assert_eq!(size_of::<ValueHeader>(), size_of::<i16>());
impl ReadableRelative for ValueHeader {}
fn read_animation_values(
@ -177,17 +180,14 @@ fn read_animation_values(
.0
.map::<_, Result<_, ModelError>>(|base_pointer| {
if base_pointer == 0 {
Ok(0.0)
Ok(0)
} else {
let header = read_single(data, base_pointer)?;
let values = FrameValues {
header,
data: &data[base_pointer as usize..],
};
Ok(values.get(frame as u8)? as f32)
let values: FrameValues = read_single(data, base_pointer)?;
Ok(values.get(frame as u8)?)
}
});
Ok([x?, y?, z?])
let [x, y, z] = [x?, y?, z?];
Ok([x as f32, y as f32, z as f32])
}
/// I hate this data structure
@ -206,25 +206,37 @@ struct FrameValues<'a> {
data: &'a [u8], // data starting at self.header
}
impl<'a> ReadRelative<'a> for FrameValues<'a> {
type Header = ValueHeader;
fn read(data: &'a [u8], header: Self::Header) -> Result<Self, ModelError> {
Ok(FrameValues {
header,
data: &data
.get(size_of::<ValueHeader>()..)
.ok_or(ModelError::OutOfBounds {
data: "animation frame data",
offset: size_of::<ValueHeader>(),
})?,
})
}
}
impl FrameValues<'_> {
pub fn get(&self, index: u8) -> Result<i16, ModelError> {
if self.header.total <= index {
let offset_count = self.header.valid + 1;
let offset_count = self.header.valid;
let offset = (offset_count as usize) * size_of::<ValueHeader>();
let next_header: ValueHeader = read_single(self.data, offset)?;
let next = FrameValues {
header: next_header,
data: &self.data[offset..],
};
if next_header.total == 0 {
let next: FrameValues = read_single(self.data, offset)?;
if next.header.total == 0 {
return Ok(0);
}
next.get(index - self.header.total)
} else {
let offset_count = if self.header.valid > index {
index + 1
let offset_count = if index < self.header.valid {
index
} else {
self.header.valid
self.header.valid - 1
};
let offset = (offset_count as usize) * size_of::<i16>();
read_single(self.data, offset)
@ -391,7 +403,7 @@ fn read_animation(
let value_data = &data[offset..];
let values: Vec<RadianEuler> = (0..frames)
.map(|frame| read_animation_values(value_data, frame, pointers))
.map_ok(|[pitch, yaw, roll]| RadianEuler { roll, yaw, pitch })
.map_ok(|[pitch, yaw, roll]| RadianEuler { pitch, yaw, roll })
.collect::<Result<_, ModelError>>()?;
RotationData::from(values)
} else {
@ -518,7 +530,7 @@ pub struct AnimationSequence {
pub bone_weights: Vec<f32>,
}
impl ReadRelative for AnimationSequence {
impl ReadRelative<'_> for AnimationSequence {
type Header = AnimationSequenceHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self, ModelError> {

View file

@ -91,7 +91,7 @@ pub struct Bone {
pub contents: ContentFlags,
}
impl ReadRelative for Bone {
impl ReadRelative<'_> for Bone {
type Header = BoneHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self, ModelError> {
@ -364,7 +364,7 @@ pub struct SourceBoneTransform {
pub post_transform: Transform3x4,
}
impl ReadRelative for SourceBoneTransform {
impl ReadRelative<'_> for SourceBoneTransform {
type Header = SourceBoneTransformHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self, ModelError> {
@ -427,7 +427,7 @@ pub struct BoneController {
pub input_field: i32,
}
impl ReadRelative for BoneController {
impl ReadRelative<'_> for BoneController {
type Header = BoneControllerHeader;
fn read(_data: &[u8], header: Self::Header) -> Result<Self, ModelError> {

View file

@ -32,7 +32,7 @@ pub struct BodyPart {
pub models: Vec<Model>,
}
impl ReadRelative for BodyPart {
impl ReadRelative<'_> for BodyPart {
type Header = BodyPartHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -47,7 +47,7 @@ pub struct Model {
pub lods: Vec<ModelLod>,
}
impl ReadRelative for Model {
impl ReadRelative<'_> for Model {
type Header = ModelHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -63,7 +63,7 @@ pub struct ModelLod {
pub switch_point: f32,
}
impl ReadRelative for ModelLod {
impl ReadRelative<'_> for ModelLod {
type Header = ModelLodHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -80,7 +80,7 @@ pub struct Mesh {
pub flags: MeshFlags,
}
impl ReadRelative for Mesh {
impl ReadRelative<'_> for Mesh {
type Header = MeshHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -100,7 +100,7 @@ pub struct StripGroup {
pub flags: StripGroupFlags,
}
impl ReadRelative for StripGroup {
impl ReadRelative<'_> for StripGroup {
type Header = StripGroupHeader;
fn read(data: &[u8], header: Self::Header) -> Result<Self> {
@ -121,7 +121,7 @@ pub struct Strip {
indices: Range<usize>,
}
impl ReadRelative for Strip {
impl ReadRelative<'_> for Strip {
type Header = StripHeader;
fn read(_data: &[u8], header: Self::Header) -> Result<Self> {