use super::tokens::*;
use super::topology::joint_index_map;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SkinningMethod {
#[default]
ClassicLinear,
DualQuaternion,
}
impl SkinningMethod {
pub fn as_token(self) -> &'static str {
match self {
SkinningMethod::ClassicLinear => SKINNING_METHOD_CLASSIC_LINEAR,
SkinningMethod::DualQuaternion => SKINNING_METHOD_DUAL_QUATERNION,
}
}
pub fn from_token(s: &str) -> Option<Self> {
Some(match s {
SKINNING_METHOD_CLASSIC_LINEAR => SkinningMethod::ClassicLinear,
SKINNING_METHOD_DUAL_QUATERNION => SkinningMethod::DualQuaternion,
_ => return None,
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum InfluenceInterpolation {
Constant,
#[default]
Vertex,
}
impl InfluenceInterpolation {
pub fn as_token(self) -> &'static str {
match self {
InfluenceInterpolation::Constant => INTERP_CONSTANT,
InfluenceInterpolation::Vertex => INTERP_VERTEX,
}
}
pub fn from_token(s: &str) -> Option<Self> {
Some(match s {
INTERP_CONSTANT => InfluenceInterpolation::Constant,
INTERP_VERTEX => InfluenceInterpolation::Vertex,
_ => return None,
})
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct ReadSkelRoot {
pub path: String,
pub extent: Option<[[f32; 3]; 2]>,
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct ReadSkeleton {
pub path: String,
pub joints: Vec<String>,
pub bind_transforms: Vec<[f64; 16]>,
pub rest_transforms: Vec<[f64; 16]>,
}
impl ReadSkeleton {
pub fn joint_parent_indices(&self) -> Vec<Option<usize>> {
let by_path = joint_index_map(&self.joints);
self.joints
.iter()
.map(|p| {
p.rsplit_once('/')
.map(|(parent, _)| parent)
.and_then(|parent_path| by_path.get(parent_path).copied())
})
.collect()
}
pub fn joint_short_names(&self) -> Vec<&str> {
self.joints
.iter()
.map(|p| p.rsplit_once('/').map(|(_, n)| n).unwrap_or(p.as_str()))
.collect()
}
pub fn map_anim_joints(&self, anim_joints: &[String]) -> Vec<Option<usize>> {
let by_path = joint_index_map(&self.joints);
anim_joints.iter().map(|p| by_path.get(p.as_str()).copied()).collect()
}
}
#[derive(Debug, Clone, Default)]
pub struct ReadSkelAnimation {
pub path: String,
pub joints: Vec<String>,
pub blend_shapes: Vec<String>,
pub translations: Vec<(f64, Vec<[f32; 3]>)>,
pub rotations: Vec<(f64, Vec<[f32; 4]>)>,
pub scales: Vec<(f64, Vec<[f32; 3]>)>,
pub blend_shape_weights: Vec<(f64, Vec<f32>)>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ReadInbetween {
pub name: String,
pub weight: Option<f32>,
pub offsets: Vec<[f32; 3]>,
pub normal_offsets: Vec<[f32; 3]>,
}
#[derive(Debug, Clone, Default)]
pub struct ReadBlendShape {
pub path: String,
pub offsets: Vec<[f32; 3]>,
pub normal_offsets: Vec<[f32; 3]>,
pub point_indices: Vec<i32>,
pub inbetweens: Vec<ReadInbetween>,
}
#[derive(Debug, Clone, Default)]
pub struct ReadSkelBinding {
pub path: String,
pub skeleton: Option<String>,
pub animation_source: Option<String>,
pub joint_indices: Vec<i32>,
pub joint_weights: Vec<f32>,
pub elements_per_element: i32,
pub interpolation: InfluenceInterpolation,
pub joint_subset: Vec<String>,
pub blend_shapes: Vec<String>,
pub blend_shape_targets: Vec<String>,
pub geom_bind_transform: Option<[f64; 16]>,
pub skinning_method: SkinningMethod,
}
#[derive(Debug, Clone, Default)]
pub struct SkelPrims {
pub skel_roots: Vec<String>,
pub skeletons: Vec<String>,
pub animations: Vec<String>,
pub blend_shapes: Vec<String>,
pub bindings: Vec<String>,
}