use libc::{c_double, c_uint};
use std::fmt;
use util::{ptr_ptr_to_slice, ptr_to_slice};
use types::{Vector3D, Quaternion, AiString};
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
pub struct VectorKey {
pub time: c_double,
pub value: Vector3D,
}
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
pub struct QuatKey {
pub time: c_double,
pub value: Quaternion,
}
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
pub struct MeshKey {
pub time: c_double,
pub value: c_uint,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[repr(C)]
pub enum AnimBehaviour {
Default = 0x0,
Constant = 0x1,
Linear = 0x2,
Repeat = 0x3,
}
#[repr(C)]
pub struct NodeAnim {
pub name: AiString,
pub num_position_keys: c_uint,
position_keys: *mut VectorKey,
pub num_rotation_keys: c_uint,
rotation_keys: *mut QuatKey,
pub num_scaling_keys: c_uint,
scaling_keys: *mut VectorKey,
pub pre_state: AnimBehaviour,
pub post_state: AnimBehaviour,
}
impl NodeAnim {
pub fn get_rotation_keys(&self) -> &[QuatKey] {
unsafe { ptr_to_slice(self.rotation_keys, self.num_rotation_keys as usize) }
}
pub fn get_position_keys(&self) -> &[VectorKey] {
unsafe { ptr_to_slice(self.position_keys, self.num_position_keys as usize) }
}
pub fn get_scaling_keys(&self) -> &[VectorKey] {
unsafe { ptr_to_slice(self.scaling_keys, self.num_scaling_keys as usize) }
}
}
#[repr(C)]
pub struct MeshAnim {
pub name: AiString,
pub num_keys: c_uint,
keys: *mut MeshKey,
}
impl MeshAnim {
pub fn get_keys(&self) -> &[MeshKey] {
unsafe { ptr_to_slice(self.keys, self.num_keys as usize) }
}
}
#[repr(C)]
pub struct Animation {
pub name: AiString,
pub duration: c_double,
pub ticks_per_sec: c_double,
pub num_channels: c_uint ,
channels: *mut*mut NodeAnim,
pub num_mesh_channels: c_uint ,
mesh_channels: *mut*mut MeshAnim,
}
impl<'a> Animation {
pub fn get_channels(&self) -> &[&NodeAnim] {
unsafe { ptr_ptr_to_slice(self.channels, self.num_channels as usize) }
}
pub fn get_mesh_channels(&self) -> &[&MeshAnim] {
unsafe { ptr_ptr_to_slice(self.mesh_channels,
self.num_mesh_channels as usize) }
}
pub fn find_node_anim(&'a self, name: &AiString) -> Option<&'a NodeAnim> {
for node in self.get_channels().iter() {
if node.name == *name {
return Some(*node)
}
}
return None
}
pub fn find_mesh_anim(&'a self, name: &AiString) -> Option<&'a MeshAnim> {
for node in self.get_mesh_channels().iter() {
if node.name == *name {
return Some(*node)
}
}
return None
}
}
impl<'a> fmt::Display for Animation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Animation {{ \
name: {}, \
duration: {}, \
ticks_per_sec: {}, \
num_channels: {}, \
num_mesh_channels: {} \
}}",
self.name,
self.duration,
self.ticks_per_sec,
self.num_channels,
self.num_mesh_channels)
}
}