use std::vec::Vec;
use nalgebra::{Matrix4, Quaternion, UnitQuaternion, Vector3};
use serde::{Deserialize, Serialize};
use crate::logging::EnigmaError;
use crate::smart_format;
pub(crate) const MAX_BONES: usize = 128;
#[derive(Clone)]
pub struct Bone {
pub name: String,
pub id: usize,
pub node_index: usize,
pub parent_id: Option<usize>,
pub inverse_bind_pose: Matrix4<f32>
}
#[derive(Serialize, Deserialize, Clone)]
pub struct BoneSerializer {
pub name: String,
pub id: usize,
pub node_index: usize,
pub parent_id: Option<usize>,
pub inverse_bind_pose: [[f32;4];4]
}
impl Bone {
pub fn to_serializer(&self) -> BoneSerializer {
BoneSerializer {
name: self.name.clone(),
id: self.id,
node_index: self.node_index,
parent_id: self.parent_id,
inverse_bind_pose: self.inverse_bind_pose.into()
}
}
pub fn from_serializer(serializer: BoneSerializer) -> Self{
Self {
name: serializer.name,
id: serializer.id,
node_index: serializer.node_index,
parent_id: serializer.parent_id,
inverse_bind_pose: Matrix4::from(serializer.inverse_bind_pose)
}
}
}
#[derive(Clone)]
pub struct Skeleton {
pub bones: Vec<Bone>,
pub root_transform: Matrix4<f32>,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct SkeletonSerializer {
pub bones: Vec<BoneSerializer>,
pub root_transform: [[f32; 4]; 4],
}
impl Skeleton {
pub fn to_serializer(&self) -> SkeletonSerializer {
SkeletonSerializer {
bones: self.bones.iter().map(|x| x.to_serializer()).collect(),
root_transform: self.root_transform.into(),
}
}
pub fn from_serializer(serializer: SkeletonSerializer) -> Self {
let mut bones = Vec::new();
for s in serializer.bones {
let bone = Bone::from_serializer(s);
bones.push(bone);
}
Self {
bones,
root_transform: Matrix4::from(serializer.root_transform),
}
}
pub fn validate(&self) -> Result<(), EnigmaError> {
for bone in self.bones.iter() {
if let Some(parent_id) = bone.parent_id {
if parent_id >= self.bones.len() {
return Err(EnigmaError::new(Some(smart_format!("Invalid parent ID {} for bone {} with id {}. There are only {} bones in the skeleton.", parent_id, bone.name, bone.id, self.bones.len()).as_str()), true))
}
}
}
Ok(())
}
pub fn try_fix(&mut self) -> Result<(), EnigmaError> {
let len = self.bones.len();
for bone in self.bones.iter_mut() {
if let Some(parent_id) = bone.parent_id {
if parent_id >= len {
bone.parent_id = None;
}
}
}
Ok(())
}
}
#[derive(Serialize, Deserialize, Clone)]
pub enum AnimationTransform {
Translation([f32; 3]),
Rotation([f32;4]),
Scale([f32;3]),
}
#[derive(Clone)]
pub struct AnimationKeyframe{
pub time: f32,
pub transform: AnimationTransform,
}
impl AnimationKeyframe {
pub fn to_serializer(&self) -> AnimationKeyframeSerializer {
AnimationKeyframeSerializer {
time: self.time.clone(),
transform: self.transform.clone()
}
}
pub fn from_serializer(serializer: AnimationKeyframeSerializer) -> Self {
Self {
time: serializer.time,
transform: serializer.transform
}
}
pub fn get_matrix(&self) -> Matrix4<f32> {
match &self.transform {
AnimationTransform::Translation(translation) => {
Matrix4::new_translation(&Vector3::new(translation[0], translation[1], translation[2]))
},
AnimationTransform::Rotation(quaternion) => {
let quat = UnitQuaternion::new_normalize(
Quaternion::new(quaternion[3], quaternion[0], quaternion[1], quaternion[2])
);
quat.to_homogeneous()
},
AnimationTransform::Scale(scale) => {
Matrix4::new_nonuniform_scaling(&Vector3::new(scale[0], scale[1], scale[2]))
}
}
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct AnimationKeyframeSerializer {
pub time: f32,
pub transform: AnimationTransform,
}
#[derive(Clone)]
pub struct AnimationChannel {
pub bone_id: usize,
pub keyframes: Vec<AnimationKeyframe>,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct AnimationState {
pub name: String,
pub time: f32,
pub speed: f32,
pub looping: bool,
}
impl AnimationChannel {
pub fn to_serializer(&self) -> AnimationChannelSerializer {
AnimationChannelSerializer {
bone_id: self.bone_id.clone(),
keyframes: self.keyframes.iter().map(|x| x.to_serializer()).collect()
}
}
pub fn from_serializer(serializer: AnimationChannelSerializer) -> Self {
let mut keyframes = Vec::new();
for s in serializer.keyframes {
let keyframe = AnimationKeyframe::from_serializer(s);
keyframes.push(keyframe);
}
Self {
bone_id: serializer.bone_id,
keyframes
}
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct AnimationChannelSerializer {
pub bone_id: usize,
pub keyframes: Vec<AnimationKeyframeSerializer>,
}
#[derive(Clone)]
pub struct Animation {
pub name: String,
pub duration: f32,
pub channels: Vec<AnimationChannel>,
}
impl Animation {
pub fn to_serializer(&self) -> AnimationSerializer {
AnimationSerializer {
name: self.name.clone(),
duration: self.duration.clone(),
channels: self.channels.iter().map(|x| x.to_serializer()).collect()
}
}
pub fn from_serializer(serializer: AnimationSerializer) -> Self {
let mut channels = Vec::new();
for s in serializer.channels {
let channel = AnimationChannel::from_serializer(s);
channels.push(channel);
}
Self {
name: serializer.name,
duration: serializer.duration,
channels
}
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct AnimationSerializer {
pub name: String,
pub duration: f32,
pub channels: Vec<AnimationChannelSerializer>,
}