1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
extern crate xml;
extern crate vecmath;

#[macro_use]
extern crate log;

pub use obj::*;
pub use vecmath::Matrix4;

pub mod document;
mod utils;
mod obj;

#[derive(Debug, Clone)]
pub struct Skeleton {
    ///
    /// All joints in the skeleton
    ///
    pub joints: Vec<Joint>,

    ///
    /// Default parent-relative transforms for each joint (at time of vertex binding)
    /// Column-major.
    ///
    pub bind_poses: Vec<Matrix4<f32>>,
}

#[derive(Debug, Clone)]
pub struct Joint {
    ///
    /// Name of joint
    ///
    pub name: String,

    ///
    /// Index of parent joint in Skeleton's 'joints' vector
    ///
    pub parent_index: JointIndex,

    ///
    /// Matrix transforming vertex coordinates from model-space to joint-space
    /// Column-major.
    ///
    pub inverse_bind_pose: Matrix4<f32>,
}

impl Joint {
    pub fn is_root(&self) -> bool {
        self.parent_index == ROOT_JOINT_PARENT_INDEX
    }
}

///
/// A COLLADA animation consists of mapping of sample times to pose transforms
/// for a single node in the scene (usually a skeleton joint)
///
/// Note - COLLADA supports animating arbitrary 'outputs', not just pose transforms,
/// (eg colors, texture offsets, etc), but we'll leave those unsupported for now.
///
#[derive(Debug)]
pub struct Animation {
    ///
    /// The node (joint) this animation is targeting
    ///
    pub target: String,

    ///
    /// Times for each sample (in seconds)
    ///
    pub sample_times: Vec<f32>,

    ///
    /// Node pose transforms for each sample.
    /// Column-major.
    ///
    pub sample_poses: Vec<Matrix4<f32>>,
}

///
/// Skeleton-Mesh Binding Data
///

#[derive(Debug)]
pub struct BindDataSet {
    pub bind_data: Vec<BindData>,
}

#[derive(Debug)]
pub struct BindData {
    pub object_name: String,
    pub skeleton_name: String,
    pub joint_names: Vec<String>,

    /// Vertex weights, for vertex by index in mesh and joint by index in 'joint_names'
    /// and weight by index in 'weights'
    pub vertex_weights: Vec<VertexWeight>,

    /// Weight values that are indexed by VertexWeights
    pub weights: Vec<f32>,

    /// Inverse bind pose matrices listed in order of joint_names
    /// Column-major
    pub inverse_bind_poses: Vec<Matrix4<f32>>,
}

#[derive(Debug, Copy, Clone)]
pub struct VertexWeight {
    pub vertex: VertexIndex,
    pub joint: JointIndex,
    pub weight: WeightIndex,
}

pub type WeightIndex = usize;

pub type JointIndex = u8;
pub const ROOT_JOINT_PARENT_INDEX: JointIndex  = 255u8;