use cgmath::One;
#[derive(Debug)]
pub struct BvhData {
pub rest_local_positions: Vec<Position>,
pub rest_local_rotations: Vec<Quaternion>,
pub rest_global_positions: Vec<Position>,
pub rest_global_rotations: Vec<Quaternion>,
pub pose_global_positions: Vec<Vec<Position>>,
pub pose_global_rotations: Vec<Vec<Quaternion>>,
pub pose_local_rotations: Vec<Vec<Quaternion>>, pub pose_local_positions: Vec<Vec<Position>>, }
impl BvhData {
pub fn print_rest_local(&self) {
println!("==== REST LOCAL ====");
for i in 0..self.rest_local_positions.len() {
println!(
"{}: {:<10.2?} {:<10.2?}",
i, self.rest_local_positions[i], self.rest_local_rotations[i]
);
}
Position::identity();
}
pub fn print_rest_global(&self) {
println!("==== REST GLOBAL ====");
for i in 0..self.rest_local_positions.len() {
println!(
"{}: {:<10.2?} {:<10.2?}",
i, self.rest_global_positions[i], self.rest_global_rotations[i]
);
}
}
}
pub type Index = usize;
pub type ParentIndex = isize; pub type Quaternion = cgmath::Quaternion<f64>;
pub type Position = cgmath::Vector3<f64>;
pub type Depth = usize;
#[derive(Debug)]
pub struct Joint {
pub name: String,
pub index: Index,
pub parent_index: ParentIndex,
pub depth: Depth,
pub children: Vec<Index>,
pub is_leaf: bool,
pub endsite: Option<Endsite>,
}
#[derive(Debug)]
pub struct Endsite {
pub offset: Position,
}
#[derive(Debug)]
pub struct BvhMetadata {
pub joints: Vec<Joint>,
pub num_frames: usize,
pub frame_time: f64,
pub fps: u32,
}
impl BvhMetadata {
pub fn find_joint_by_name(&self, name: &str) -> &Joint {
self
.joints
.iter()
.find(|joint| joint.name == name)
.expect(&format!("Joint {} not found", name))
}
pub fn find_joint_by_index(&self,index: Index) -> &Joint {
self
.joints
.iter()
.find(|joint| joint.index == index)
.expect(&format!("Joint with parent index {} not found", index))
}
pub fn get_kinematic_chains(&self) -> Vec<Vec<Index>> {
let mut kinematic_chains: Vec<Vec<Index>> = Vec::new();
let mut chain: Vec<Index> = Vec::new();
let mut last_depth: isize = -1;
for joint in self.joints.iter() {
if last_depth != joint.depth as isize - 1 {
kinematic_chains.push(chain.clone());
chain.clear();
}
last_depth = joint.depth as isize;
chain.push(joint.index);
}
kinematic_chains.push(chain.clone());
return kinematic_chains
}
}
pub trait Identity {
fn identity() -> Self;
}
impl Identity for Quaternion {
fn identity() -> Self {
Quaternion::one()
}
}
impl Identity for Position {
fn identity() -> Self {
Position {
x: 0.0,
y: 0.0,
z: 0.0,
}
}
}