extern crate mazth;
use std::str;
use std::clone::Clone;
use self::mazth::quat::Quat;
use implement::file::md5anim;
#[derive(Debug, Clone)]
pub struct RigJoint {
pub _name: String,
pub _parent: i64,
pub _pos: [f32;3],
pub _orient: Quat<f32>,
}
#[derive(Debug, Clone)]
pub struct PoseJoints {
pub _joints: Vec< RigJoint >,
}
#[derive(Debug, Clone)]
pub struct PoseCollection {
pub _frames: Vec< PoseJoints >,
pub _framerate: u64,
}
pub fn process( anim: & md5anim::Md5AnimRoot ) -> Result< PoseCollection, & 'static str > {
let mut pc = PoseCollection {
_frames: vec![],
_framerate: 0u64,
};
for i in 0..anim._frames.len() { let pj = match process_posejoints( & anim._frames[i], & anim._bounds[i], & anim._hierarchy, & anim._baseframe ){
Ok( posejoint ) => posejoint,
Err(e) => return Err(e)
};
pc._frames.push( pj );
}
pc._framerate = anim._framerate;
Ok( pc )
}
fn process_posejoints( f: & md5anim::Frame, _bbox: & md5anim::Bound, hier: & Vec< md5anim::JointHierarchy >, baseframe: & Vec< md5anim::FrameJoint > ) -> Result< PoseJoints, & 'static str > {
let mut pj = PoseJoints {
_joints: vec![],
};
for i in 0..hier.len() {
let start = hier[i]._start_index;
let flag = hier[i]._flags;
let mut bf_pos = baseframe[i]._pos;
let mut bf_rot = baseframe[i]._orient;
let mut offset = 0;
for j in 0..3 { if (flag & (1u64 << j)) > 0 {
assert!( start + offset < f._data.len() as u64 );
bf_pos[j] = f._data[ ( start + offset ) as usize ];
offset += 1;
}
}
for j in 0..3 {
if (flag & (8u64 << j)) > 0 {
assert!( start + offset < f._data.len() as u64 );
bf_rot[j] = f._data[ ( start + offset ) as usize ];
offset += 1;
}
}
let bf_orient = Quat::<f32>::init_from_vals_auto_w( bf_rot[0], bf_rot[1], bf_rot[2] ).normalize();
let parent_joint_index = hier[i]._parent;
let rj = if parent_joint_index >= 0 { assert!( parent_joint_index < pj._joints.len() as i64 ); let parent_joint_frame = & pj._joints[ parent_joint_index as usize ];
let pos_quat = Quat::<f32>::init_from_vals_raw( bf_pos[0], bf_pos[1], bf_pos[2], 0. );
let orient_inv = parent_joint_frame._orient.inverse().normalize();
let res = parent_joint_frame._orient.mul( pos_quat ).mul( orient_inv );
RigJoint {
_name: hier[i]._name.clone(),
_parent: hier[i]._parent,
_pos: [ parent_joint_frame._pos[0] + res._x,
parent_joint_frame._pos[1] + res._y,
parent_joint_frame._pos[2] + res._z, ],
_orient: parent_joint_frame._orient.mul( bf_orient ).normalize(),
}
}else{ RigJoint {
_name: hier[i]._name.clone(),
_parent: hier[i]._parent,
_pos: bf_pos,
_orient: bf_orient,
}
};
pj._joints.push( rj );
}
Ok( pj )
}