use libc::{c_uint, c_void};
use std::mem;
use std::fmt;
use animation::Animation;
use camera::Camera;
use light::Light;
use material::Material;
use mesh::Mesh;
use texture::Texture;
use types::{Matrix4x4, AiString, MemoryInfo};
use util::{ptr_ptr_to_slice, ptr_to_slice};
use postprocess::Process;
use ffi;
#[repr(C)]
pub struct Node {
pub name: AiString,
pub transformation: Matrix4x4,
parent: *mut Node,
pub num_children: c_uint,
children: *mut*mut Node,
pub num_meshes: c_uint,
meshes: *mut c_uint,
}
impl Node {
pub fn get_parent(&self) -> Option<&Node> {
if self.parent.is_null() {
None
} else {
unsafe {
Some(&*self.parent)
}
}
}
pub fn get_children(&self) -> &[&Node] {
unsafe { ptr_ptr_to_slice(self.children, self.num_children as usize) }
}
pub fn get_meshes(&self) -> &[u32] {
unsafe { ptr_to_slice(self.meshes, self.num_meshes as usize) }
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[repr(C, u32)]
pub enum SceneFlags {
Incomplete = 0x1,
Validated = 0x2,
ValidationWarning = 0x4,
NonVerboseFormat = 0x8,
Terrain = 0x10,
}
#[doc(hidden)]
#[repr(C)]
pub struct RawScene {
pub flags: c_uint,
pub root_node: *mut Node,
pub num_meshes: c_uint,
pub meshes: *mut*mut Mesh,
pub num_materials: c_uint,
pub materials: *mut*mut Material,
pub num_animations: c_uint,
pub animations: *mut*mut Animation,
pub num_textures: c_uint,
pub textures: *mut*mut Texture,
pub num_lights: c_uint,
pub lights: *mut*mut Light,
pub num_cameras: c_uint,
pub cameras: *mut*mut Camera,
pub private: *mut c_void,
}
pub struct Scene<'a> {
raw_scene: &'a RawScene,
pub flags: c_uint,
pub num_meshes: c_uint,
pub num_materials: c_uint,
pub num_animations: c_uint,
pub num_textures: c_uint,
pub num_lights: c_uint,
pub num_cameras: c_uint,
}
impl<'a> Scene<'a> {
#[doc(hidden)]
pub unsafe fn from_raw_scene(raw: *const RawScene) -> Scene<'a> {
let raw = &*raw;
Scene {
raw_scene: raw,
flags: raw.flags,
num_meshes: raw.num_meshes,
num_materials: raw.num_materials,
num_animations: raw.num_animations,
num_textures: raw.num_textures,
num_lights: raw.num_lights,
num_cameras: raw.num_cameras,
}
}
pub fn check_flag(&self, flag: SceneFlags) -> bool {
(self.flags & flag as u32) != 0
}
pub fn get_root_node(&self) -> &Node {
unsafe {
&*(self.raw_scene.root_node)
}
}
pub fn get_animations(&self) -> &[&Animation] {
unsafe { ptr_ptr_to_slice(self.raw_scene.animations,
self.raw_scene.num_animations as usize) }
}
pub fn get_meshes(&self) -> &[&Mesh] {
unsafe { ptr_ptr_to_slice(self.raw_scene.meshes,
self.raw_scene.num_meshes as usize) }
}
pub fn get_lights(&self) -> &[&Light] {
unsafe { ptr_ptr_to_slice(self.raw_scene.lights,
self.raw_scene.num_lights as usize) }
}
pub fn get_cameras(&self) -> &[&Camera] {
unsafe { ptr_ptr_to_slice(self.raw_scene.cameras,
self.raw_scene.num_cameras as usize) }
}
pub fn get_materials(&self) -> &[&Material] {
unsafe { ptr_ptr_to_slice(self.raw_scene.materials,
self.raw_scene.num_materials as usize) }
}
pub fn get_textures(&self) -> &[&Texture] {
unsafe { ptr_ptr_to_slice(self.raw_scene.textures,
self.raw_scene.num_textures as usize) }
}
pub fn get_memory_info(&self) -> MemoryInfo {
unsafe {
let mut mem_info = mem::zeroed();
ffi::aiGetMemoryRequirements(self.raw_scene, &mut mem_info);
mem_info
}
}
pub fn apply_postprocessing(&mut self,
steps: &[Process])
-> Result<(), &str> {
unsafe {
let flags = steps.iter().fold(0, |x, &y| x | y as u32);
let scene = ffi::aiApplyPostProcessing(self.raw_scene,
flags);
if scene.is_null() {
Err("Post processing failed")
} else {
Ok(())
}
}
}
}
impl<'a> fmt::Display for Scene<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Scene {{ \
num_meshes: {}, \
num_materials: {}, \
num_animations: {}, \
num_textures: {}, \
num_lights: {}, \
num_cameras: {} }}",
self.num_meshes,
self.num_materials,
self.num_animations,
self.num_textures,
self.num_lights,
self.num_cameras,)
}
}
impl<'a> Drop for Scene<'a> {
fn drop(&mut self) {
unsafe { ffi::aiReleaseImport(mem::transmute(self.raw_scene)) }
}
}