diff --git a/src/property.rs b/src/property.rs index 1a0865b..2ed055a 100644 --- a/src/property.rs +++ b/src/property.rs @@ -99,229 +99,3 @@ impl> From for PropertyStore { props } } - -#[cfg(test)] -mod test { - use std::path::Path; - - use crate::node::Node; - use crate::scene::{PostProcess, PostProcessSteps, Scene}; - use crate::sys::{ - AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, - AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, - AI_CONFIG_PP_OG_EXCLUDE_LIST, AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION, - AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, - }; - use crate::{utils, RussimpError, Russult}; - - use super::{Property, PropertyStore}; - - fn load_scene_with_props( - model: &str, - flags: Option, - props: &PropertyStore, - from_buffer: bool, - ) -> Russult { - let model = utils::get_model(model); - let flags = flags.unwrap_or(vec![]); - if from_buffer { - let model_path = Path::new(model.as_str()); - let buffer = std::fs::read(model.as_str()) - .map_err(|_| RussimpError::Import(String::from("Failed to read file")))?; - let file_name = model_path - .file_name() - .and_then(|n| n.to_str()) - .unwrap_or(""); - Scene::from_buffer_with_props(buffer.as_slice(), flags, file_name, props) - } else { - Scene::from_file_with_props(model.as_str(), flags, props) - } - } - - #[test] - fn import_fbx_without_preserving_pivots() { - fn traverse_check_fbx_node(node: &Node) -> bool { - if node.name.ends_with("_$AssimpFbx$_RotationPivot") - || node.name.ends_with("_$AssimpFbx$_RotationOffset") - || node.name.ends_with("_$AssimpFbx$_PreRotation") - || node.name.ends_with("_$AssimpFbx$_PostRotation") - || node.name.ends_with("_$AssimpFbx$_ScalingPivot") - || node.name.ends_with("_$AssimpFbx$_ScalingOffset") - || node.name.ends_with("_$AssimpFbx$_Translation") - || node.name.ends_with("_$AssimpFbx$_Scaling") - || node.name.ends_with("_$AssimpFbx$_Rotation") - { - return false; - } - for child in node.children.borrow().iter() { - if !traverse_check_fbx_node(&*child) { - return false; - } - } - true - } - - let props: PropertyStore = [( - AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS as &[u8], - Property::Integer(0), - )] - .into_iter() - .into(); - let scene = load_scene_with_props("models/FBX/y_bot_run.fbx", None, &props, false).unwrap(); - - // NOTE: A scene with collapsed FBX transforms should not contain - // nodes with names like "_$AssimpFbx$_" - // https://github.com/assimp/assimp/blob/master/code/AssetLib/FBX/FBXImportSettings.h#L141 - if let Some(root) = scene.root { - assert!(traverse_check_fbx_node(&root)); - } - } - - #[test] - fn import_fbx_without_weights() { - let props: PropertyStore = [( - AI_CONFIG_IMPORT_FBX_READ_WEIGHTS as &[u8], - Property::Integer(0), - )] - .into_iter() - .into(); - let scene = load_scene_with_props("models/FBX/y_bot_run.fbx", None, &props, true).unwrap(); - assert_eq!(scene.meshes.len(), 2); - for mesh in &scene.meshes { - for bone in &mesh.bones { - assert_eq!(bone.weights.len(), 0); - } - } - } - - #[test] - fn import_collada_with_ignore_up_direction() { - let props: PropertyStore = [( - AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION as &[u8], - Property::Integer(1), - )] - .into_iter() - .into(); - let scene = - load_scene_with_props("models/COLLADA/blender_cube.dae", None, &props, false).unwrap(); - - // NOTE: Ignoring the COLLADA file's UP direction should yield - // an identity matrix as the root node transformation, meaning - // we are now using blender coordinate system (+Z up instead of +Y up) - if let Some(root) = scene.root { - let is_identity = root.transformation.a1 == 1.0 - && root.transformation.a2 == 0.0 - && root.transformation.a3 == 0.0 - && root.transformation.a4 == 0.0 - && root.transformation.b1 == 0.0 - && root.transformation.b2 == 1.0 - && root.transformation.b3 == 0.0 - && root.transformation.b4 == 0.0 - && root.transformation.c1 == 0.0 - && root.transformation.c2 == 0.0 - && root.transformation.c3 == 1.0 - && root.transformation.c4 == 0.0 - && root.transformation.d1 == 0.0 - && root.transformation.d2 == 0.0 - && root.transformation.d3 == 0.0 - && root.transformation.d4 == 1.0; - assert!(is_identity); - } - } - - #[test] - fn import_collada_with_use_collada_names() { - let props: PropertyStore = [( - AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES as &[u8], - Property::Integer(1), - )] - .into_iter() - .into(); - let scene = - load_scene_with_props("models/COLLADA/blender_cube.dae", None, &props, true).unwrap(); - - // NOTE: Importing a COLLADA file with this option enabled - // should yield the real mesh names like: "Cube.001" - // instead of "Cube_001-mesh" as the importer should use - // the geometry's `name` property instead of `id` - assert_eq!(scene.meshes.len(), 1); - assert_eq!(scene.meshes[0].name, "Cube.001"); - } - - #[test] - fn import_pp_ptv_root_transformation() { - let props: PropertyStore = [ - ( - AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, - Property::Integer(1), - ), - ( - AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION, - Property::Integer(1), - ), - ( - AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, - Property::Matrix([ - [1.0, 0.0, 0.0, 0.0], - [0.0, 0.0, -1.0, 0.0], - [0.0, 1.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 1.0], - ]), - ), - ] - .into_iter() - .into(); - let scene = load_scene_with_props( - "models/COLLADA/blender_plane.dae", - Some(vec![PostProcess::PreTransformVertices]), - &props, - false, - ) - .unwrap(); - - // NOTE: The exported blender plane's normal is facing +Z (ignoring COLLADA up direction) - // If we pre-transform its vertices with the above matrix, - // its normal should be aligned with the Y axis, - // i.e. all the Y coordinates of its vertices should be equal to 0 - assert_eq!(scene.meshes.len(), 1); - for vertex in &scene.meshes[0].vertices { - assert_eq!(vertex.y, 0.0); - } - } - - #[test] - fn import_pp_og_exclude_list() { - fn traverse_find_bone_end(node: &Node) -> bool { - if node.name.as_str() == "Bone_end" { - return true; - } - for child in node.children.borrow().iter() { - if traverse_find_bone_end(&*child) { - return true; - } - } - return false; - } - - let props: PropertyStore = [( - AI_CONFIG_PP_OG_EXCLUDE_LIST as &[u8], - Property::String("Bone_end"), - )] - .into_iter() - .into(); - let scene = load_scene_with_props( - "models/FBX/cube_armature.fbx", - Some(vec![PostProcess::OptimizeGraph]), - &props, - true, - ) - .unwrap(); - - // NOTE: Exported FBX file contains a cube with a single bone. - // The bone's end is also exported and is technically unused, - // but setting this option should preserve it in the hierarchy. - if let Some(root) = &scene.root { - assert!(traverse_find_bone_end(&*root)); - } - } -}