diff --git a/src/animation.rs b/src/animation.rs index 55f817f..bc98a0d 100644 --- a/src/animation.rs +++ b/src/animation.rs @@ -212,6 +212,18 @@ pub struct Animation { scales: Vec, } +/// Animation meta in `Archive`. +#[derive(Debug, Clone)] +pub struct AnimationMeta { + pub version: u32, + pub duration: f32, + pub num_tracks: i32, + pub name: String, + pub translation_count: i32, + pub rotation_count: i32, + pub scale_count: i32, +} + impl Animation { /// `Animation` resource file tag for `Archive`. #[inline] @@ -244,8 +256,8 @@ impl Animation { }; } - /// Reads an `Animation` from an `Archive`. - pub fn from_archive(archive: &mut Archive) -> Result { + /// Reads an `AnimationMeta` from an `Archive`. + pub fn read_meta(archive: &mut Archive) -> Result { if archive.tag() != Self::tag() { return Err(OzzError::InvalidTag); } @@ -259,20 +271,36 @@ impl Animation { let translation_count: i32 = archive.read()?; let rotation_count: i32 = archive.read()?; let scale_count: i32 = archive.read()?; - + let mut name = String::new(); if name_len != 0 { let buf = archive.read_vec(name_len as usize)?; name = String::from_utf8(buf).map_err(|e| e.utf8_error())?; } - let translations: Vec = archive.read_vec(translation_count as usize)?; - let rotations: Vec = archive.read_vec(rotation_count as usize)?; - let scales: Vec = archive.read_vec(scale_count as usize)?; - return Ok(Animation { + return Ok(AnimationMeta { + version: archive.version(), duration, - num_tracks: num_tracks as usize, + num_tracks, name, + translation_count, + rotation_count, + scale_count, + }); + } + + /// Reads an `Animation` from an `Archive`. + pub fn from_archive(archive: &mut Archive) -> Result { + let meta = Animation::read_meta(archive)?; + + let translations: Vec = archive.read_vec(meta.translation_count as usize)?; + let rotations: Vec = archive.read_vec(meta.rotation_count as usize)?; + let scales: Vec = archive.read_vec(meta.scale_count as usize)?; + + return Ok(Animation { + duration: meta.duration, + num_tracks: meta.num_tracks as usize, + name: meta.name, translations, rotations, scales, diff --git a/src/sampling_job.rs b/src/sampling_job.rs index bd93fed..0d6c2aa 100644 --- a/src/sampling_job.rs +++ b/src/sampling_job.rs @@ -507,40 +507,40 @@ pub struct ArchivedSamplingContext { #[cfg(feature = "rkyv")] impl ArchivedSamplingContext { - pub fn translations(&self) -> &[InterpSoaFloat3] { - return unsafe { slice::from_raw_parts(self.translations_ptr.as_ptr(), self.max_soa_tracks as usize) }; + pub unsafe fn translations(&self) -> &[InterpSoaFloat3] { + return slice::from_raw_parts(self.translations_ptr.as_ptr(), self.max_soa_tracks as usize); } - pub fn rotations(&self) -> &[InterpSoaQuaternion] { - return unsafe { slice::from_raw_parts(self.rotations_ptr.as_ptr(), self.max_soa_tracks as usize) }; + pub unsafe fn rotations(&self) -> &[InterpSoaQuaternion] { + return slice::from_raw_parts(self.rotations_ptr.as_ptr(), self.max_soa_tracks as usize); } - pub fn scales(&self) -> &[InterpSoaFloat3] { - return unsafe { slice::from_raw_parts(self.scales_ptr.as_ptr(), self.max_soa_tracks as usize) }; + pub unsafe fn scales(&self) -> &[InterpSoaFloat3] { + return slice::from_raw_parts(self.scales_ptr.as_ptr(), self.max_soa_tracks as usize); } - pub fn translation_keys(&self) -> &[i32] { - return unsafe { slice::from_raw_parts(self.translation_keys_ptr.as_ptr(), self.max_tracks as usize * 2) }; + pub unsafe fn translation_keys(&self) -> &[i32] { + return slice::from_raw_parts(self.translation_keys_ptr.as_ptr(), self.max_tracks as usize * 2); } - pub fn rotation_keys(&self) -> &[i32] { - return unsafe { slice::from_raw_parts(self.rotation_keys_ptr.as_ptr(), self.max_tracks as usize * 2) }; + pub unsafe fn rotation_keys(&self) -> &[i32] { + return slice::from_raw_parts(self.rotation_keys_ptr.as_ptr(), self.max_tracks as usize * 2); } - pub fn scale_keys(&self) -> &[i32] { - return unsafe { slice::from_raw_parts(self.scale_keys_ptr.as_ptr(), self.max_tracks as usize * 2) }; + pub unsafe fn scale_keys(&self) -> &[i32] { + return slice::from_raw_parts(self.scale_keys_ptr.as_ptr(), self.max_tracks as usize * 2); } - pub fn outdated_translations(&self) -> &[u8] { - return unsafe { slice::from_raw_parts(self.outdated_translations_ptr.as_ptr(), self.num_outdated as usize) }; + pub unsafe fn outdated_translations(&self) -> &[u8] { + return slice::from_raw_parts(self.outdated_translations_ptr.as_ptr(), self.num_outdated as usize); } - pub fn outdated_rotations(&self) -> &[u8] { - return unsafe { slice::from_raw_parts(self.outdated_rotations_ptr.as_ptr(), self.num_outdated as usize) }; + pub unsafe fn outdated_rotations(&self) -> &[u8] { + return slice::from_raw_parts(self.outdated_rotations_ptr.as_ptr(), self.num_outdated as usize); } - pub fn outdated_scales(&self) -> &[u8] { - return unsafe { slice::from_raw_parts(self.outdated_scales_ptr.as_ptr(), self.num_outdated as usize) }; + pub unsafe fn outdated_scales(&self) -> &[u8] { + return slice::from_raw_parts(self.outdated_scales_ptr.as_ptr(), self.num_outdated as usize); } } @@ -677,26 +677,28 @@ impl rkyv::Deserialize for Archi let mut context = SamplingContext::new(archived.max_tracks as usize); context.animation_id = archived.animation_id; context.ratio = archived.ratio; - context.translations_mut().copy_from_slice(archived.translations()); - context.rotations_mut().copy_from_slice(archived.rotations()); - context.scales_mut().copy_from_slice(archived.scales()); - context - .translation_keys_mut() - .copy_from_slice(archived.translation_keys()); - context.rotation_keys_mut().copy_from_slice(archived.rotation_keys()); - context.scale_keys_mut().copy_from_slice(archived.scale_keys()); - context.translation_cursor = archived.translation_cursor as usize; - context.rotation_cursor = archived.rotation_cursor as usize; - context.scale_cursor = archived.scale_cursor as usize; - context - .outdated_translations_mut() - .copy_from_slice(archived.outdated_translations()); - context - .outdated_rotations_mut() - .copy_from_slice(archived.outdated_rotations()); - context - .outdated_scales_mut() - .copy_from_slice(archived.outdated_scales()); + unsafe { + context.translations_mut().copy_from_slice(archived.translations()); + context.rotations_mut().copy_from_slice(archived.rotations()); + context.scales_mut().copy_from_slice(archived.scales()); + context + .translation_keys_mut() + .copy_from_slice(archived.translation_keys()); + context.rotation_keys_mut().copy_from_slice(archived.rotation_keys()); + context.scale_keys_mut().copy_from_slice(archived.scale_keys()); + context.translation_cursor = archived.translation_cursor as usize; + context.rotation_cursor = archived.rotation_cursor as usize; + context.scale_cursor = archived.scale_cursor as usize; + context + .outdated_translations_mut() + .copy_from_slice(archived.outdated_translations()); + context + .outdated_rotations_mut() + .copy_from_slice(archived.outdated_rotations()); + context + .outdated_scales_mut() + .copy_from_slice(archived.outdated_scales()); + } return Ok(context); } } @@ -1594,15 +1596,17 @@ mod sampling_tests { assert_eq!(archived.translation_cursor as usize, ctx.translation_cursor); assert_eq!(archived.rotation_cursor as usize, ctx.rotation_cursor); assert_eq!(archived.scale_cursor as usize, ctx.scale_cursor); - assert_eq!(archived.translations(), ctx.translations()); - assert_eq!(archived.rotations(), ctx.rotations()); - assert_eq!(archived.scales(), ctx.scales()); - assert_eq!(archived.translation_keys(), ctx.translation_keys()); - assert_eq!(archived.rotation_keys(), ctx.rotation_keys()); - assert_eq!(archived.scale_keys(), ctx.scale_keys()); - assert_eq!(archived.outdated_translations(), ctx.outdated_translations()); - assert_eq!(archived.outdated_rotations(), ctx.outdated_rotations()); - assert_eq!(archived.outdated_scales(), ctx.outdated_scales()); + unsafe { + assert_eq!(archived.translations(), ctx.translations()); + assert_eq!(archived.rotations(), ctx.rotations()); + assert_eq!(archived.scales(), ctx.scales()); + assert_eq!(archived.translation_keys(), ctx.translation_keys()); + assert_eq!(archived.rotation_keys(), ctx.rotation_keys()); + assert_eq!(archived.scale_keys(), ctx.scale_keys()); + assert_eq!(archived.outdated_translations(), ctx.outdated_translations()); + assert_eq!(archived.outdated_rotations(), ctx.outdated_rotations()); + assert_eq!(archived.outdated_scales(), ctx.outdated_scales()); + } let ctx_de: SamplingContext = archived.deserialize(&mut rkyv::Infallible).unwrap(); assert_eq!(ctx_de.size(), ctx.size()); diff --git a/src/skeleton.rs b/src/skeleton.rs index b153d2a..d28796f 100644 --- a/src/skeleton.rs +++ b/src/skeleton.rs @@ -85,6 +85,14 @@ pub struct Skeleton { joint_names: JointHashMap, } +/// Skeleton meta in `Archive`. +pub struct SkeletonMeta { + pub version: u32, + pub num_joints: i32, + pub joint_names: JointHashMap, + pub joint_parents: Vec, +} + impl Skeleton { /// `Skeleton` resource file tag for `Archive`. #[inline] @@ -111,8 +119,8 @@ impl Skeleton { }; } - /// Reads a `Skeleton` from a reader. - pub fn from_archive(archive: &mut Archive) -> Result { + /// Reads a `SkeletonMeta` from a reader. + pub fn read_meta(archive: &mut Archive, with_joints: bool) -> Result { if archive.tag() != Self::tag() { return Err(OzzError::InvalidTag); } @@ -121,11 +129,12 @@ impl Skeleton { } let num_joints: i32 = archive.read()?; - if num_joints == 0 { - return Ok(Skeleton { - joint_rest_poses: Vec::new(), - joint_parents: Vec::new(), + if num_joints == 0 || !with_joints { + return Ok(SkeletonMeta{ + version: Self::version(), + num_joints, joint_names: BiHashMap::with_hashers(DeterministicState::new(), DeterministicState::new()), + joint_parents: Vec::new(), }); } @@ -141,7 +150,19 @@ impl Skeleton { let joint_parents: Vec = archive.read_vec(num_joints as usize)?; - let soa_num_joints = (num_joints + 3) / 4; + return Ok(SkeletonMeta{ + version: Self::version(), + num_joints, + joint_names, + joint_parents, + }); + } + + /// Reads a `Skeleton` from a reader. + pub fn from_archive(archive: &mut Archive) -> Result { + let meta = Skeleton::read_meta(archive, true)?; + + let soa_num_joints = (meta.num_joints + 3) / 4; let mut joint_rest_poses: Vec = Vec::with_capacity(soa_num_joints as usize); for _ in 0..soa_num_joints { joint_rest_poses.push(archive.read()?); @@ -149,8 +170,8 @@ impl Skeleton { return Ok(Skeleton { joint_rest_poses, - joint_parents, - joint_names, + joint_parents: meta.joint_parents, + joint_names: meta.joint_names, }); }