pose to bone transform

This commit is contained in:
Robin Appelman 2023-12-30 18:44:40 +01:00
commit 03a309f3f7
3 changed files with 59 additions and 5 deletions

View file

@ -1,3 +1,4 @@
use cgmath::{Matrix4, Quaternion};
use std::env::args;
use std::fs;
use std::path::PathBuf;
@ -22,7 +23,10 @@ fn main() -> Result<(), vmdl::ModelError> {
for bone in mdl.bones {
println!(
"{}: from {} at\n\t{:?}\n\t{:?}",
bone.name, bone.parent, bone.rot, bone.contents
bone.name,
bone.parent,
bone.quaternion,
bone.pose_to_bone.rotation()
);
}

View file

@ -1,4 +1,4 @@
use crate::{ModelError, Quaternion, RadianEuler, ReadRelative, Readable, Vector};
use crate::{ModelError, Quaternion, RadianEuler, ReadRelative, Readable, Transform3x4, Vector};
use bitflags::bitflags;
use bytemuck::{Pod, Zeroable};
use num_enum::TryFromPrimitive;
@ -17,7 +17,7 @@ pub struct BoneHeader {
pub pos_scale: Vector,
pub rot_scale: Vector,
pub pose_to_bone: [[f32; 3]; 4], // 3x4 matrix
pub pose_to_bone: Transform3x4,
pub q_alignment: Quaternion,
pub flags: BoneFlags,
pub proc_type: i32,
@ -45,7 +45,7 @@ pub struct Bone {
pub pos_scale: Vector,
pub rot_scale: Vector,
pub pose_to_bone: [[f32; 3]; 4], // 3x4 matrix
pub pose_to_bone: Transform3x4,
pub q_alignment: Quaternion,
pub flags: BoneFlags,
pub procedural_rules: Option<ProceduralBone>,

View file

@ -1,7 +1,7 @@
use crate::{ModelError, StringError};
use arrayvec::ArrayString;
use bytemuck::{Pod, Zeroable};
use cgmath::{Deg, Euler, Rad, Rotation3, Vector3};
use cgmath::{Deg, Euler, Matrix3, Matrix4, Rad, Rotation3, Vector3};
use std::fmt;
use std::fmt::{Display, Formatter};
use std::ops::{Add, Mul};
@ -199,3 +199,53 @@ impl<const LEN: usize> Display for FixedString<LEN> {
Display::fmt(&self.0, f)
}
}
#[derive(Debug, Clone, Copy, Zeroable, Pod, PartialEq)]
#[repr(C)]
pub struct Transform3x4 {
transform: [[f32; 4]; 3],
}
impl Transform3x4 {
pub fn rotation_matrix(&self) -> Matrix3<f32> {
Matrix3 {
x: Vector3 {
x: self.transform[0][0],
y: self.transform[0][1],
z: self.transform[0][2],
},
y: Vector3 {
x: self.transform[1][0],
y: self.transform[1][1],
z: self.transform[1][2],
},
z: Vector3 {
x: self.transform[2][0],
y: self.transform[2][1],
z: self.transform[2][2],
},
}
}
pub fn rotation(&self) -> Quaternion {
cgmath::Quaternion::from(self.rotation_matrix()).into()
}
pub fn translate(&self) -> Vector {
[
self.transform[0][3],
self.transform[1][3],
self.transform[2][3],
]
.into()
}
}
impl From<Transform3x4> for Matrix4<f32> {
fn from(value: Transform3x4) -> Self {
let translate = value.translate();
let rotate = value.rotation_matrix();
let rotate = Matrix4::from(rotate);
rotate * Matrix4::from_translation(translate.into())
}
}